]> git.sesse.net Git - vlc/blob - modules/demux/rtp.c
8641e897e58830b78fb7198463bdce76dcc080ea
[vlc] / modules / demux / rtp.c
1 /**
2  * @file rtp.c
3  * @brief Real-Time Protocol (RTP) demux module for VLC media player
4  */
5 /*****************************************************************************
6  * Copyright (C) 2001-2005 the VideoLAN team
7  * Copyright © 2007-2008 Rémi Denis-Courmont
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2.0
12  * of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22  ****************************************************************************/
23
24 #ifdef HAVE_CONFIG_H
25 # include <config.h>
26 #endif
27 #include <stdarg.h>
28 #include <assert.h>
29
30 #include <vlc_common.h>
31 #include <vlc_demux.h>
32 #include <vlc_aout.h>
33 #include <vlc_network.h>
34 #include <vlc_plugin.h>
35
36 #include <vlc_codecs.h>
37
38 #include "rtp.h"
39
40 #define RTP_CACHING_TEXT N_("RTP de-jitter buffer length (msec)")
41 #define RTP_CACHING_LONGTEXT N_( \
42     "How long to wait for late RTP packets (and delay the performance)." )
43
44 #define RTP_MAX_SRC_TEXT N_("Maximum RTP sources")
45 #define RTP_MAX_SRC_LONGTEXT N_( \
46     "How many distinct active RTP sources are allowed at a time." )
47
48 #define RTP_TIMEOUT_TEXT N_("RTP source timeout (sec)")
49 #define RTP_TIMEOUT_LONGTEXT N_( \
50     "How long to wait for any packet before a source is expired.")
51
52 #define RTP_MAX_DROPOUT_TEXT N_("Maximum RTP sequence number dropout")
53 #define RTP_MAX_DROPOUT_LONGTEXT N_( \
54     "RTP packets will be discarded if they are too much ahead (i.e. in the " \
55     "future) by this many packets from the last received packet." )
56
57 #define RTP_MAX_MISORDER_TEXT N_("Maximum RTP sequence number misordering")
58 #define RTP_MAX_MISORDER_LONGTEXT N_( \
59     "RTP packets will be discarded if they are too far behind (i.e. in the " \
60     "past) by this many packets from the last received packet." )
61
62 static int  Open (vlc_object_t *);
63 static void Close (vlc_object_t *);
64
65 /*
66  * Module descriptor
67  */
68 vlc_module_begin ();
69     set_shortname (_("RTP"));
70     set_description (_("(Experimental) Real-Time Protocol demuxer"));
71     set_category (CAT_INPUT);
72     set_subcategory (SUBCAT_INPUT_DEMUX);
73     set_capability ("access_demux", 10);
74     set_callbacks (Open, Close);
75
76     add_integer ("rtp-caching", 1000, NULL, RTP_CACHING_TEXT,
77                  RTP_CACHING_LONGTEXT, true);
78         change_integer_range (0, 65535);
79     add_integer ("rtp-max-src", 1, NULL, RTP_MAX_SRC_TEXT,
80                  RTP_MAX_SRC_LONGTEXT, true);
81         change_integer_range (1, 255);
82     add_integer ("rtp-timeout", 5, NULL, RTP_TIMEOUT_TEXT,
83                  RTP_TIMEOUT_LONGTEXT, true);
84     add_integer ("rtp-max-dropout", 3000, NULL, RTP_MAX_DROPOUT_TEXT,
85                  RTP_MAX_DROPOUT_LONGTEXT, true);
86         change_integer_range (0, 32767);
87     add_integer ("rtp-max-misorder", 100, NULL, RTP_MAX_MISORDER_TEXT,
88                  RTP_MAX_MISORDER_LONGTEXT, true);
89         change_integer_range (0, 32767);
90
91     add_shortcut ("rtp");
92 vlc_module_end ();
93
94 /*
95  * TODO: so much stuff
96  * - send RTCP-RR and RTCP-BYE
97  * - dynamic payload types (need SDP parser)
98  * - multiple medias (need SDP parser, and RTCP-SR parser for lip-sync)
99  * - support for access_filter in case of stream_Demux (MPEG-TS)
100  */
101
102 /*
103  * Local prototypes
104  */
105 static int Demux (demux_t *);
106 static int Control (demux_t *, int i_query, va_list args);
107 static int extract_port (char **phost);
108
109 /**
110  * Probes and initializes.
111  */
112 static int Open (vlc_object_t *obj)
113 {
114     demux_t *demux = (demux_t *)obj;
115
116     if (strcmp (demux->psz_access, "rtp"))
117         return VLC_EGENERIC;
118
119     char *tmp = strdup (demux->psz_path);
120     char *shost = tmp;
121     if (shost == NULL)
122         return VLC_ENOMEM;
123
124     char *dhost = strchr (shost, '@');
125     if (dhost)
126         *dhost++ = '\0';
127
128     /* Parses the port numbers */
129     int sport = 0, dport = 0;
130     sport = extract_port (&shost);
131     if (dhost != NULL)
132         dport = extract_port (&dhost);
133     if (dport == 0)
134         dport = 5004; /* avt-profile-1 port */
135
136     /* Try to connect */
137     int fd = net_OpenDgram (obj, dhost, dport, shost, sport,
138                             AF_UNSPEC, IPPROTO_UDP);
139     free (tmp);
140     if (fd == -1)
141         return VLC_EGENERIC;
142
143     /* Initializes demux */
144     demux_sys_t *p_sys = malloc (sizeof (*p_sys));
145     if (p_sys == NULL)
146         goto error;
147
148     p_sys->caching      = var_CreateGetInteger (obj, "rtp-caching");
149     p_sys->max_src      = var_CreateGetInteger (obj, "rtp-max-src");
150     p_sys->timeout      = var_CreateGetInteger (obj, "rtp-timeout");
151     p_sys->max_dropout  = var_CreateGetInteger (obj, "rtp-max-dropout");
152     p_sys->max_misorder = var_CreateGetInteger (obj, "rtp-max-misorder");
153     p_sys->autodetect   = true;
154
155     demux->pf_demux   = Demux;
156     demux->pf_control = Control;
157     demux->p_sys      = p_sys;
158
159     p_sys->session = rtp_session_create (demux);
160     if (p_sys->session == NULL)
161         goto error;
162
163     p_sys->fd = fd;
164     return VLC_SUCCESS;
165
166 error:
167     net_Close (fd);
168     free (p_sys);
169     return VLC_EGENERIC;
170 }
171
172
173 /**
174  * Releases resources
175  */
176 static void Close (vlc_object_t *obj)
177 {
178     demux_t *demux = (demux_t *)obj;
179     demux_sys_t *p_sys = demux->p_sys;
180
181     rtp_session_destroy (demux, p_sys->session);
182     net_Close (p_sys->fd);
183     free (p_sys);
184 }
185
186
187 /**
188  * Extracts port number from "[host]:port" or "host:port" strings,
189  * and remove brackets from the host name.
190  * @param phost pointer to the string upon entry,
191  * pointer to the hostname upon return.
192  * @return port number, 0 if missing.
193  */
194 static int extract_port (char **phost)
195 {
196     char *host = *phost, *port;
197
198     if (host[0] == '[')
199     {
200         host = *++phost; /* skip '[' */
201         port = strchr (host, ']');
202         if (port)
203             *port++ = '\0'; /* skip ']' */
204     }
205     else
206         port = strchr (host, ':');
207
208     if (port == NULL)
209         return 0;
210     *port++ = '\0'; /* skip ':' */
211     return atoi (port);
212 }
213
214
215 /**
216  * Control callback
217  */
218 static int Control (demux_t *demux, int i_query, va_list args)
219 {
220     demux_sys_t *p_sys = demux->p_sys;
221
222     switch (i_query)
223     {
224         case DEMUX_GET_POSITION:
225         {
226             float *v = va_arg (args, float *);
227             *v = 0.;
228             return 0;
229         }
230
231         case DEMUX_GET_LENGTH:
232         case DEMUX_GET_TIME:
233         {
234             int64_t *v = va_arg (args, int64_t *);
235             *v = 0;
236             return 0;
237         }
238
239         case DEMUX_GET_PTS_DELAY:
240         {
241             int64_t *v = va_arg (args, int64_t *);
242             *v = p_sys->caching;
243             return 0;
244         }
245     }
246
247     return VLC_EGENERIC;
248 }
249
250
251 /**
252  * Gets a datagram from the network
253  */
254 static block_t *rtp_dgram_recv (demux_t *demux, int fd)
255 {
256     block_t *block = block_Alloc (0xffff);
257
258     ssize_t len = net_Read (VLC_OBJECT (demux), fd, NULL,
259                             block->p_buffer, block->i_buffer, false);
260     if (len == -1)
261     {
262         block_Release (block);
263         return NULL;
264     }
265     return block_Realloc (block, 0, len);
266 }
267
268
269 /*
270  * Generic packet handlers
271  */
272
273 static void *codec_init (demux_t *demux, es_format_t *fmt)
274 {
275     return es_out_Add (demux->out, fmt);
276 }
277
278 static void codec_destroy (demux_t *demux, void *data)
279 {
280     if (data)
281         es_out_Del (demux->out, (es_out_id_t *)data);
282 }
283
284 /* Send a packet to decoder */
285 static void codec_decode (demux_t *demux, void *data, block_t *block)
286 {
287     if (data)
288     {
289         block->i_dts = 0; /* RTP does not specify this */
290         es_out_Control (demux->out, ES_OUT_SET_PCR,
291                         block->i_pts - demux->p_sys->caching * 1000);
292         es_out_Send (demux->out, (es_out_id_t *)data, block);
293     }
294     else
295         block_Release (block);
296 }
297
298
299 static void *stream_init (demux_t *demux, const char *name)
300 {
301     return stream_DemuxNew (demux, name, demux->out);
302 }
303
304 static void stream_destroy (demux_t *demux, void *data)
305 {
306     if (data)
307         stream_DemuxDelete ((stream_t *)data);
308     (void)demux;
309 }
310
311 /* Send a packet to a chained demuxer */
312 static void stream_decode (demux_t *demux, void *data, block_t *block)
313 {
314     if (data)
315         stream_DemuxSend ((stream_t *)data, block);
316     else
317         block_Release (block);
318     (void)demux;
319 }
320
321 /*
322  * Static payload types handler
323  */
324
325 /* PT=14
326  * MPA: MPEG Audio (RFC2250, §3.4)
327  */
328 static void *mpa_init (demux_t *demux)
329 {
330     es_format_t fmt;
331
332     es_format_Init (&fmt, AUDIO_ES, VLC_FOURCC ('m', 'p', 'g', 'a'));
333     fmt.audio.i_channels = 2;
334     return codec_init (demux, &fmt);
335 }
336
337 static void mpa_decode (demux_t *demux, void *data, block_t *block)
338 {
339     if (block->i_buffer < 4)
340     {
341         block_Release (block);
342         return;
343     }
344
345     block->i_buffer -= 4; /* 32-bits RTP/MPA header */
346     block->p_buffer += 4;
347
348     codec_decode (demux, data, block);
349 }
350
351
352 /* PT=32
353  * MPV: MPEG Video (RFC2250, §3.5)
354  */
355 static void *mpv_init (demux_t *demux)
356 {
357     es_format_t fmt;
358
359     es_format_Init (&fmt, VIDEO_ES, VLC_FOURCC ('m', 'p', 'g', 'v'));
360     return codec_init (demux, &fmt);
361 }
362
363 static void mpv_decode (demux_t *demux, void *data, block_t *block)
364 {
365     if (block->i_buffer < 4)
366     {
367         block_Release (block);
368         return;
369     }
370
371     block->i_buffer -= 4; /* 32-bits RTP/MPV header */
372     block->p_buffer += 4;
373 #if 0
374     if (block->p_buffer[-3] & 0x4)
375     {
376         /* MPEG2 Video extension header */
377         /* TODO: shouldn't we skip this too ? */
378     }
379 #endif
380     codec_decode (demux, data, block);
381 }
382
383
384 /* PT=33
385  * MP2: MPEG TS (RFC2250, §2)
386  */
387 static void *ts_init (demux_t *demux)
388 {
389     return stream_init (demux, "ts");
390 }
391
392
393 /*
394  * Dynamic payload type handlers
395  * Hmm, none implemented yet.
396  */
397
398 /**
399  * Processing callback
400  */
401 static int Demux (demux_t *demux)
402 {
403     demux_sys_t *p_sys = demux->p_sys;
404     block_t     *block;
405
406     block = rtp_dgram_recv (demux, p_sys->fd);
407     if (block)
408     {
409         /* Not using SDP, we need to guess the payload format used */
410         if (p_sys->autodetect && block->i_buffer >= 2)
411         {
412             rtp_pt_t pt = {
413                 .init = NULL,
414                 .destroy = codec_destroy,
415                 .decode = codec_decode,
416                 .frequency = 0,
417                 .number = block->p_buffer[1] & 0x7f,
418             };
419
420             switch (pt.number)
421             {
422               case 14:
423                 msg_Dbg (demux, "detected MPEG Audio over RTP");
424                 pt.init = mpa_init;
425                 pt.decode = mpa_decode;
426                 pt.frequency = 44100;
427                 break;
428
429               case 32:
430                 msg_Dbg (demux, "detected MPEG Video over RTP");
431                 pt.init = mpv_init;
432                 pt.decode = mpv_decode;
433                 pt.frequency = 90000;
434                 break;
435
436               case 33:
437                 msg_Dbg (demux, "detected MPEG2 TS over RTP");
438                 pt.init = ts_init;
439                 pt.destroy = stream_destroy;
440                 pt.decode = stream_decode;
441                 pt.frequency = 90000;
442                 break;
443
444               case 72: /* muxed SR */
445               case 73: /* muxed RR */
446               case 74: /* muxed SDES */
447               case 75: /* muxed BYE */
448               case 76: /* muxed APP */
449               default:
450                 block_Release (block); /* ooh! ignoring RTCP is evil! */
451                 return 1;
452             }
453             rtp_add_type (demux, p_sys->session, &pt);
454             p_sys->autodetect = false;
455         }
456
457         rtp_receive (demux, p_sys->session, block);
458     }
459
460     return 1;
461 }