GStreamer appsink设置drop=true时CPU负载过高问题求解
GStreamer appsink设置drop=true时CPU负载异常升高
问题描述
使用GStreamer的appsink组件时,设置drop=true参数后CPU负载异常升高。
以下Pipeline可正常运行:
gst-launch-1.0 -v rtspsrc location="rtsp://somelink" latency=300 ! rtph265depay ! h265parse ! avdec_h265 ! videoconvert ! appsink caps="video/x-raw,format=BGR"
上述Pipeline使用默认配置的appsink时运行正常,一旦为appsink添加drop=true配置,CPU负载会大幅升高,单核CPU占用可达100%。
源码排查
查阅appsink源码,drop逻辑相关代码如下:
if (priv->drop) { GstMiniObject *old; /* we need to drop the oldest buffer/list and try again */ if ((old = dequeue_buffer (appsink))) { GST_DEBUG_OBJECT (appsink, "dropping old buffer/list %p", old); gst_mini_object_unref (old); } }
进一步查看dequeue_buffer函数的实现:
static GstMiniObject * dequeue_buffer (GstAppSink * appsink) { GstMiniObject *obj; do { obj = dequeue_object (appsink); if (GST_IS_BUFFER (obj) || GST_IS_BUFFER_LIST (obj)) { break; } gst_mini_object_unref (obj); } while (TRUE); return obj; }
函数内存在while (TRUE)循环逻辑,高度怀疑这是导致CPU占用过高的原因,暂未找到有效调试方法,希望确认是否有同类问题的可行解决方案。
回答
根因分析
你观察到的while(TRUE)循环确实是CPU占满的直接原因,本质是配置缺失叠加旧版本代码缺陷共同导致:
- 配置逻辑问题:
appsink的drop=true丢帧逻辑只有在内部缓冲区队列达到max-buffers阈值时才会触发,未配置max-buffers时该参数默认值为0,代表队列无长度上限,此时drop逻辑本身不会按预期丢弃旧帧,但每次新buffer入队都会触发队列检查流程。 - 旧版本自旋bug:1.16版本之前的GStreamer中,
dequeue_buffer函数在队列内没有可取出的有效buffer(队列空、或队列头部全是流事件/EOS事件等非buffer对象)时,dequeue_object会直接返回NULL,循环不会做任何等待直接进入下一轮调用,形成无意义的CPU空转,直接占满单个CPU核心。 - 触发条件放大:如果应用层拉取
appsink帧的速度慢于解码输出速度,队列内事件和buffer的排布会大幅提升空转逻辑的触发概率。
解决方案
按落地成本从低到高排序:
- 优先补充
max-buffers配置:根据帧处理延迟将该值设为1~3即可,配置后队列达到长度阈值才会触发丢帧,不会出现无意义的空队列检查,绝大多数场景下可直接解决问题,修改后pipeline的appsink片段示例如下:appsink caps="video/x-raw,format=BGR" drop=true max-buffers=2 - 升级GStreamer版本:如果当前使用版本低于1.16,升级到1.16及以上稳定版即可,官方已在该版本修复
dequeue_buffer的自旋问题,取不到buffer时会进入条件变量等待,不会空转占用CPU。 - 优化消费逻辑:检查应用层的帧拉取代码,不要在
appsink的sample拉取线程中执行耗时的图像处理、磁盘/网络IO操作,这类逻辑要放到独立工作线程执行,避免阻塞appsink的流式调度线程,减少队列堆积概率。 - 临时规避方案:如果暂时无法升级版本或调整业务逻辑,可以去掉appsink的
drop=true配置,在appsink前插入带下游丢帧能力的queue元素实现相同效果,规避appsink的逻辑bug,对应pipeline片段示例如下:! queue leaky=downstream max-size-buffers=2 ! appsink caps="video/x-raw,format=BGR"
内容的提问来源于stack exchange,提问作者Felix F Xu
相关产品推荐
相关产品推荐

