之前用Jrtp的库来传输H264视频时,将摄像头编码后的视频数据直接发送,然后在另外一个开放板接收数据,解码,显示,实现效果很不错。一个开发板编码发送,一个开发板接收解码,不用考虑帧率,也不用考虑RTP数据报头部数据各个位的含义。然而想做到在开发板上采集,电脑上通过VLC播放时,却一直实现不了。后来在网上找了个通过UDP实现RTP协议的代码,终于OK了。通过WireShark抓包发现,我在用Jrtp传输H264视频时,数据报负载部分(Payload)是没啥问题,可数据报的头部那12个字节确有点莫名其妙,与直接用UDP socket函数发送的抓包数据差异很大,这个要解决,估计也只能查查Jrtplib的源码了,看看哪里没配置对。看Jrtplib的网站,自2011年后就没有更新了,我也打算后续用更为强大的ffmpeg库来做实时视频传输,所以Jrtplib就暂停研究,后面我会写个用它做板子到板子之间视频传输的博客。这里就先写一写已经实现了通过RTP传输H264格式视频的过程,首先来介绍几个概念。
实时传输协议(RTP)是在Internet上处理多媒体数据流的一种网络协议,利用它能够在一对一或者一对多的网络环境中实现流媒体数据的实时传输。RTP通常使用UDP来进行多媒体数据的传输,但如果需要的话也可以使用TCP等其他协议,整个RTP协议由两个密切相关的部分组成:RTP数据协议和RTCP控制协议。
RTP数据协议负责对流媒体数据进行封包并实现媒体流的实时传输,每一个RTP数据报都由头部(Header)和负载(Payload)两个部分组成,其中头部前12个字节的含义是固定的,而负载则可以使音频或者视频数据。
RTCP控制协议需要与RTP数据协议一起配合使用,当应用程序启动一个RTP会话时将同时占用两个端口,分别供RTP和RTCP使用。RTP本身并不能为按序传输数据包提供可靠的保证,也不提供流量控制和拥塞控制,这些都由RTCP来负责完成。通常RTCP会采用与RTP相同的分发机制,向会话中的所有成员周期性地发送控制信息,应用程序通过接收这些数据,从中获取会话参与者的相关资料,以及网络状况、分组丢失概率等反馈信息,从而能够对服务质量进行控制或者对网络状况进行诊断。
实时流协议RTSP,它的意义在于使得实时流媒体数据的受控和点播变得可能。总的来说,RTSP是一个流媒体表示协议,主要来控制具有实时特性的数据发送,但它本身并不传输数据,而是必须依赖于下层传输协议所提供的某些服务。RTSP可以对流媒体提供诸如播放、暂停、快进等操作,它负责定义具体的控制消息、操作方法、状态码等,此外还描述了与RTP间的交互操作。
接下来要做的就比较清楚了,只要实现RTP数据协议即可实现直播的效果。发送RTP数据报时,需要设置的为头部(Header)和负载(Payload)两部分,也就是“数据头+数据”这样的形式。先来看下Header。
这张图中,前12个字节在每个RTP包中都存在,他们是:V版版号(2bit),P填充位(1bit),X扩展位(1bit),CC是CSRC的计数位(4bits);M标记位(1bit),PT有效