记一次ffmpeg进程阻塞的问题排查过程

Posted 「已注销」

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次ffmpeg进程阻塞的问题排查过程相关的知识,希望对你有一定的参考价值。

背景

在生产环境中,我们使用ffmpeg进行视频转码,将RTSP转HLS或者FLV在web端观看.每一路视频对应一个ffmpeg进程.一直都跑的挺好的.

问题

最近运维人员发现一个故障点:

有一路视频停了,其它都正常.

排查

检查后发现该路视频的确不正常:

  1. 看进程输出的m3u8ts,长时间不更新了.
  2. 看任务管理器,该路ffmpeg进程存在,但是其IO确实不正常,基本上不变,而其它路的IO都是持续增长的.这说明一个问题,该路ffmpeg进程阻塞了.

生产环境需要尽快恢复,所以我重启了一下这个进程,问题解决.但是墨菲定律告诉我们,这个问题发生了,那肯定会继续发生下去.所以要排查原因.
过程十分艰苦,但最终发现似乎是因为aac编码阻塞导致的,网上也有类似的问题反馈:
https://stackoverflow.com/questions/2410459/encode-audio-to-aac-with-libavcodec
以及:
https://ffmpeg.org/pipermail/libav-user/2011-August/000501.html

阻塞点是aacenc里面aac_encode_frame进入了无限循环无法退出,就是这个:

这个代码横竖看不懂,我猜是因为aac编码时,默认需要一个合适的固定码率,如果码率没达到,会重复某个动作直到码率达标.但是这个过程出现了bug,导致死循环了.
看代码,在重复过程中的确有个条件可以退出循环:

        if (avctx->flags & AV_CODEC_FLAG_QSCALE) 
            /* When using a constant Q-scale, don't mess with lambda */
            break;
        

即给编码器设置AV_CODEC_FLAG_QSCALE属性,这个属性在ffmpeg官方文档里面这样说的:

Variable Bit Rate with -qscale

You can select an audio quality level with -qscale:a (or the alias -q:a). The value changes depending on the audio encoder. Since this guide uses libmp3lame see the MP3 Encoding Guide for examples and more information.

Example:

ffmpeg -i input.avi -c:v mpeg4 -vtag xvid -qscale:v 3 -c:a libmp3lame -qscale:a 4 output.avi

就是可以通过-qscale参数配置可变码率,这种情况下,编码器不再追求码率达标,也就不存在循环逻辑了(可能对于CPU占用还有优化呢!). 果然,配置了-qscale:a 4后,avctx->flags & AV_CODEC_FLAG_QSCALE这个条件被触发了,应该不会再阻塞了.

测试

首先搜索代码,发现这个改变对功能影响很小,可以放心启用.
部署,测试,跟踪…
一周后, 暂未发现问题.也许这个问题就解决了

以上是关于记一次ffmpeg进程阻塞的问题排查过程的主要内容,如果未能解决你的问题,请参考以下文章

记一次ffmpeg进程阻塞的问题排查过程

记一次生产环境线程阻塞的排查

Kafka 异步消息也会阻塞?记一次 Dubbo 频繁超时排查过程

记一次HBase RegionServer 经常挂掉 故障排查过程

记一次Xmrig挖矿木马排查过程

记一次Log4j2引发的线程阻塞