ffmpeg编码aac文件通过extradata添加adts头
Posted 朱韦刚
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ffmpeg编码aac文件通过extradata添加adts头相关的知识,希望对你有一定的参考价值。
转载一篇文章:
1:ffmpeg的aac通过pcm编码得到的数据是latm的,如果需要存成adts能播的文件需要加头,ffmpeg并没有给相关的filter,通过extradata自己做解析加头;
2:aac_adtstoasc这个filter是把adts转成latm;
3:h264_mp4toannexb是将4个字节长度前缀的h264转成00 00 00 01 前缀的能播放的h264;
下面为转载;
转载链接:https://blog.csdn.net/lichen18848950451/article/details/78266054
根据雷神的代码,可以获取mp3等音频文件。网址是:http://blog.csdn.net/leixiaohua1020/article/details/39767055
同时,还可以把数据回调出去,进行其他的处理,是没有任何问题的。可是,现在的视频文件大都是H264+AAC。可是,根据雷神的代码是获取的数据,在播放器上播放失败。这是由于获取的aac数据是缺少adts文件头,添加上去就可以了。说着容易,可是做就难了。
网上的文章大都是介绍adts的,进行处理的代码很少。不过还是找到了,网址是http://blog.csdn.net/leixiaohua1020/article/details/39767055
不过,他的代码只是提供一些写好的函数,关于如何调用,自己还是花了不少时间研究。
typedef struct
int write_adts;
int objecttype;
int sample_rate_index;
int channel_conf;
ADTSContext;
以上是定义的一个结构体。
int aac_decode_extradata(ADTSContext *adts, unsigned char *pbuf, int bufsize)
int aot, aotext, samfreindex;
int i, channelconfig;
unsigned char *p = pbuf;
if (!adts || !pbuf || bufsize<2)
return -1;
aot = (p[0]>>3)&0x1f;
if (aot == 31)
aotext = (p[0]<<3 | (p[1]>>5)) & 0x3f;
aot = 32 + aotext;
samfreindex = (p[1]>>1) & 0x0f;
if (samfreindex == 0x0f)
channelconfig = ((p[4]<<3) | (p[5]>>5)) & 0x0f;
else
channelconfig = ((p[1]<<3)|(p[2]>>5)) & 0x0f;
else
samfreindex = ((p[0]<<1)|p[1]>>7) & 0x0f;
if (samfreindex == 0x0f)
channelconfig = (p[4]>>3) & 0x0f;
else
channelconfig = (p[1]>>3) & 0x0f;
#ifdef AOT_PROFILE_CTRL
if (aot < 2) aot = 2;
#endif
adts->objecttype = aot-1;
adts->sample_rate_index = samfreindex;
adts->channel_conf = channelconfig;
adts->write_adts = 1;
return 0;
上面的这个函数用来获取用来获取adts所需要的信息。第一个参数就不必说了,关键是后两个参数。是结构体AVCodecContext中的两个元素:
uint8_t *extradata; int extradata_size;adts中的信息在extradata中。通过处理,就可以获得adts的信息。
int aac_set_adts_head(ADTSContext *acfg, unsigned char *buf, int size)
unsigned char byte;
if (size < ADTS_HEADER_SIZE)
return -1;
buf[0] = 0xff;
buf[1] = 0xf1;
byte = 0;
byte |= (acfg->objecttype & 0x03) << 6;
byte |= (acfg->sample_rate_index & 0x0f) << 2;
byte |= (acfg->channel_conf & 0x07) >> 2;
buf[2] = byte;
byte = 0;
byte |= (acfg->channel_conf & 0x07) << 6;
byte |= (ADTS_HEADER_SIZE + size) >> 11;
buf[3] = byte;
byte = 0;
byte |= (ADTS_HEADER_SIZE + size) >> 3;
buf[4] = byte;
byte = 0;
byte |= ((ADTS_HEADER_SIZE + size) & 0x7) << 5;
byte |= (0x7ff >> 6) & 0x1f;
buf[5] = byte;
byte = 0;
byte |= (0x7ff & 0x3f) << 2;
buf[6] = byte;
return 0;
传入的第一个参数就是上面第一个函数获取的结构体,第二个参数是自己传入的一个指针,用来获取adts。第三个参数是长度,是每个packet的size。
下面是伪代码,希望对大家有所帮助吧:
ADTSContext AdtsCtx;
AVCodecContext* pCodecCtx;
while(av_read_frame(,&packet)>=0)
aac_decode_extradata(&AdtsCtx, pCodecCtx->extradata, pCodecCtx->extradata_size);
char* pAdts = new char [7];
aac_set_adts_head(&AdtsCtx, pAdts, packet.size);
fwrite(pAdts, 1, 7, fp);
fwrite(packet.data, 1, packet.size, fp);
————————————————
版权声明:本文为CSDN博主「那年晴天」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lichen18848950451/article/details/78266054
上述有不足之处请各位指正。
如有错误请指正:
交流请加QQ群:62054820
QQ:379969650.
以上是关于ffmpeg编码aac文件通过extradata添加adts头的主要内容,如果未能解决你的问题,请参考以下文章