当前位置: 代码迷 >> 综合 >> aac mpeg2-adts header 分析
  详细解决方案

aac mpeg2-adts header 分析

热度:45   发布时间:2024-01-16 14:32:37.0

参考文档 ISO/IEC 13818-7

简述了adts,由mpeg2标准中产生,后mpeg4也采纳并修订,是Audio Data Transport Stream的英文缩写.
结构其实非常简单,7个字节的header,然后是数据,然后有是7字节header,然后是数据,,,,
重点在header,数据是encoder层级的,暂时不关注.
header包括两部分,先是Fixed Header,然后是Variable Header.
援引标准文档
Table 8 – Syntax of adts_fixed_header() 
adts_fixed_header()   
{   
 syncword;  12 bslbf 
 ID;  1 bslbf 
 layer;  2 uimsbf 
 protection_absent;  1 bslbf 
 profile;  2  uimsbf 
 sampling_frequency_index;  4 uimsbf 
 private_bit;  1 bslbf 
 channel_configuration;  3 uimsbf 
 original/copy;  1 bslbf 
 home;  1  bslbf 
}

Table 9 – Syntax of adts_variable_header() 
adts_variable_header()   
{   
 copyright_identification_bit;  1 bslbf 
 copyright_identification_start;  1  bslbf 
 frame_length;   13  bslbf 
 adts_buffer_fullness;  11  bslbf 
 number_of_raw_data_blocks_in_frame;  2  uimsfb 
}

可以看到,两部分各28比特位,共56比特位,7字节.

如何填充一个header结构?
先看Fixed部分

首两个字节一般都是1111 1111 1111 0001,如果音频数据包含crc校验信息,最后一位就是0(看文档是这样的,但没有实作).
对应关系如下:
syncword 1111 1111 1111
ID 0
layer 00
protection_absent 1

ID比较奇怪,标准文档中是这么说的"MPEG identifier, set to ‘1’. See ISO/IEC 11172-3",但我写0了,也可以.

然后接下来的一个半字节,

如下:
profile 两位,见下表
sampling_frequency_index 四位,见下表

private_bit 0
channel_configuration  三位,见下表,立体声为2,即010
original_copy 0
home 0

这部分标志位需要解释一下
援引标准文档

profile
Table 31 – Profiles
 0  Main profile 
 1  Low Complexity profile (LC) 
 2  Scalable Sampling Rate profile (SSR)
 3  (reserved) 

sampling_frequency_index 
Table 35 – Sampling frequency dependent on sampling_frequency_index
sampling_frequency_index  sampling frequeny [Hz] 
0x0                       96000 
0x1                       88200 
0x2                       64000 
0x3                       48000 
0x4                       44100 
0x5                       32000 
0x6                       24000 
0x7                       22050 
0x8                       16000 
0x9                       12000 
0xa                       11025 
0xb                       8000 
0xc                       reserved 
0xd                       reserved 
0xe                       reserved 
0xf                       reserved 

channel_configuration  
indicates the channel configuration used. If 
channel_configuration is greater than 0, the 
channel configuration is given by the ‘Default
bitstream index number’ in Table 42, see 
subclause 8.5. If channel_configuration equals 0, 
the channel configuration is not specified in the 
header and must be given by a 
program_config_element() following as first 
syntactic element in the first raw_data_block() afte
the header, or by the implicit configuration (see 
subclause 8.5) or must be known in the application
(Table 8). 

再看Variable部分
前两位,一般都是00
copyright_identification_bit 0
copyright_identification_start 0

数值,等于数据包大小加上7--header的大小.其实就是第二个adts chunck的起始地址.
frame_length 00 0001 1000 000

全是1,即0x7FF
adts_buffer_fullness 1 1111 1111 11

一般为00
number_of_raw_data_blocks_in_frame 00

总结,比特位映像如下:

1111 
1111 
1111 
0 00 1 
xx xx-
xx 0 x-
x x 0 0
0 0 xx-
xxxx
xxxx
xxx 1-
1111
1111-
11 00


 示例,32000采样,双声道,16000比特率

....

uint64_t adts_hdr = 0x00fff16080001ffcLL;

unsigned char* hdr_ptr = (unsigned char*)&adts_hdr;

uint64_t lleenn = (aaclen+7);

lleenn = (lleenn << 13);

lleenn = lleenn & 0x000000000fffe000LL;

adts_hdr |= lleenn;

fwrite(hdr_ptr+6, 1, 1, etv_file);
fwrite(hdr_ptr+5, 1, 1, etv_file);
fwrite(hdr_ptr+4, 1, 1, etv_file);
fwrite(hdr_ptr+3, 1, 1, etv_file);
fwrite(hdr_ptr+2, 1, 1, etv_file);
fwrite(hdr_ptr+1, 1, 1, etv_file);
fwrite(hdr_ptr+0, 1, 1, etv_file);
fwrite(aacout, 1, aaclen, etv_file);

gcc 4.3 + mingw验证通过

end

  相关解决方案