pyav / libav / ffmpeg 当来自实时源的帧处理速度不够快时会发生什么
pyav / libav / ffmpeg what happens when frame from live source are not processed fast enough
我正在使用 pyav
处理实时 RTSP 流:
import av
import time
URL = "RTSP_url"
container = av.open(
url, 'r',
options={
'rtsp_transport': 'tcp',
'stimeout': '5000000',
'max_delay': '5000000',
}
)
for packet in self.container.demux(video=0):
for frame in packet.decode():
# do something
time.sleep(10)
如果我 do something
太慢会怎样?帧/数据包是否被丢弃或被缓冲?
我想同样的问题也适用于 libav
或 ffmpeg
。
tcp
是一种具有内置流量控制的保证传送协议。如果你没有像接收到的那样快速处理传入的数据,tcp
堆栈将缓冲数据直到其缓冲区已满,此时 tcp
协议将让发送方知道它无法接收任何更多的数据。如果这种情况持续下去,发送方的输出缓冲区最终将填满,然后由发送方决定要做什么。
此时的 IP 摄像机可能会丢失帧,甚至可能会断开连接。大多数 IP 摄像机还使用保持活动机制,通常是通过通过 RTSP 流发送的 RTCP 数据包。相机可以发送发送方报告,接收方应发回接收方报告。如果摄像头在超时时间内没有收到 Receiver Report,它将断开连接。我不得不假设 av
库或 ffmpeg
正在这样做。
你可能不想做 time.sleep(10)
。
如果你真的觉得你需要丢弃数据包,那么你可以在调用 decode
之前检查你的数据包,看看你是否落后了。如果你落后太多,你可以丢弃不是关键帧的数据包,直到你赶上。效果就是视频会有跳动。
根据我的经验,gstreamer 可以将旧帧存储在缓冲区中,甚至在几分钟后 return 它们。不确定 PyAv 是否会做同样的事情。
我正在使用 pyav
处理实时 RTSP 流:
import av
import time
URL = "RTSP_url"
container = av.open(
url, 'r',
options={
'rtsp_transport': 'tcp',
'stimeout': '5000000',
'max_delay': '5000000',
}
)
for packet in self.container.demux(video=0):
for frame in packet.decode():
# do something
time.sleep(10)
如果我 do something
太慢会怎样?帧/数据包是否被丢弃或被缓冲?
我想同样的问题也适用于 libav
或 ffmpeg
。
tcp
是一种具有内置流量控制的保证传送协议。如果你没有像接收到的那样快速处理传入的数据,tcp
堆栈将缓冲数据直到其缓冲区已满,此时 tcp
协议将让发送方知道它无法接收任何更多的数据。如果这种情况持续下去,发送方的输出缓冲区最终将填满,然后由发送方决定要做什么。
此时的 IP 摄像机可能会丢失帧,甚至可能会断开连接。大多数 IP 摄像机还使用保持活动机制,通常是通过通过 RTSP 流发送的 RTCP 数据包。相机可以发送发送方报告,接收方应发回接收方报告。如果摄像头在超时时间内没有收到 Receiver Report,它将断开连接。我不得不假设 av
库或 ffmpeg
正在这样做。
你可能不想做 time.sleep(10)
。
如果你真的觉得你需要丢弃数据包,那么你可以在调用 decode
之前检查你的数据包,看看你是否落后了。如果你落后太多,你可以丢弃不是关键帧的数据包,直到你赶上。效果就是视频会有跳动。
根据我的经验,gstreamer 可以将旧帧存储在缓冲区中,甚至在几分钟后 return 它们。不确定 PyAv 是否会做同样的事情。