如何将重采样的数据扔给编码器(AVAudioFifo)

来源:互联网 发布:知乎手机上网页版 编辑:程序博客网 时间:2024/06/09 13:13

上一篇文件中写了一段重采样的测试代码,也提到过如何将resample的音频数据扔给编码器的方法,经过验证发现,该方法的确可行(我测试的音频为AAC格式,32bit,其它格式大家需要稍作改动)。

首先需创建AVAudioFifo *fifo并为它申请空间:

[cpp] view plain copy
  1. int FFmpegDecoder::InitAudioFifo()  
  2. {  
  3.     fifo = av_audio_fifo_alloc(AV_SAMPLE_FMT_FLTP, cp.ap.channel, 1);  
  4.     if(!fifo)  
  5.     {  
  6.         cout << "Could not allocate fifo" << endl;  
  7.         return -1;  
  8.     }  
  9.     return 0;  
  10. }  

这里仅为fifo申请了一个字节,因为后面会对fifo重新申请内存,所以此处的大小不用关心

创建好fifo后,resamples后的数据存到该fifo中,调用如下函数:

[cpp] view plain copy
  1. int FFmpegDecoder::FeedingSamples2Fifo(uint8_t **data, const int data_size)  
  2. {  
  3.     int ret;  
  4.     ret = av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + data_size);  
  5.     if(ret < 0)  
  6.     {  
  7.         cout << "av_audio_fifo realloc failed" << endl;  
  8.         return ret;  
  9.     }  
  10.   
  11.     if(av_audio_fifo_write(fifo, (void **)data, data_size) < data_size)  
  12.     {  
  13.         cout << "Could not write data to fifo" << endl;  
  14.         return AVERROR_EXIT;  
  15.     }  
  16.     return 0;  
  17. }  
存储到fifo后,我们需要判断该fifo中是否有一帧数据,如果有,则从fifo中取出,也有可能fifo中含有多帧,所以从fifo中取出数据的时候,需要用到while循环。在取出fifo中的数据前,同样需要先申请一帧音频帧的空间:

[cpp] view plain copy
  1. AVFrame *FFmpegDecoder::AllocAudioFrame()  
  2. {  
  3.     AVFrame *frame = av_frame_alloc();  
  4.     if(!frame)  
  5.     {  
  6.         cout << "Could not allocate frame" << endl;  
  7.         return NULL;  
  8.     }  
  9.   
  10.     frame->nb_samples = 1024;  
  11.     frame->channels = cp.ap.channel;  
  12.     frame->channel_layout = av_get_default_channel_layout(cp.ap.channel);  
  13.     frame->format = AV_SAMPLE_FMT_FLTP;  
  14.     frame->sample_rate = cp.ap.samplerate;  
  15.   
  16.     av_frame_get_buffer(frame, 0);  
  17.     return frame;  
  18. }  
申请好空间后,需要开始从fifo中读取音频数据了


[cpp] view plain copy
  1. while(av_audio_fifo_size > 1024)  
  2. {  
  3.     AVFrame *f = AllocAudioFrame();  
  4.     av_audio_fifo_read(fifo,(void**)f->data,1024);  
  5. }  
为什么是1024?这个是AAC的nb_samples长度,其它音频格式可能又不一样了,这方面的知识我就不介绍了,好了,代码至此,已经贴完了。
阅读全文
0 0
原创粉丝点击