JCHub

  • Home
  • Category
    • A/V
    • WebRTC
    • Beauty of Programming
    • Linux
    • Windows
    • Moments of Life
    • Campus Life
  • Reference
    • API Reference
    • Utilities
    • AV Test
    • Doc
  • Message Board
  • About
JCHub
Code as My Sword, Lost in Obsession
  1. Main page
  2. A/V
  3. Main content

flv文件adts头计算

2016年4月29日 3280hotness 3likes 0comments

常见flv文件封装的音频用的都是aac编码,aac文件有两种格式,一个是AIDS,一个是ADTS(Audio Data Transport Stream 音频数据传输流)。其中ADTS格式用于流式传输,因为每一帧都包含头信息,可以从任一帧开始解码,故用于流式传输。本文主要讲下flv文件中的adts。

adts的头部结构

adts头部大小7个字节或者9个字节(决定于是否包含CRC)。结构定义如下图所示:
adts结构

MPEG-4 Audio Object Type

  • 0: Null
  • 1: AAC Main
  • 2: AAC LC (Low Complexity)
  • 3: AAC SSR (Scalable Sample Rate)
  • 4: AAC LTP (Long Term Prediction)
  • 5: SBR (Spectral Band Replication)
  • 6: AAC Scalable
  • 7: TwinVQ
  • 8: CELP (Code Excited Linear Prediction)
  • 9: HXVC (Harmonic Vector eXcitation Coding)
  • 10: Reserved
  • 11: Reserved
  • 12: TTSI (Text-To-Speech Interface)
  • 13: Main Synthesis
  • 14: Wavetable Synthesis
  • 15: General MIDI

······

MPEG-4 Sampling Frequency Index

  • 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

MPEG-4 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

flv文件获取AudioSpecificConfig

在flv文件中,上述Audio Object Type,Channel Configrartion等信息存储在AudioSpecificConfig结构中,该AudioSpecificConfig结构一般存储在第一个Audio Tag数据中。在ISO 14496-3中AudioSpecificConfig结构按如下定义:
audiospecificconfig
也就是:

1
2
3
4
5
6
5 bits: audio object type
4 bits: sampling frequency index
if (frequency index == 15)
    24 bits: frequency index
4 bits: channel configuration
other bits: audio object type specific config

如下图所示,我们打开一个音频为aac编码的flv视频文件(本文讨论的都是aac编码的),红色框处是tag data部分数据:
audio_tag_data

由flv标准文档AudioData定义可知,Audio Tag data部分第一个字节(0xAF)结构如下:
audio_tag_data

接着一个字节为AACPacketType(0x00):
auido_tag_data

第一个Audio Tag只包含头信息,不包含具体音频数据,所以AACPacketType值为0。Audio Tag data剩余的才是真正adts帧数据,也就是要把Audio Tag data除去前两个字节。到这里,我们得到了AudioSpecificConfig数据为:0x13 0x88 0x56 0xE5 0xA5 0x48 0x80。在程序中我们先构造一个字符数组,用于存储该数据:

C++
1
char szAudioSpecificConfig[64] = {0};

从flv文件中读取Audio Tag data除去前两个字节的数据:

C++
1
2
//第一个auido tag数据包含AudioSpecificConfig,解析后用于生成adts头
fread(szAudioSpecificConfig, 1, tagheader_datasize - 2, m_pFlvFile);

解析AudioSpecificConfig

由前一部分得知AudioSpecificConfig按如下解析:

C++
1
2
3
4
5
6
5 bits: audio object type
4 bits: sampling frequency index
if (frequency index == 15)
    24 bits: frequency index
4 bits: channel configuration
other bits: audio object type specific config

通过位操作得到相应信息,代码如下:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
uint8_t audio_object_type = 0;
uint8_t sampling_frequency_index = 0;
uint8_t channel_config = 0;
 
//audio object type:5bit
audio_object_type = szAudioSpecificConfig[0] & 0xf8;
audio_object_type >>= 3;
 
//sampling frequency index:4bit
//高3bits
sampling_frequency_index = szAudioSpecificConfig[0] & 0x07;
sampling_frequency_index <<= 1;
//低1bit
uint8_t tmp = szAudioSpecificConfig[1] & 0x80;
tmp >>= 7;
sampling_frequency_index |= tmp;
 
