]> git.sesse.net Git - vlc/blob - modules/access/udp.c
access_udp: remove UDP-Lite support
[vlc] / modules / access / udp.c
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
6  * $Id$
7  *
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>
12  *          Remi Denis-Courmont
13  *
14  * Reviewed: 23 October 2003, Jean-Paul Saman <jpsaman _at_ videolan _dot_ org>
15  *
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.
20  *
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.
25  *
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  *****************************************************************************/
30
31 /*****************************************************************************
32  * Preamble
33  *****************************************************************************/
34
35 #ifdef HAVE_CONFIG_H
36 # include "config.h"
37 #endif
38
39 #include <vlc_common.h>
40 #include <vlc_plugin.h>
41 #include <vlc_access.h>
42 #include <vlc_network.h>
43
44 #ifndef SOCK_DCCP /* provisional API */
45 # ifdef __linux__
46 #  define SOCK_DCCP 6
47 # endif
48 #endif
49
50 #ifndef IPPROTO_DCCP
51 # define IPPROTO_DCCP 33 /* IANA */
52 #endif
53
54 #define MTU 65535
55
56 /*****************************************************************************
57  * Module descriptor
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." )
63
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)." )
68
69 static int  Open ( vlc_object_t * );
70 static void Close( vlc_object_t * );
71
72 vlc_module_begin();
73     set_shortname( N_("UDP/RTP" ) );
74     set_description( N_("UDP/RTP input") );
75     set_category( CAT_INPUT );
76     set_subcategory( SUBCAT_INPUT_ACCESS );
77
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" );
82
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" );
90
91     set_callbacks( Open, Close );
92 vlc_module_end();
93
94 /*****************************************************************************
95  * Local prototypes
96  *****************************************************************************/
97 #define RTP_HEADER_LEN 12
98
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 );
104
105 struct access_sys_t
106 {
107     int fd;
108
109     bool b_framed_rtp, b_comedia;
110
111     /* reorder rtp packets when out-of-sequence */
112     uint16_t i_last_seqno;
113     mtime_t i_rtp_late;
114     block_t *p_list;
115     block_t *p_end;
116     block_t *p_partial_frame; /* Partial Framed RTP packet */
117 };
118
119 /*****************************************************************************
120  * Open: open the socket
121  *****************************************************************************/
122 static int Open( vlc_object_t *p_this )
123 {
124     access_t     *p_access = (access_t*)p_this;
125     access_sys_t *p_sys;
126
127     char *psz_name = strdup( p_access->psz_path );
128     char *psz_parser;
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;
132
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));
139
140     if (strlen (p_access->psz_access) > 0)
141     {
142         switch (p_access->psz_access[strlen (p_access->psz_access) - 1])
143         {
144             case '4':
145                 fam = AF_INET;
146                 break;
147
148             case '6':
149                 fam = AF_INET6;
150                 break;
151         }
152
153         if (strncmp (p_access->psz_access, "udp", 3 ) == 0 )
154             p_access->pf_block = BlockChoose;
155         else
156         if (strcmp (p_access->psz_access, "rtptcp") == 0)
157             proto = IPPROTO_TCP;
158         else
159         if (strcmp (p_access->psz_access, "dccp") == 0)
160             proto = IPPROTO_DCCP;
161     }
162
163     i_bind_port = var_CreateGetInteger( p_access, "server-port" );
164
165     /* Parse psz_name syntax :
166      * [serveraddr[:serverport]][@[bindaddr]:[bindport]] */
167     psz_parser = strchr( psz_name, '@' );
168     if( psz_parser != NULL )
169     {
170         /* Found bind address and/or bind port */
171         *psz_parser++ = '\0';
172         psz_bind_addr = psz_parser;
173
174         if( psz_bind_addr[0] == '[' )
175             /* skips bracket'd IPv6 address */
176             psz_parser = strchr( psz_parser, ']' );
177
178         if( psz_parser != NULL )
179         {
180             psz_parser = strchr( psz_parser, ':' );
181             if( psz_parser != NULL )
182             {
183                 *psz_parser++ = '\0';
184                 i_bind_port = atoi( psz_parser );
185             }
186         }
187     }
188
189     psz_server_addr = psz_name;
190     psz_parser = ( psz_server_addr[0] == '[' )
191         ? strchr( psz_name, ']' ) /* skips bracket'd IPv6 address */
192         : psz_name;
193
194     if( psz_parser != NULL )
195     {
196         psz_parser = strchr( psz_parser, ':' );
197         if( psz_parser != NULL )
198         {
199             *psz_parser++ = '\0';
200             i_server_port = atoi( psz_parser );
201         }
202     }
203
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 );
206
207     /* Hmm, the net_* connection functions may need to be unified... */
208     switch (proto)
209     {
210         case IPPROTO_UDP:
211             p_sys->fd = net_OpenDgram( p_access, psz_bind_addr, i_bind_port,
212                                        psz_server_addr, i_server_port, fam,
213                                        proto );
214             break;
215
216         case IPPROTO_TCP:
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;
220             break;
221
222         case IPPROTO_DCCP:
223 #ifdef SOCK_DCCP
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 );
228 #else
229             p_sys->fd = -1;
230             msg_Err( p_access, "DCCP support not compiled-in!" );
231 #endif
232             p_sys->b_comedia = true;
233             break;
234     }
235     free (psz_name);
236     if( p_sys->fd == -1 )
237     {
238         msg_Err( p_access, "cannot open socket" );
239         free( p_sys );
240         return VLC_EGENERIC;
241     }
242
243     shutdown( p_sys->fd, SHUT_WR );
244     net_SetCSCov (p_sys->fd, -1, 12);
245
246     /* Update default_pts to a suitable value for udp access */
247     var_Create( p_access, "udp-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
248
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;
253     p_sys->p_end = NULL;
254     return VLC_SUCCESS;
255 }
256
257 /*****************************************************************************
258  * Close: free unused data structures
259  *****************************************************************************/
260 static void Close( vlc_object_t *p_this )
261 {
262     access_t     *p_access = (access_t*)p_this;
263     access_sys_t *p_sys = p_access->p_sys;
264
265     block_ChainRelease( p_sys->p_list );
266     net_Close( p_sys->fd );
267     free( p_sys );
268 }
269
270 /*****************************************************************************
271  * Control:
272  *****************************************************************************/
273 static int Control( access_t *p_access, int i_query, va_list args )
274 {
275     bool   *pb_bool;
276     int          *pi_int;
277     int64_t      *pi_64;
278
279     switch( i_query )
280     {
281         /* */
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* );
287             *pb_bool = false;
288             break;
289         /* */
290         case ACCESS_GET_MTU:
291             pi_int = (int*)va_arg( args, int * );
292             *pi_int = MTU;
293             break;
294
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;
298             break;
299
300         /* */
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:
307             return VLC_EGENERIC;
308
309         default:
310             msg_Warn( p_access, "unimplemented query in control" );
311             return VLC_EGENERIC;
312
313     }
314     return VLC_SUCCESS;
315 }
316
317 /*****************************************************************************
318  * BlockUDP:
319  *****************************************************************************/
320 static block_t *BlockUDP( access_t *p_access )
321 {
322     access_sys_t *p_sys = p_access->p_sys;
323     block_t      *p_block;
324     ssize_t len;
325
326     if( p_access->info.b_eof )
327         return NULL;
328
329     /* Read data */
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 );
333     if( ( len < 0 )
334      || ( p_sys->b_comedia && ( len == 0 ) ) )
335     {
336         if( p_sys->b_comedia )
337         {
338             p_access->info.b_eof = true;
339             msg_Dbg( p_access, "connection-oriented media hangup" );
340         }
341         block_Release( p_block );
342         return NULL;
343     }
344
345     return block_Realloc( p_block, 0, p_block->i_buffer = len );
346 }
347
348 /*****************************************************************************
349  * BlockTCP: Framed RTP/AVP packet reception for COMEDIA (see RFC4571)
350  *****************************************************************************/
351 static block_t *BlockTCP( access_t *p_access )
352 {
353     access_sys_t *p_sys = p_access->p_sys;
354     block_t      *p_block = p_sys->p_partial_frame;
355
356     if( p_access->info.b_eof )
357         return NULL;
358
359     if( p_block == NULL )
360     {
361         /* MTU should always be 65535 in this case */
362         p_sys->p_partial_frame = p_block = block_New( p_access, 2 + MTU );
363         if (p_block == NULL)
364             return NULL;
365     }
366
367     /* Read RTP framing */
368     if (p_block->i_buffer < 2)
369     {
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 );
373         if( i_read <= 0 )
374             goto error;
375
376         p_block->i_buffer += i_read;
377         if (p_block->i_buffer < 2)
378             return NULL;
379     }
380
381     uint16_t framelen = GetWLE( p_block->p_buffer );
382     /* Read RTP frame */
383     if( framelen > 0 )
384     {
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 );
388         if( i_read <= 0 )
389             goto error;
390
391         p_block->i_buffer += i_read;
392     }
393
394     if( p_block->i_buffer < (2u + framelen) )
395         return NULL; // incomplete frame
396
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;
401     return p_block;
402
403 error:
404     p_access->info.b_eof = true;
405     block_Release( p_block );
406     p_sys->p_partial_frame = NULL;
407     return NULL;
408 }
409
410
411 /*
412  * rtp_ChainInsert - insert a p_block in the chain and
413  * look at the sequence numbers.
414  */
415 static inline bool rtp_ChainInsert( access_t *p_access, block_t *p_block )
416 {
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;
421     uint16_t i_tmp = 0;
422
423     if( !p_sys->p_list )
424     {
425         p_sys->p_list = p_block;
426         p_sys->p_end = p_block;
427         return true;
428     }
429     /* walk through the queue from top down since the new packet is in
430     most cases just appended to the end */
431
432     for( ;; )
433     {
434         i_tmp = i_new - (uint16_t) p->i_dts;
435
436         if( !i_tmp )   /* trash duplicate */
437             break;
438
439         if ( i_tmp < 32768 )
440         {   /* insert after this block ( i_new > p->i_dts ) */
441             p_block->p_next = p->p_next;
442             p->p_next = p_block;
443             p_block->p_prev = p;
444             if (p_prev)
445             {
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 );
449             }
450             else
451             {
452                 p_sys->p_end = p_block;
453             }
454             return true;
455         }
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) )
460             {
461                 msg_Dbg(p_access, "RTP reordering: prepend %d before %d",
462                         i_new, (uint16_t) p->i_dts );
463                 p_block->p_next = p;
464                 p->p_prev = p_block;
465                 p_sys->p_list = p_block;
466                 return true;
467             }
468
469             if( !i_tmp )   /* trash duplicate */
470                 break;
471
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;
479             return true;
480         }
481         p_prev = p;
482         p = p->p_prev;
483     }
484     block_Release( p_block );
485     return false;
486 }
487
488 /*****************************************************************************
489  * BlockParseRTP: decapsulate the RTP packet and return it
490  *****************************************************************************/
491 static block_t *BlockParseRTP( access_t *p_access, block_t *p_block )
492 {
493     int      i_payload_type;
494     size_t   i_skip = RTP_HEADER_LEN;
495
496     if( p_block == NULL )
497         return NULL;
498
499     if( p_block->i_buffer < RTP_HEADER_LEN )
500     {
501         msg_Dbg( p_access, "short RTP packet received" );
502         goto trash;
503     }
504
505     /* Parse the header and make some verifications.
506      * See RFC 3550. */
507     // Version number:
508     if( ( p_block->p_buffer[0] >> 6 ) != 2)
509     {
510         msg_Dbg( p_access, "RTP version is %u instead of 2",
511                  p_block->p_buffer[0] >> 6 );
512         goto trash;
513     }
514     // Padding bit:
515     uint8_t pad = (p_block->p_buffer[0] & 0x20)
516                     ? p_block->p_buffer[p_block->i_buffer - 1] : 0;
517     // CSRC count:
518     i_skip += (p_block->p_buffer[0] & 0x0F) * 4;
519     // Extension header:
520     if (p_block->p_buffer[0] & 0x10) /* Extension header */
521     {
522         i_skip += 4;
523         if ((size_t)p_block->i_buffer < i_skip)
524             goto trash;
525
526         i_skip += 4 * GetWBE( p_block->p_buffer + i_skip - 2 );
527     }
528
529     i_payload_type    = p_block->p_buffer[1] & 0x7F;
530
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 );
534
535     /* FIXME: use rtpmap */
536     const char *psz_demux = NULL;
537
538     switch( i_payload_type )
539     {
540         case 14: // MPA: MPEG Audio (RFC2250, §3.4)
541             i_skip += 4; // 32 bits RTP/MPA header
542             psz_demux = "mpga";
543             break;
544
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 )
548                 goto trash;
549             if( p_block->p_buffer[i_skip - 3] & 0x4 )
550             {
551                 /* MPEG2 Video extension header */
552                 /* TODO: shouldn't we skip this too ? */
553             }
554             psz_demux = "mpgv";
555             break;
556
557         case 33: // MP2: MPEG TS (RFC2250, §2)
558             /* plain TS over RTP */
559             psz_demux = "ts";
560             break;
561
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! */
568
569         default:
570             msg_Dbg( p_access, "unsupported RTP payload type: %u", i_payload_type );
571             goto trash;
572     }
573
574     if( (size_t)p_block->i_buffer < (i_skip + pad) )
575         goto trash;
576
577     /* Remove the RTP header */
578     p_block->i_buffer -= i_skip;
579     p_block->p_buffer += i_skip;
580
581     /* This is the place for deciphering and authentication */
582
583     /* Remove padding (at the end) */
584     p_block->i_buffer -= pad;
585
586 #if 0
587     /* Emulate packet loss */
588     if ( (i_sequence_number % 4000) == 0)
589     {
590         msg_Warn( p_access, "Emulating packet drop" );
591         block_Release( p_block );
592         return NULL;
593     }
594 #endif
595
596     if( !p_access->psz_demux || !*p_access->psz_demux )
597     {
598         free( p_access->psz_demux );
599         p_access->psz_demux = strdup( psz_demux );
600     }
601
602     return p_block;
603
604 trash:
605     block_Release( p_block );
606     return NULL;
607 }
608
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 )
614 {
615     access_sys_t *p_sys = p_access->p_sys;
616     block_t *p;
617
618     while ( !p_sys->p_list ||
619              ( mdate() - p_sys->p_list->i_pts ) < p_sys->i_rtp_late )
620     {
621         p = BlockParseRTP( p_access,
622                            p_sys->b_framed_rtp ? BlockTCP( p_access )
623                                                : BlockUDP( p_access ) );
624         if ( !p )
625             return NULL;
626
627         rtp_ChainInsert( p_access, p );
628     }
629
630     p = p_sys->p_list;
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 )
634     {
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;
638     }
639     p->p_next = NULL;
640     return p;
641 }
642
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 )
649 {
650     access_sys_t *p_sys = p_access->p_sys;
651     mtime_t   i_first = mdate();
652     int       i_count = 0;
653     block_t   *p = p_block;
654
655     if( BlockParseRTP( p_access, p_block ) == NULL )
656         return NULL;
657
658     for( ;; )
659     {
660         mtime_t i_date = mdate();
661
662         if( p && rtp_ChainInsert( p_access, p ))
663             i_count++;
664
665         /* Require at least 2 packets in the buffer */
666         if( i_count > 2 && (i_date - i_first) > p_sys->i_rtp_late )
667             break;
668
669         p = BlockParseRTP( p_access, BlockUDP( p_access ) );
670         if( !p && (i_date - i_first) > p_sys->i_rtp_late )
671         {
672             msg_Err( p_access, "error in RTP prebuffering!" );
673             return NULL;
674         }
675     }
676
677     msg_Dbg( p_access, "RTP: prebuffered %d packets", i_count - 1 );
678     p_access->info.b_prebuffered = true;
679     p = p_sys->p_list;
680     p_sys->p_list = p_sys->p_list->p_next;
681     p_sys->i_last_seqno = (uint16_t) p->i_dts;
682     p->p_next = NULL;
683     return p;
684 }
685
686 static block_t *BlockStartRTP( access_t *p_access )
687 {
688     p_access->pf_block = BlockRTP;
689     return BlockPrebufferRTP( p_access, BlockUDP( p_access ) );
690 }
691
692
693 /*****************************************************************************
694  * BlockChoose: decide between RTP and UDP
695  *****************************************************************************/
696 static block_t *BlockChoose( access_t *p_access )
697 {
698     block_t *p_block;
699     int     i_rtp_version;
700     int     i_payload_type;
701
702     if( ( p_block = BlockUDP( p_access ) ) == NULL )
703         return NULL;
704
705     if( p_block->p_buffer[0] == 0x47 )
706     {
707         msg_Dbg( p_access, "detected TS over raw UDP" );
708         p_access->pf_block = BlockUDP;
709         p_access->info.b_prebuffered = true;
710         return p_block;
711     }
712
713     if( p_block->i_buffer < RTP_HEADER_LEN )
714         return p_block;
715
716     /* Parse the header and make some verifications.
717      * See RFC 3550. */
718
719     i_rtp_version  = p_block->p_buffer[0] >> 6;
720     i_payload_type = ( p_block->p_buffer[1] & 0x7F );
721
722     if( i_rtp_version != 2 )
723     {
724         msg_Dbg( p_access, "no supported RTP header detected" );
725         p_access->pf_block = BlockUDP;
726         p_access->info.b_prebuffered = true;
727         return p_block;
728     }
729
730     switch( i_payload_type )
731     {
732         case 33:
733             msg_Dbg( p_access, "detected MPEG2 TS over RTP" );
734             free( p_access->psz_demux );
735             p_access->psz_demux = strdup( "ts" );
736             break;
737
738         case 14:
739             msg_Dbg( p_access, "detected MPEG Audio over RTP" );
740             free( p_access->psz_demux );
741             p_access->psz_demux = strdup( "mpga" );
742             break;
743
744         case 32:
745             msg_Dbg( p_access, "detected MPEG Video over RTP" );
746             free( p_access->psz_demux );
747             p_access->psz_demux = strdup( "mpgv" );
748             break;
749
750         default:
751             msg_Dbg( p_access, "no RTP header detected" );
752             p_access->pf_block = BlockUDP;
753             p_access->info.b_prebuffered = true;
754             return p_block;
755     }
756
757     p_access->pf_block = BlockRTP;
758     return BlockPrebufferRTP( p_access, p_block );
759 }