【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()

在這裏插入圖片描述

  • 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,解碼時忽略
    在這裏插入圖片描述
    在這裏插入圖片描述

可變頭信息:adts_variable_header()

在這裏插入圖片描述

  • 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個採樣及相關數據)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章