2

我正在研究一个应用程序,它需要检测接收视频帧的延迟,然后在检测到延迟时采取行动。接收视频帧的延迟被视为渲染窗口上的视频冻结。动作是在视频冻结发生后在实时视频之间插入一个 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 帧

  1. 因此,根据我的应用程序要求,要实现这一点,我必须了解从 Tx 发送的视频帧的时间戳,并将此时间戳与 Rx 设备上的当前时间戳一起使用,以获得传输延迟。

    帧延迟 = Rx 的当前时间 - Tx 的帧时间戳

由于我以 30 fps 的速度工作,理想情况下,我应该期望每 33 毫秒在 Rx 设备上接收一次视频帧。考虑到它的 WiFi 和其他延迟(包括编码/解码)的情况,我知道这 33 毫秒的精度很难实现,对我来说完全没问题。

  1. 因为,我使用的是 RTP/RTCP ,所以我查看了 WebRTC,但它更适合仅针对从 Tx -> Rx 发送的一小部分数据发送 SR/RR(网络统计信息)。我还尝试使用 UDP 源超时功能,该功能检测源是否在预定义的时间内没有数据包,并发出信号通知超时。但是,这仅在 Tx 设备完全停止(使用 Ctrl+C 停止管道)时才有效。如果数据包被延迟,则不会发生超时,因为内核会缓冲一些旧数据。

我有以下问题:

  1. 使用每个视频帧/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 数据操作。

  2. 我应该在 Rx 设备上考虑哪些时间戳?为了计算延迟,我需要 Tx 和 Rx 设备之间的通用参考,我对此一无所知。我可以访问 RTP 缓冲区的 PTS 和 DTS,但由于没有可用的参考,我无法使用它来检测延迟。有没有其他方法可以做到这一点?

  3. 我的帽子有以下参数(只显示了几个参数):

    caps = application/x-rtp , clock-rate = 90000, timestamp-offset = 2392035930,seqnum-offset= 23406

这可以用来计算 Tx 和 Rx 的参考吗?我不确定我是否理解这些数字以及如何在 Rx 设备上使用它们来获得参考。关于理解这些参数的任何指示?

  1. 可以为此类应用程序采取的任何其他可能的方法。我的上述想法可能太不切实际了,我愿意接受解决这个问题的建议。
4

1 回答 1

3

您可以从 RTP/RTCP 获取绝对 NTP 时间。检查 RTP RFC。了解流之间的流同步是如何完成的。基本上,每个音频和视频流彼此一无所知。但是每个流都有自己的 RTP 时基,并通过 RTCP 发送该时基在 NTP 中表示的信息。

所以 - 对于每一帧,你都可以获得它的 NTP 时间表示。因此,假设您的设备已正确同步到 NTP,您应该能够将接收到的 NTP 时间与接收器的当前 NTP 时间进行比较,并且您应该 - 大致我猜 - 两者之间的延迟。

如果每帧有多个数据包,那并没有太大区别。属于一帧的所有数据包都应携带相同的时间戳。所以你可能想抓住第一个——如果你收到带有时间戳的数据包,你已经知道你只是忽略它们。

这实际上有多准确 - 我不知道。通常视频流具有高峰值帧(关键帧),但通常会平滑发送以防止数据包丢失。这将引入相当多的抖动来衡量你正在尝试做的事情。

于 2018-11-06T13:24:24.957 回答