AAC编码

作者: coder_feng | 来源:发表于2021-05-20 21:03 被阅读0次

    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编解码器

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

    移除原因

    - 支持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编码

        本文链接:https://www.haomeiwen.com/subject/rtmejltx.html