Remove old school plugins listing generator
[platform/upstream/gstreamer.git] / markdown / additional / design / rtp.md
1 # RTP
2
3 These design docs detail some of the lower-level mechanism of certain parts
4 of GStreamer's RTP stack. For a higher-level overview see the [RTP and RTSP
5 support](additional/rtp.md) section.
6
7 # RTP auxiliary stream design
8
9 ## Auxiliary elements
10
11 There are two kind of auxiliary elements, sender and receiver. Let's
12 call them rtpauxsend and rtpauxreceive.
13
14 rtpauxsend has always one sink pad and can have unlimited requested src
15 pads. If only src pad then it works in SSRC-multiplexed mode, if several
16 src pads then it works in session multiplexed mode.
17
18 rtpauxreceive has always one ssrc pad and can have unlimited requested
19 sink pads. If only one sink pad then it works in SSRC-multiplexed mode,
20 if several sink pads then it works in session multiplexed mode.
21
22 ## Rtpbin and auxiliary elements
23
24 ### Basic mechanism
25
26 rtpbin knows for which session ids the given auxiliary element belong
27 to. It's done through "set-aux-send", for rtpauxsend kind, and through
28 "set-aux-receive" for rtpauxreceive kind. You can call those signals as
29 much as needed for each auxiliary element. So for aux elements that work
30 in SSRC-multiplexed mode this signal action is called only one time.
31
32 The user has to call those action signals before to request the
33 differents rtpbin pads. rtpbin is in charge to link those auxiliary
34 elements with the sessions, and on receiver side, rtpbin has also to
35 handle the link with ssrcdemux.
36
37 rtpbin never knows if the given rtpauxsend is actually a rtprtxsend
38 element or another aux element. rtpbin never knows if the given
39 rtpauxreceive is actually a rtprtxreceive element or another aux
40 element. rtpbin has to be kept generic so that more aux elements can be
41 added later without changing rtpbin.
42
43 It's currently not possible to use rtpbin with auxiliary stream from
44 gst-launch. We can discuss about having the ability for rtpbin to
45 instanciate itself the special aux elements rtprtxsend and rtprtxreceive
46 but they need to be configured ("payload-type" and "payload-types"
47 properties) to make retransmission work. So having several rtprtxsend
48 and rtprtxreceive in a rtpbin would require a lot of properties to
49 manage them form rtpbin. And for each auxiliary elements.
50
51 If you want to use rtprtxreceive and rtprtpsend from gst-launch you have
52 to use rtpsession, ssrcdemux and rtpjitterbuffer elements yourself. See
53 gtk-doc of rtprtxreceive for an example.
54
55 ### Requesting the rtpbin's pads on the pipeline receiver side
56
57 If rtpauxreceive is set for session, i, j, k then it has to call
58 rtpbin::"set-aux-receive" 3 times giving those ids and this aux element.
59 It has to be done before requesting the `recv_rtp_sink_i`,
60 `recv_rtp_sink_j`, `recv_rtp_sink_k`. For a concrete case
61 rtprtxreceive, if the user wants it for session i, then it has to call
62 rtpbin::"set-aux-receive" one time giving i and this aux element. Then
63 the user can request `recv_rtp_sink_i` pad.
64
65 Calling rtpbin::"set-aux-receive" does not create the session. It add
66 the given session id and aux element to a hashtable(key:session id,
67 value: aux element). Then when the user ask for
68 `rtpbin.recv_rtp_sink_i`, rtpbin lookup if there is an aux element for
69 this i session id. If yes it requests a sink pad to this aux element and
70 links it with the `recv_rtp_src` pad of the new gstrtpsession. rtpbin
71 also checks that this aux element is connected only one time to
72 ssrcdemux. Because rtpauxreceive has only one source pad. Each call to
73 request `rtpbin.recv_rtp_sink_k` will also creates
74 `rtpbin.recv_rtp_src_k_ssrc_pt` as usual. So that the user have it
75 when then it requests rtpbin. (from gst-launch) or using
76 `on_rtpbinreceive_pad_added` callback from an application.
77
78 ### Requesting the rtpbin's pads on the pipeline sender side
79
80 For the sender this is similar but a bit more complicated to implement.
81 When the user asks for `rtpbin.send_rtp_sink_i`, rtpbin will lookup in
82 its second map (key:session id, value: aux send element). If there is
83 one aux element, then it will set the sink pad of this aux sender
84 element to be the ghost pad `rtpbin.send_rtp_sink_i` that the user
85 asked. rtpbin will also request a src pad of this aux element to connect
86 it to `gstrtpsession_i`. It will automatically create
87 `rtpbin.send_rtp_src_i` the usuall way. Then if the user asks
88 `rtpbin.send_rtp_src_k`, then rtpbin will also lookup in that map and
89 request another source pad of the aux element and connect it to the new
90 `gstrtpsession_k`.
91
92 # RTP collision design
93
94 ## GstRTPCollision
95
96 Custon upstream event which contains the ssrc marked as collided.
97
98 This event is generated on both pipeline sender and receiver side by the
99 gstrtpsession element when it detects a conflict between ssrc. (same
100 session id and same ssrc)
101
102 It's an upstream event so that means this event is for now only useful
103 on pipeline sender side. Because elements generating packets with the
104 collided SSRC are placed upstream from the gstrtpsession.
105
106 ## rtppayloader
107
108 When handling a `GstRTPCollision` event, the rtppayloader has to choose
109 another ssrc.
110
111 ## BYE only the corresponding source, not the whole session.
112
113 When a collision happens for the given ssrc, the associated source is
114 marked bye. But we make sure that the whole session is not itself set
115 bye. Because internally, gstrtpsession can manages several sources and
116 all have their own distinct ssrc.
117
118 # RTP retransmission design
119
120 ## GstRTPRetransmissionRequest
121
122 Custom upstream event which mainly contains the ssrc and the seqnum of
123 the packet which is asked to be retransmisted.
124
125 On the pipeline receiver side this event is generated by the
126 gstrtpjitterbuffer element. Then it is translated to a NACK to be sent
127 over the network.
128
129 On the pipeline sender side, this event is generated by the
130 gstrtpsession element when it receives a NACK from the network.
131
132 ## rtprtxsend element
133
134 ### Basic mechanism
135
136 rtprtxsend keeps a history of rtp packets that it has already sent. When
137 it receives the event `GstRTPRetransmissionRequest` from the downstream
138 gstrtpsession element, it loopkup the requested seqnum in its stored
139 packets. If the packet is present in its history, it will create a RTX
140 packet according to RFC 4588. Then this rtx packet is pushed to its src
141 pad as other packets.
142
143 rtprtxsend works in SSRC-multiplexed mode, so it has one always sink and
144 src pad.
145
146 ### Building retransmission packet fron original packet
147
148 A rtx packet is mostly the same as an orignal packet, except it has its
149 own ssrc and its own seqnum. That's why rtprtxsend works in
150 SSRC-multiplexed mode. It also means that the same session is used.
151 Another difference between rtx packet and its original is that it
152 inserts the original seqnum (OSN: 2 bytes) at the beginning of the
153 payload. Also rtprtxsend builds rtx packet without padding, to let other
154 elements do that. The last difference is the payload type. For now the
155 user has to set it through the rtx-payload-type property. Later it will
156 be automatically retreive this information from SDP. See fmtp field as
157 specifies in the RPC4588 (a=fmtp:99 apt=98) fmtp is the payload type of
158 the retransmission stream and apt the payload type of its associated
159 master stream.
160
161 ### Retransmission ssrc and seqnum
162
163 To choose `rtx_ssrc` it randomly selects a number between 0 and 2^32-1
164 until it is different than `master_ssrc`. `rtx_seqnum` is randomly
165 selected between 0 and 2^16-1
166
167 ### Deeper in the stored buffer history
168
169 For the history it uses a GSequence with 2^15-1 as its maximum size.
170 Which is resonable as the default value is 100. It contains the packets
171 in reverse order they have been sent (head:newest, tail:oldest)
172 GSequence allows to add and remove an element in constant time (like a
173 queue). Also GSequence allows to do a binary search when rtprtxsend
174 lookup in its history. It's important if it receives a lot of requests
175 or if the history is large.
176
177 ### Pending rtx packets
178
179 When looking up in its history, if seqnum is found then it pushes the
180 buffer into a GQueue to its tail. Before to send the current master
181 stream packet, rtprtxsend sends all the buffers which are in this
182 GQueue. Taking care of converting them to rtx packets. This way, rtx
183 packets are sent in the same order they have been requested.
184 (`g_list_foreach` traverse the queue from head to tail) The `GQueue` is
185 cleared between sending 2 master stream packets. So for this `GQueue` to
186 contain more than one element, it means that rtprtxsend receives more
187 than one rtx request between sending 2 master packets.
188
189 ### Collision
190
191 When handling a `GstRTPCollision` event, if the ssrc is its rtx ssrc then
192 rtprtxsend clear its history and its pending retransmission queue. Then
193 it chooses a `rtx_ssrc` until it's different than master ssrc. If the
194 `GstRTPCollision` event does not contain its rtx ssrc, for example its
195 master ssrc or other, then it just forwards the event to upstream. So
196 that it can be handled by the rtppayloader.
197
198 ## Rtprtxreceive element
199
200 ### Basic mechanism
201
202 The same rtprtxreceive instance can receive several master streams and
203 several retransmission streams. So it will try to dynamically associate
204 a rtx ssrc with its master ssrc. So that it can reconstruct the original
205 from the proper rtx packet.
206
207 The algorithm is based on the fact that seqnums of different streams
208 (considering all master and all rtx streams) evolve at a different rate.
209 It means that the initial seqnum is random for each one and the offset
210 could also be different. So that they are statistically all different at
211 a given time. If bad luck then the association is delayed to the next
212 rtx request.
213
214 The algorithm also needs to know if a given packet is a rtx packet or
215 not. To know this information there is the `rtx-payload-types` property.
216 For now the user as to configure it but later it will be automatically
217 retreive this information from SDP. It needs to know if the current
218 packet is rtx or not in order to know if it can extract the OSN from the
219 payload. Otherwise it would extract the OSN even on master streams which
220 means nothing and so it could do bad things. In theory maybe it could
221 work but we have this information in SDP so why not using it to avoid
222 bad associations.
223
224 Note that it also means that several master streams can have the same
225 payload type. And also several rtx streams can have the same payload
226 type. So the information from SDP which gives us which rtx payload type
227 belong to a give master payload type is not enough to do the association
228 between rtx ssrc and master ssrc.
229
230 rtprtxreceive works in SSRC-multiplexed mode, so it has one always sink
231 and src pad.
232
233 ### Deeper in the association algorithm
234
235 When it receives a `GstRTPRetransmissionRequest` event it will remember
236 the ssrc and the seqnum from this request.
237
238 On incoming packets, if the packet has its ssrc already associated then
239 it knows if the ssrc is an rtx ssrc or a master stream ssrc. If this is
240 a rtx packet then it recontructs the original and pushs the result to
241 src pad as if it was a master packet.
242
243 If the ssrc is not yet associated rtprtxreceive checks the payload type.
244 if the packet has its payload type marked as rtx then it will extract
245 the OSN (original seqnum number) and lookup in its stored requests if a
246 seqnum matchs. If found, then it associates the current ssrc to the
247 master ssrc marked in the request. If not found it just drops the
248 packet. Then it removes the request from the stored requests.
249
250 If there are 2 requests with the same seqnum and different ssrc, then
251 the couple seqnum,ssrc is removed from the stored requests. A stored
252 request actually means that actually the couple seqnum,ssrc is stored.
253 If it's happens the request is droped but it avoids to do bad
254 associations. In this case the association is just delayed to the next
255 request.
256
257 ### Building original packet from rtx packet
258
259 Header, extensions, payload and padding are mostly the same. Except that
260 the OSN is removed from the payload. Then ssrc, seqnum, and original
261 payload type are correctly set. Original payload type is actually also
262 stored when the rtx request is handled.