从IP摄像机播放rtsp流时,我遇到~5 sec
延迟。经过一堆谷歌搜索(尤其是this question)后,我使用以下命令将延迟降低为~1 sec
:
ffplay -fflags nobuffer -flags low_delay -framedrop -strict experimental \
-probesize 32 -sync ext rtsp://xxx.xxx.xxx.xxx
但是当我从同一问题尝试mplayer -benchmark
命令时,我发现延迟立即消失(即几乎为0的延迟)。
在mplayer
的手册页中说:
-基准
在播放结束时打印一些有关CPU使用率和丢帧的统计信息。与-nosound和-vo null结合使用,仅对视频编解码器进行基准测试。
注意:使用此选项,MPlayer在仅播放视频时也将忽略帧持续时间(您可以将其视为无限fps)。
我认为这个“忽略帧持续时间”是问题的关键,但是经过一堆谷歌搜索之后,我在ffmpeg
中没有发现与此相关的任何标志。我想知道如何在ffmpeg
中强制忽略输入帧持续时间?
另一方面,我使用ffmpeg
的原因是因为我需要使用opencv
进行图像处理,而我发现它似乎正在使用ffmpeg
的某些部分做完这些事
cv.VideoCapture('rtsp://xxx.xxx.xxx.xxx')
直接解决opencv
中问题的解决方案将受到更大的赞赏。我确实尝试过在一个单独的线程中反复读取VideoCapture
,但没有帮助。
有关RTSP流的一些信息:h264、1920x1080、15fps,每4s 1个关键帧
我尝试过的其他解决方案:
ffmpeg -r 99999 -i ...
# didn't work
mplayer ... -dumpstream
# it core dumped
答案 0 :(得分:0)
由于I / O延迟减少,因此在单独的线程中使用VideoCapture()
读取帧应提高性能。 read()
操作被阻止,因此主程序被暂停,直到从相机流中读取一帧为止。通过将读取的帧放在单独的线程中,我们应该能够并行抓取和显示帧,而不是依赖单个线程按顺序抓取帧。将src
替换为您的RTSP流链接。
可能会有延迟的另一个原因可能是因为您的分辨率为1920x1080
。在显示框架之前,您可以调整其大小,这样可以提供更好的性能。
from threading import Thread
import cv2, time
class VideoStreamWidget(object):
def __init__(self, src=0):
self.capture = cv2.VideoCapture(src)
# Start the thread to read frames from the video stream
self.thread = Thread(target=self.update, args=())
self.thread.daemon = True
self.thread.start()
def update(self):
# Read the next frame from the stream in a different thread
while True:
if self.capture.isOpened():
(self.status, self.frame) = self.capture.read()
time.sleep(.01)
def show_frame(self):
# Display frames in main program
cv2.imshow('frame', self.frame)
key = cv2.waitKey(1)
if key == ord('q'):
self.capture.release()
cv2.destroyAllWindows()
exit(1)
if __name__ == '__main__':
video_stream_widget = VideoStreamWidget()
while True:
try:
video_stream_widget.show_frame()
except AttributeError:
pass