作者:星宿 | 来源:互联网 | 2024-11-18 19:26
本文介绍了如何在AAC原始流中添加ADTS头以便通过FFmpeg进行软解码或系统硬解码。我们将详细解释ADTS头的结构,并提供一个示例代码来演示如何动态生成ADTS头。
AAC原始流可以通过FFmpeg进行软解码或系统硬解码。为了简化处理,可以在流的前面添加ADTS头。ADTS头由7个字节组成,下面是生成ADTS头的示例代码,每次传递数据都以一个样本为单位:
uint8_t adts_header[7] = {0xff, 0xf9, 0x00, 0x00, 0x00, 0x1f, 0xfc};
// 设置AAC级别
switch (aac_level) {
case AUDIO_AACM:
adts_header[2] |= (0x00 <<6) & 0xc0;
break;
case AUDIO_AACL:
adts_header[2] |= (0x01 <<6) & 0xc0;
break;
case AUDIO_AACS:
adts_header[2] |= (0x02 <<6) & 0xc0;
break;
default: // 默认使用AACL
adts_header[2] |= (0x01 <<6) & 0xc0;
break;
}
// 设置采样率
switch (aac_sample_rate) {
case SAMPLING_RATE_96000:
adts_header[2] |= (0x00 <<2) & 0x3c;
break;
case SAMPLING_RATE_88200:
adts_header[2] |= (0x01 <<2) & 0x3c;
break;
case SAMPLING_RATE_64000:
adts_header[2] |= (0x02 <<2) & 0x3c;
break;
case SAMPLING_RATE_48000:
adts_header[2] |= (0x03 <<2) & 0x3c;
break;
case SAMPLING_RATE_44100:
adts_header[2] |= (0x04 <<2) & 0x3c;
break;
case SAMPLING_RATE_32000:
adts_header[2] |= (0x05 <<2) & 0x3c;
break;
case SAMPLING_RATE_24000:
adts_header[2] |= (0x06 <<2) & 0x3c;
break;
case SAMPLING_RATE_22050:
adts_header[2] |= (0x07 <<2) & 0x3c;
break;
case SAMPLING_RATE_16000:
adts_header[2] |= (0x08 <<2) & 0x3c;
break;
case SAMPLING_RATE_12000:
adts_header[2] |= (0x09 <<2) & 0x3c;
break;
case SAMPLING_RATE_11025:
adts_header[2] |= (0x0a <<2) & 0x3c;
break;
case SAMPLING_RATE_8000:
adts_header[2] |= (0x0b <<2) & 0x3c;
break;
default: // 默认使用44100Hz
adts_header[2] |= (0x04 <<2) & 0x3c;
break;
}
// 设置声道数
switch (aac_channel_count) {
case 1:
adts_header[2] |= (0x01 >> 2) & 0x01;
adts_header[3] |= (0x01 <<6) & 0xc0;
break;
case 2:
adts_header[2] |= (0x02 >> 2) & 0x01;
adts_header[3] |= (0x02 <<6) & 0xc0;
break;
case 3:
adts_header[2] |= (0x03 >> 2) & 0x01;
adts_header[3] |= (0x03 <<6) & 0xc0;
break;
case 4:
adts_header[2] |= (0x04 >> 2) & 0x01;
adts_header[3] |= (0x04 <<6) & 0xc0;
break;
case 5:
adts_header[2] |= (0x05 >> 2) & 0x01;
adts_header[3] |= (0x05 <<6) & 0xc0;
break;
case 6:
adts_header[2] |= (0x06 >> 2) & 0x01;
adts_header[3] |= (0x06 <<6) & 0xc0;
break;
case 8:
adts_header[2] |= (0x07 >> 2) & 0x01;
adts_header[3] |= (0x07 <<6) & 0xc0;
break;
default: // 默认使用2个声道
adts_header[2] |= (0x02 >> 2) & 0x01;
adts_header[3] |= (0x02 <<6) & 0xc0;
break;
}
// 设置帧长度
adts_header[3] |= (aac_frame_length >> 11) & 0x03;
adts_header[4] = (aac_frame_length >> 3) & 0xff;
adts_header[5] |= ((aac_frame_length & 0x07) <<5);
通过上述代码,您可以根据实际的AAC流参数动态生成ADTS头,从而实现对AAC原始流的解码和播放。