视频文件解复用获取的aac文件添加adts头

根据雷神的代码,可以获取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);
}


  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值