//channel config:4bits
channel_config = szAudioSpecificConfig[1] & 0x78;
channel_config >>= 3;

程序中得到的3个数据我们将在下一部分使用。

计算adts头部

这里我们只讨论adts头部为7个字节的,首先构造一个字符数组存储adts头部:

C++
1
char szAdtsheader[7] = {0};

接着计算得到flv文件所有adts帧头部相同部分:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
szAdtsHeader[0] = 0xff;         //syncword:0xfff                          高8bits
szAdtsHeader[1] = 0xf0;         //syncword:0xfff                          低4bits
szAdtsHeader[1] |= (0 << 3);    //MPEG Version:0 for MPEG-4,1 for MPEG-2  1bit
szAdtsHeader[1] |= (0 << 1);    //Layer:0                                 2bits
szAdtsHeader[1] |= 1;           //protection absent:1                     1bit
 
szAdtsHeader[2] = (audio_object_type - 1)<<6;            //profile:audio_object_type - 1                      2bits
szAdtsHeader[2] |= (sampling_frequency_index & 0x0f)<<2; //sampling frequency index:sampling_frequency_index  4bits
szAdtsHeader[2] |= (0 << 1);                             //private bit:0                                      1bit
szAdtsHeader[2] |= (channel_config & 0x04)>>2;           //channel configuration:channel_config               高1bit
 
szAdtsHeader[3] = (channel_config & 0x03)<<6;     //channel configuration:channel_config      低2bits
szAdtsHeader[3] |= (0 << 5);                      //original:0                               1bit
szAdtsHeader[3] |= (0 << 4);                      //home:0                                   1bit
szAdtsHeader[3] |= (0 << 3);                      //copyright id bit:0                       1bit  
szAdtsHeader[3] |= (0 << 2);                      //copyright id start:0                     1bit

接下来要计算的数据跟每一个adts帧长度有关,是变化的。如下所示是flv tag的结构,在flv每个tag中,数据部分长度为datasize(tagheader_datasize)。
flv tag

由前面可知flv中Audio Tag存储的真实adts帧数据长度为tagheader_datasize - 2,此时还要加上7个字节adts头部长度才是完整一帧 adts长度,我们设置该长度为:

C++
1
int AdtsLen = tagheader_datasize - 2 + 7;

然后根据该AdtsLen计算得到头部剩下几位:

C++
1
2
3
4
5
szAdtsHeader[3] |= ((AdtsLen & 0x1800) >> 11);           //frame length:value   高2bits
szAdtsHeader[4] = (uint8_t)((AdtsLen & 0x7f8) >> 3);     //frame length:value    中间8bits
szAdtsHeader[5] = (uint8_t)((AdtsLen & 0x7) << 5);       //frame length:value    低3bits
szAdtsHeader[5] |= 0x1f;                                 //buffer fullness:0x7ff 高5bits
szAdtsHeader[6] = 0xfc;

至此我们可以得到了每一帧7个字节的adts头部,加上每一个adts帧的数据,可以得到完整的adts文件。

参考文档

1.flv标准说明video_file_format_spec_v10.pdf:https://pan.baidu.com/s/1z8RSGdQ_wzeXf8J50JMEQA
2.ISO/IEC 14496-3ISO_IEC_14496-3.PDF:https://pan.baidu.com/s/1TNrwlSshmDM3ZcglPHlHCA

This article is licensed with Creative Commons Attribution-NonCommercial-No Derivatives 4.0 International License
Tag: 音视频
Last updated:2018年12月23日

Jeff

管理员——代码为剑,如痴如醉

Tip the author Like
< Last article
Next article >

Comments

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
Cancel

This site uses Akismet to reduce spam. Learn how your comment data is processed.

文章目录
  • adts的头部结构
    • MPEG-4 Audio Object Type
    • MPEG-4 Sampling Frequency Index
    • MPEG-4 Channel Configuration
  • flv文件获取AudioSpecificConfig
  • 解析AudioSpecificConfig
  • 计算adts头部
    • 参考文档
Related Posts
  • 告别CapCut收费!开源视频剪辑工具OpenCut 来了
  • 音视频开发入门:视频基础
  • 大话WebRTC
  • WebRTC音视频传输基础:NAT穿透
  • Intel平台硬件加速视频编解码开发
Categories

COPYRIGHT © 2026 jianchihu.net. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang