Ffmpeg音频转码 卡顿(MP2转AAC)

        最好经手一个小的功能将mp2实时流转成AAC并发布成rtmp音频流,本身不是很难的一个需求,

一个晚上就能将功能开发好。功能开发完毕后,找来一音频文件利用Ffmpeg命令将音视频文件推成

实时udp格式音频流,具体的推送命令是:

ffmpeg.exe -r -i F:	est.mp2 -acodec copy -f mp2 udp://127.0.0.1:1234

  测试程序以udp://127.0.0.1:1234为输入源,rtmp://127.0.0.1/live/stream为输出流。从输入到输出

经过解码、过滤器、编码最后封装,这些基本的原理及代码之前的博文已经写过,也有相关的视频进行

讲述,本文不再赘述。

       测试程序运行后,通过ffplay播放输出音频流地址rtmp://127.0.0.1/live/stream,开始一分钟左右可以

音频播放正常,过了一分钟后声音出现卡顿。开始以为是推送的速度问题,对原有的程序做了些改进:将

读包一单独线程,编解码及发送单独一线程。修改程序后,卡顿的现象还在,显然没有找到问题。接下来

考虑可能是读udp数据出了问题,增加各种UDP参数设置重新再测试,卡顿的现象依然在。经过多番折腾

发现问题出在filter上:filter SRC端每Push一次,SINK端需要一直读取Frame直到读取方法返回负值。源

代码也是这么写的,不小心埋了Bug,实际执行的情况是每次SINK端只读一次即返回。正常的代码片段如下

void Transcode(std::shared_ptr<AVPacket> packet)
{
    int gotOutput = 0;
    AVFrame *pSrcAudioFrame = av_frame_alloc();
    bool  decodeResult = decodeAudio(packet.get(),pSrcAudioFrame);
    if(decodeResult)
    {
        while (true)
        {
            AVFrame *filtFrame  = av_frame_alloc();        
            int ret = av_buffersink_get_frame_flags(buffersinkCtx, filtFrame, 0);
            if(ret < 0)
            {
                av_frame_free(&filtFrame);
                break;
            }
            std::shared_ptr<AVPacket> pkt(static_cast<AVPacket*>(av_malloc(sizeof(AVPacket))), [&](AVPacket *p) { av_packet_free(&p); av_freep(&p); });
            av_init_packet(pkt.get());
            pkt->data = NULL;
            pkt->size = 0;

            ret = avcodec_encode_audio2(encodeContext, pkt.get(), filtFrame, &gotOutput);
            if (ret >= 0 && gotOutput)
            {
                WritePacket(pkt);
            }
            av_frame_free(&filtFrame);    
        }
    }
    av_frame_free(&pSrcAudioFrame);
}

如需交流可加QQ群1038388075,766718184 或者QQ3501870

 博主提供Ffmpeg、GB28181视频教程

播放地址: http://www.iqiyi.com/u/1426749687

源码及Demo下载地址:http://www.chungen90.com/?news_2/

视频下载地址:     http://www.chungen90.com/?news_3/

原文地址:https://www.cnblogs.com/wanggang123/p/10321715.html