为什么使用视频速率降低帧速率会导致显着的 CPU 性能损失?
Why does decreasing the framerate with videorate incur a significant CPU performance penalty?
我对videorate element is that framerate correction is performed by simply dropping frames and no "fancy algorithm" is used. I've profiled CPU usage for a gst-launch-1.0 pipeline and I've observed that as the framerate decreases below 1 FPS, CPU usage, counter-intuitively, increases dramatically.的理解
示例管道(您可以通过更改帧率分数来观察性能损失):
gst-launch-1.0 filesrc location=test.mp4 ! qtdemux ! h264parse ! avdec_h264 ! videorate drop-only=true ! video/x-raw,framerate=1/10 ! autovideosink
我预计降低帧率会减少整个管道其余部分所需的处理量。任何对这种现象的见解都将不胜感激。
系统信息: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 上限中删除帧率会使 CPU 使用率为 1%,并且使用率会随着 videorate 帧率的增加而增加。同时,将源设置为 25/1 FPS 会将 CPU 使用率增加到 50%,并随着视频帧率的增加而降低。
videorate
很棘手,您需要结合管道中的所有其他元素来考虑它。您还需要注意实际上有多少 CPU 时间可以中断。例如,如果您正在解码一个 60fps 的文件并以 1fps 的速度显示它,您仍然会消耗很多 CPU。您可以输出到 fakesink
并将 sync
设置为 true 以查看您实际可以节省多少 CPU。
我建议添加一些调试信息以更好地理解 videorate 的行为。
export GST_DEBUG=2,videorate:7
然后你可以 grep for "pushing buffer" 因为当它推送时:
gst-launch-1.0 [PIPELINE] 2>&1 | grep "pushing buffer"
..并在接收数据时用于存储缓冲区:
gst-launch-1.0 [PIPELINE] 2>&1 | grep "storing buffer"
在解码 filesrc 的情况下,你会看到 CPU activity 的爆发,因为解码器会 运行 通过说 60 帧,实现管道已满,暂停,等待 need-buffers
事件进入,然后突然达到 100% CPU 以再次填充管道。
还有其他因素。就像您可能需要注意在某些瓶颈之间有 queue
元素,并设置正确的 max-size
属性。或者您的接收器或源元素可能以意想不到的方式运行。
为了获得您问题的最佳答案,我建议您发布您打算使用的确切管道,包括和不包括视频速率。如果您有类似 "autovideosink" 的内容,请将其更改为它在您的系统上实际解析为的元素。
以下是我测试过的一些管道:
gst-launch-1.0 videotestsrc pattern=snow ! video/x-raw,width=320,height=180,framerate=60/1 ! videorate ! videoscale method=lanczos ! video/x-raw,width=1920,height=1080,framerate=60/1 ! ximagesink
30% CPU 在 htop
gst-launch-1.0 videotestsrc pattern=snow ! video/x-raw,width=320,height=180,framerate=60/1 ! videorate ! videoscale method=lanczos ! video/x-raw,width=1920,height=1080,framerate=1/10
0%,htop 中有 10% 的峰值
Tozar 我将专门解决您在上面的评论中发布的管道。
如果您只打算每十秒发送一次帧,则可能不需要使用 h264。十秒后,帧将完全改变,并且将没有数据相似性需要编码以节省带宽。编码器可能只是假设需要一个新的关键帧。您可以选择 jpegenc 和 rtpjpegpay。
如果您重新编码内容,您肯定会每十秒看到一个 CPU 峰值。这是不可避免的。
如果你想在进行转换的机器上尽可能降低 CPU 使用率,你可以去解析传入的 h264 数据,提取关键帧(IDR 帧),然后将它们传递到次要目的地。这将假设原始发射器发送了关键帧(没有帧内刷新)。这并不容易。
您可能想就您尝试做的事情提出一个更笼统的问题。进行转换的机器的作用是什么?它是否必须自己使用数据?什么类型的机器每十秒接收一次帧,它的作用是什么?
我对videorate element is that framerate correction is performed by simply dropping frames and no "fancy algorithm" is used. I've profiled CPU usage for a gst-launch-1.0 pipeline and I've observed that as the framerate decreases below 1 FPS, CPU usage, counter-intuitively, increases dramatically.
gst-launch-1.0 filesrc location=test.mp4 ! qtdemux ! h264parse ! avdec_h264 ! videorate drop-only=true ! video/x-raw,framerate=1/10 ! autovideosink
我预计降低帧率会减少整个管道其余部分所需的处理量。任何对这种现象的见解都将不胜感激。
系统信息: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 上限中删除帧率会使 CPU 使用率为 1%,并且使用率会随着 videorate 帧率的增加而增加。同时,将源设置为 25/1 FPS 会将 CPU 使用率增加到 50%,并随着视频帧率的增加而降低。
videorate
很棘手,您需要结合管道中的所有其他元素来考虑它。您还需要注意实际上有多少 CPU 时间可以中断。例如,如果您正在解码一个 60fps 的文件并以 1fps 的速度显示它,您仍然会消耗很多 CPU。您可以输出到 fakesink
并将 sync
设置为 true 以查看您实际可以节省多少 CPU。
我建议添加一些调试信息以更好地理解 videorate 的行为。
export GST_DEBUG=2,videorate:7
然后你可以 grep for "pushing buffer" 因为当它推送时:
gst-launch-1.0 [PIPELINE] 2>&1 | grep "pushing buffer"
..并在接收数据时用于存储缓冲区:
gst-launch-1.0 [PIPELINE] 2>&1 | grep "storing buffer"
在解码 filesrc 的情况下,你会看到 CPU activity 的爆发,因为解码器会 运行 通过说 60 帧,实现管道已满,暂停,等待 need-buffers
事件进入,然后突然达到 100% CPU 以再次填充管道。
还有其他因素。就像您可能需要注意在某些瓶颈之间有 queue
元素,并设置正确的 max-size
属性。或者您的接收器或源元素可能以意想不到的方式运行。
为了获得您问题的最佳答案,我建议您发布您打算使用的确切管道,包括和不包括视频速率。如果您有类似 "autovideosink" 的内容,请将其更改为它在您的系统上实际解析为的元素。
以下是我测试过的一些管道:
gst-launch-1.0 videotestsrc pattern=snow ! video/x-raw,width=320,height=180,framerate=60/1 ! videorate ! videoscale method=lanczos ! video/x-raw,width=1920,height=1080,framerate=60/1 ! ximagesink
30% CPU 在 htop
gst-launch-1.0 videotestsrc pattern=snow ! video/x-raw,width=320,height=180,framerate=60/1 ! videorate ! videoscale method=lanczos ! video/x-raw,width=1920,height=1080,framerate=1/10
0%,htop 中有 10% 的峰值
Tozar 我将专门解决您在上面的评论中发布的管道。
如果您只打算每十秒发送一次帧,则可能不需要使用 h264。十秒后,帧将完全改变,并且将没有数据相似性需要编码以节省带宽。编码器可能只是假设需要一个新的关键帧。您可以选择 jpegenc 和 rtpjpegpay。
如果您重新编码内容,您肯定会每十秒看到一个 CPU 峰值。这是不可避免的。
如果你想在进行转换的机器上尽可能降低 CPU 使用率,你可以去解析传入的 h264 数据,提取关键帧(IDR 帧),然后将它们传递到次要目的地。这将假设原始发射器发送了关键帧(没有帧内刷新)。这并不容易。
您可能想就您尝试做的事情提出一个更笼统的问题。进行转换的机器的作用是什么?它是否必须自己使用数据?什么类型的机器每十秒接收一次帧,它的作用是什么?