]> git.sesse.net Git - vlc/blob - modules/access/rtp/session.c
Update LGPL license blurb, choosing v2.1+.
[vlc] / modules / access / rtp / session.c
1 /**
2  * @file session.c
3  * @brief RTP session handling
4  */
5 /*****************************************************************************
6  * Copyright © 2008 Rémi Denis-Courmont
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21  ****************************************************************************/
22
23 #ifdef HAVE_CONFIG_H
24 # include <config.h>
25 #endif
26
27 #include <stdlib.h>
28 #include <assert.h>
29 #include <errno.h>
30
31 #include <vlc_common.h>
32 #include <vlc_demux.h>
33
34 #include "rtp.h"
35
36 typedef struct rtp_source_t rtp_source_t;
37
38 /** State for a RTP session: */
39 struct rtp_session_t
40 {
41     rtp_source_t **srcv;
42     unsigned       srcc;
43     uint8_t        ptc;
44     rtp_pt_t      *ptv;
45 };
46
47 static rtp_source_t *
48 rtp_source_create (demux_t *, const rtp_session_t *, uint32_t, uint16_t);
49 static void
50 rtp_source_destroy (demux_t *, const rtp_session_t *, rtp_source_t *);
51
52 static void rtp_decode (demux_t *, const rtp_session_t *, rtp_source_t *);
53
54 /**
55  * Creates a new RTP session.
56  */
57 rtp_session_t *
58 rtp_session_create (demux_t *demux)
59 {
60     rtp_session_t *session = malloc (sizeof (*session));
61     if (session == NULL)
62         return NULL;
63
64     session->srcv = NULL;
65     session->srcc = 0;
66     session->ptc = 0;
67     session->ptv = NULL;
68
69     (void)demux;
70     return session;
71 }
72
73
74 /**
75  * Destroys an RTP session.
76  */
77 void rtp_session_destroy (demux_t *demux, rtp_session_t *session)
78 {
79     for (unsigned i = 0; i < session->srcc; i++)
80         rtp_source_destroy (demux, session, session->srcv[i]);
81
82     free (session->srcv);
83     free (session->ptv);
84     free (session);
85     (void)demux;
86 }
87
88 static void *no_init (demux_t *demux)
89 {
90     (void)demux;
91     return NULL;
92 }
93
94 static void no_destroy (demux_t *demux, void *opaque)
95 {
96     (void)demux; (void)opaque;
97 }
98
99 static void no_decode (demux_t *demux, void *opaque, block_t *block)
100 {
101     (void)demux; (void)opaque;
102     block_Release (block);
103 }
104
105 /**
106  * Adds a payload type to an RTP session.
107  */
108 int rtp_add_type (demux_t *demux, rtp_session_t *ses, const rtp_pt_t *pt)
109 {
110     if (ses->srcc > 0)
111     {
112         msg_Err (demux, "cannot change RTP payload formats during session");
113         return EINVAL;
114     }
115
116     rtp_pt_t *ppt = realloc (ses->ptv, (ses->ptc + 1) * sizeof (rtp_pt_t));
117     if (ppt == NULL)
118         return ENOMEM;
119
120     ses->ptv = ppt;
121     ppt += ses->ptc++;
122
123     ppt->init = pt->init ? pt->init : no_init;
124     ppt->destroy = pt->destroy ? pt->destroy : no_destroy;
125     ppt->decode = pt->decode ? pt->decode : no_decode;
126     ppt->frequency = pt->frequency;
127     ppt->number = pt->number;
128     msg_Dbg (demux, "added payload type %"PRIu8" (f = %"PRIu32" Hz)",
129              ppt->number, ppt->frequency);
130
131     assert (ppt->frequency > 0); /* SIGFPE! */
132     (void)demux;
133     return 0;
134 }
135
136 /** State for an RTP source */
137 struct rtp_source_t
138 {
139     uint32_t ssrc;
140     uint32_t jitter;  /* interarrival delay jitter estimate */
141     mtime_t  last_rx; /* last received packet local timestamp */
142     uint32_t last_ts; /* last received packet RTP timestamp */
143
144     uint32_t ref_rtp; /* sender RTP timestamp reference */
145     mtime_t  ref_ntp; /* sender NTP timestamp reference */
146
147     uint16_t bad_seq; /* tentatively next expected sequence for resync */
148     uint16_t max_seq; /* next expected sequence */
149
150     uint16_t last_seq; /* sequence of the next dequeued packet */
151     block_t *blocks; /* re-ordered blocks queue */
152     void    *opaque[0]; /* Per-source private payload data */
153 };
154
155 /**
156  * Initializes a new RTP source within an RTP session.
157  */
158 static rtp_source_t *
159 rtp_source_create (demux_t *demux, const rtp_session_t *session,
160                    uint32_t ssrc, uint16_t init_seq)
161 {
162     rtp_source_t *source;
163
164     source = malloc (sizeof (*source) + (sizeof (void *) * session->ptc));
165     if (source == NULL)
166         return NULL;
167
168     source->ssrc = ssrc;
169     source->jitter = 0;
170     source->ref_rtp = 0;
171     /* TODO: use 0, but VLC does not like negative PTS at the moment */
172     source->ref_ntp = UINT64_C (1) << 62;
173     source->max_seq = source->bad_seq = init_seq;
174     source->last_seq = init_seq - 1;
175     source->blocks = NULL;
176
177     /* Initializes all payload */
178     for (unsigned i = 0; i < session->ptc; i++)
179         source->opaque[i] = session->ptv[i].init (demux);
180
181     msg_Dbg (demux, "added RTP source (%08x)", ssrc);
182     return source;
183 }
184
185
186 /**
187  * Destroys an RTP source and its associated streams.
188  */
189 static void
190 rtp_source_destroy (demux_t *demux, const rtp_session_t *session,
191                     rtp_source_t *source)
192 {
193     msg_Dbg (demux, "removing RTP source (%08x)", source->ssrc);
194
195     for (unsigned i = 0; i < session->ptc; i++)
196         session->ptv[i].destroy (demux, source->opaque[i]);
197     block_ChainRelease (source->blocks);
198     free (source);
199 }
200
201 static inline uint16_t rtp_seq (const block_t *block)
202 {
203     assert (block->i_buffer >= 4);
204     return GetWBE (block->p_buffer + 2);
205 }
206
207 static inline uint32_t rtp_timestamp (const block_t *block)
208 {
209     assert (block->i_buffer >= 12);
210     return GetDWBE (block->p_buffer + 4);
211 }
212
213 static const struct rtp_pt_t *
214 rtp_find_ptype (const rtp_session_t *session, rtp_source_t *source,
215                 const block_t *block, void **pt_data)
216 {
217     uint8_t ptype = rtp_ptype (block);
218
219     for (unsigned i = 0; i < session->ptc; i++)
220     {
221         if (session->ptv[i].number == ptype)
222         {
223             if (pt_data != NULL)
224                 *pt_data = source->opaque[i];
225             return &session->ptv[i];
226         }
227     }
228     return NULL;
229 }
230
231 /**
232  * Receives an RTP packet and queues it. Not a cancellation point.
233  *
234  * @param demux VLC demux object
235  * @param session RTP session receiving the packet
236  * @param block RTP packet including the RTP header
237  */
238 void
239 rtp_queue (demux_t *demux, rtp_session_t *session, block_t *block)
240 {
241     demux_sys_t *p_sys = demux->p_sys;
242
243     /* RTP header sanity checks (see RFC 3550) */
244     if (block->i_buffer < 12)
245         goto drop;
246     if ((block->p_buffer[0] >> 6 ) != 2) /* RTP version number */
247         goto drop;
248
249     /* Remove padding if present */
250     if (block->p_buffer[0] & 0x20)
251     {
252         uint8_t padding = block->p_buffer[block->i_buffer - 1];
253         if ((padding == 0) || (block->i_buffer < (12u + padding)))
254             goto drop; /* illegal value */
255
256         block->i_buffer -= padding;
257     }
258
259     mtime_t        now = mdate ();
260     rtp_source_t  *src  = NULL;
261     const uint16_t seq  = rtp_seq (block);
262     const uint32_t ssrc = GetDWBE (block->p_buffer + 8);
263
264     /* In most case, we know this source already */
265     for (unsigned i = 0, max = session->srcc; i < max; i++)
266     {
267         rtp_source_t *tmp = session->srcv[i];
268         if (tmp->ssrc == ssrc)
269         {
270             src = tmp;
271             break;
272         }
273
274         /* RTP source garbage collection */
275         if ((tmp->last_rx + p_sys->timeout) < now)
276         {
277             rtp_source_destroy (demux, session, tmp);
278             if (--session->srcc > 0)
279                 session->srcv[i] = session->srcv[session->srcc - 1];
280         }
281     }
282
283     if (src == NULL)
284     {
285         /* New source */
286         if (session->srcc >= p_sys->max_src)
287         {
288             msg_Warn (demux, "too many RTP sessions");
289             goto drop;
290         }
291
292         rtp_source_t **tab;
293         tab = realloc (session->srcv, (session->srcc + 1) * sizeof (*tab));
294         if (tab == NULL)
295             goto drop;
296         session->srcv = tab;
297
298         src = rtp_source_create (demux, session, ssrc, seq);
299         if (src == NULL)
300             goto drop;
301
302         tab[session->srcc++] = src;
303         /* Cannot compute jitter yet */
304     }
305     else
306     {
307         const rtp_pt_t *pt = rtp_find_ptype (session, src, block, NULL);
308
309         if (pt != NULL)
310         {
311             /* Recompute jitter estimate.
312              * That is computed from the RTP timestamps and the system clock.
313              * It is independent of RTP sequence. */
314             uint32_t freq = pt->frequency;
315             int64_t ts = rtp_timestamp (block);
316             int64_t d = ((now - src->last_rx) * freq) / CLOCK_FREQ;
317             d        -=    ts - src->last_ts;
318             if (d < 0) d = -d;
319             src->jitter += ((d - src->jitter) + 8) >> 4;
320         }
321     }
322     src->last_rx = now;
323     block->i_pts = now; /* store reception time until dequeued */
324     src->last_ts = rtp_timestamp (block);
325
326     /* Check sequence number */
327     /* NOTE: the sequence number is per-source,
328      * but is independent from the payload type. */
329     int16_t delta_seq = seq - src->max_seq;
330     if ((delta_seq > 0) ? (delta_seq > p_sys->max_dropout)
331                         : (-delta_seq > p_sys->max_misorder))
332     {
333         msg_Dbg (demux, "sequence discontinuity"
334                  " (got: %"PRIu16", expected: %"PRIu16")", seq, src->max_seq);
335         if (seq == src->bad_seq)
336         {
337             src->max_seq = src->bad_seq = seq + 1;
338             src->last_seq = seq - 0x7fffe; /* hack for rtp_decode() */
339             msg_Warn (demux, "sequence resynchronized");
340             block_ChainRelease (src->blocks);
341             src->blocks = NULL;
342         }
343         else
344         {
345             src->bad_seq = seq + 1;
346             goto drop;
347         }
348     }
349     else
350     if (delta_seq >= 0)
351         src->max_seq = seq + 1;
352
353     /* Queues the block in sequence order,
354      * hence there is a single queue for all payload types. */
355     block_t **pp = &src->blocks;
356     for (block_t *prev = *pp; prev != NULL; prev = *pp)
357     {
358         int16_t delta_seq = seq - rtp_seq (prev);
359         if (delta_seq < 0)
360             break;
361         if (delta_seq == 0)
362         {
363             msg_Dbg (demux, "duplicate packet (sequence: %"PRIu16")", seq);
364             goto drop; /* duplicate */
365         }
366         pp = &prev->p_next;
367     }
368     block->p_next = *pp;
369     *pp = block;
370
371     /*rtp_decode (demux, session, src);*/
372     return;
373
374 drop:
375     block_Release (block);
376 }
377
378
379 static void
380 rtp_decode (demux_t *demux, const rtp_session_t *session, rtp_source_t *src)
381 {
382     block_t *block = src->blocks;
383
384     assert (block);
385     src->blocks = block->p_next;
386     block->p_next = NULL;
387
388     /* Discontinuity detection */
389     uint16_t delta_seq = rtp_seq (block) - (src->last_seq + 1);
390     if (delta_seq != 0)
391     {
392         if (delta_seq >= 0x8000)
393         {   /* Trash too late packets (and PIM Assert duplicates) */
394             msg_Dbg (demux, "ignoring late packet (sequence: %"PRIu16")",
395                       rtp_seq (block));
396             goto drop;
397         }
398         msg_Warn (demux, "%"PRIu16" packet(s) lost", delta_seq);
399         block->i_flags |= BLOCK_FLAG_DISCONTINUITY;
400     }
401     src->last_seq = rtp_seq (block);
402
403     /* Match the payload type */
404     void *pt_data;
405     const rtp_pt_t *pt = rtp_find_ptype (session, src, block, &pt_data);
406     if (pt == NULL)
407     {
408         msg_Dbg (demux, "unknown payload (%"PRIu8")",
409                  rtp_ptype (block));
410         goto drop;
411     }
412
413     /* Computes the PTS from the RTP timestamp and payload RTP frequency.
414      * DTS is unknown. Also, while the clock frequency depends on the payload
415      * format, a single source MUST only use payloads of a chosen frequency.
416      * Otherwise it would be impossible to compute consistent timestamps. */
417     const uint32_t timestamp = rtp_timestamp (block);
418     block->i_pts = src->ref_ntp
419        + CLOCK_FREQ * (int32_t)(timestamp - src->ref_rtp) / pt->frequency;
420     /* TODO: proper inter-medias/sessions sync (using RTCP-SR) */
421     src->ref_ntp = block->i_pts;
422     src->ref_rtp = timestamp;
423
424     /* CSRC count */
425     size_t skip = 12u + (block->p_buffer[0] & 0x0F) * 4;
426
427     /* Extension header (ignored for now) */
428     if (block->p_buffer[0] & 0x10)
429     {
430         skip += 4;
431         if (block->i_buffer < skip)
432             goto drop;
433
434         skip += 4 * GetWBE (block->p_buffer + skip - 2);
435     }
436
437     if (block->i_buffer < skip)
438         goto drop;
439
440     block->p_buffer += skip;
441     block->i_buffer -= skip;
442
443     pt->decode (demux, pt_data, block);
444     return;
445
446 drop:
447     block_Release (block);
448 }
449
450
451 /**
452  * Dequeues an RTP packet and pass it to decoder. Not cancellation-safe(?).
453  *
454  * @param demux VLC demux object
455  * @param session RTP session receiving the packet
456  * @param deadlinep pointer to deadline to call rtp_dequeue() again
457  * @return true if the buffer is not empty, false otherwise.
458  * In the later case, *deadlinep is undefined.
459  */
460 bool rtp_dequeue (demux_t *demux, const rtp_session_t *session,
461                   mtime_t *restrict deadlinep)
462 {
463     mtime_t now = mdate ();
464     bool pending = false;
465
466     *deadlinep = INT64_MAX;
467
468     for (unsigned i = 0, max = session->srcc; i < max; i++)
469     {
470         rtp_source_t *src = session->srcv[i];
471         block_t *block;
472
473         /* Because of IP packet delay variation (IPDV), we need to guesstimate
474          * how long to wait for a missing packet in the RTP sequence
475          * (see RFC3393 for background on IPDV).
476          *
477          * This situation occurs if a packet got lost, or if the network has
478          * re-ordered packets. Unfortunately, the MSL is 2 minutes, orders of
479          * magnitude too long for multimedia. We need a trade-off.
480          * If we underestimated IPDV, we may have to discard valid but late
481          * packets. If we overestimate it, we will either cause too much
482          * delay, or worse, underflow our downstream buffers, as we wait for
483          * definitely a lost packets.
484          *
485          * The rest of the "de-jitter buffer" work is done by the internal
486          * LibVLC E/S-out clock synchronization. Here, we need to bother about
487          * re-ordering packets, as decoders can't cope with mis-ordered data.
488          */
489         while (((block = src->blocks)) != NULL)
490         {
491             if ((int16_t)(rtp_seq (block) - (src->last_seq + 1)) <= 0)
492             {   /* Next (or earlier) block ready, no need to wait */
493                 rtp_decode (demux, session, src);
494                 continue;
495             }
496
497             /* Wait for 3 times the inter-arrival delay variance (about 99.7%
498              * match for random gaussian jitter).
499              */
500             mtime_t deadline;
501             const rtp_pt_t *pt = rtp_find_ptype (session, src, block, NULL);
502             if (pt)
503                 deadline = CLOCK_FREQ * 3 * src->jitter / pt->frequency;
504             else
505                 deadline = 0; /* no jitter estimate with no frequency :( */
506
507             /* Make sure we wait at least for 25 msec */
508             if (deadline < (CLOCK_FREQ / 40))
509                 deadline = CLOCK_FREQ / 40;
510
511             /* Additionnaly, we implicitly wait for the packetization time
512              * multiplied by the number of missing packets. block is the first
513              * non-missing packet (lowest sequence number). We have no better
514              * estimated time of arrival, as we do not know the RTP timestamp
515              * of not yet received packets. */
516             deadline += block->i_pts;
517             if (now >= deadline)
518             {
519                 rtp_decode (demux, session, src);
520                 continue;
521             }
522             if (*deadlinep > deadline)
523                 *deadlinep = deadline;
524             pending = true; /* packet pending in buffer */
525             break;
526         }
527     }
528     return pending;
529 }