rtp学习ing

来源:互联网 发布:帝国cms模板表单 编辑:程序博客网 时间:2024/05/22 01:27

rtp的包头如果没有附加数据的话至少有12个字节


指定rtp端口时必须是偶数

 

下一个奇数端口是给对应的rtcp的

 

SetMaximumPacketSize(size_t max)时,应设置为 你的数据长+12包头


multicast distribution 组播分发


/******************************************************************************************************************

RTP包头的灵活运用
1、负载类型位(pt)7比特
2、标志位(M)1比特
3、扩展(X)1比特,置位时有扩展数据

在jrtp的RTPSession::SendPacketEx函数如下
int RTPSession::SendPacketEx(const void *data,size_t len,
                      uint8_t pt,bool mark,uint32_t timestampinc,
                      uint16_t hdrextID,const void *hdrextdata,size_t numhdrextwords);

pt:
是负载类型位

mark:
是标志位

uint16_t hdrextID,const void *hdrextdata,size_t numhdrextwords:
扩展数据部分,hdrextID扩展数据的自定义标识,hdrextdata指向扩展数据,numhdrextwords扩展数据长


data:

负载数据

len:

负载数据长

*******************************************************************************************************************/


/******************************************************************************************************************

之前抓的一个bug,隐藏的比较深,这里做一下记录,这里是对live555的改造


现象:


客户端模拟了一个拖流程序,拖流路数可设,目标500路,只拖流不解码

拖流路数上了一定数量(??)后,其中一些会断开,网络流量下降。


解决:

  最后发现是一个deadBuf_设置为static的了,导致所有session的FramedSource的deadBuf_是同一个,虽然live555是单线程的,但是session的执行是有时间的,当session A 填充了deadBuf_后,推送给了scheduler要求过了时间t后执行,也就是不一定马上得到执行,就在session A等待被调度的时候,session B被调度了,此时session B执行的操作是填充deadBuf_!!!他把session A向其填充的内容给覆盖了!!!(炸弹就此埋下了),然后session B再次被推送给scheduler,等待他的下一次执行,接下来session A先于session B被唤醒了,此时此刻,session A的任务是发送deadBuf_的内容,而deadBuf_的内容却是session B填充的内容,deadBuf_里有什么呢?有ssrc标识,也就是说session A发送的内容里出现了session B的同步源标识。
  每个session发送的目的地是不同的,和客户端(使用jrtplib)的session是一一对应的,session A对应的客户端session接收到该rtp包后发现了新的同步源标识(实际上是session B的ssrc)就将该ssrc加入进来,这里称其为fake ssrc。由于rtcp/rtp协议具有timeout机制,正常的session会定期检测对端(同步源)的存活状态(使用接收到的rtp或rtcp包),很明显fake ssrc是通不过timeout机制检测的,说以,在客户端会在一定时间收不到fake ssrc标识的包后,将该同步源timeout掉,移除该fake ssrc, 同时还执行了一个操作就是将收到该fake ssrc的对端的地址移除掉!!!这个地址实际上和该session的正常ssrc是同一个地址,地址保存在hashtable里,也就是相当于把正常源的地址给移除掉了!!!有不有!!!导致客户端发送地址列表为空, 客户端是要定期向服务端发送rtcp包的,列表为空后,也发不了了。虽然此时客户端还是在不停的收到服务端发来的正常rtp/rtcp包,但是收到后是通过检查ssrc是否为新值来添加流源,同时添加地址的。
  服务端的session A也是会做定时检测的,这里采取的具体方式是收到rtcp包后,更新掉对应的超时处理任务将被处理的时间,只要能在该时间内收到rtcp包,则超时处理就不会执行。前面说到客户端的发送地址被删了,没有rtcp包发出来。则在服务端的session A的超时处理任务会被调度,将session A停掉!!!即不再发rtp/rtcp包了,在客户端看来就表现为网络流量下将了


*******************************************************************************************************************/

//关于时间戳

在使用jrtplib时,SetOwnTimestampUnit是设置时间戳单位,即一个单位的时间戳表示多少时间,比如SetOwnTimestampUnit(1.0/90000);

SetDefaultTimestampIncrement表示时间戳的增量,即一包数据的时间增量,比如SetDefaultTimestampIncrement(90000/25),一秒25帧数据,那么一帧数据的时间增量为90000/25。

http://xingyunbaijunwei.blog.163.com/blog/static/7653806720126121014111/


h264的rtp封装

视音频数据PS封装


当x位置位时表示有扩展数据,扩展数据开始的的2个字节是扩展标识,由用户定义是什么扩展数据,然后的2字节是扩展数据长度,指示了跟在后面的扩展数据长度