下载Nero StartSmart,实现快速简单的CD DVD刻录
一、AAC ADTS格式分析
1.ADTS是个啥
ADTS全称是(Audio Data Transport Stream),是AAC的一种十分常见的传输格式。
记得第一次做demux的时候,把AAC音频的ES流从FLV封装格式中抽出来送给硬件解码器时,不能播;保存到本地用pc的播放器播时,我靠也不能播。当时崩溃了,后来通过查找资料才知道。一般的AAC解码器都需要把AAC的ES流打包成ADTS的格式,一般是在AAC ES流前添加7个字节的ADTS header。也就是说你可以吧ADTS这个头看作是AAC的frameheader。
2.ADTS内容及结构
ADTS 头中相对有用的信息 采样率、声道数、帧长度。想想也是,我要是解码器的话,你给我一堆得AAC音频ES流我也解不出来。每一个带ADTS头信息的AAC流会清晰的告送解码器他需要的这些信息。
一般情况下ADTS的头信息都是7个字节,分为2部分:
adts_fixed_header();
adts_variable_header();
syncword :同步头 总是0xFFF, all bits must be 1,代表着一个ADTS帧的开始
ID:MPEG Version: 0 for MPEG-4, 1 for MPEG-2
Layer:always: ’00’
profile:表示使用哪个级别的AAC,有些芯片只支持AAC LC 。在MPEG-2 AAC中定义了3种:
sampling_frequency_index:表示使用的采样率下标,通过这个下标在 Sampling Frequencies[ ]数组中查找得知采样率的值。
There are 13 supported frequencies:
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
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
frame_length : 一个ADTS帧的长度包括ADTS头和AAC原始流.
adts_buffer_fullness:0x7FF 说明是码率可变的码流
3.将AAC打包成ADTS格式
如果是通过嵌入式高清解码芯片做产品的话,一般情况的解码工作都是由硬件来完成的。所以大部分的工作是把AAC原始流打包成ADTS的格式,然后丢给硬件就行了。
通过对ADTS格式的了解,很容易就能把AAC打包成ADTS。我们只需得到封装格式里面关于音频采样率、声道数、元数据长度、aac格式类型等信息。然后在每个AAC原始流前面加上个ADTS头就OK了。
贴上ffmpeg中添加ADTS头的代码,就可以很清晰的了解ADTS头的结构:
int ff_adts_write_frame_header(ADTSContext *ctx,
uint8_t *buf, int size, int pce_size)
{
PutBitContext pb;
init_put_bits(&pb, buf, ADTS_HEADER_SIZE);
/* 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 */
/* adts_variable_header */
put_bits(&pb, 1, 0); /* copyright_identification_bit */
put_bits(&pb, 1, 0); /* copyright_identification_start */
put_bits(&pb, 13, ADTS_HEADER_SIZE + size + pce_size); /* aac_frame_length */
put_bits(&pb, 11, 0x7ff); /* adts_buffer_fullness */
put_bits(&pb, 2, 0); /* number_of_raw_data_blocks_in_frame */
flush_put_bits(&pb);
return 0;
}
二、AAC文件格式与解码流程
1.文件格式
1.1 概述及分类
AAC“Advanced Audio Coding”的缩写,中文称为“高级音频编码”,被手机界称为“21世纪数据压缩方式”,AAC所采用的运算方式是与MP3的运算有所不同,AAC同时可以支持多达48个音轨,15个低频音轨,更多种取样率和比特率与及有多种言语的兼容能力,更高的译码效率,总括来说,AAC可以在对比MP3文件缩小30%的前题下提供更好的音质。
AAC帧与帧之间编码完全独立,所以其广泛运用于流媒体。
由于对AAC有重要贡献的公司比较多,如Fraunhofer,Dolby, Sony和AT&T,导致AAC子格式多,很容易搞混。
他们是共分为9种规格,以适应不同场合的需要:
a. MPEG-2 AAC LC 低复杂度规格 (Low Complexity)
b. MPEG-2 AAC Main 主规格
c. MPEG-2 AAC SSR 可变取样率规格 (Scaleable Sample Rate)
d. MPEG-4 AAC LC 低复杂度规格(Low Complexity),现在的手机比较常见的MP4文件中的音频部份就包括了该规格音频文件
e. MPEG-4 AAC Main 主规格
f. MPEG-4 AAC SSR 可变取样率规格 (Scaleable Sample Rate)
g. MPEG-4 AAC LTP 长时期预测规格(Long Term Predicition)
h. MPEG-4 AAC LD 低延迟规格(Low Delay)
i. MPEG-4 AAC HE 高效率规格(High Efficiency)(即AAC+,含SBR)
上述的规格中,主规格“Main”包含了除增益控制之外的全部功能,其音质是最好,而低复杂度规格则是比较简单,没有了增益控制,但提高了编码效率,至“SSR”对“LC”规格大体是相同,但是多了增益的控制功能,另外,MPEG- 4/AAC/LTP/LD/HE,都是用在低码率下编码,特别是“HE”是有Nero ACC编码器支持,是近来多用的一种编码率种,不过通常来说,Main规格和LC规格的音质相差是不大。
以上规格的划分是比较官方的分发,wiki上也是如此划分。事实上MPEG-4与MPEG-2 AAC流除了在文件头(header)上并没有什么区别。只是一些应用软件象QuickTime并不承认MPEG-2 AAC。Real的解码程序中,并未对这2种进行区分。
所以从编解码来看,按如下划分更清晰:
a. LC profile:最简单的profile,苹果iTune使用这种格式(iTune也使用Apple LosslessAAC ,不过似乎没有划分到AAC家族中,一个文件通常上20M)。
b. MAIN profile: LC profile + 后向预测(backwards prediction)
c. SRS: sample-rate scalability,submitted by Sony and reportedly
d. LTP:long term prediction, main profile + forward prediction
e. HE-AAC: high efficiency AAC,又叫aacPlus,使用SBR,可能使用PS.AAC + SBR(Spectral Band Replication)aacPlusv1, AAC + SBR + PS(Parametric Stereo)aacPlus v2. 如图所示:
其中,aacPlus v1已被运动图像专家组MPEG指定为其标准MPEG-4 HE AAC.
1.2 AAC的编码器
a. FhG Fraunhofer IIS研发的权威编码器,拥有很好的音质,不对外开放。
b. Nero AAC可能是目前最完美的AAC编码器了,同时支持”LC AAC/HE AAC”规格,Nero AAC编码器提供了品质最好的”VBR LC AAC”格式,同时亦对面”HE AAC”规格保证了在低码率下也有良好的表现,千千静听 + Nero插件,就可以编码AAC文件了,我当初就这么做测试向量的,哈哈。
c. QuickTime/iTune Apple公司的两款Media软件都提供了AAC编码功能,其编码技术来自“DolbyLaboratories”,是目前音质最好的中码编率编码器,它编码的48kbps立体声音质比其它AAC编码器好20 – 25%,甚至64 kbps的Dolby AAC音效可媲美128 kbps的MP3。
d. FAAC:免费,开源,郑重推荐。
1.3 文件后缀名
用aac编码的文件可能使用这三种后缀名:aac,m4a,mp4.
AAC:以aac为后缀的文件无文件头,由一些列的帧组成文件,帧头分ADIF和ADTS两种。
M4A:用MP4作为container,这种MP4文件里面只有音频帧,无视频帧。由MP4文件头+一系列的帧组成,帧头比AAC为后缀的文件要短。所以在保持压缩数据不变的情况下,将AAC转为M4A,文件会小一些,因为每帧省几个字节,合起来省下的字节数通常比MP4文件头还大。
MP4:可以同时有视频帧和音频帧,也可以只有音频或视频帧。
注:在下面的1.5节中,会详细说一下AAC为后缀的文件格式,MP4 container的格式可以参照我的另一篇文章,MPEG4-Part14 — MP4 file format。
1.4 编码工具推荐
FAAC 和 千千静听+nero插件
1.5 File format specification–以aac为后缀名的文件格式
AAC没有文件头,由帧序列组成。一共有2种格式的帧头,ADTS和ADIF。
一个文件中通常不会2种帧共存,并且大多数AAC文件包含的帧为 ADTS。
ADIF:Audio Data Interchange Format 音频数据交换格式。这种格式的特征是可以确定的找到这个音频数据的开始,不需进行在音频数据流中间开始的解码,即它的解码必须在明确定义的开始处进行。故这种格式常用在磁盘文件中。
ADTS:Audio Data Transport Stream 音频数据传输流。这种格式的特征是它是一个有同步字的比特流,解码可以在这个流中任何位置开始。
//以下对文件格式说明使用的表格来自ISO-IEC-13818-7
1.5.1 ADIF
ADIF的帧序列按如下方式组成一个文件:
[url=]Table
[/url]2– Syntax of adif_sequence()
Syntax
No. of bits
Mnemonic
adif_sequence()
{
adif_header();
byte_alignment();
raw_data_stream();
}
其中Header结构如下:
[url=]Table
[/url]3 – Syntax of adif_header()
Syntax
No. of bits
Mnemonic
adif_header()
{
adif_id;
32
bslbf
copyright_id_present;
1
bslbf
if (copyright_id_present) {
copyright_id;
72
bslbf
}
original_copy;
1
bslbf
home;
1
bslbf
bitstream_type;
1
bslbf
bitrate;
23
uimsbf
num_program_config_elements;
4
bslbf
if (bitstream_type == ‘0’) {
adif_buffer_fullness;
20
uimsbf
}
for (i = 0; i < num_program_config_elements + 1; i++) {program_config_element();}}1.5.2 ADTSADTS文件有帧序列组成,如下表所示:[url=]Table[/url]4 – Syntax of adts_sequence()
Syntax
No. of bits
Mnemonic
adts_sequence()
{
while (nextbits() == syncword) {
adts_frame();
}
}
每帧除去最前面的同步字后,结构如下:
[url=]Table
[/url]5 – Syntax of adts_frame()
Syntax
No. of bits
Mnemonic
adts_frame()
{
adts_fixed_header();
adts_variable_header();
if (number_of_raw_data_blocks_in_frame == 0) {
adts_error_check();
raw_data_block();
}
else {
adts_header_error_check();
for (i = 0; i <= number_of_raw_data_blocks_in_frame; i++) {raw_data_block();adts_raw_data_block_error_check();}}}其中,ADTS头分两部分,固定头和可变头,固定头每帧一样,可变头帧与帧可以不同。[url=]Table[/url]8 – Syntax of adts_fixed_header()
Syntax
No. of bits
Mnemonic
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
}
[url=]Table
[/url]9 – Syntax of adts_variable_header()
Syntax
No. of bits
Mnemonic
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
}
如发现本站有涉嫌抄袭侵权/违法违规等内容,请<举报!一经查实,本站将立刻删除。