RTSP协议浅析和花屏检测

简单介绍

RTSP(Real Time Streamin Protocol),是TCP/IP协议体系中的一个应用层协议,由哥伦比亚大学、网景和RealNetworks公司提交的IETF RFC标准。该协议定义了一对多应用程序如何有效地通过IP网络传输多媒体数据。RTSP在体系结构上位于RTP和RTCP之上,使用TCP或UDP完成数据传输

在这里插入图片描述

RTP(Real-time Transport Protocol),由IETF地多媒体传输工作小组1996年在RFC1880中公布。RTP协议详细说明了在network上传递音频和视频的标准数据包格式。它创建在UDP协议上。
RTCP(Real-time ControlProtocol),是和RTP一起工作的控制协议,主要功能是为数据传输提供服务质量反馈
根据上述介绍,可以得知RTSP、RTP和RTCP三个协议分别负责的内容如下图所示:

在这里插入图片描述

实时传输协议RTP

**RTP**为语音、图像、传真等多种需要实时传输流媒体数据提供端到端的实时传输服务,但不保证服务质量,服务质量由RTCP来提供。
流媒体,指的是Internet上使用流式传输技术的时基媒体。与常见的下载方式不同,流式传输的特点是边下载边观看,无需等到音频或视频数据全部下载完成后在播放。

RTP协议的工作原理

RTPRTCP位于传输层,运行在UDP协议之上。UDP协议具有实时性好,数据传输延时低等特点,且可以利用UDP的多路复用、校验和服务。

RTP报文分析

RTP数据协议负责对流媒体数据进行封包并实现流媒体数据的实时传输,每个RTP数据packet都由headerpayload两部分组成,其中header的前12个字节的含义是固定的,而payload可以是音频或者视频数据。

在这里插入图片描述

其中RTP packetheader定义和含义如下所示:

在这里插入图片描述

RTP封包

当应用程序建立一个RTP会话时,应用程序将确定一对目的传输地址。目的传输地址由一个网络地址和一对端口组成,RTP数据发向偶数的UDP端口,而对应的控制信号RTCP数据发给相邻的奇数UDP端口,这样就构成一个UDP端口对。
RTP协议从上层接收流媒体信息码流,封装成RTP数据包,然后将其发往UDP端口对中偶数端口。
下面以H264视频数据为例,介绍RTP如何封装H264数据。H264有三种打包方式如下:

  • 单NALU打包:一个RTP packet包含一个完整的NALU;
  • 聚合打包:对应较小的NALU,一个RTP报可包含多个完整的NALU;
  • 分片打包:对于较大的NALU,一个NALU可以分为多个RTP packet发送;

每一个RTP packet都包含一个RTP header和 payload,但是不同的打包方式下,除了header和payload之外,还包含了一些其他东西。

  • 单NALU打包

所谓单NALU打包就是将一整个NALU的数据放入RTP包的载荷中,这是最简单的一种方式。

  • 分片打包

每个RTP包都有大小限制的,因为RTP一般都是使用UDP发送,UDP没有流量控制,所以要限制每一次 发送的大小,所以如果一个NALU的太大,就需要分成多个RTP包发送。
分片打包下,RTP中除了header和payload之外,在payload开始之前还有两个字节的信息,如下所 示:

在这里插入图片描述


第一个字节,称为FU Indicator,其格式如下:

在这里插入图片描述

其中高三位,与NAL头的高三位相同,后五位为Type,值为28,表示该RTP packet的分片类型。

  Type    Packet      Type name                       
  ---------------------------------------------------------
  0       undefined                                    -
  1-23    NAL unit     Single NAL unit packet per H.264  
  24      STAP-A       Single-time aggregation packet    
  25      STAP-B       Single-time aggregation packet    
  26      MTAP16       Multi-time aggregation packet     
  27      MTAP24       Multi-time aggregation packet     
  28      FU-A         Fragmentation unit                
  29      FU-B         Fragmentation unit                 
  30-31   undefined  

第二个字节,称为FU Header,其格式如下:

在这里插入图片描述

