Gstreamer 为什么使用videorate降低帧速率会导致CPU性能下降?

Gstreamer 为什么使用videorate降低帧速率会导致CPU性能下降?,gstreamer,Gstreamer,我对该元素的理解是,帧速率校正是通过简单地删除帧来执行的,并且没有使用“奇特的算法”。我已经分析了gst-launch-1.0管道的CPU使用情况,并且我观察到,随着帧速率降低到1fps以下,CPU使用量(与直觉相反)会显著增加。 示例管道(您可以通过更改帧率分数来观察性能损失): 我希望降低帧速率可以减少管道其余部分所需的处理量。对这一现象的任何洞察都将不胜感激 系统信息:Centos 7,GStreamer 1.4.5 编辑:似乎videotestsrc也会发生这种情况,但只有在源上指定高帧

我对该元素的理解是,帧速率校正是通过简单地删除帧来执行的,并且没有使用“奇特的算法”。我已经分析了gst-launch-1.0管道的CPU使用情况,并且我观察到,随着帧速率降低到1fps以下,CPU使用量(与直觉相反)会显著增加。 示例管道(您可以通过更改帧率分数来观察性能损失):

我希望降低帧速率可以减少管道其余部分所需的处理量。对这一现象的任何洞察都将不胜感激

系统信息:Centos 7,GStreamer 1.4.5

编辑:似乎videotestsrc也会发生这种情况,但只有在源上指定高帧率时才会发生

videotestsrc pattern=snow ! video/x-raw,width=1920,height=1080,framerate=25/1 ! videorate drop-only=true ! video/x-raw,framerate=1/10 ! autovideosink

从videotestsrc caps中删除帧率会使CPU使用率为1%,并且使用率会随着videorate帧率的增加而增加。同时,将源设置为25/1 fps将CPU使用率提高到50%,并且随着视频帧帧率的增加而降低。

<代码> Value是棘手的,需要结合流水线中的其他元素来考虑它。您还需要知道实际有多少CPU时间可供切断。例如,如果您解码一个60fps的文件并以1fps的速度显示它,您仍然会消耗大量的CPU。您可以将
sync
设置为true,输出到
fakesink
,以查看实际可以节省多少CPU

我建议添加一些调试信息,以便更好地理解videorate的行为

export GST\u DEBUG=2,视频速率:7

然后,您可以在“推送缓冲区”推送时对其进行grep:

gst-launch-1.0[PIPELINE]2>&1|grep“推送缓冲区”

..以及用于在接收数据时存储缓冲区:

gst-launch-1.0[PIPELINE]2>&1|grep“存储缓冲区”

在解码文件RC的情况下,您将看到CPU活动的突发,因为发生的是解码器将运行60帧,意识到管道已满,暂停,等待
需要缓冲区
事件出现,然后突发到100%CPU以再次填充管道

还有其他因素。您可能需要小心,在某些瓶颈之间有
队列
元素,并设置了正确的
最大大小
属性。或者,您的接收器或源元素可能以意外的方式运行

为了给你的问题找到最好的答案,我建议你公布你打算使用的确切管道,有视频收费和没有视频收费。如果您有类似“autovideosink”的内容,请将其更改为系统上它实际解析到的元素

以下是我测试的几个管道:

gst-launch-1.0 videotestsrc pattern=snow!视频/x-raw,宽度=320,高度=180,帧速率=60/1!视频速率!videoscale方法=lanczos!视频/x-raw,宽度=1920,高度=1080,帧速率=60/1!ximagesink
htop中30%的CPU


gst-launch-1.0 videotestsrc pattern=snow!视频/x-raw,宽度=320,高度=180,帧速率=60/1!视频速率!videoscale方法=lanczos!视频/X-RAW,宽度=1920,高度=1080,帧数=1/10</代码>0%,在HTTP

<代码> Value中有10%个尖峰是棘手的,您需要结合流水线中的每个其他元素来考虑它。您还需要知道实际有多少CPU时间可供切断。例如,如果您解码一个60fps的文件并以1fps的速度显示它,您仍然会消耗大量的CPU。您可以将

sync
设置为true,输出到
fakesink
,以查看实际可以节省多少CPU

我建议添加一些调试信息,以便更好地理解videorate的行为

export GST\u DEBUG=2,视频速率:7

然后,您可以在“推送缓冲区”推送时对其进行grep:

gst-launch-1.0[PIPELINE]2>&1|grep“推送缓冲区”

..以及用于在接收数据时存储缓冲区:

gst-launch-1.0[PIPELINE]2>&1|grep“存储缓冲区”

在解码文件RC的情况下,您将看到CPU活动的突发,因为发生的是解码器将运行60帧,意识到管道已满,暂停,等待
需要缓冲区
事件出现,然后突发到100%CPU以再次填充管道

还有其他因素。您可能需要小心,在某些瓶颈之间有
队列
元素,并设置了正确的
最大大小
属性。或者,您的接收器或源元素可能以意外的方式运行

为了给你的问题找到最好的答案,我建议你公布你打算使用的确切管道,有视频收费和没有视频收费。如果您有类似“autovideosink”的内容,请将其更改为系统上它实际解析到的元素

以下是我测试的几个管道:

gst-launch-1.0 videotestsrc pattern=snow!视频/x-raw,宽度=320,高度=180,帧速率=60/1!视频速率!videoscale方法=lanczos!视频/x-raw,宽度=1920,高度=1080,帧速率=60/1!ximagesink
htop中30%的CPU


gst-launch-1.0 videotestsrc pattern=snow!视频/x-raw,宽度=320,高度=180,帧速率=60/1!视频速率!videoscale方法=lanczos!视频/x-raw,宽度=1920,高度=1080,帧速率=1/10
0%,在htop中有10%的峰值

Tozar我将特别针对您在上面的评论中发布的管道

如果您只打算每10秒发送一次帧,则可能不需要使用h264。在十秒钟内,帧将完全改变,并且将不会有数据相似性进行编码以节省带宽。编码器可能只是假设需要一个新的关键帧。您可以选择jpegenc和rtpjpegpay

如果您正在对内容进行编码,您肯定会看到
videotestsrc pattern=snow ! video/x-raw,width=1920,height=1080,framerate=25/1 ! videorate drop-only=true ! video/x-raw,framerate=1/10 ! autovideosink