记一次ffmpeg进程阻塞的问题排查过程
Posted John0551
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次ffmpeg进程阻塞的问题排查过程相关的知识,希望对你有一定的参考价值。
背景
在生产环境中,我们使用ffmpeg进行视频转码,将RTSP转HLS或者FLV在web端观看.每一路视频对应一个ffmpeg进程.一直都跑的挺好的.
问题
最近运维人员发现一个故障点:
有一路视频停了,其它都正常.
排查
检查后发现该路视频的确不正常:
- 看进程输出的
m3u8
和ts
,长时间不更新了. - 看任务管理器,该路
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进程阻塞的问题排查过程的主要内容,如果未能解决你的问题,请参考以下文章
Kafka 异步消息也会阻塞?记一次 Dubbo 频繁超时排查过程