RDT_Feature_Level 中文
术语:
RTT:Round Trip Time是从一个包离开发送者到发送者接收
到接收者发送的对该包的响应所经历的时间。
一、RDT_Feature_Level_20
I. RDT data packets
一个RDT stream有多个stream。每个packet在stream的序列号从0开始,到0xff00重复循环。因此stream_id和sequence number保证了packet的唯一性。
is_reliable flag将stream指定为high priority or less loss tolerant的datatype。这些stream中有全局的second sequence number来表示所有is_reliable flag被置位的packet。这种second sequence number是由应用程序指定的。
如果RDT data packet的length_included_flag被置位,则存在packet聚合——将多个packet放进一个UDP包。聚合的packet存在length字段,方便客户端跳到下一个RDT header。在server端可以用--dpa命令禁止packet聚合。
-------------------------------------------------------------------------------
II. Packets lost before transport
所有的RealNetworks datatype都可以忍受一定的丢包。如果encoder间server发生了不可重获的丢包,那么server无法将所有的packet都发给client,这时server需要以所丢失包的序列号发送一个空包(没有payload data),则client知道发生了丢包而不会发送NAK packet。注意,在TCP模式下,server只是用序列号的间隙来表示丢包,因为丢包无疑是在传输之前产生的。
-------------------------------------------------------------------------------
Table C. RDT NAK/ACK PACKET
RDT NAK PACKET
012 78 24 40 56 72
+++----++---------------+------...+---...+------...+-------+
||| ||0xff02 |stream_id|seq_no|bit_count|map_len|
+++----++---------------+------...+---...+------...+-------+
^
|
lost_high (1 for NAK)
- NAK packet的前三个字节总是0x40ff02
- NAK的bit_count和map_len总是0
- stream_id with seq_no指明了丢包位置
- lost_high是丢包指示位,在NAK中总是被置位
RDT ACK PACKET
|<---Repeated for each stream in session--->|
012 78 24 40 56 72 80
+++----++---------------+------...+---...+------...+-------+-----...+
||| ||0xff02 |stream id|seq_no|bit_count|map_len|bitfield|
+++----++---------------+------...+---...+------...+-------+-----...+
^
|
lost_high (almost always 0 for ACK)
- lost_high在ACK中几乎从不置位.见section III.
- 每个stream一个data portion
- stream_id指示被ACK通知的stream
- seq_no是bitfield中的最高序列号.
- bit_count指示bitfield中的bit数目(packets being ACKed)
- map_len指示bitfield的byte数目(rounded up)
- There is one bitfield for every packet ACKed. 1 indicates packet was
received. 0 indicates packet was not received.
III. Packets lost in transport
client通过发送ACK/NAK packet来使数据恢复。client一旦发现序列号有间隙,就为每个缺少的序列号发送一个NAK packet。这意味着server将会为收到的乱序packet产生一个NAK。此外client每间隔一秒发送一个ACK packet。在ACK packet中,session中的每个stream对应一个bitfield,field中的1表示收到,0表示没有。server一旦收到NAK packet或者表示有丢包的ACK packet,就会重传相应的packet。所有标记为收到的packet会从server的缓冲区中清除掉。
本文中所说的ACK/NAK packet实际上有相同的结构。它们的区别在于lost_high flag,这个标志位指明对应序列号的packet丢失了。ACK packet是基于收到的最高的序列号产生的,因此最高序列号的packet不会被认为是丢失了,而只是还没到达。
唯一的例外是以下情况:a stream ACK的大小超过了最大bitset限制而只能用2个ACK packet发送,第一个ACK section中的最后一个ACK packet正好丢失了。最大bitset是48byte。因为每秒发送一个ACK,这种情况只发生在大于1.5Mbps的stream上。
IV. Identifying RDT data recovery on the wire
NAK packet总是以0x40ff02开始,每个丢掉的包产生一个;
ACK packet总是以0x00ff02开始,每秒产生一个;
用于传输前产生的丢包的Placeholder packets总是10字节长;
-------------------------------------------------------------------------------
Appendix - packet definitions and field summaries
(if expressions indicate differing packet formats based on values in static
fields)
packlen struct TNGDataPacket
{
bit[1] length_included_flag; /* Inc. length field
*/
bit[1] need_reliable_flag; /* Inc. rel. seq no */
bit[5] stream_id; /* 31 == expansion */
bit[1] is_reliable;
u_int16 seq_no; /* overload for packet type*/
if(length_included_flag == 1)
{
u_int16 rdt_packet_length; // payload length if
// length flag is set
}
bit[1] back_to_back_packet;
bit[1] slow_data;
bit[6] asm_rule_number; /* 63 is expansion */
u_int32 timestamp;
if(stream_id == 31)
{
u_int16 stream_id_expansion;
}
if(need_reliable_flag == 1)
{
u_int16 total_reliable;
}
if(asm_rule_number == 63)
{
u_int16 asm_rule_number_expansion;
}
buffer data;
}
- length_included_flag:指示packet聚合.当datagram大小未规定时,指示payload大小
- need_reliable_flag:总是置位
- stream_id:跟数据类型相关(usually 0 for audio, 1 for video)
stream_id 31:保留为将来扩展之用,目前还未使用
- is_reliable:用于less tolerant to loss的数据
- seq_no:在0和0xff00之间循环.每个stream内有自己的seq_nos.
高于0xff00的表示特殊packet类型(such as ACK 0xff02)
- back_to_back_packet:用于校时,每十个packet中有一个有效
- slow_data:保留为将来扩展之用,目前还未使用
- asm_rule_number:在SureStream与ASM rulebook in file headers共同作用,以使client可以根据带宽选择流. asm_rule_number 63保留为将来扩展之用,目前还未使用
- timestamp:数据类型相关,按时间递增
- total_reliable:给定的stream中is_reliable被置位的packet的总和.
struct TNGACKPacket
{
bit[1] length_included_flag;
bit[1] lost_high;
bit[5] dummy0; /* 0 */
bit[1] dummy1; /* 0 */
u_int16 packet_type; /* 0xff02 */
if(length_included_flag == 1)
{
u_int16 length;
}
/*
* data consists of header + bitmap repeated for each stream:
* u_int16 stream_number
* u_int16 last_seq_no
* u_int16 bit_count
* u_int8 bitmap_length
* buffer bitmap
*/
buffer data;
}
- length_included_flag:ACK中固定为0
- lost_high indicates that the sequence number in the data segment is
a lost packet. These packets have no ACK component. These packets will only
have a data segment for 1 stream.
- packet_type:对于ACK/NAK packets是0xff02.
二、RDT_Feature_Level_30
4 Specification
只有服务端和客户端的RTSP header同时支持RDTFeatureLevel时,此规格有效。
4.1 RDTTransportInfoRequestPacket
struct RDTTransportInfoRequestPacket
{
bit[1] dummy0; /* 0 */
bit[5] dummy1; /* 0 */
bit[1] request_rtt_info;
bit[1] request_buffer_info;
u_int16 packet_type; /* 0xff09 */
if (request_rtt_info == 1)
{
u_int32 request_time_ms;
}
}
RDTTransportInfoRequestPacket用于请求传播时延和/或接收buffer状态。流的接收端和发送端都可以发出此请求,接收端发出此请求时不能给request_buffer_info字段置位。此请求的发送方需要保证the traffic generated does
not exceed the feedback of delayed ACK TCP as specified in [ 9 ].此请求可以包含在其它RDT包中,但不能超过大小限制。
4.2 RDTTransportInfoResponsePacket
struct RDTBufferInfo
{
u_int16 stream_id;
u_int32 lowest_timestamp;
u_int32 highest_timestamp;
u_int32 bytes_buffered;
}
struct RDTTransportInfoResponsePacket
{
bit[1] dummy0; /* 0 */
bit[4] dummy1; /* 0 */
bit[1] has_rtt_info;
bit[1] is_delayed;
bit[1] has_buffer_info;
u_int16 packet_type; /* 0xff0a */
if (has_rtt_info == 1)
{
u_int32 request_time_ms;
if (is_delayed)
{
u_int32 response_time_ms;
}
}
if (has_buffer_info == 1)
{
u_int16 buffer_info_count;
RDTBufferInfo[buffer_info_count] buffer_info;
}
}
RDTTransportInfoResponsePacket是对RDTTransportInfoRequestPacket的响应.因为这些包是经由不可靠信道传送的,服务端不应该依赖于任何这些相应。
4.2.1 has_rtt_info response
response_time_ms表示从收到对应 request packet起经过的时间。packet接收方需要尽可能快地响应每一个request。
4.2.2 has_buffer_info response
当response packet中的has_buffer_info被置位时,每一个stream对应一个RDTBufferInfo structure。stream的顺序对应于session的stream_id。RDTBufferInfo中的数据应该包括stream中所有还未传至renderer的packet。对于bytes_buffered,接受方需要保证所有timestamp相同且等于lowest_timestamp的packet都作为一个整体进行计算.bytes_buffered字段只包含payload data,没有任何传输相关的header。如果缓冲区的数据存在timestamp间隙,接收方需要在相应datagram包括一个RDTNakPacket。如果缓冲区没有packet,接收方必须将最后送入renderer的packet的timestamp作为highest_timestamp and lowest_timestamp;如果没有数据送入renderer,这两个字段都设为0。
4.3 Bandwidth Overhead for TransportInfo packets
4.4 Handling of NULL Packets