GStreamer:计算接收到的视频帧/缓冲区中的延迟以检测Tx和Rx之间的通信延迟

时间:2018-11-06 10:07:34

标签: gstreamer video-processing rtp rtcp

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

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

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

由于我的工作速率为30 fps,因此理想情况下,我应该期望每33ms在Rx设备上接收一次视频帧。考虑到它的WiFi以及包括编码/解码在内的其他延迟的情况,我了解到这种33ms的精度很难实现,并且对我来说非常好。

  1. 由于我使用的是RTP / RTCP,因此对WebRTC进行了研究,但它更适合发送SR / RR(网络统计信息),仅用于从Tx-> Rx发送的部分数据。我还尝试使用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. 可以为这种应用程序采取的任何其他可能的方法。我的上述想法可能太不切实际,我愿意提出解决该问题的建议。

1 个答案:

答案 0 :(得分:2)

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

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

如果每帧有多个数据包,那么差别不大。属于一帧的所有数据包应带有相同的时间戳。因此,您可能想捕获第一个-如果收到带有时间戳的数据包,您已经知道您只是忽略它们。

实际上有多精确-我不知道。通常,视频流具有较高的峰值帧(关键帧),但通常会平滑发送以防止丢包。这会引入很多抖动来衡量您要尝试执行的操作。