AAC编码

AAC概述

AAC是高级音频编码(Advanced Audio Coding)的缩写,出现于1997年,最初是基于MPEG-2的音频编码技术。由Fraunhofer IIS、Dolby Laboratories、AT&T、Sony等公司共同开发,目的是取代MP3格式。2000年,MPEG-4标准出台,AAC重新集成了其它技术(PS,SBR),为区别于传统的MPEG-2 AAC,故含有SBR或PS特性的AAC又称为MPEG-4 AAC。

AAC是新一代的音频有损压缩技术,它通过一些附加的编码技术(比如PS,SBR等),衍生出了LC-AAC,HE-AAC,HE-AACv2三种主要的编码,LC-AAC就是比较传统的AAC,相对而言,主要用于中高码率(>=80Kbps),HE-AAC(相当于AAC+SBR)主要用于中低码(<=80Kbps),而新近推出的HE-AACv2(相当于AAC+SBR+PS)主要用于低码率(<=48Kbps),事实上大部分编码器设成<=48Kbps自动启用PS技术,而>48Kbps就不加PS,就相当于普通的HE-AAC。

AAC特点

  • AAC是一种高压缩比的音频压缩算法,但它的压缩比要远超过较老的音频压缩算法,如AC-3、MP3等。并且其质量可以同未压缩的CD音质相媲美
  • AAC也是采用了变换编码算法,但AAC使用了分辨率更高的滤波器组,因此它可以达到更高的压缩比
  • AAC使用了临时噪声重整、后向自适应线性预测、联合立体声技术和量化哈夫曼编码等最新技术,这些新技术的使用都使压缩比得到进一步的提高
  • AAC支持更多种采样率和比特率、支持1个到48个音轨、支持多达15个低频音轨、具有多种语言的兼容能力、还有多达15个内嵌数据流
  • AAC支持更宽的声音频率范围,最高可达到96kHz,最低可达8KHz,远宽于MP3的16KHz-48kHz的范围
  • 不同于MP3及WMA,AAC几乎不损失声音频率中的甚高、甚低频率成分,并且比WMA在频谱结构上更接近于原始音频,因而声音的保真度更好

ACC的规格

  • MPEG-2 AAC LC:低复杂度规格(Low Complexity)
  • MPEG-2 AAC Main:主规格
  • MPEG-2 AAC SSR:可变采样率规格(Scaleable Sample Rate)
  • MPEG-4 AAC LC:低复杂度规格(Low Complexity)
  • MPEG-4 AAC Main:主规格
  • MPEG-4 AAC SSR:可变采样率规格(Scaleable Sample Rate)
  • MPEG-4 AAC LTP:长时期预测规格(Long Term Predicition)
  • MPEG-4 AAC LD:低延迟规格(Low Delay)
  • MPEG-4 AAC HE:高效率规格(High Efficiency)

LC到HE发展历程图

AAC发展历程图.png

LC 适合中等比特率,比如96kbps ~ 192kbps之间
从图中可以了解到MPEG-4 AAC LC 相当于MPEG-2 AAC LC + PNS(PNS 可以提高AAC的编码效率)

PNS(Perceptual Noise Substitution)

HE 存在v1和v2 两个版本,适合低比特率
v1:适合48kbps ~ 64kbps
v2:适合低于32kbps,可在低至32kbps的比特率下提供接近CD品质的声音
MPEG-4 AAC HE v1 相当于MPEG-4 AAC LC + SBR(是一种增强的压缩技术、可以将高频信号存储在少量的SBR data中、解码器可以根据SBR data恢复出高频信号)
MPEG-4 AAC HE v2 相当于MPEG-4 AAC HE v1 + PS(是一种有损的音频压缩算法,可以进一步提高压缩率、以将左右声道信号组合成单声道信号,声道之间的差异信息存储到少量的PS data中(大概占2 ~ 3kbps)、解码器可以根据PS data中恢复出立体声信号)

SBR Spectral Band Replication
PS(Parametric Stereo)

PS.png

AAC音频文件格式

首先需要了解的是AAC文件格式有ADIF和ADTS两种

  • ADIF:Audio Data Interchange Format 音频数据交换格式。这种格式的特征是可以确定的找到这个音频数据的开始,不需进行在音频数据流中间开始的解码,即它的解码必须在明确定义的开始处进行。故这种格式常用在磁盘文件中。
  • ADTS:Audio Data Transport Stream 音频数据传输流。这种格式的特征是它是一个有同步字的比特流,解码可以在这个流中任何位置开始。它的特征类似于mp3数据流格式。
    简单说,ADTS可以在任意帧解码,也就是说它每一帧都有头信息。ADIF只有一个统一的头,所以必须得到所有的数据后解码。且这两种的header的格式也是不同的,目前一般编码后的和抽取出的都是ADTS格式的音频,。
    目前主流使用的都是ADTS格式,所以这里只介绍ADTS ACC文件格式
    AAC音频文件的每一帧都由一个ADTS头和AAC ES(AAC音频数据)组成。
    AAC ADTS.png

ADTS头包含了AAC文件的采样率、通道数、帧数据长度等信息。ADTS头分为固定头信息和可变头信息两个部分,固定头信息在每个帧中的是一样的,可变头信息在各个帧中并不是固定值。ADTS头一般是7个字节((28+28)/ 8)长度,如果需要对数据进行CRC校验,则会有2个Byte的校验码,所以ADTS头的实际长度是7个字节或9个字节

