1 /*****************************************************************************
2 * udp.c: raw UDP & RTP input module
3 *****************************************************************************
4 * Copyright (C) 2001-2005 the VideoLAN team
5 * Copyright (C) 2007 Remi Denis-Courmont
8 * Authors: Christophe Massiot <massiot@via.ecp.fr>
9 * Tristan Leteurtre <tooney@via.ecp.fr>
10 * Laurent Aimar <fenrir@via.ecp.fr>
11 * Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
14 * Reviewed: 23 October 2003, Jean-Paul Saman <jpsaman _at_ videolan _dot_ org>
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
29 *****************************************************************************/
31 /*****************************************************************************
33 *****************************************************************************/
39 #include <vlc_common.h>
40 #include <vlc_plugin.h>
41 #include <vlc_access.h>
42 #include <vlc_network.h>
44 #ifndef SOCK_DCCP /* provisional API */
51 # define IPPROTO_DCCP 33 /* IANA */
56 /*****************************************************************************
58 *****************************************************************************/
59 #define CACHING_TEXT N_("Caching value in ms")
60 #define CACHING_LONGTEXT N_( \
61 "Caching value for UDP streams. This " \
62 "value should be set in milliseconds." )
64 #define RTP_LATE_TEXT N_("RTP reordering timeout in ms")
65 #define RTP_LATE_LONGTEXT N_( \
66 "VLC reorders RTP packets. The input will wait for late packets at most "\
67 "the time specified here (in milliseconds)." )
69 static int Open ( vlc_object_t * );
70 static void Close( vlc_object_t * );
73 set_shortname( N_("UDP/RTP" ) );
74 set_description( N_("UDP/RTP input") );
75 set_category( CAT_INPUT );
76 set_subcategory( SUBCAT_INPUT_ACCESS );
78 add_integer( "udp-caching", DEFAULT_PTS_DELAY / 1000, NULL, CACHING_TEXT,
79 CACHING_LONGTEXT, true );
80 add_integer( "rtp-late", 100, NULL, RTP_LATE_TEXT, RTP_LATE_LONGTEXT, true );
81 add_obsolete_bool( "udp-auto-mtu" );
83 set_capability( "access", 0 );
84 add_shortcut( "udp" );
85 add_shortcut( "udpstream" );
86 add_shortcut( "udp4" );
87 add_shortcut( "udp6" );
88 add_shortcut( "rtptcp" ); /* tcp name is already taken */
89 add_shortcut( "dccp" );
91 set_callbacks( Open, Close );
94 /*****************************************************************************
96 *****************************************************************************/
97 #define RTP_HEADER_LEN 12
99 static block_t *BlockUDP( access_t * );
100 static block_t *BlockStartRTP( access_t * );
101 static block_t *BlockRTP( access_t * );
102 static block_t *BlockChoose( access_t * );
103 static int Control( access_t *, int, va_list );
109 bool b_framed_rtp, b_comedia;
111 /* reorder rtp packets when out-of-sequence */
112 uint16_t i_last_seqno;
116 block_t *p_partial_frame; /* Partial Framed RTP packet */
119 /*****************************************************************************
120 * Open: open the socket
121 *****************************************************************************/
122 static int Open( vlc_object_t *p_this )
124 access_t *p_access = (access_t*)p_this;
127 char *psz_name = strdup( p_access->psz_path );
129 const char *psz_server_addr, *psz_bind_addr = "";
130 int i_bind_port, i_server_port = 0;
131 int fam = AF_UNSPEC, proto = IPPROTO_UDP;
133 /* Set up p_access */
134 access_InitFields( p_access );
135 ACCESS_SET_CALLBACKS( NULL, BlockStartRTP, Control, NULL );
136 p_access->info.b_prebuffered = false;
137 MALLOC_ERR( p_access->p_sys, access_sys_t ); p_sys = p_access->p_sys;
138 memset (p_sys, 0, sizeof (*p_sys));
140 if (strlen (p_access->psz_access) > 0)
142 switch (p_access->psz_access[strlen (p_access->psz_access) - 1])
153 if (strncmp (p_access->psz_access, "udp", 3 ) == 0 )
154 p_access->pf_block = BlockChoose;
156 if (strcmp (p_access->psz_access, "rtptcp") == 0)
159 if (strcmp (p_access->psz_access, "dccp") == 0)
160 proto = IPPROTO_DCCP;
163 i_bind_port = var_CreateGetInteger( p_access, "server-port" );
165 /* Parse psz_name syntax :
166 * [serveraddr[:serverport]][@[bindaddr]:[bindport]] */
167 psz_parser = strchr( psz_name, '@' );
168 if( psz_parser != NULL )
170 /* Found bind address and/or bind port */
171 *psz_parser++ = '\0';
172 psz_bind_addr = psz_parser;
174 if( psz_bind_addr[0] == '[' )
175 /* skips bracket'd IPv6 address */
176 psz_parser = strchr( psz_parser, ']' );
178 if( psz_parser != NULL )
180 psz_parser = strchr( psz_parser, ':' );
181 if( psz_parser != NULL )
183 *psz_parser++ = '\0';
184 i_bind_port = atoi( psz_parser );
189 psz_server_addr = psz_name;
190 psz_parser = ( psz_server_addr[0] == '[' )
191 ? strchr( psz_name, ']' ) /* skips bracket'd IPv6 address */
194 if( psz_parser != NULL )
196 psz_parser = strchr( psz_parser, ':' );
197 if( psz_parser != NULL )
199 *psz_parser++ = '\0';
200 i_server_port = atoi( psz_parser );
204 msg_Dbg( p_access, "opening server=%s:%d local=%s:%d",
205 psz_server_addr, i_server_port, psz_bind_addr, i_bind_port );
207 /* Hmm, the net_* connection functions may need to be unified... */
211 p_sys->fd = net_OpenDgram( p_access, psz_bind_addr, i_bind_port,
212 psz_server_addr, i_server_port, fam,
217 p_sys->fd = net_ConnectTCP( p_access, psz_server_addr, i_server_port );
218 p_access->pf_block = BlockRTP;
219 p_sys->b_comedia = p_sys->b_framed_rtp = true;
224 var_Create( p_access, "dccp-service", VLC_VAR_STRING );
225 var_SetString( p_access, "dccp-service", "RTPV" );
226 p_sys->fd = net_Connect( p_access, psz_server_addr, i_server_port,
227 SOCK_DCCP, IPPROTO_DCCP );
230 msg_Err( p_access, "DCCP support not compiled-in!" );
232 p_sys->b_comedia = true;
236 if( p_sys->fd == -1 )
238 msg_Err( p_access, "cannot open socket" );
243 shutdown( p_sys->fd, SHUT_WR );
244 net_SetCSCov (p_sys->fd, -1, 12);
246 /* Update default_pts to a suitable value for udp access */
247 var_Create( p_access, "udp-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
249 /* RTP reordering for out-of-sequence packets */
250 p_sys->i_rtp_late = var_CreateGetInteger( p_access, "rtp-late" ) * 1000;
251 p_sys->i_last_seqno = 0;
252 p_sys->p_list = NULL;
257 /*****************************************************************************
258 * Close: free unused data structures
259 *****************************************************************************/
260 static void Close( vlc_object_t *p_this )
262 access_t *p_access = (access_t*)p_this;
263 access_sys_t *p_sys = p_access->p_sys;
265 block_ChainRelease( p_sys->p_list );
266 net_Close( p_sys->fd );
270 /*****************************************************************************
272 *****************************************************************************/
273 static int Control( access_t *p_access, int i_query, va_list args )
282 case ACCESS_CAN_SEEK:
283 case ACCESS_CAN_FASTSEEK:
284 case ACCESS_CAN_PAUSE:
285 case ACCESS_CAN_CONTROL_PACE:
286 pb_bool = (bool*)va_arg( args, bool* );
291 pi_int = (int*)va_arg( args, int * );
295 case ACCESS_GET_PTS_DELAY:
296 pi_64 = (int64_t*)va_arg( args, int64_t * );
297 *pi_64 = var_GetInteger( p_access, "udp-caching" ) * 1000;
301 case ACCESS_SET_PAUSE_STATE:
302 case ACCESS_GET_TITLE_INFO:
303 case ACCESS_SET_TITLE:
304 case ACCESS_SET_SEEKPOINT:
305 case ACCESS_SET_PRIVATE_ID_STATE:
306 case ACCESS_GET_CONTENT_TYPE:
310 msg_Warn( p_access, "unimplemented query in control" );
317 /*****************************************************************************
319 *****************************************************************************/
320 static block_t *BlockUDP( access_t *p_access )
322 access_sys_t *p_sys = p_access->p_sys;
326 if( p_access->info.b_eof )
330 p_block = block_New( p_access, MTU );
331 len = net_Read( p_access, p_sys->fd, NULL,
332 p_block->p_buffer, MTU, false );
334 || ( p_sys->b_comedia && ( len == 0 ) ) )
336 if( p_sys->b_comedia )
338 p_access->info.b_eof = true;
339 msg_Dbg( p_access, "connection-oriented media hangup" );
341 block_Release( p_block );
345 return block_Realloc( p_block, 0, p_block->i_buffer = len );
348 /*****************************************************************************
349 * BlockTCP: Framed RTP/AVP packet reception for COMEDIA (see RFC4571)
350 *****************************************************************************/
351 static block_t *BlockTCP( access_t *p_access )
353 access_sys_t *p_sys = p_access->p_sys;
354 block_t *p_block = p_sys->p_partial_frame;
356 if( p_access->info.b_eof )
359 if( p_block == NULL )
361 /* MTU should always be 65535 in this case */
362 p_sys->p_partial_frame = p_block = block_New( p_access, 2 + MTU );
367 /* Read RTP framing */
368 if (p_block->i_buffer < 2)
370 int i_read = net_Read( p_access, p_sys->fd, NULL,
371 p_block->p_buffer + p_block->i_buffer,
372 2 - p_block->i_buffer, false );
376 p_block->i_buffer += i_read;
377 if (p_block->i_buffer < 2)
381 uint16_t framelen = GetWLE( p_block->p_buffer );
385 int i_read = net_Read( p_access, p_sys->fd, NULL,
386 p_block->p_buffer + p_block->i_buffer,
387 2 + framelen - p_block->i_buffer, false );
391 p_block->i_buffer += i_read;
394 if( p_block->i_buffer < (2u + framelen) )
395 return NULL; // incomplete frame
397 /* Hide framing from RTP layer */
398 p_block->p_buffer += 2;
399 p_block->i_buffer -= 2;
400 p_sys->p_partial_frame = NULL;
404 p_access->info.b_eof = true;
405 block_Release( p_block );
406 p_sys->p_partial_frame = NULL;
412 * rtp_ChainInsert - insert a p_block in the chain and
413 * look at the sequence numbers.
415 static inline bool rtp_ChainInsert( access_t *p_access, block_t *p_block )
417 access_sys_t *p_sys = (access_sys_t *) p_access->p_sys;
418 block_t *p_prev = NULL;
419 block_t *p = p_sys->p_end;
420 uint16_t i_new = (uint16_t) p_block->i_dts;
425 p_sys->p_list = p_block;
426 p_sys->p_end = p_block;
429 /* walk through the queue from top down since the new packet is in
430 most cases just appended to the end */
434 i_tmp = i_new - (uint16_t) p->i_dts;
436 if( !i_tmp ) /* trash duplicate */
440 { /* insert after this block ( i_new > p->i_dts ) */
441 p_block->p_next = p->p_next;
446 p_prev->p_prev = p_block;
447 msg_Dbg(p_access, "RTP reordering: insert after %d, new %d",
448 (uint16_t) p->i_dts, i_new );
452 p_sys->p_end = p_block;
456 if( p == p_sys->p_list )
457 { /* we've reached bottom of chain */
458 i_tmp = p_sys->i_last_seqno - i_new;
459 if( !p_access->info.b_prebuffered || (i_tmp > 32767) )
461 msg_Dbg(p_access, "RTP reordering: prepend %d before %d",
462 i_new, (uint16_t) p->i_dts );
465 p_sys->p_list = p_block;
469 if( !i_tmp ) /* trash duplicate */
472 /* reordering failed - append the packet to the end of queue */
473 msg_Dbg(p_access, "RTP: sequence changed (or buffer too small) "
474 "new: %d, buffer %d...%d", i_new, (uint16_t) p->i_dts,
475 (uint16_t) p_sys->p_end->i_dts);
476 p_sys->p_end->p_next = p_block;
477 p_block->p_prev = p_sys->p_end;
478 p_sys->p_end = p_block;
484 block_Release( p_block );
488 /*****************************************************************************
489 * BlockParseRTP: decapsulate the RTP packet and return it
490 *****************************************************************************/
491 static block_t *BlockParseRTP( access_t *p_access, block_t *p_block )
494 size_t i_skip = RTP_HEADER_LEN;
496 if( p_block == NULL )
499 if( p_block->i_buffer < RTP_HEADER_LEN )
501 msg_Dbg( p_access, "short RTP packet received" );
505 /* Parse the header and make some verifications.
508 if( ( p_block->p_buffer[0] >> 6 ) != 2)
510 msg_Dbg( p_access, "RTP version is %u instead of 2",
511 p_block->p_buffer[0] >> 6 );
515 uint8_t pad = (p_block->p_buffer[0] & 0x20)
516 ? p_block->p_buffer[p_block->i_buffer - 1] : 0;
518 i_skip += (p_block->p_buffer[0] & 0x0F) * 4;
520 if (p_block->p_buffer[0] & 0x10) /* Extension header */
523 if ((size_t)p_block->i_buffer < i_skip)
526 i_skip += 4 * GetWBE( p_block->p_buffer + i_skip - 2 );
529 i_payload_type = p_block->p_buffer[1] & 0x7F;
531 /* Remember sequence number in i_dts */
532 p_block->i_pts = mdate();
533 p_block->i_dts = (mtime_t) GetWBE( p_block->p_buffer + 2 );
535 /* FIXME: use rtpmap */
536 const char *psz_demux = NULL;
538 switch( i_payload_type )
540 case 14: // MPA: MPEG Audio (RFC2250, §3.4)
541 i_skip += 4; // 32 bits RTP/MPA header
545 case 32: // MPV: MPEG Video (RFC2250, §3.5)
546 i_skip += 4; // 32 bits RTP/MPV header
547 if( (size_t)p_block->i_buffer < i_skip )
549 if( p_block->p_buffer[i_skip - 3] & 0x4 )
551 /* MPEG2 Video extension header */
552 /* TODO: shouldn't we skip this too ? */
557 case 33: // MP2: MPEG TS (RFC2250, §2)
558 /* plain TS over RTP */
562 case 72: /* muxed SR */
563 case 73: /* muxed RR */
564 case 74: /* muxed SDES */
565 case 75: /* muxed BYE */
566 case 76: /* muxed APP */
567 goto trash; /* ooh! ignoring RTCP is evil! */
570 msg_Dbg( p_access, "unsupported RTP payload type: %u", i_payload_type );
574 if( (size_t)p_block->i_buffer < (i_skip + pad) )
577 /* Remove the RTP header */
578 p_block->i_buffer -= i_skip;
579 p_block->p_buffer += i_skip;
581 /* This is the place for deciphering and authentication */
583 /* Remove padding (at the end) */
584 p_block->i_buffer -= pad;
587 /* Emulate packet loss */
588 if ( (i_sequence_number % 4000) == 0)
590 msg_Warn( p_access, "Emulating packet drop" );
591 block_Release( p_block );
596 if( !p_access->psz_demux || !*p_access->psz_demux )
598 free( p_access->psz_demux );
599 p_access->psz_demux = strdup( psz_demux );
605 block_Release( p_block );
609 /*****************************************************************************
610 * BlockRTP: receives an RTP packet, parses it, queues it queue,
611 * then dequeues the oldest packet and returns it to input/demux.
612 ****************************************************************************/
613 static block_t *BlockRTP( access_t *p_access )
615 access_sys_t *p_sys = p_access->p_sys;
618 while ( !p_sys->p_list ||
619 ( mdate() - p_sys->p_list->i_pts ) < p_sys->i_rtp_late )
621 p = BlockParseRTP( p_access,
622 p_sys->b_framed_rtp ? BlockTCP( p_access )
623 : BlockUDP( p_access ) );
627 rtp_ChainInsert( p_access, p );
631 p_sys->p_list = p_sys->p_list->p_next;
632 p_sys->i_last_seqno++;
633 if( p_sys->i_last_seqno != (uint16_t) p->i_dts )
635 msg_Dbg( p_access, "RTP: packet(s) lost, expected %d, got %d",
636 p_sys->i_last_seqno, (uint16_t) p->i_dts );
637 p_sys->i_last_seqno = (uint16_t) p->i_dts;
643 /*****************************************************************************
644 * BlockPrebufferRTP: waits until we have at least two RTP datagrams,
645 * so that we can synchronize the RTP sequence number.
646 * This is only useful for non-reliable transport protocols.
647 ****************************************************************************/
648 static block_t *BlockPrebufferRTP( access_t *p_access, block_t *p_block )
650 access_sys_t *p_sys = p_access->p_sys;
651 mtime_t i_first = mdate();
653 block_t *p = p_block;
655 if( BlockParseRTP( p_access, p_block ) == NULL )
660 mtime_t i_date = mdate();
662 if( p && rtp_ChainInsert( p_access, p ))
665 /* Require at least 2 packets in the buffer */
666 if( i_count > 2 && (i_date - i_first) > p_sys->i_rtp_late )
669 p = BlockParseRTP( p_access, BlockUDP( p_access ) );
670 if( !p && (i_date - i_first) > p_sys->i_rtp_late )
672 msg_Err( p_access, "error in RTP prebuffering!" );
677 msg_Dbg( p_access, "RTP: prebuffered %d packets", i_count - 1 );
678 p_access->info.b_prebuffered = true;
680 p_sys->p_list = p_sys->p_list->p_next;
681 p_sys->i_last_seqno = (uint16_t) p->i_dts;
686 static block_t *BlockStartRTP( access_t *p_access )
688 p_access->pf_block = BlockRTP;
689 return BlockPrebufferRTP( p_access, BlockUDP( p_access ) );
693 /*****************************************************************************
694 * BlockChoose: decide between RTP and UDP
695 *****************************************************************************/
696 static block_t *BlockChoose( access_t *p_access )
702 if( ( p_block = BlockUDP( p_access ) ) == NULL )
705 if( p_block->p_buffer[0] == 0x47 )
707 msg_Dbg( p_access, "detected TS over raw UDP" );
708 p_access->pf_block = BlockUDP;
709 p_access->info.b_prebuffered = true;
713 if( p_block->i_buffer < RTP_HEADER_LEN )
716 /* Parse the header and make some verifications.
719 i_rtp_version = p_block->p_buffer[0] >> 6;
720 i_payload_type = ( p_block->p_buffer[1] & 0x7F );
722 if( i_rtp_version != 2 )
724 msg_Dbg( p_access, "no supported RTP header detected" );
725 p_access->pf_block = BlockUDP;
726 p_access->info.b_prebuffered = true;
730 switch( i_payload_type )
733 msg_Dbg( p_access, "detected MPEG2 TS over RTP" );
734 free( p_access->psz_demux );
735 p_access->psz_demux = strdup( "ts" );
739 msg_Dbg( p_access, "detected MPEG Audio over RTP" );
740 free( p_access->psz_demux );
741 p_access->psz_demux = strdup( "mpga" );
745 msg_Dbg( p_access, "detected MPEG Video over RTP" );
746 free( p_access->psz_demux );
747 p_access->psz_demux = strdup( "mpgv" );
751 msg_Dbg( p_access, "no RTP header detected" );
752 p_access->pf_block = BlockUDP;
753 p_access->info.b_prebuffered = true;
757 p_access->pf_block = BlockRTP;
758 return BlockPrebufferRTP( p_access, p_block );