其中,第一位:S,表示该 RTP packet为NALU分片的第一个包,第二位:E,表示该 RTP packet为NALU分片的最后一个包,第三位:保留位,必须设置为0,最后五位:NALU的Type信息。
因此,对于RTP封装H264流数据,在不同打包方式下,RTP数据包的内容如下图所示:

在这里插入图片描述

RTP解包

RTP解包,对于H264数据而言,指的是接收到一个RTP packet,首先需要判断RTP打包方式是单NALU打包还是分片打包,然后在packet payload中获取得到H264NAL数据,并加上0x00000001起始字节一并写进文件中即可。

RTSP的pipeline

Gstreamer对于RTP和RTSP具有良好的支持。在实际的视觉任务中,都需要通过RTSP获取到实时数据,然后使用深度学习模型对其进行分析。深度学习推理框架Deepstream基于Gstreamer搭建而成,因此对RTSP的pipeline进行分析非常有必要。

pipeline

Deepstream的环境下,通过如下的命令可以实现拉取RTSP流,然后使用模型对数据进行分析,然后识别的结果保存成一张张连续的图像数据。

gst-launch-1.0 rtspsrc location=rtsp://10.9.4.133/30012 ! rtph264depay ! h264parse ! nvv4l2decoder ! m.sink_0 nvstreammux name=m batch-size=1 width=1920 height=1080 ! nvinfer config-file-path=/opt/nvidia/deepstream/deepstream-6.0/samples/configs/deepstream-app/config_infer_primary.txt batch-size=4 unique-id=1 ! nvmultistreamtiler rows=1 columns=1 width=1920 height=1080 ! nvvideoconvert ! nvdsosd display-bbox=0 display-text=0 ! nvvideoconvert ! jpegenc ! multifilesink location=test%d.jpg

pipeline可视化

对于上述的pipeline,可以通过如下的步骤导出pipeline的结构图,具体如下:

  1. 安装dot
 sudo apt-get install graphviz
  1. 设置文件输出环境变量
export GST_DEBUG_DUMP_DOT_DIR=/tmp/
  1. 运行pipeline

新建终端,拷贝上述的命令,修改实际的RTSP地址,运行命令。在上述指定的路径下,此时会生成很 多dot文件,如下图所示:

$  ls /tmp 
0.00.00.238129310-gst-launch.NULL_READY.dot
0.00.00.247064574-gst-launch.READY_PAUSED.dot
0.00.00.632677398-gst-launch.PAUSED_PLAYING.dot
0.00.05.464861472-gst-launch.PLAYING_PAUSED.dot
0.00.05.484623147-gst-launch.PAUSED_READY.dot
  1. 生成pipeline结构图
dot -Tpng 0.00.05.464861472-gst-launch.PLAYING_PAUSED.dot > aa.png
dot -Tpdf 0.00.05.464861472-gst-launch.PLAYING_PAUSED.dot > aa.pdf

相关的elements介绍

pipeline的结构如下图所示,由于上述命令的pipeline结构比较复杂,这里主要提出了参与RTSP的部分elements

在这里插入图片描述


在这里插入图片描述

rtpjitterbuffer

This element reorders and removes duplicate RTP packets as they are received from a network source.
该元素重新排序并删除从网络源接收到的重复 RTP 数据包
该element需要RTP payload的clock-rate信息,用于评估delay延迟。
如果接收到packet时间比较迟,则会触发一个GstRTPPacketLost event。通过该event,depayloader或者其他element可以创建concealment数据或者一些其他逻辑来处理丢失的数据packet。
jitterbuffer 结合输入buffer的DTS属性和PTP packet中的rtptime属性来初始化输出buffer的PTS属性。
jitterbuffer通过初步计算一个packet何时到达,如果一个packet到达时间过迟,可以向上游发送一个GstRTPRetransmissionRequest event(重传)。
This element will automatically be used inside rtpbin.(RtpBuffer)

rtph264depay

Extracts H264 video from RTP packets
RTP 数据包中提取 H264 视频,也就是我们上面介绍的RTP解包过程。在该element的实现中,gst_rtp_h264_depay_process函数中实现了RTP数据包的解包工作。

