【FFmpeg】编写 ACC 的 ADTS 信息头

背景

  在保存aac格式的信息流时必须要对每一帧aac信息流加以头信息,否则解码器无法识别aac信息流,这个信息头就是ADTS信息头。

代码

int write_ADTS_header(AVPacket *pkt, AVCodecParameters& codecpar) {

	int length = pkt->size + ADTS_HEADER_SIZE;
	uint8_t *data1 = new uint8_t[length];
	memcpy(data1 + ADTS_HEADER_SIZE, pkt->data, pkt->size);

	uint8_t pb[ADTS_HEADER_SIZE] = { 0 };
	int sample_index = 0x4;
	int channel = codecpar.channels;
	switch (codecpar.sample_rate)
	{
	case 48000:sample_index = 0x3;
		break;
	case 44100:sample_index = 0x4;
		break;
	case 32000:sample_index = 0x5;
		break;
	}
	
	// # 编辑信息头
	pb[0] = 0xff;
	pb[1] = 0xf1;
	pb[2] = 0x40 | (sample_index << 2) | (channel >> 2);
	pb[3] = ((channel & 0x3) << 6) | (length >> 11);
	pb[4] = (length >> 3) & 0xff;
	pb[5] = ((length << 5) & 0xff) | 0x1f;
	pb[6] = 0xfc;
	// # end 编辑信息头
	
	memcpy(data1, &pb, ADTS_HEADER_SIZE);
	av_packet_unref(pkt);
	pkt->data = data1;
	pkt->size = length;
	return 0;
}

上面的函数不能直接使用,这个函数是错误的,仅供参考


代码参考数据

以下信息转载自黄梦轩:AAC的ADTS头解析

  ADTS头包含了AAC文件的采样率、通道数、帧数据长度等信息。ADTS头分为固定头信息和可变头信息两个部分,固定头信息在每个帧中的是一样的,可变头信息在各个帧中并不是固定值。ADTS头一般是7个字节((28+28)/ 8)长度,如果需要对数据进行CRC校验,则会有2个Byte的校验码,所以ADTS头的实际长度是7个字节或9个字节。

ADTS头的固定头信息在每个帧中都是一样的。

固定头信息:adts_fixed_header()

【FFmpeg】编写 ACC 的 ADTS 信息头_第1张图片

  • syncword:帧同步标识一个帧的开始,固定为0xFFF
  • ID:MPEG 标示符。0表示MPEG-4,1表示MPEG-2
  • layer:固定为’00’
  • protection_absent:标识是否进行误码校验。0表示有CRC校验,1表示没有CRC校验
  • profile:标识使用哪个级别的AAC。
    • 1: AAC Main
    • 2:AAC LC (Low Complexity)
    • 3:AAC SSR (Scalable Sample Rate)
    • 4:AAC LTP (Long Term Prediction)
  • sampling_frequency_index:标识使用的采样率的下标
  • private_bit:私有位,编码时设置为0,解码时忽略
  • channel_configuration:标识声道数
  • original_copy:编码时设置为0,解码时忽略
  • home:编码时设置为0,解码时忽略
    【FFmpeg】编写 ACC 的 ADTS 信息头_第2张图片
    【FFmpeg】编写 ACC 的 ADTS 信息头_第3张图片

可变头信息:adts_variable_header()

【FFmpeg】编写 ACC 的 ADTS 信息头_第4张图片

  • copyrighted_id_bit:编码时设置为0,解码时忽略
  • copyrighted_id_start:编码时设置为0,解码时忽略
  • aac_frame_length:ADTS帧长度包括ADTS长度和AAC声音数据长度的和。即 aac_frame_length = (protection_absent == 0 ? 9 : 7) + audio_data_length
  • adts_buffer_fullness:固定为0x7FF。表示是码率可变的码流
  • number_of_raw_data_blocks_in_frame:表示当前帧有number_of_raw_data_blocks_in_frame + 1 个原始帧(一个AAC原始帧包含一段时间内1024个采样及相关数据)。

你可能感兴趣的:(音视频,FFmpeg,C++)