• AAC 音频数据结构实例分析:


    AAC 音频数据结构实例分析:

    AAC 有两种数据交换格式:ADTS 和 ADIF
    ADIF: Audio Data Interchange Format, 一个文件只有一个头,可类比dvd中使用的ps流。
    ADTS:Audio Data Transport Stream, 每个frame中都有这个同步头, 可类比dvb中的ts流.
    本博客只介绍 ADTS 格式AAC
    基本构成是7bytes 头部+原始数据. 循环重复

    一、AAC文件头信息
    ADTS的头信息分为:固定头信息(adts_fixed_header,28bits)和可变头信息(adts_variable_header,28bits)两部分。
    下面是iso13818-7 的说明.

    固定头:
    syncword :同步头代表着1个ADTS帧的开始,所有bit置1,即 0xFFF
    ID:MPEG标识符,0标识MPEG-4,1标识MPEG-2
    Layer: 直接置00,解码时忽略这个参数
    protection_absent:表示是否误码校验。1 no CRC , 0 has CRC
    profile:AAC 编码级别, 0: Main Profile, 1:LC(最常用), 2: SSR, 3: reserved.
    sampling_frequency_index:采样率标识,重要!
    Private bit:直接置0,解码时忽略这个参数
    channel_configuration: 声道数标识,重要!
    original_copy: 直接置0,解码时忽略这个参数
    home:直接置0,解码时忽略这个参数

    重点关注:
    1. sample_freq_index    : 4代表44100hz
    2. channel_configuration: 2表示双声道
    3. frame_length : 13bits

    可变头:
    copyright_identification_bit: 直接置0,解码时忽略这个参数
    copyright_identification_start: 直接置0,解码时忽略这个参数
    aac_frame_lenght: 当前音频帧的字节数. 重要!
    adts_buffer_fullness: 当设置为0x7FF时表示时可变码率
    number_of_raw_data_blocks_in_frames: 当前音频包里面包含的音频编码帧数,为0代表1frame.

    重点关注:
    1. sample_freq_index    : 4代表44100hz
    2. channel_configuration: 2表示双声道
    3. frame_length : 13bits

    二 . AAC 数据实例

    数据分析都在图片里了.

    贴上采样表及channel配置表
    采样率表
    const int avpriv_mpeg4audio_sample_rates[16] = {
        96000, 88200, 64000, 48000, 44100, 32000,
        24000, 22050, 16000, 12000, 11025, 8000, 7350
    };

    通道配置表
    const uint8_t ff_mpeg4audio_channels[14] = {
        0,
        1, // mono (1/0)
        2, // stereo (2/0)
        3, // 3/0
        4, // 3/1
        5, // 3/2
        6, // 3/2.1
        8, // 5/2.1
        0,
        0,
        0,
        7, // 3/3.1
        8, // 3/2/2.1
        24 // 3/3/3 - 5/2/3 - 3/0/0.2
    };


    另外,frame 个数number_of_raw_block(用0表示)总是1,raw_data_in_frame总是1024

    记录一次调试堆栈,望文生义可以看看函数名称及参数.真正搞懂要调试代码!

    (gdb) bt parse 出一个frame 的调用栈
      #0  ff_adts_header_parse (gbc=0x7fffffff8ad0, hdr=0x7fffffff8ab0) at libavcodec/adts_header.c:38
      #1  0x00007ffff6783069 in aac_sync (state=72050243209011196, hdr_info=0x555555573240, need_next_header=0x5555555732a8, new_frame_start=0x7fffffff8b88) at libavcodec/aac_parser.c:45
      #2  0x00007ffff678162e in ff_aac_ac3_parse (s1=0x555555573040, avctx=0x555555559040, poutbuf=0x555555573318, poutbuf_size=0x555555573320, buf=0x7fffffff8d10 "\377\371P\200t\037\374!\020\005 \244\033\377\300", buf_size=20480) at libavcodec/aac_ac3_parser.c:52
      #3  0x00007ffff6f27cc7 in av_parser_parse2 (s=0x555555573040, avctx=0x555555559040, poutbuf=0x555555573318, poutbuf_size=0x555555573320, buf=0x7fffffff8d10 "\377\371P\200t\037\374!\020\005 \244\033\377\300", buf_size=20480, pts=-9223372036854775808, dts=-9223372036854775808, pos=0) at libavcodec/parser.c:169
      #4  0x0000555555555b13 in main (argc=3, argv=0x7fffffffde58) at decode_audio.c:186


    (gdb) bt decode_frame 的调用栈
      #0  ff_adts_header_parse (gbc=0x7fffffff8a90, hdr=0x7fffffff8780) at libavcodec/adts_header.c:38
      #1  0x00007ffff67a4078 in parse_adts_frame_header (ac=0x555555559480, gb=0x7fffffff8a90) at libavcodec/aacdec_template.c:3091
      #2  0x00007ffff67a47e8 in aac_decode_frame_int (avctx=0x555555559040, data=0x55555555bac0, got_frame_ptr=0x7fffffff8af8, gb=0x7fffffff8a90, avpkt=0x55555555c080) at libavcodec/aacdec_template.c:3234
      #3  0x00007ffff67a53ad in aac_decode_frame (avctx=0x555555559040, data=0x55555555bac0, got_frame_ptr=0x7fffffff8af8, avpkt=0x55555555c080) at libavcodec/aacdec_template.c:3480
      #4  0x00007ffff699cd56 in decode_simple_internal (avctx=0x555555559040, frame=0x55555555bac0, discarded_samples=0x7fffffff8bb0) at libavcodec/decode.c:327
      #5  0x00007ffff699da08 in decode_simple_receive_frame (avctx=0x555555559040, frame=0x55555555bac0) at libavcodec/decode.c:526
      #6  0x00007ffff699db0c in decode_receive_frame_internal (avctx=0x555555559040, frame=0x55555555bac0) at libavcodec/decode.c:546
      #7  0x00007ffff699dd97 in avcodec_send_packet (avctx=0x555555559040, avpkt=0x555555573300) at libavcodec/decode.c:608
      #8  0x0000555555555635 in decode (dec_ctx=0x555555559040, pkt=0x555555573300, frame=0x555555573400, outfile=0x555555573ab0) at decode_audio.c:81
      #9  0x0000555555555ba3 in main (argc=3, argv=0x7fffffffde58) at decode_audio.c:197

    参考:libavcodec/adts_header.c
    参考:libavcodec/aac_parser.c
    参考:libavcodec/decode.c
    参考:iso-iec-13818-7

  • 相关阅读:
    【Leetcode】13. 罗马数字转整数
    指令系统、流水线
    万界星空科技电子制造业MES系统解决方案
    元素定位不到的 9 种情况
    mfc140u.dll丢失的详细解决方法,最详细修复mfc140u.dll丢失的办法分享
    Ventory制作多系统启动u盘 和 安装 windows10+ubuntu双系统
    JS中数据类型
    gcc和g++区别
    【手把手带你刷好题】Java刷题记录 09—>>14
    星火模型(Spark)的langchain 实现
  • 原文地址:https://blog.csdn.net/hejinjing_tom_com/article/details/127558649