丢包模拟

流媒体数据通过RTSP协议传输在实际场景下,由于网络、带宽等原因,数据在传输过程中存在丢包(RTP packet)导致解码得到的图像数据存在花屏,而对于视觉算法而言,花屏就会导致误检降低检测性能,因此需要尽可能避免花屏的出现。
在这一小节中,首先介绍如何人为制造花屏数据,以便进行后续花屏检测的测试工作。在Linux平台下,提供一个流量控制工具TC,能够模拟一些异常的网络情况,例如网络延时长、丢包、网络地址连接不通等。
TC工具的主要用法如下:
传输延迟

  • 将设备eth0网卡的传输设置为延迟100毫秒发送
tc qdisc add dev eth0 root netem delay 100ms
  • 将传输设置为延迟100ms ± 10ms
tc qdisc add dev eth0 root netem delay 100ms 10ms

模拟网络丢包

  • 随机丢掉1%的数据包
tc qdisc add dev eth0 root netem loss 1%
  • 随机丢掉1%的数据包,成功率为30%
tc qdisc add dev eth0 root netem loss 1% 30%

模拟包重复

  • 随机产生1%的重复数据包
tc qdisc add dev eth0 root netem duplicate 1%

模拟包损坏

  • 随机产生 0.2% 的损坏的数据包
tc qdisc add dev eth0 root netem corrupt 0.2%

模拟包乱序

  • 有 25% 的数据包(50%相关)会被立即发送,其他的延迟10 秒
tc qdisc change dev eth0 root netem delay 10ms reorder 25% 50%

删除规则

sudo tc qdisc del dev eth0 root

显示规则

sudo tc -s qdisc ls dev eth0

利用TC实现花屏

RTSP传输数据过程中,花屏造成的主要原因是RTP packet内部数据丢失造成,因此通过TC工具的模拟队丢包命令即可得到花屏数据。

  1. 模型丢包

首先在一台机器上将视频数据完成RTSP推理,然后输入如下模拟丢包命令:

# 在当前设备上模拟丢包5%
tc qdisc add dev eth0 root netem loss 5%
# 查看当前设备已经运行的TC命令
sudo tc -s qdisc ls dev eth0
  1. 运行命令,拉取RTSP流

输入如下命令,拉取RTSP流,得到每一帧的图像数据

gst-launch-1.0 rtspsrc location=rtsp://10.9.4.133/30012 ! rtph264depay ! h264parse ! nvv4l2decoder ! m.sink_0 nvstreammux name=m batch-size=1 width=1920 height=1080 ! nvinfer config-file-path=/opt/nvidia/deepstream/deepstream-6.0/samples/configs/deepstream-app/config_infer_primary.txt batch-size=4 unique-id=1 ! nvmultistreamtiler rows=1 columns=1 width=1920 height=1080 ! nvvideoconvert ! nvdsosd display-bbox=0 display-text=0 ! nvvideoconvert ! jpegenc ! multifilesink location=test%d.jpg
  1. 查看花屏数据
    在这里插入图片描述

花屏检测

造成花屏的本质原因是数据传输过程中RTP包丢失,也即RTP packetheaderseqnum不连续,因此花屏检测的思路如下:

在这里插入图片描述

1. 接收RTP packet,与上一个packetseqnum对比,判断seqnum是否连续;
2. 如果seqnum不连续,判断接收到的RTP packetNAL Type,判断是否为关键帧;
3. 如果不是关键帧,则将该RTP packet的数据抛弃;
4. 一直抛弃数据,直到下一个关键帧,才开始重启处理数据;
上述花屏检测的业务逻辑可以在**rtph264depay element**的源码中实现,上述过程存在一个问题,由于花屏会丢弃一些数据,导致画面帧可能不连续~~~

参考链接

  • https://zhuanlan.zhihu.com/p/72917813
  • https://blog.csdn.net/u013554213/article/details/98078955
  • https://developer.aliyun.com/article/243398
  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值