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

GStreamer:计算接收到的视频帧/缓冲区中的延迟,以检测Tx和Rx之间的通信延迟,gstreamer,video-processing,rtp,rtcp,Gstreamer,Video Processing,Rtp,Rtcp,我正在研究一个应用程序,它需要检测接收视频帧的延迟,然后在检测到延迟时采取行动。接收视频帧的延迟被视为渲染窗口上的视频冻结。该操作是在视频冻结后在实时视频之间插入IMU帧。以下是管道: Tx-Rx使用WiFi以临时模式连接,无需更多设备。此外,这里只传输视频,音频不受关注 Tx(iMX6设备): Rx(ubuntu PC): 现在根据我的应用,我打算在接收设备上检测接收帧的延迟。延迟可由许多因素引起,包括: 拥挤 丢包 噪音等 一旦检测到延迟,我打算在实时视频帧之间插入一个IMU(惯性测量单

我正在研究一个应用程序,它需要检测接收视频帧的延迟,然后在检测到延迟时采取行动。接收视频帧的延迟被视为渲染窗口上的视频冻结。该操作是在视频冻结后在实时视频之间插入IMU帧。以下是管道:

Tx-Rx使用WiFi以临时模式连接,无需更多设备。此外,这里只传输视频,音频不受关注

Tx(iMX6设备):

Rx(ubuntu PC):

现在根据我的应用,我打算在接收设备上检测接收帧的延迟。延迟可由许多因素引起,包括:

  • 拥挤
  • 丢包
  • 噪音等
一旦检测到延迟,我打算在实时视频帧之间插入一个IMU(惯性测量单元)帧(自定义可视化)。例如,如果每3帧延迟一次,视频将如下所示:

                    V | V | I | V | V | I | V | V | I | V | ..... 
其中,接收到V-视频帧,并在接收设备处插入I-IMU帧

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

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

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

  • 因为我使用的是RTP/RTCP,所以我对WebRTC进行了研究,但它更倾向于发送SR/RR(网络统计数据),只发送从Tx->Rx发送的一小部分数据。我还尝试使用UDP源超时功能,检测在预定义的时间内源是否没有数据包,并发出信号通知超时。但是,这仅在Tx设备完全停止(使用Ctrl+C停止管道)的情况下起作用。如果数据包被延迟,则不会发生超时,因为内核会缓冲一些旧数据 我有以下问题:

  • 使用每个视频帧/RTP缓冲器的时间戳来检测Rx设备接收帧的延迟有意义吗?对于这样的用例,考虑什么更好的设计呢?还是考虑到每帧/缓冲器的时间戳开销太大,我可以考虑像每第五个视频帧/缓冲器之类的视频帧的时间戳,或者每帧10帧/缓冲器的时间戳?另外,RTP数据包与FPS不同,这意味着对于30 FPS的视频,我可以在GStreamer中接收30多个RTP缓冲区。考虑到每个备用帧延迟的最坏情况,视频将具有以下序列:

               V | I | V| I | V | I | V | I | V | I | ..... 
    
    我知道,每个备用帧的精度可能难以处理,因此我的目标是在66毫秒内检测和插入IMU帧。此外,在实时视频帧和插入帧之间切换也是一个问题。我使用OpenGL插件来处理IMU数据

  • 我应该在接收设备上考虑哪些时间戳?为了计算延迟,我需要一个Tx和Rx设备之间的公共参考,我不知道这一点。我可以访问RTP缓冲区的PTS和DTS,但由于没有可用的参考,我无法使用它来检测延迟。我还有别的办法吗

  • My caps具有以下参数(仅显示少数参数):

    caps=application/x-rtp,时钟速率=90000,时间戳偏移=2392035930,seqnum偏移=23406

  • 这可用于计算Tx和Rx处的参考值吗?我不确定我是否理解这些数字,以及如何在Rx设备上使用它们来获得参考。了解这些参数有什么建议吗

  • 可用于此类应用的任何其他可能方法。我的上述想法可能太不切实际,我愿意接受解决这个问题的建议
    您可以从RTP/RTCP获得绝对NTP时间。检查RTP RFC。了解流之间的流同步是如何完成的。基本上,每个音频和视频流都彼此一无所知。但每个流都有自己的RTP时基,并通过RTCP发送信息,该时基在NTP中表示什么

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

    如果您每帧有多个数据包,这并没有多大区别。属于同一帧的所有数据包都应带有相同的时间戳。因此,您可能希望捕获第一个数据包-如果您收到带有时间戳的数据包,您已经知道,您只需忽略它们


    这到底有多准确——我不知道。通常视频流具有高峰值帧(关键帧),但发送通常是平滑的,以防止数据包丢失。这将引入大量抖动,用于测量您尝试执行的操作。

    事实上,您不需要同步到NTP Tx和Rx设备,但您可以分别使用Tx和Rx帧之间的时差,并对它们进行比较。您还可以估计设备之间的时间差,至少为所有帧的
    (帧接收时间(Ntp Rx)-发送时间(Ntp Tx))
    ,然后使用该差进行帧分析。@Kozyr&@Florian如果我理解正确,我必须在元素
    rtpbin
    的Rx管道上添加一个探针,并分析缓冲区时间戳。这将给我发送时间(Ntp Tx
                        V | V | I | V | V | I | V | V | I | V | ..... 
    
               V | I | V| I | V | I | V | I | V | I | .....