souphttpsrc: check if request was cancelled when sending message
[platform/upstream/gst-plugins-good.git] / docs / design / design-rtpretransmission.txt
1 RTP retransmission design
2
3
4 GstRTPRetransmissionRequest
5 ---------------------------
6
7 Custom upstream event which mainly contains the ssrc and the seqnum of the
8 packet which is asked to be retransmisted.
9
10 On the pipeline receiver side this event is generated by the
11 gstrtpjitterbuffer element. Then it is translated to a NACK to be sent over
12 the network.
13
14 On the pipeline sender side, this event is generated by the gstrtpsession
15 element when it receives a NACK from the network.
16
17
18 rtprtxsend element
19 ------------------
20
21 -- basic mechanism
22
23 rtprtxsend keeps a history of rtp packets that it has already sent.
24 When it receives the event GstRTPRetransmissionRequest from the downstream
25 gstrtpsession element, it loopkup the requested seqnum in its stored packets.
26 If the packet is present in its history, it will create a RTX packet according
27 to RFC 4588. Then this rtx packet is pushed to its src pad as other packets.
28
29 rtprtxsend works in SSRC-multiplexed mode, so it has one always sink and
30 src pad.
31
32 -- building retransmission packet fron original packet
33
34 A rtx packet is mostly the same as an orignal packet, except it has its own
35 ssrc and its own seqnum. That's why rtprtxsend works in SSRC-multiplexed mode.
36 It also means that the same session is used.
37 Another difference between rtx packet and its original is that it inserts the
38 original seqnum (OSN: 2 bytes) at the beginning of the payload.
39 Also rtprtxsend builds rtx packet without padding, to let other elements do that.
40 The last difference is the payload type. For now the user has to set it through
41 the rtx-payload-type property. Later it will be automatically retreive this
42 information from SDP. See fmtp field as specifies in the RPC4588
43 (a=fmtp:99 apt=98) fmtp is the payload type of the retransmission stream
44 and apt the payload type of its associated master stream.
45
46 -- restransmission ssrc and seqnum
47
48 To choose rtx_ssrc it randomly selects a number between 0 and 2^32-1 until
49 it is different than master_ssrc.
50 rtx_seqnum is randomly selected between 0 and 2^16-1
51
52 -- deeper in the stored buffer history
53
54 For the history it uses a GSequence with 2^15-1 as its maximum size.
55 Which is resonable as the default value is 100.
56 It contains the packets in reverse order they have been sent
57 (head:newest, tail:oldest)
58 GSequence allows to add and remove an element in constant time (like a queue).
59 Also GSequence allows to do a binary search when rtprtxsend lookup in its
60 history.
61 It's important if it receives a lot of requests or if the history is large.
62
63 -- pending rtx packets
64
65 When looking up in its history, if seqnum is found then it pushes the buffer
66 into a GQueue to its tail.
67 Before to send the current master stream packet, rtprtxsend sends all the
68 buffers which are in this GQueue. Taking care of converting them to rtx
69 packets.
70 This way, rtx packets are sent in the same order they have been requested.
71 (g_list_foreach traverse the queue from head to tail)
72 The GQueue is cleared between sending 2 master stream packets.
73 So for this GQueue to contain more than one element, it means that rtprtxsend
74 receives more than one rtx request between sending 2 master packets.
75
76 -- collision
77
78 When handling a GstRTPCollision event, if the ssrc is its rtx ssrc then
79 rtprtxsend clear its history and its pending retransmission queue.
80 Then it chooses a rtx_ssrc until it's different than master ssrc.
81 If the GstRTPCollision event does not contain its rtx ssrc, for example
82 its master ssrc or other, then it just forwards the event to upstream.
83 So that it can be handled by the rtppayloader.
84
85
86 rtprtxreceive element
87 ------------------
88
89 -- basic mechanism
90
91 The same rtprtxreceive instance can receive several master streams and several
92 retransmission streams.
93 So it will try to dynamically associate a rtx ssrc with its master ssrc.
94 So that it can reconstruct the original from the proper rtx packet.
95
96 The algorithm is based on the fact that seqnums of different streams
97 (considering all master and all rtx streams) evolve at a different rate.
98 It means that the initial seqnum is random for each one and the offset could
99 also be different. So that they are statistically all different at a given
100 time. If bad luck then the association is delayed to the next rtx request.
101
102 The algorithm also needs to know if a given packet is a rtx packet or not.
103 To know this information there is the rtx-payload-types property. For now the
104 user as to configure it but later it will be automatically retreive this
105 information from SDP.
106 It needs to know if the current packet is rtx or not in order to know if
107 it can extract the OSN from the payload. Otherwise it would extract the OSN
108 even on master streams which means nothing and so it could do bad things.
109 In theory maybe it could work but we have this information in SDP so why not
110 using it to avoid bad associations.
111
112 Note that it also means that several master streams can have the same payload
113 type. And also several rtx streams can have the same payload type.
114 So the information from SDP which gives us which rtx payload type belong to
115 a give master payload type is not enough to do the association between rtx ssrc
116 and master ssrc.
117
118 rtprtxreceive works in SSRC-multiplexed mode, so it has one always sink and
119 src pad.
120
121 -- deeper in the association algorithm
122
123 When it receives a GstRTPRetransmissionRequest event it will remember the ssrc
124 and the seqnum from this request.
125
126 On incoming packets, if the packet has its ssrc already associated then it
127 knows if the ssrc is an rtx ssrc or a master stream ssrc.
128 If this is a rtx packet then it recontructs the original and pushs the result to
129 src pad as if it was a master packet.
130
131 If the ssrc is not yet associated rtprtxreceive checks the payload type.
132 if the packet has its payload type marked as rtx then it will extract the OSN
133 (original seqnum number) and lookup in its stored requests if a seqnum matchs.
134 If found, then it associates the current ssrc to the master ssrc marked in the
135 request. If not found it just drops the packet.
136 Then it removes the request from the stored requests.
137
138 If there are 2 requests with the same seqnum and different ssrc, then the
139 couple seqnum,ssrc is removed from the stored requests.
140 A stored request actually means that actually the couple seqnum,ssrc is stored.
141 If it's happens the request is droped but it avoids to do bad associations.
142 In this case the association is just delayed to the next request.
143
144 -- building original packet from rtx packet
145
146 Header, extensions, payload and padding are mostly the same. Except that the
147 OSN is removed from the payload. Then ssrc, seqnum, and original payload type
148 are correctly set. Original payload type is actually also stored when the
149 rtx request is handled.