ffmpeg (三):ffmpeg结合SDL2.0解码音频流

来源:互联网 发布:俄罗斯地狱入口 知乎 编辑:程序博客网 时间:2024/05/22 05:06
转自:http://blog.csdn.net/oldmtn/article/details/20830285
我自己解码的时候遇到点问题,暂时先占位。后面若搞定了,再添加。

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// 2014/3/9 -- 19:24更新

[cpp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. FILE *pFile;  
  2. pFile = fopen("wavinflag.pcm""wb");  
  3.   
  4. while( av_read_frame(pFormatCtx, packet) >= 0 ) {  
  5.     if( packet->stream_index == audioStream ) {  
  6.         int got_picture;  
  7.         int ret = avcodec_decode_audio4( audioCodecCtx, audioFrame, &got_picture, packet);  
  8.         if( ret < 0 ) {  
  9.             printf("Error in decoding audio frame.\n");  
  10.             exit(0);  
  11.         }  
  12.         if( got_picture ) {  
  13.             int in_samples = audioFrame->nb_samples;  
  14.             short *sample_buffer = (short*)malloc(audioFrame->nb_samples * 2 * 2);  
  15.             memset(sample_buffer, 0, audioFrame->nb_samples * 4);  
  16.             printf("in_samples = %d\n", in_samples);  
  17.   
  18.             int i=0;  
  19.             float *inputChannel0 = (float*)(audioFrame->extended_data[0]);  
  20.   
  21.             // Mono  
  22.             if( audioFrame->channels == 1 ) {  
  23.                 for( i=0; i<in_samples; i++ ) {  
  24.                     float sample = *inputChannel0++;  
  25.                     if( sample < -1.0f ) {  
  26.                         sample = -1.0f;  
  27.                     } else if( sample > 1.0f ) {  
  28.                         sample = 1.0f;  
  29.                     }  
  30.   
  31.                     sample_buffer[i] = (int16_t)(sample * 32767.0f);  
  32.                 }  
  33.             } else { // Stereo  
  34.                 float* inputChannel1 = (float*)(audioFrame->extended_data[1]);  
  35.                 for( i=0; i<in_samples; i++) {  
  36.                     sample_buffer[i*2] = (int16_t)((*inputChannel0++) * 32767.0f);  
  37.                     sample_buffer[i*2+1] = (int16_t)((*inputChannel1++) * 32767.0f);  
  38.                 }  
  39.             }  
  40.   
  41.             fwrite(sample_buffer, 2, in_samples*2, pFile);  
  42.         }  
  43.     }  
  44.   
  45.     // Free the packet that was allocated by av_read_frame  
  46.     av_free_packet(packet);  
  47. }  

在使用ffmpeg解码aac的时候,如果使用avcodec_decode_audio4函数解码,那么解码出来的会是AV_SAMPLE_FMT_FLTP 格式的数据( float, 4bit , planar), 如果我们希望得到16bit的数据(如AV_SAMPLE_FMT_S16P数据),那么我们需要转换一下:

解決方式: 
   將 samples 由 32bits 转为16bits. 参考 ffmpeg samplefmt.h 
   若 sample 是 AV_SAMPLE_FMT_FLTP,則 sample 會是 float 格式,且值域为 [-1.0, 1.0] 
   若 sample 是 AV_SAMPLE_FMT_S16, 則 sample 會是 int16 格式,且值域为 [-32767, +32767] 

这里SDL2.0播放pcm有点问题,还没弄会。

将FLTP转为S16代码,详细代码这里下载。

0 0
原创粉丝点击