固定头部信息:adts_fixed_header

   /* adts_fixed_header */
    put_bits(&pb, 12, 0xfff);   /* syncword */
    put_bits(&pb, 1, 0);        /* ID */
    put_bits(&pb, 2, 0);        /* layer */
    put_bits(&pb, 1, 1);        /* protection_absent */
    put_bits(&pb, 2, ctx->objecttype); /* profile_objecttype */
    put_bits(&pb, 4, ctx->sample_rate_index);
    put_bits(&pb, 1, 0);        /* private_bit */
    put_bits(&pb, 3, ctx->channel_conf); /* channel_configuration */
    put_bits(&pb, 1, 0);        /* original_copy */
    put_bits(&pb, 1, 0);        /* home */
  • syncword:帧同步标识一个帧的开始,固定为0xFFF
  • ID:MPEG 标示符。0表示MPEG-4,1表示MPEG-2
  • layer:固定为’00’
  • protection_absent:标识是否进行误码校验。0表示有CRC校验,1表示没有CRC校验
  • profile:标识使用哪个级别的AAC。1: AAC Main 2:AAC LC (Low Complexity) 3:AAC SSR (Scalable Sample Rate) 4:AAC LTP (Long Term Prediction)
  • sampling_frequency_index:标识使用的采样率的下标
  • private_bit:私有位,编码时设置为0,解码时忽略
  • channel_configuration:标识声道数
  • original_copy:编码时设置为0,解码时忽略
  • home:编码时设置为0,解码时忽略

sampling_frequency_index

index Hz
0 96000 Hz
1 88200 Hz
2 64000 Hz
3 48000 Hz
4 44100 Hz
5 32000 Hz
6 24000 Hz
7 22050 Hz
8 16000 Hz
9 12000 Hz
10 11025 Hz
11 8000 Hz
12 7350 Hz
13 Reserved
14 Reserved
15 frequency is written explictly

profile

PROFILE SAMPLES
HE-AAC v1/v2 2048
AAC-LC 1024
AAC-LD/AAC-ELD 480/512

Channel Configuration

  • 0: Defined in AOT Specifc Config
  • 1: 1 channel: front-center
  • 2: 2 channels: front-left, front-right
  • 3: 3 channels: front-center, front-left, front-right
  • 4: 4 channels: front-center, front-left, front-right, back-center
  • 5: 5 channels: front-center, front-left, front-right, back-left, back-right
  • 6: 6 channels: front-center, front-left, front-right, back-left, back-right, LFE-channel
  • 7: 8 channels: front-center, front-left, front-right, side-left, side-right, back-left, back-right, LFE-channel
  • 8-15: Reserved

可变头信息:adts_variable_header()

  /* adts_variable_header */
    put_bits(&pb, 1, 0);        /* copyright_identification_bit */
    put_bits(&pb, 1, 0);        /* copyright_identification_start */
    put_bits(&pb, 13, full_frame_size); /* aac_frame_length */
    put_bits(&pb, 11, 0x7ff);   /* adts_buffer_fullness */
    put_bits(&pb, 2, 0);        /* number_of_raw_data_blocks_in_frame */
  • copyrighted_id_bit:编码时设置为0,解码时忽略
  • copyrighted_id_start:编码时设置为0,解码时忽略
  • aac_frame_length:ADTS帧长度包括ADTS长度和AAC声音数据长度的和。即 aac_frame_length = (protection_absent == 0 ? 9 : 7) + audio_data_length
  • adts_buffer_fullness:固定为0x7FF。表示是码率可变的码流
  • number_of_raw_data_blocks_in_frame:表示当前帧有- number_of_raw_data_blocks_in_frame + 1 个原始帧(一个AAC原始帧包含一段时间内1024个采样及相关数据)。

AAC编解码器

之前说到个音频的一些文件格式,包括WAV,AAC等,如果现在想对PCM数据进行ACC编码压缩的话,我们需要用到ACC编码器,相反如果想对ACC编码后的数据解压出PCM数据,那么久需要用到ACC解码器;

集中常用的ACC编解码器

  • Nero AAC
支持LC/HE 规格,目前已经停止维护
  • FFmpeg AAC
FFmpeg 官方内置的AAC编解码器,在libavcodec
库中,编解码器名字叫做aac
  • FAAC(Freeware Advanced Audio Coder)
- 支持LC规格
- 可以集成到FFmpeg的libavcodec 中,编解码器名字叫做libfaac,2016年后ffmpeg已经移除了对FAAC的支持

移除原因

  • Fraunhofer FDK AAC
- 支持LC/HE规格
- 目前质量最高AAC编解码器https://trac.ffmpeg.org/wiki/Encode/AAC

FDK AAC的学习

mac下通过brew 安装的FFmpeg通常是没有集成libfdk_aac的,这个可以在终端通过命令行下检查

 songlin@feng-sl  /usr/local/Cellar/ffmpeg/4.3.2_4/bin   master ±  ./ffmpeg -codecs | grep aac
ffmpeg version 4.3.2 Copyright (c) 2000-2021 the FFmpeg developers
  built with Apple clang version 12.0.0 (clang-1200.0.32.29)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.3.2_4 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
 DEAIL. aac                  AAC (Advanced Audio Coding) (decoders: aac aac_fixed aac_at ) (encoders: aac aac_at )
 D.AIL. aac_latm             AAC LATM (Advanced Audio Coding LATM syntax)

从终端的输出结果中,可以发现是没有libfdk_aac的,所以我们需要手动编译FFmpeg源码,让编译后的ffmpeg集成我们需要的功能,至于如何手动编译FFmpeg,可以参考这篇文章

你可能感兴趣的:(AAC编码)