我正在研究一种需要检测接收视频帧中的延迟,然后在检测到延迟时采取措施的应用程序。接收视频帧的延迟被认为是渲染窗口上的视频冻结。由于发生视频冻结,因此操作是在实时视频之间插入IMU帧。以下是管道:
Tx-Rx使用WiFi临时连接,没有更多设备。此外,仅传输视频,这里不关心音频。
Tx(iMX6设备):
v4l2src fps-n=30 -> h264encode -> rtph264pay -> rtpbin -> udpsink(port=5000) ->
rtpbin.send_rtcp(port=5001) -> rtpbin.recv_rtcp(port=5002)
Rx(ubuntu PC):
udpsrc(port=5000) -> rtpbin -> rtph264depay -> avdec_h264 -> rtpbin.recv_rtcp(port=5001) ->
rtpbin.send_rtcp(port=5002) -> custom IMU frame insertion plugin -> videosink
现在按照我的应用程序,我打算检测Rx设备接收帧的延迟。造成延迟的原因有很多,其中包括:
一旦检测到延迟,我打算在实况视频帧之间插入一个IMU(惯性测量单位)帧(自定义可视化)。例如,如果每3帧被延迟,视频将如下所示:
V | V | I | V | V | I | V | V | I | V | .....
其中V-收到视频帧,I-在Rx设备上插入IMU帧
因此,根据我的应用程序要求,要实现此目的,我必须了解从Tx发送的视频帧的时间戳,并将此时间戳与Rx设备上的当前时间戳结合使用以获取传输延迟。
帧延迟= Rx处的当前时间-Tx处的帧时间戳
由于我的工作速率为30 fps,因此理想情况下,我应该期望每33ms在Rx设备上接收一次视频帧。考虑到它的WiFi以及包括编码/解码在内的其他延迟的情况,我了解到这种33ms的精度很难实现,并且对我来说非常好。
我有以下问题:
使用每个视频帧/ RTP缓冲区的时间戳来检测Rx设备在接收帧中的延迟是否有意义?对于这样的用例,考虑哪种更好的设计呢?还是考虑每个帧/缓冲区的时间戳是否有太多开销,也许我可以考虑像第5个视频帧/缓冲区或每10个帧/缓冲区这样的视频帧因子的时间戳?另外,RTP数据包与FPS不同,这意味着对于30 fps的视频,我可以在GStreamer中接收30个以上的RTP缓冲区。考虑到最坏的情况,每个替代帧都会延迟,视频将具有以下顺序:
V | I | V| I | V | I | V | I | V | I | .....
我知道每个备用帧的精度可能难以处理,因此我的目标是至少在66毫秒内检测和插入IMU帧。同样,实况视频帧和插入帧之间的切换也是一个问题。我使用OpenGL插件执行IMU数据操作。
我应该在Rx设备上考虑哪个时间戳?要计算延迟,我需要Tx和Rx设备之间的通用参考,而我对此并不了解。我可以访问RTP缓冲区的PTS和DTS,但是由于没有可用的引用,因此无法使用它来检测延迟。我还有其他方法可以做到吗?
我的帽子有以下参数(仅显示了几个参数):
caps = application/x-rtp , clock-rate = 90000, timestamp-offset = 2392035930,seqnum-offset= 23406
这可以用来计算Tx和Rx处的参考吗?我不确定我是否理解这些数字以及如何在Rx设备上使用它们以获得参考。关于了解这些参数的任何指示?
答案 0 :(得分:2)
您可以从RTP / RTCP获得绝对NTP时间。检查RTP RFC。了解流之间如何完成流同步。基本上,每个音频和视频流彼此都不知道。但是每个流确实都有自己的RTP时基,并通过RTCP发送信息,该时基在NTP中表示什么。
所以-对于每个帧,您都可以获取其NTP时间表示。因此,假设您的设备已正确同步到NTP,则您应该能够将接收到的NTP时间与接收器的当前NTP时间进行比较,并且-我大概应该知道两者之间的延迟。
如果每帧有多个数据包,那么差别不大。属于一帧的所有数据包应带有相同的时间戳。因此,您可能想捕获第一个-如果收到带有时间戳的数据包,您已经知道您只是忽略它们。
实际上有多精确-我不知道。通常,视频流具有较高的峰值帧(关键帧),但通常会平滑发送以防止丢包。这会引入很多抖动来衡量您要尝试执行的操作。