FFMpeg杂音问题解决方案

发布时间:2024-12-12 22:19

设计思维适用于解决复杂问题的解决方案 #生活技巧# #创意技巧# #设计思维应用#

最近在调试网上下载的android ffmpeg播放器的源代码。因为编译ffmpeg过程中,觉得很麻烦,因此就没有继续编译SDL库了。打算在Java层使用Bitmap显示视频帧,在C层使用OpenSLES播放音频帧。

     将网上的相关源代码整合到一块后,发现音视频解码,都没有错误。并且视频可以播放出来,但是声音声调不对,主要还有杂音。试了网上的一些方法也不行。最后自己尝试性地改了一个变量。杂音就消失了,但是声调还不对。

   网上的解码音频数据包,然后将解码后的原始数据push到音频缓冲区的源代码中有以下几行代码

   //音频数据解码

   len = avcodec_decode_audio4(aCodecCtx, frame, &got_frame, &packet); 

   //得到解码音频数据的大小

   data_size = av_samples_get_buffer_size(   NULL, aCodecCtx->channels,  
                                                                        frame->nb_samples,aCodecCtx->sample_fmt, 1);  

  //将解码的音频数据push到音频缓冲区
   memcpy(stream, (uint8_t*)(frame->data[0]), data_size]); 

  我将  memcpy(stream, (uint8_t*)(frame->data[0]), data_size]); 

  改为  memcpy(stream, (uint8_t*)(frame->data[0]), frame->linesize[0]);  后杂音就消失了。但是声音明显比正常的要快。

  这个时候,感觉再去网上找方法也没什么用了。必须老老实实地理解AVFrame结构体中,各个字段的具体意思和PCM的相关知识点。

      后来知道了杂音和声调不对的原因了。

      杂音是因为avcodec_decode_audio4(aCodecCtx, frame, &got_frame, &packet)解码后的两个声道的音频数据分别存放在frame->data[0]和frame->data[1]中,而 frame->linesize[0]和 frame->linesize[1] 分别是前两者的大小。(我用来调试的视频文件,音频部分是双声道的)。而data_size表示的是两个声道的音频数据的总和。  因此memcpy(stream, (uint8_t*)(frame->data[0]), data_size])将一大段错误的数据push到缓冲区了。

     声音明显比正常的要快的原因是,memcpy(stream, (uint8_t*)(frame->data[0]), frame->linesize[0])只是push了一个声道的音频数据,而创建OpenSLES的播放器是却设置成了双 声道。format_pcm.numChannels = aCodecCtx->channels(实际上为2)。两个通道播放一个通道的数据,自然变快了。为尽快播放出正常的声音,将播放器声道数设为1,此时听到了正常的音乐。

    当然最正确的方法是正确地将编码后的音频数据,转换为正确的PCM格式。这样就可以双声道播放了。

    小结一下:遇到不是程序本身存在的问题时。还需要从原理入手,学习相关的知识,这样才能够真正理解一段代码的工作流程和原理。

网址:FFMpeg杂音问题解决方案 https://www.yuejiaxmz.com/news/view/457018

相关内容

蓝牙芯片蓝牙模块音频发射器杂音噪音问题解决方案
楼上噪音如何解决噪音问题
简易语音助手—python
C# ffmpeg 视频处理
常见问题解析及解决方案总结.docx
生活问题及解决方案.pptx
如何解决小区噪音问题?这种解决方案对居民生活质量有何改善?
如何处理房屋噪音问题?这些解决方案的有效性如何?
生活中的问题与解决方案
生活问题以及解决方案.pptx

随便看看