AAC audio format ADTS header detailed explanation

        There is no way to play the AAC data of the naked stream, because the device cannot find the relevant information of the AAC format; it needs to add the ADTS header to be able to play, and each frame of audio package has an ADTS header, and the ADTS header has 7 characters if there is no crc check Section length, if there is crc check, it is 9 bytes long.

 ADTS field protocol:

ADTS header protocol
field length describe
synword 12bit Fixed 0xFFF, used for synchronization, the beginning of a frame
id 1bit MPEG identifier, 0: MPEG-4, 1: MPEG-2
layer

2bit

Usually 00
protection_absent 1bit CRC verification flag, 0: with CRC verification, 1: without CRC verification
profile 2bit

AAC level, in AVStream of ffmpeg: streams[audio]->codecpar->profile

audio: frame index

sampling_frequency_index 4 bits

Sampling rate subscript, the sampling rate corresponding to the subscript is as follows:

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
: 210 Hz 10
: 11 7350 Hz
13 : Reserved
14 : Reserved
15 : frequency is written explictly
The sampling rate is also in ffmpeg's AVStream:

streams[audio]->codecpar->sample_rate

audio: frame index

private_bit 1bit Private bit, 0 when encoding, ignored when decoding
channel_configuration 3bit

声道数。
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
front - center:中置声道

front - left: left channel

front - right:右声道

back - left:后置左

back - right:后置右

side - left:侧置左

side - right:侧置右

LFE - channel:低频声道

音频通道也在ffmpeg的AVStream中:

streams[audio]->codecpar->channels

audio:帧索引

orininal_copy 1bit 编码是设置为0,解码时忽略
home 1bit 编码时设置为0,解码时忽略
copyrigth_identification_bit 1bit 编码时设置为0,解码时忽略
copyrigth_identification_stat 1bit 编码时设置为0,解码时忽略
aac_frame_length 13bit 一个ADTS帧的⻓度,包括ADTS头和AAC原始流。
adts_bufferfullness 11bit 缓冲区充满度,0x7FF说明是码率可变的码流,不需要此字段。CBR可能需要此字段,不同编码器使用情况不同。具体查看附录。
number_of_raw_data_blocks_in_frame 2bit 表示ADTS帧中有number_of_raw_data_blocks_in_frame + 1个AAC原始帧,为0表示说ADTS帧中只有一个AAC数据.
crc 16bit protection_absent为0就有该字段,否则没有该字段

        ffmpeg解复用时,MP4,FLV格式的包解出的音频流是纯AAC流,不带ADTS头数据,需要人工添加ADTS头。

        添加头的代码实现接口:

        

int adts_header(char *const p_adts_header, const int data_length,
		const int profile, const int samplerate,
		const int channels) {

	int sampling_frequency_index = 3; // 默认使用48000hz
	int adtsLen = data_length + 7;

	// 匹配采样率
	int frequencies_size = sizeof(sampling_frequencies) / sizeof(sampling_frequencies[0]);
	int i = 0;
	for (i = 0; i < frequencies_size; i++) {
		if (sampling_frequencies[i] == samplerate) {
			sampling_frequency_index = i;
			break;
		}
	}
	if (i >= frequencies_size) {
		std::cout << "没有找到支持的采样率" << std::endl;
		return -1;
	}

	p_adts_header[0] = 0xff;         //前12bit固定0xfff                          高8bits
	p_adts_header[1] = 0xf0;         //前12bit的低四位                          低4bits
	p_adts_header[1] |= (0 << 3);    //0:MPEG-4, 1:MPEG-2  1bit
	p_adts_header[1] |= (0 << 1);    //一般为0                                 2bits
	p_adts_header[1] |= 1;           //1:没有crc校验字段                    1bit

	p_adts_header[2] = (profile) << 6;            //aac级别,可以使用ffmpeg获取               2bits
	p_adts_header[2] |=
		(sampling_frequency_index & 0x0f) << 2; //可以使用ffgmpeg从包中获得  4bits
	p_adts_header[2] |= (0 << 1);             //私有位 编码时为0                   1bit
	p_adts_header[2] |= (channels & 0x04) >> 2; //3bit的声道设置的最高位  高1bit

	p_adts_header[3] = (channels & 0x03) << 6; //3bit的声道设置的最低两位 低2bits
	p_adts_header[3] |= (0 << 5);               //编码设置为0                1bit
	p_adts_header[3] |= (0 << 4);               //编码设置为0                    1bit
	p_adts_header[3] |= (0 << 3);               //编码设置为0        1bit
	p_adts_header[3] |= (0 << 2);               //编码设置为0      1bit
	p_adts_header[3] |= ((adtsLen & 0x1800) >> 11);           //帧长度包括ADTS头长度   高2bits

	p_adts_header[4] = (uint8_t) ((adtsLen & 0x7f8) >> 3);     //帧长度包括ADTS头长度    中间8bits
	p_adts_header[5] = (uint8_t) ((adtsLen & 0x7) << 5);       //帧长度包括ADTS头长度    低3bits
	p_adts_header[5] |= 0x1f;                                 //可变码率vbr:0x7ff 高5bits
	p_adts_header[6] = 0xfc;      //‭11111100‬       //buffer fullness:0x7ff 低6bits

	return 0;
}

代码中的sampling_frequencies[]数组是一个sampling_frequency_index字段的采样率对照表 。       

Guess you like

Origin blog.csdn.net/qq_39466755/article/details/127322079