转自:http://rockmen1.bokee.com/4961895.html
RTSP协议下载RealPlay Helix服务器数据时的RDT数据格式说
RDT是Real的私有协议,这篇文档并非对RDT格式的标准说明,而是基于MPlayer和Xine的开源代码和自己对字段的理解而成,如发现和实际有所出入,请自己权衡判断。如果哪位朋友发现哪里理解错误,欢迎指正。另外如果有朋友愿意翻译一下贴到Xine或MPlayer的论坛,能为他们带来一些帮助的话,不胜感激。(英文太烂了,)
再次感谢MPlayer和Xine开发者所做出的贡献!Thanks MPlayer and Xine!
正常的RDT包应该以0x40或0x42开头(目前尚未发现其他字节开头的正常包),该字节的第二位标明了StreamId,即0x42=1000010,streamid=1;0x40=1000000,streamid=0。
第二和第三个字节表明了该流的传输编号(seq),依次递增。我认为该值应该是根据PLAY RTSP Request的Response中RTP-Info字段中seq中值为基础递增的。典型的RTP-Info返回值如:
RTP-Info: url=rtsp://localhost/1.rm/streamid=0;seq=0;rtptime=0, url=rtsp://localhost/1.rm/streamid=1;seq=0;rtptime=0
意味着stream 0和stream 1传输编号都是从0开始。如果在播放媒体文件当中用户跳转,会发送PAUSE,PLAY指令,该PLAY指令返回值的RTP-Info指明了新的seq,意味着客户端应该丢弃该seq前的数据包,从该seq数据包开始解码。
Virtual Example:
–> PLAY rtsp://localhost/1.rm RTSP/1.0 …… Range: npt=0- …..
<– RTSP/1.0 200 OK ……. RTP-Info: url=rtsp://localhost/1.rm/streamid=0;seq=0;rtptime=0, url=rtsp://localhost/1.rm/streamid=1;seq=0;rtptime=0
<– Transfer Protocol Header(Such as RTSP Embedded Binary Data, see RFC 2326 10.12) 0x40 0x00 0x00 ….
<– … 0x40 0x00 0x01 …
<– … 0x42 0x00 0x00 …
<– … 0x40 0x00 0x02 …
<– …….
<– … 0x40 0x10 0x81 …
<– … 0x42 0x08 0x22 …
–> PAUSE rtsp://localhost/1.rm RTSP/1.0 ……..
<– RTSP/1.0 200 OK ……
–> PLAY rtsp://localhost/1.rm RTSP/1.0 ….. Range: npt=500- …… //Jump to npt 500
<– RTSP/1.0 200 OK …….RTP-Info: url=rtsp://localhost/1.rm/streamid=0;seq=4227;rtptime=0, url=rtsp://localhost/1.rm/streamid=1;seq=2084;rtptime=0
<– … 0x40 0x10 0x82 …. //Should ignore
<– … 0x42 0x08 0x23 … //Should ignore
<– … 0x40 0x10 0x83 … //That’s the right message 0x1083=4227
<– … 0x42 0x08 0x24 … //And so on 0x0824=2084
<– … 0x40 0x10 0x84 …
第4个字节还未研究透彻,但是该字节的最后一位代表着该包是否为关键帧(keyframe),如果最后一位为0则是keyframe,为1则不是。关键帧的作用是用来建立索引,所有Real媒体的播放和跳转都是从关键帧开始,非关键帧都是根据关键帧图像做一些移动和变换所生成,因此不能直接从非关键帧开始播放。
Virtual Example:
<– … 0x40 0x00 0x00 0x80 …. //Keyframe
<– … 0x42 0x00 0x00 0x00 …. //Keyframe
<– … 0x40 0x00 0x00 0x01 … //Not keyframe
第5-8个字节表明该帧的时间(timestamp),毫秒为单位。
第9-10个字节常为0。
后面即为正常的数据包,根据不同编码器而定。
Virtual Example:
<– … 0x42 0x00 0x30 0x41 0x00 0x00 0x05 0x58 0x00 0x00 ……
means: streamid=1, seq=48, keyframe=false, timestamp=1368ms
<– … 0x40 0x00 0x20 0x00 0x00 0x00 0x0e 0x83 0x00 0x00 ……
means: streamid=0, seq=32, keyframe=true, timestamp=3715ms
非正常的RDT包是在正常的RDT包前面增加了若干字节,猜想类似于RTCP的一些反馈消息,因为实际应用中不增加这些字节,RealPlayer的行为没有发现任何变化。
非正常包的首字节第1位肯定是1,即>=80 (10000000)
Stream End: 0x??0xFF 0x06 0x?? 0x?? 0x00 0x00 0x00 0x00 0x00 0x00
判断流结束可以判断第1个字节不是0x40和0x42,并且第3个字节是0x06。
其中第1个字节的第3位可以用于判断是哪个流结束。如0x82=10000010,0x84=10000100(streamid),第4-5个字节表示该流发送的最后一个包的seq。
Unknown Packet: 0x?? 0xff 0x08 0x00 0x09 0x?? 0x?? 0x?? 0x?? Normal RDT Packet
其中6-10个字节是一个timestamp,一般从0开始,随着发送时间递增,并越来越接近正常RDT包的timestamp。如,即使播放ntp=10-0,即normal RDT packet timestamp = 10000,unknown RDT packet timestamp = 0,但是越放到后面,该值越接近normal RDT packet,尚不知道其作用。
一般除了stream end外,其余非正常RDT可以忽略掉,目前尚未发现任何不良影响。