我正在研究一个应用程序,它需要检测接收视频帧的延迟,然后在检测到延迟时采取行动。接收视频帧的延迟被视为渲染窗口上的视频冻结。动作是在视频冻结发生后在实时视频之间插入一个 IMU 帧。以下是管道:
Tx-Rx 使用 WiFi 以 adhoc 模式连接,无需更多设备。也只传输视频,音频在这里不是问题。
Tx(iMX6 设备):
v4l2src fps-n=30 -> h264encode -> rtph264pay -> rtpbin -> udpsink(port=5000) ->
rtpbin.send_rtcp(port=5001) -> rtpbin.recv_rtcp(port=5002)
接收(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 的速度工作,理想情况下,我应该期望每 33 毫秒在 Rx 设备上接收一次视频帧。考虑到它的 WiFi 和其他延迟(包括编码/解码)的情况,我知道这 33 毫秒的精度很难实现,对我来说完全没问题。
- 因为,我使用的是 RTP/RTCP ,所以我查看了 WebRTC,但它更适合仅针对从 Tx -> Rx 发送的一小部分数据发送 SR/RR(网络统计信息)。我还尝试使用 UDP 源超时功能,该功能检测源是否在预定义的时间内没有数据包,并发出信号通知超时。但是,这仅在 Tx 设备完全停止(使用 Ctrl+C 停止管道)时才有效。如果数据包被延迟,则不会发生超时,因为内核会缓冲一些旧数据。
我有以下问题:
使用每个视频帧/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 设备上使用它们来获得参考。关于理解这些参数的任何指示?
- 可以为此类应用程序采取的任何其他可能的方法。我的上述想法可能太不切实际了,我愿意接受解决这个问题的建议。