使用OpenCV GStreamer读取HLS流时,CPU使用率很高

时间:2019-03-25 21:47:44

标签: python opencv gstreamer

我有以下代码创建一个gstreamer管道来处理HLS流。

cap = cv2.VideoCapture(
    f"souphttpsrc is_live=true location={hls_stream_link} ! hlsdemux ! 
    queue ! decodebin ! videorate ! video/x-raw,framerate=1/1 ! 
    videoconvert ! appsink max-buffers=1 drop=true sync=false",
cv2.CAP_GSTREAMER)

我现在这样读取流:

while True:
    success, frame = cap.read()
    time.sleep(1.0)

注意,我以1 FPS的速度读取流,并且具有属性max-buffers=1 drop=true sync=false。这样,我总是从缓冲区必须提供的流中获取最新的帧。

与此有关的问题是CPU使用率非常高,在我的i7机器上有时达到120%。取消睡眠会使情况变得更糟。

关于为何处理HLS流如此之多的CPU密集度的任何解决方案或想法都是很不错的。同样,关于减少使用量的想法也很棒。

2 个答案:

答案 0 :(得分:1)

您正在解码完整的流。用软件完成时,这可能会非常昂贵。我在这里看到的一个潜在的优化步骤是在解码器之前添加GstPadProbe并将一个比特解析为比特流,并丢弃所有非IDR的样本。然后,您将仅将IDR帧发送到解码器。这样做会减少解码器的负载,但是只有在每个IDR帧间隔(通常为每2秒(但可能在每个之间可能有所不同))之后,您才会得到一个新帧。

答案 1 :(得分:0)

您的应用程序出现峰值的一个原因可能是由于读取帧时的I / O延迟。 cv2.VideoCapture().read()是一项阻止操作,因此您的程序将停顿,直到从流中读取一帧为止。一种提高性能的方法是生成另一个线程以 parallel 的方式处理抓帧,而不是依赖单个线程以 sequential 的顺序抓帧。通过指定一个仅轮询新帧的单独线程,可以提高性能,因为您的主线程可以执行其他操作。

from threading import Thread
import time

def read_frames():
    while True:
        if cap.isOpened():
            success, frame = cap.read()
        time.sleep(1)

thread = Thread(target=read_frames, args=())
thread.daemon = True
thread.start()