]> git.sesse.net Git - vlc/blob - modules/stream_out/rtp.c
Added DEMUX_CAN_CONTROL_RATE and DEMUX_SET_RATE implementation based
[vlc] / modules / stream_out / rtp.c
1 /*****************************************************************************
2  * rtp.c: rtp stream output module
3  *****************************************************************************
4  * Copyright (C) 2003-2004 the VideoLAN team
5  * Copyright © 2007 Rémi Denis-Courmont
6  * $Id$
7  *
8  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28
29 #include <vlc/vlc.h>
30 #include <vlc_sout.h>
31 #include <vlc_block.h>
32
33 #include <vlc_httpd.h>
34 #include <vlc_url.h>
35 #include <vlc_network.h>
36 #include <vlc_charset.h>
37 #include <vlc_strings.h>
38
39 #include "rtp.h"
40
41 #ifdef HAVE_UNISTD_H
42 #   include <sys/types.h>
43 #   include <unistd.h>
44 #   include <fcntl.h>
45 #   include <sys/stat.h>
46 #endif
47 #ifdef HAVE_LINUX_DCCP_H
48 #   include <linux/dccp.h>
49 #endif
50 #ifndef IPPROTO_DCCP
51 # define IPPROTO_DCCP 33
52 #endif
53 #ifndef IPPROTO_UDPLITE
54 # define IPPROTO_UDPLITE 136
55 #endif
56
57 #include <errno.h>
58
59 /*****************************************************************************
60  * Module descriptor
61  *****************************************************************************/
62
63 #define DST_TEXT N_("Destination")
64 #define DST_LONGTEXT N_( \
65     "This is the output URL that will be used." )
66 #define SDP_TEXT N_("SDP")
67 #define SDP_LONGTEXT N_( \
68     "This allows you to specify how the SDP (Session Descriptor) for this RTP "\
69     "session will be made available. You must use an url: http://location to " \
70     "access the SDP via HTTP, rtsp://location for RTSP access, and sap:// " \
71     "for the SDP to be announced via SAP." )
72 #define MUX_TEXT N_("Muxer")
73 #define MUX_LONGTEXT N_( \
74     "This allows you to specify the muxer used for the streaming output. " \
75     "Default is to use no muxer (standard RTP stream)." )
76
77 #define NAME_TEXT N_("Session name")
78 #define NAME_LONGTEXT N_( \
79     "This is the name of the session that will be announced in the SDP " \
80     "(Session Descriptor)." )
81 #define DESC_TEXT N_("Session description")
82 #define DESC_LONGTEXT N_( \
83     "This allows you to give a short description with details about the stream, " \
84     "that will be announced in the SDP (Session Descriptor)." )
85 #define URL_TEXT N_("Session URL")
86 #define URL_LONGTEXT N_( \
87     "This allows you to give an URL with more details about the stream " \
88     "(often the website of the streaming organization), that will " \
89     "be announced in the SDP (Session Descriptor)." )
90 #define EMAIL_TEXT N_("Session email")
91 #define EMAIL_LONGTEXT N_( \
92     "This allows you to give a contact mail address for the stream, that will " \
93     "be announced in the SDP (Session Descriptor)." )
94 #define PHONE_TEXT N_("Session phone number")
95 #define PHONE_LONGTEXT N_( \
96     "This allows you to give a contact telephone number for the stream, that will " \
97     "be announced in the SDP (Session Descriptor)." )
98
99 #define PORT_TEXT N_("Port")
100 #define PORT_LONGTEXT N_( \
101     "This allows you to specify the base port for the RTP streaming." )
102 #define PORT_AUDIO_TEXT N_("Audio port")
103 #define PORT_AUDIO_LONGTEXT N_( \
104     "This allows you to specify the default audio port for the RTP streaming." )
105 #define PORT_VIDEO_TEXT N_("Video port")
106 #define PORT_VIDEO_LONGTEXT N_( \
107     "This allows you to specify the default video port for the RTP streaming." )
108
109 #define TTL_TEXT N_("Hop limit (TTL)")
110 #define TTL_LONGTEXT N_( \
111     "This is the hop limit (also known as \"Time-To-Live\" or TTL) of " \
112     "the multicast packets sent by the stream output (0 = use operating " \
113     "system built-in default).")
114
115 #define RTCP_MUX_TEXT N_("RTP/RTCP multiplexing")
116 #define RTCP_MUX_LONGTEXT N_( \
117     "This sends and receives RTCP packet multiplexed over the same port " \
118     "as RTP packets." )
119
120 #define DCCP_TEXT N_("DCCP transport")
121 #define DCCP_LONGTEXT N_( \
122     "This enables DCCP instead of UDP as a transport for RTP." )
123 #define TCP_TEXT N_("TCP transport")
124 #define TCP_LONGTEXT N_( \
125     "This enables TCP instead of UDP as a transport for RTP." )
126 #define UDP_LITE_TEXT N_("UDP-Lite transport")
127 #define UDP_LITE_LONGTEXT N_( \
128     "This enables UDP-Lite instead of UDP as a transport for RTP." )
129
130 #define RFC3016_TEXT N_("MP4A LATM")
131 #define RFC3016_LONGTEXT N_( \
132     "This allows you to stream MPEG4 LATM audio streams (see RFC3016)." )
133
134 static int  Open ( vlc_object_t * );
135 static void Close( vlc_object_t * );
136
137 #define SOUT_CFG_PREFIX "sout-rtp-"
138 #define MAX_EMPTY_BLOCKS 200
139
140 vlc_module_begin();
141     set_shortname( _("RTP"));
142     set_description( _("RTP stream output") );
143     set_capability( "sout stream", 0 );
144     add_shortcut( "rtp" );
145     set_category( CAT_SOUT );
146     set_subcategory( SUBCAT_SOUT_STREAM );
147
148     add_string( SOUT_CFG_PREFIX "dst", "", NULL, DST_TEXT,
149                 DST_LONGTEXT, VLC_TRUE );
150     add_string( SOUT_CFG_PREFIX "sdp", "", NULL, SDP_TEXT,
151                 SDP_LONGTEXT, VLC_TRUE );
152     add_string( SOUT_CFG_PREFIX "mux", "", NULL, MUX_TEXT,
153                 MUX_LONGTEXT, VLC_TRUE );
154
155     add_string( SOUT_CFG_PREFIX "name", "", NULL, NAME_TEXT,
156                 NAME_LONGTEXT, VLC_TRUE );
157     add_string( SOUT_CFG_PREFIX "description", "", NULL, DESC_TEXT,
158                 DESC_LONGTEXT, VLC_TRUE );
159     add_string( SOUT_CFG_PREFIX "url", "", NULL, URL_TEXT,
160                 URL_LONGTEXT, VLC_TRUE );
161     add_string( SOUT_CFG_PREFIX "email", "", NULL, EMAIL_TEXT,
162                 EMAIL_LONGTEXT, VLC_TRUE );
163     add_string( SOUT_CFG_PREFIX "phone", "", NULL, PHONE_TEXT,
164                 PHONE_LONGTEXT, VLC_TRUE );
165
166     add_integer( SOUT_CFG_PREFIX "port", 1234, NULL, PORT_TEXT,
167                  PORT_LONGTEXT, VLC_TRUE );
168     add_integer( SOUT_CFG_PREFIX "port-audio", 1230, NULL, PORT_AUDIO_TEXT,
169                  PORT_AUDIO_LONGTEXT, VLC_TRUE );
170     add_integer( SOUT_CFG_PREFIX "port-video", 1232, NULL, PORT_VIDEO_TEXT,
171                  PORT_VIDEO_LONGTEXT, VLC_TRUE );
172
173     add_integer( SOUT_CFG_PREFIX "ttl", 0, NULL, TTL_TEXT,
174                  TTL_LONGTEXT, VLC_TRUE );
175
176     add_bool( SOUT_CFG_PREFIX "rtcp-mux", VLC_FALSE, NULL,
177               RTCP_MUX_TEXT, RTCP_MUX_LONGTEXT, VLC_FALSE );
178
179     add_bool( SOUT_CFG_PREFIX "dccp", VLC_FALSE, NULL,
180               DCCP_TEXT, DCCP_LONGTEXT, VLC_FALSE );
181     add_bool( SOUT_CFG_PREFIX "tcp", VLC_FALSE, NULL,
182               TCP_TEXT, TCP_LONGTEXT, VLC_FALSE );
183     add_bool( SOUT_CFG_PREFIX "udplite", VLC_FALSE, NULL,
184               UDP_LITE_TEXT, UDP_LITE_LONGTEXT, VLC_FALSE );
185
186     add_bool( SOUT_CFG_PREFIX "mp4a-latm", 0, NULL, RFC3016_TEXT,
187                  RFC3016_LONGTEXT, VLC_FALSE );
188
189     set_callbacks( Open, Close );
190 vlc_module_end();
191
192 /*****************************************************************************
193  * Exported prototypes
194  *****************************************************************************/
195 static const char *ppsz_sout_options[] = {
196     "dst", "name", "port", "port-audio", "port-video", "*sdp", "ttl", "mux",
197     "description", "url", "email", "phone",
198     "rtcp-mux", "dccp", "tcp", "udplite",
199     "mp4a-latm", NULL
200 };
201
202 static sout_stream_id_t *Add ( sout_stream_t *, es_format_t * );
203 static int               Del ( sout_stream_t *, sout_stream_id_t * );
204 static int               Send( sout_stream_t *, sout_stream_id_t *,
205                                block_t* );
206 static sout_stream_id_t *MuxAdd ( sout_stream_t *, es_format_t * );
207 static int               MuxDel ( sout_stream_t *, sout_stream_id_t * );
208 static int               MuxSend( sout_stream_t *, sout_stream_id_t *,
209                                   block_t* );
210
211 static sout_access_out_t *GrabberCreate( sout_stream_t *p_sout );
212 static void ThreadSend( vlc_object_t *p_this );
213
214 static void SDPHandleUrl( sout_stream_t *, char * );
215
216 static int SapSetup( sout_stream_t *p_stream );
217 static int FileSetup( sout_stream_t *p_stream );
218 static int HttpSetup( sout_stream_t *p_stream, vlc_url_t * );
219
220 struct sout_stream_sys_t
221 {
222     /* SDP */
223     char    *psz_sdp;
224     vlc_mutex_t  lock_sdp;
225
226     /* SDP to disk */
227     vlc_bool_t b_export_sdp_file;
228     char *psz_sdp_file;
229
230     /* SDP via SAP */
231     vlc_bool_t b_export_sap;
232     session_descriptor_t *p_session;
233
234     /* SDP via HTTP */
235     httpd_host_t *p_httpd_host;
236     httpd_file_t *p_httpd_file;
237
238     /* RTSP */
239     rtsp_stream_t *rtsp;
240
241     /* */
242     char     *psz_destination;
243     uint8_t   proto;
244     uint8_t   i_ttl;
245     uint16_t  i_port;
246     uint16_t  i_port_audio;
247     uint16_t  i_port_video;
248     vlc_bool_t b_latm;
249     vlc_bool_t rtcp_mux;
250
251     /* when need to use a private one or when using muxer */
252     int i_payload_type;
253
254     /* in case we do TS/PS over rtp */
255     sout_mux_t        *p_mux;
256     sout_access_out_t *p_grab;
257     block_t           *packet;
258
259     /* */
260     vlc_mutex_t      lock_es;
261     int              i_es;
262     sout_stream_id_t **es;
263 };
264
265 typedef int (*pf_rtp_packetizer_t)( sout_stream_t *, sout_stream_id_t *,
266                                     block_t * );
267
268 typedef struct rtp_sink_t
269 {
270     int rtp_fd;
271     rtcp_sender_t *rtcp;
272 } rtp_sink_t;
273
274 struct sout_stream_id_t
275 {
276     VLC_COMMON_MEMBERS
277
278     sout_stream_t *p_stream;
279     /* rtp field */
280     uint16_t    i_sequence;
281     uint8_t     i_payload_type;
282     uint8_t     ssrc[4];
283
284     /* for sdp */
285     const char  *psz_enc;
286     char        *psz_fmtp;
287     int          i_clock_rate;
288     int          i_port;
289     int          i_cat;
290     int          i_channels;
291     int          i_bitrate;
292
293     /* Packetizer specific fields */
294     pf_rtp_packetizer_t pf_packetize;
295     int          i_mtu;
296
297     /* Packets sinks */
298     vlc_mutex_t       lock_sink;
299     int               sinkc;
300     rtp_sink_t       *sinkv;
301     rtsp_stream_id_t *rtsp_id;
302     int              *listen_fd;
303
304     block_fifo_t     *p_fifo;
305     int64_t           i_caching;
306 };
307
308
309 /*****************************************************************************
310  * Open:
311  *****************************************************************************/
312 static int Open( vlc_object_t *p_this )
313 {
314     sout_stream_t       *p_stream = (sout_stream_t*)p_this;
315     sout_instance_t     *p_sout = p_stream->p_sout;
316     sout_stream_sys_t   *p_sys = NULL;
317     config_chain_t      *p_cfg = NULL;
318     char                *psz;
319     vlc_bool_t          b_rtsp = VLC_FALSE;
320
321     config_ChainParse( p_stream, SOUT_CFG_PREFIX,
322                        ppsz_sout_options, p_stream->p_cfg );
323
324     p_sys = malloc( sizeof( sout_stream_sys_t ) );
325     if( p_sys == NULL )
326         return VLC_ENOMEM;
327
328     p_sys->psz_destination = var_GetNonEmptyString( p_stream, SOUT_CFG_PREFIX "dst" );
329
330     p_sys->i_port       = var_GetInteger( p_stream, SOUT_CFG_PREFIX "port" );
331     p_sys->i_port_audio = var_GetInteger( p_stream, SOUT_CFG_PREFIX "port-audio" );
332     p_sys->i_port_video = var_GetInteger( p_stream, SOUT_CFG_PREFIX "port-video" );
333     p_sys->rtcp_mux   = var_GetBool( p_stream, SOUT_CFG_PREFIX "rtcp-mux" );
334
335     p_sys->psz_sdp_file = NULL;
336
337     if( p_sys->i_port_audio == p_sys->i_port_video )
338     {
339         msg_Err( p_stream, "audio and video port cannot be the same" );
340         p_sys->i_port_audio = 0;
341         p_sys->i_port_video = 0;
342     }
343
344     for( p_cfg = p_stream->p_cfg; p_cfg != NULL; p_cfg = p_cfg->p_next )
345     {
346         if( !strcmp( p_cfg->psz_name, "sdp" )
347          && ( p_cfg->psz_value != NULL )
348          && !strncasecmp( p_cfg->psz_value, "rtsp:", 5 ) )
349         {
350             b_rtsp = VLC_TRUE;
351             break;
352         }
353     }
354     if( !b_rtsp )
355     {
356         psz = var_GetNonEmptyString( p_stream, SOUT_CFG_PREFIX "sdp" );
357         if( psz != NULL )
358         {
359             if( !strncasecmp( psz, "rtsp:", 5 ) )
360                 b_rtsp = VLC_TRUE;
361             free( psz );
362         }
363     }
364
365     /* Transport protocol */
366     p_sys->proto = IPPROTO_UDP;
367
368     if( var_GetBool( p_stream, SOUT_CFG_PREFIX "dccp" ) )
369     {
370         p_sys->proto = IPPROTO_DCCP;
371         p_sys->rtcp_mux = VLC_TRUE; /* Force RTP/RTCP mux */
372     }
373 #if 0
374     else
375     if( var_GetBool( p_stream, SOUT_CFG_PREFIX "tcp" ) )
376     {
377         p_sys->proto = IPPROTO_TCP;
378         p_sys->rtcp_mux = VLC_TRUE; /* Force RTP/RTCP mux */
379     }
380     else
381 #endif
382     if( var_GetBool( p_stream, SOUT_CFG_PREFIX "udplite" ) )
383         p_sys->proto = IPPROTO_UDPLITE;
384
385     if( ( p_sys->psz_destination == NULL ) && !b_rtsp )
386     {
387         msg_Err( p_stream, "missing destination and not in RTSP mode" );
388         free( p_sys );
389         return VLC_EGENERIC;
390     }
391
392     p_sys->i_ttl = var_GetInteger( p_stream, SOUT_CFG_PREFIX "ttl" );
393     if( p_sys->i_ttl == 0 )
394     {
395         /* Normally, we should let the default hop limit up to the core,
396          * but we have to know it to build our SDP properly, which is why
397          * we ask the core. FIXME: broken when neither sout-rtp-ttl nor
398          * ttl are set. */
399         p_sys->i_ttl = config_GetInt( p_stream, "ttl" );
400     }
401
402     p_sys->b_latm = var_GetBool( p_stream, SOUT_CFG_PREFIX "mp4a-latm" );
403
404     p_sys->i_payload_type = 96;
405     p_sys->i_es = 0;
406     p_sys->es   = NULL;
407     p_sys->rtsp = NULL;
408     p_sys->psz_sdp = NULL;
409
410     p_sys->b_export_sap = VLC_FALSE;
411     p_sys->b_export_sdp_file = VLC_FALSE;
412     p_sys->p_session = NULL;
413
414     p_sys->p_httpd_host = NULL;
415     p_sys->p_httpd_file = NULL;
416
417     p_stream->p_sys     = p_sys;
418
419     vlc_mutex_init( p_stream, &p_sys->lock_sdp );
420     vlc_mutex_init( p_stream, &p_sys->lock_es );
421
422     psz = var_GetNonEmptyString( p_stream, SOUT_CFG_PREFIX "mux" );
423     if( psz != NULL )
424     {
425         sout_stream_id_t *id;
426
427         /* Check muxer type */
428         if( strncasecmp( psz, "ps", 2 )
429          && strncasecmp( psz, "mpeg1", 5 )
430          && strncasecmp( psz, "ts", 2 ) )
431         {
432             msg_Err( p_stream, "unsupported muxer type for RTP (only TS/PS)" );
433             free( psz );
434             vlc_mutex_destroy( &p_sys->lock_sdp );
435             vlc_mutex_destroy( &p_sys->lock_es );
436             free( p_sys );
437             return VLC_EGENERIC;
438         }
439
440         p_sys->p_grab = GrabberCreate( p_stream );
441         p_sys->p_mux = sout_MuxNew( p_sout, psz, p_sys->p_grab );
442         free( psz );
443
444         if( p_sys->p_mux == NULL )
445         {
446             msg_Err( p_stream, "cannot create muxer" );
447             sout_AccessOutDelete( p_sys->p_grab );
448             vlc_mutex_destroy( &p_sys->lock_sdp );
449             vlc_mutex_destroy( &p_sys->lock_es );
450             free( p_sys );
451             return VLC_EGENERIC;
452         }
453
454         id = Add( p_stream, NULL );
455         if( id == NULL )
456         {
457             sout_MuxDelete( p_sys->p_mux );
458             sout_AccessOutDelete( p_sys->p_grab );
459             vlc_mutex_destroy( &p_sys->lock_sdp );
460             vlc_mutex_destroy( &p_sys->lock_es );
461             free( p_sys );
462             return VLC_EGENERIC;
463         }
464
465         p_sys->packet = NULL;
466
467         p_stream->pf_add  = MuxAdd;
468         p_stream->pf_del  = MuxDel;
469         p_stream->pf_send = MuxSend;
470     }
471     else
472     {
473         p_sys->p_mux    = NULL;
474         p_sys->p_grab   = NULL;
475
476         p_stream->pf_add    = Add;
477         p_stream->pf_del    = Del;
478         p_stream->pf_send   = Send;
479     }
480
481     psz = var_GetNonEmptyString( p_stream, SOUT_CFG_PREFIX "sdp" );
482     if( psz != NULL )
483     {
484         config_chain_t *p_cfg;
485
486         SDPHandleUrl( p_stream, psz );
487
488         for( p_cfg = p_stream->p_cfg; p_cfg != NULL; p_cfg = p_cfg->p_next )
489         {
490             if( !strcmp( p_cfg->psz_name, "sdp" ) )
491             {
492                 if( p_cfg->psz_value == NULL || *p_cfg->psz_value == '\0' )
493                     continue;
494
495                 /* needed both :sout-rtp-sdp= and rtp{sdp=} can be used */
496                 if( !strcmp( p_cfg->psz_value, psz ) )
497                     continue;
498
499                 SDPHandleUrl( p_stream, p_cfg->psz_value );
500             }
501         }
502         free( psz );
503     }
504
505     /* update p_sout->i_out_pace_nocontrol */
506     p_stream->p_sout->i_out_pace_nocontrol++;
507
508     return VLC_SUCCESS;
509 }
510
511 /*****************************************************************************
512  * Close:
513  *****************************************************************************/
514 static void Close( vlc_object_t * p_this )
515 {
516     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
517     sout_stream_sys_t *p_sys = p_stream->p_sys;
518
519     /* update p_sout->i_out_pace_nocontrol */
520     p_stream->p_sout->i_out_pace_nocontrol--;
521
522     if( p_sys->p_mux )
523     {
524         assert( p_sys->i_es == 1 );
525         Del( p_stream, p_sys->es[0] );
526
527         sout_MuxDelete( p_sys->p_mux );
528         sout_AccessOutDelete( p_sys->p_grab );
529         if( p_sys->packet )
530         {
531             block_Release( p_sys->packet );
532         }
533         if( p_sys->b_export_sap )
534         {
535             p_sys->p_mux = NULL;
536             SapSetup( p_stream );
537         }
538     }
539
540     if( p_sys->rtsp != NULL )
541         RtspUnsetup( p_sys->rtsp );
542
543     vlc_mutex_destroy( &p_sys->lock_sdp );
544     vlc_mutex_destroy( &p_sys->lock_es );
545
546     if( p_sys->p_httpd_file )
547         httpd_FileDelete( p_sys->p_httpd_file );
548
549     if( p_sys->p_httpd_host )
550         httpd_HostDelete( p_sys->p_httpd_host );
551
552     free( p_sys->psz_sdp );
553
554     if( p_sys->b_export_sdp_file )
555     {
556 #ifdef HAVE_UNISTD_H
557         unlink( p_sys->psz_sdp_file );
558 #endif
559         free( p_sys->psz_sdp_file );
560     }
561     free( p_sys->psz_destination );
562     free( p_sys );
563 }
564
565 /*****************************************************************************
566  * SDPHandleUrl:
567  *****************************************************************************/
568 static void SDPHandleUrl( sout_stream_t *p_stream, char *psz_url )
569 {
570     sout_stream_sys_t *p_sys = p_stream->p_sys;
571     vlc_url_t url;
572
573     vlc_UrlParse( &url, psz_url, 0 );
574     if( url.psz_protocol && !strcasecmp( url.psz_protocol, "http" ) )
575     {
576         if( p_sys->p_httpd_file )
577         {
578             msg_Err( p_stream, "you can use sdp=http:// only once" );
579             goto out;
580         }
581
582         if( HttpSetup( p_stream, &url ) )
583         {
584             msg_Err( p_stream, "cannot export SDP as HTTP" );
585         }
586     }
587     else if( url.psz_protocol && !strcasecmp( url.psz_protocol, "rtsp" ) )
588     {
589         if( p_sys->rtsp != NULL )
590         {
591             msg_Err( p_stream, "you can use sdp=rtsp:// only once" );
592             goto out;
593         }
594
595         /* FIXME test if destination is multicast or no destination at all */
596         p_sys->rtsp = RtspSetup( p_stream, &url );
597         if( p_sys->rtsp == NULL )
598         {
599             msg_Err( p_stream, "cannot export SDP as RTSP" );
600         }
601
602         if( p_sys->p_mux != NULL )
603         {
604             sout_stream_id_t *id = p_sys->es[0];
605             id->rtsp_id = RtspAddId( p_sys->rtsp, id, 0, GetDWBE( id->ssrc ),
606                                      p_sys->psz_destination, p_sys->i_ttl,
607                                      id->i_port, id->i_port + 1 );
608         }
609     }
610     else if( ( url.psz_protocol && !strcasecmp( url.psz_protocol, "sap" ) ) ||
611              ( url.psz_host && !strcasecmp( url.psz_host, "sap" ) ) )
612     {
613         p_sys->b_export_sap = VLC_TRUE;
614         SapSetup( p_stream );
615     }
616     else if( url.psz_protocol && !strcasecmp( url.psz_protocol, "file" ) )
617     {
618         if( p_sys->b_export_sdp_file )
619         {
620             msg_Err( p_stream, "you can use sdp=file:// only once" );
621             goto out;
622         }
623         p_sys->b_export_sdp_file = VLC_TRUE;
624         psz_url = &psz_url[5];
625         if( psz_url[0] == '/' && psz_url[1] == '/' )
626             psz_url += 2;
627         p_sys->psz_sdp_file = strdup( psz_url );
628     }
629     else
630     {
631         msg_Warn( p_stream, "unknown protocol for SDP (%s)",
632                   url.psz_protocol );
633     }
634
635 out:
636     vlc_UrlClean( &url );
637 }
638
639 /*****************************************************************************
640  * SDPGenerate
641  *****************************************************************************/
642 /*static*/
643 char *SDPGenerate( const sout_stream_t *p_stream, const char *rtsp_url )
644 {
645     const sout_stream_sys_t *p_sys = p_stream->p_sys;
646     char *psz_sdp;
647     struct sockaddr_storage dst;
648     socklen_t dstlen;
649     int i;
650     /*
651      * When we have a fixed destination (typically when we do multicast),
652      * we need to put the actual port numbers in the SDP.
653      * When there is no fixed destination, we only support RTSP unicast
654      * on-demand setup, so we should rather let the clients decide which ports
655      * to use.
656      * When there is both a fixed destination and RTSP unicast, we need to
657      * put port numbers used by the fixed destination, otherwise the SDP would
658      * become totally incorrect for multicast use. It should be noted that
659      * port numbers from SDP with RTSP are only "recommendation" from the
660      * server to the clients (per RFC2326), so only broken clients will fail
661      * to handle this properly. There is no solution but to use two differents
662      * output chain with two different RTSP URLs if you need to handle this
663      * scenario.
664      */
665     int inclport;
666
667     if( p_sys->psz_destination != NULL )
668     {
669         inclport = 1;
670
671         /* Oh boy, this is really ugly! (+ race condition on lock_es) */
672         dstlen = sizeof( dst );
673         if( p_sys->es[0]->listen_fd != NULL )
674             getsockname( p_sys->es[0]->listen_fd[0],
675                          (struct sockaddr *)&dst, &dstlen );
676         else
677             getpeername( p_sys->es[0]->sinkv[0].rtp_fd,
678                          (struct sockaddr *)&dst, &dstlen );
679     }
680     else
681     {
682         inclport = 0;
683
684         /* Dummy destination address for RTSP */
685         memset (&dst, 0, sizeof( struct sockaddr_in ) );
686         dst.ss_family = AF_INET;
687 #ifdef HAVE_SA_LEN
688         dst.ss_len =
689 #endif
690         dstlen = sizeof( struct sockaddr_in );
691     }
692
693     psz_sdp = vlc_sdp_Start( VLC_OBJECT( p_stream ), SOUT_CFG_PREFIX,
694                              NULL, 0, (struct sockaddr *)&dst, dstlen );
695     if( psz_sdp == NULL )
696         return NULL;
697
698     /* TODO: a=source-filter */
699     if( p_sys->rtcp_mux )
700         sdp_AddAttribute( &psz_sdp, "rtcp-mux", NULL );
701
702     if( rtsp_url != NULL )
703         sdp_AddAttribute ( &psz_sdp, "control", "%s", rtsp_url );
704
705     /* FIXME: locking?! */
706     for( i = 0; i < p_sys->i_es; i++ )
707     {
708         sout_stream_id_t *id = p_sys->es[i];
709         const char *mime_major; /* major MIME type */
710         const char *proto = "RTP/AVP"; /* protocol */
711
712         switch( id->i_cat )
713         {
714             case VIDEO_ES:
715                 mime_major = "video";
716                 break;
717             case AUDIO_ES:
718                 mime_major = "audio";
719                 break;
720             case SPU_ES:
721                 mime_major = "text";
722                 break;
723             default:
724                 continue;
725         }
726
727         if( rtsp_url == NULL )
728         {
729             switch( p_sys->proto )
730             {
731                 case IPPROTO_UDP:
732                     break;
733                 case IPPROTO_TCP:
734                     proto = "TCP/RTP/AVP";
735                     break;
736                 case IPPROTO_DCCP:
737                     proto = "DCCP/RTP/AVP";
738                     break;
739                 case IPPROTO_UDPLITE:
740                     continue;
741             }
742         }
743
744         sdp_AddMedia( &psz_sdp, mime_major, proto, inclport * id->i_port,
745                       id->i_payload_type, VLC_FALSE, id->i_bitrate,
746                       id->psz_enc, id->i_clock_rate, id->i_channels,
747                       id->psz_fmtp);
748
749         if( rtsp_url != NULL )
750         {
751             assert( strlen( rtsp_url ) > 0 );
752             vlc_bool_t addslash = ( rtsp_url[strlen( rtsp_url ) - 1] != '/' );
753             sdp_AddAttribute ( &psz_sdp, "control",
754                                addslash ? "%s/trackID=%u" : "%strackID=%u",
755                                rtsp_url, i );
756         }
757         else
758         {
759             if( id->listen_fd != NULL )
760                 sdp_AddAttribute( &psz_sdp, "setup", "passive" );
761 #if 0
762             if( p_sys->proto == IPPROTO_DCCP )
763                 sdp_AddAttribute( &psz_sdp, "dccp-service-code", 
764                                   "SC:RTP%c", toupper( mime_major[0] ) );
765 #endif
766         }
767     }
768
769     return psz_sdp;
770 }
771
772 /*****************************************************************************
773  * RTP mux
774  *****************************************************************************/
775 static int rtp_packetize_l16  ( sout_stream_t *, sout_stream_id_t *, block_t * );
776 static int rtp_packetize_l8   ( sout_stream_t *, sout_stream_id_t *, block_t * );
777 static int rtp_packetize_mpa  ( sout_stream_t *, sout_stream_id_t *, block_t * );
778 static int rtp_packetize_mpv  ( sout_stream_t *, sout_stream_id_t *, block_t * );
779 static int rtp_packetize_ac3  ( sout_stream_t *, sout_stream_id_t *, block_t * );
780 static int rtp_packetize_split( sout_stream_t *, sout_stream_id_t *, block_t * );
781 static int rtp_packetize_mp4a ( sout_stream_t *, sout_stream_id_t *, block_t * );
782 static int rtp_packetize_mp4a_latm ( sout_stream_t *, sout_stream_id_t *, block_t * );
783 static int rtp_packetize_h263 ( sout_stream_t *, sout_stream_id_t *, block_t * );
784 static int rtp_packetize_h264 ( sout_stream_t *, sout_stream_id_t *, block_t * );
785 static int rtp_packetize_amr  ( sout_stream_t *, sout_stream_id_t *, block_t * );
786 static int rtp_packetize_spx  ( sout_stream_t *, sout_stream_id_t *, block_t * );
787 static int rtp_packetize_t140 ( sout_stream_t *, sout_stream_id_t *, block_t * );
788
789 static void sprintf_hexa( char *s, uint8_t *p_data, int i_data )
790 {
791     static const char hex[16] = "0123456789abcdef";
792     int i;
793
794     for( i = 0; i < i_data; i++ )
795     {
796         s[2*i+0] = hex[(p_data[i]>>4)&0xf];
797         s[2*i+1] = hex[(p_data[i]   )&0xf];
798     }
799     s[2*i_data] = '\0';
800 }
801
802
803 /** Add an ES as a new RTP stream */
804 static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
805 {
806     /* NOTE: As a special case, if we use a non-RTP
807      * mux (TS/PS), then p_fmt is NULL. */
808     sout_stream_sys_t *p_sys = p_stream->p_sys;
809     sout_stream_id_t  *id;
810     int               i_port, cscov = -1;
811     char              *psz_sdp;
812
813     id = vlc_object_create( p_stream, sizeof( sout_stream_id_t ) );
814     if( id == NULL )
815         return NULL;
816     vlc_object_attach( id, p_stream );
817
818     /* Choose the port */
819     i_port = 0;
820     if( p_fmt == NULL )
821         ;
822     else
823     if( p_fmt->i_cat == AUDIO_ES && p_sys->i_port_audio > 0 )
824     {
825         i_port = p_sys->i_port_audio;
826         p_sys->i_port_audio = 0;
827     }
828     else
829     if( p_fmt->i_cat == VIDEO_ES && p_sys->i_port_video > 0 )
830     {
831         i_port = p_sys->i_port_video;
832         p_sys->i_port_video = 0;
833     }
834
835     while( i_port == 0 )
836     {
837         if( p_sys->i_port != p_sys->i_port_audio
838          && p_sys->i_port != p_sys->i_port_video )
839         {
840             i_port = p_sys->i_port;
841             p_sys->i_port += 2;
842             break;
843         }
844         p_sys->i_port += 2;
845     }
846
847     id->p_stream   = p_stream;
848
849     id->i_sequence = rand()&0xffff;
850     id->i_payload_type = p_sys->i_payload_type;
851     id->ssrc[0] = rand()&0xff;
852     id->ssrc[1] = rand()&0xff;
853     id->ssrc[2] = rand()&0xff;
854     id->ssrc[3] = rand()&0xff;
855
856     id->psz_enc    = NULL;
857     id->psz_fmtp   = NULL;
858     id->i_clock_rate = 90000; /* most common case for video */
859     id->i_channels = 0;
860     id->i_port     = i_port;
861     if( p_fmt != NULL )
862     {
863         id->i_cat  = p_fmt->i_cat;
864         if( p_fmt->i_cat == AUDIO_ES )
865         {
866             id->i_clock_rate = p_fmt->audio.i_rate;
867             id->i_channels = p_fmt->audio.i_channels;
868         }
869         id->i_bitrate = p_fmt->i_bitrate/1000; /* Stream bitrate in kbps */
870     }
871     else
872     {
873         id->i_cat  = VIDEO_ES;
874         id->i_bitrate = 0;
875     }
876
877     id->pf_packetize = NULL;
878     id->i_mtu = config_GetInt( p_stream, "mtu" );
879     if( id->i_mtu <= 12 + 16 )
880         id->i_mtu = 576 - 20 - 8; /* pessimistic */
881
882     msg_Dbg( p_stream, "maximum RTP packet size: %d bytes", id->i_mtu );
883
884     vlc_mutex_init( p_stream, &id->lock_sink );
885     id->sinkc = 0;
886     id->sinkv = NULL;
887     id->rtsp_id = NULL;
888     id->p_fifo = NULL;
889     id->listen_fd = NULL;
890
891     id->i_caching =
892         (int64_t)1000 * var_GetInteger( p_stream, SOUT_CFG_PREFIX "caching");
893
894     if( p_sys->psz_destination != NULL )
895         switch( p_sys->proto )
896         {
897             case IPPROTO_TCP:
898             case IPPROTO_DCCP:
899                 id->listen_fd = net_Listen( VLC_OBJECT(p_stream),
900                                             p_sys->psz_destination, i_port,
901                                             p_sys->proto );
902                 if( id->listen_fd == NULL )
903                 {
904                     msg_Err( p_stream, "passive COMEDIA RTP socket failed" );
905                     goto error;
906                 }
907                 break;
908
909             default:
910             {
911                 int ttl = (p_sys->i_ttl > 0) ? p_sys->i_ttl : -1;
912                 int fd = net_ConnectDgram( p_stream, p_sys->psz_destination,
913                                            i_port, ttl, p_sys->proto );
914                 if( fd == -1 )
915                 {
916                     msg_Err( p_stream, "cannot create RTP socket" );
917                     goto error;
918                 }
919                 rtp_add_sink( id, fd, p_sys->rtcp_mux );
920             }
921         }
922
923     if( p_fmt == NULL )
924     {
925         char *psz = var_GetNonEmptyString( p_stream, SOUT_CFG_PREFIX "mux" );
926
927         if( psz == NULL ) /* Uho! */
928             ;
929         else
930         if( strncmp( psz, "ts", 2 ) == 0 )
931         {
932             id->i_payload_type = 33;
933             id->psz_enc = "MP2T";
934         }
935         else
936         {
937             id->psz_enc = "MP2P";
938         }
939     }
940     else
941     switch( p_fmt->i_codec )
942     {
943         case VLC_FOURCC( 'u', 'l', 'a', 'w' ):
944             if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 8000 )
945                 id->i_payload_type = 0;
946             id->psz_enc = "PCMU";
947             id->pf_packetize = rtp_packetize_l8;
948             break;
949         case VLC_FOURCC( 'a', 'l', 'a', 'w' ):
950             if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 8000 )
951                 id->i_payload_type = 8;
952             id->psz_enc = "PCMA";
953             id->pf_packetize = rtp_packetize_l8;
954             break;
955         case VLC_FOURCC( 's', '1', '6', 'b' ):
956             if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 44100 )
957             {
958                 id->i_payload_type = 11;
959             }
960             else if( p_fmt->audio.i_channels == 2 &&
961                      p_fmt->audio.i_rate == 44100 )
962             {
963                 id->i_payload_type = 10;
964             }
965             id->psz_enc = "L16";
966             id->pf_packetize = rtp_packetize_l16;
967             break;
968         case VLC_FOURCC( 'u', '8', ' ', ' ' ):
969             id->psz_enc = "L8";
970             id->pf_packetize = rtp_packetize_l8;
971             break;
972         case VLC_FOURCC( 'm', 'p', 'g', 'a' ):
973             id->i_payload_type = 14;
974             id->psz_enc = "MPA";
975             id->pf_packetize = rtp_packetize_mpa;
976             break;
977         case VLC_FOURCC( 'm', 'p', 'g', 'v' ):
978             id->i_payload_type = 32;
979             id->psz_enc = "MPV";
980             id->pf_packetize = rtp_packetize_mpv;
981             break;
982         case VLC_FOURCC( 'a', '5', '2', ' ' ):
983             id->psz_enc = "ac3";
984             id->pf_packetize = rtp_packetize_ac3;
985             break;
986         case VLC_FOURCC( 'H', '2', '6', '3' ):
987             id->psz_enc = "H263-1998";
988             id->pf_packetize = rtp_packetize_h263;
989             break;
990         case VLC_FOURCC( 'h', '2', '6', '4' ):
991             id->psz_enc = "H264";
992             id->pf_packetize = rtp_packetize_h264;
993             id->psz_fmtp = NULL;
994
995             if( p_fmt->i_extra > 0 )
996             {
997                 uint8_t *p_buffer = p_fmt->p_extra;
998                 int     i_buffer = p_fmt->i_extra;
999                 char    *p_64_sps = NULL;
1000                 char    *p_64_pps = NULL;
1001                 char    hexa[6+1];
1002
1003                 while( i_buffer > 4 &&
1004                        p_buffer[0] == 0 && p_buffer[1] == 0 &&
1005                        p_buffer[2] == 0 && p_buffer[3] == 1 )
1006                 {
1007                     const int i_nal_type = p_buffer[4]&0x1f;
1008                     int i_offset;
1009                     int i_size      = 0;
1010
1011                     msg_Dbg( p_stream, "we found a startcode for NAL with TYPE:%d", i_nal_type );
1012
1013                     i_size = i_buffer;
1014                     for( i_offset = 4; i_offset+3 < i_buffer ; i_offset++)
1015                     {
1016                         if( !memcmp (p_buffer + i_offset, "\x00\x00\x00\x01", 4 ) )
1017                         {
1018                             /* we found another startcode */
1019                             i_size = i_offset;
1020                             break;
1021                         }
1022                     }
1023                     if( i_nal_type == 7 )
1024                     {
1025                         p_64_sps = vlc_b64_encode_binary( &p_buffer[4], i_size - 4 );
1026                         sprintf_hexa( hexa, &p_buffer[5], 3 );
1027                     }
1028                     else if( i_nal_type == 8 )
1029                     {
1030                         p_64_pps = vlc_b64_encode_binary( &p_buffer[4], i_size - 4 );
1031                     }
1032                     i_buffer -= i_size;
1033                     p_buffer += i_size;
1034                 }
1035                 /* */
1036                 if( p_64_sps && p_64_pps &&
1037                     ( asprintf( &id->psz_fmtp,
1038                                 "packetization-mode=1;profile-level-id=%s;"
1039                                 "sprop-parameter-sets=%s,%s;", hexa, p_64_sps,
1040                                 p_64_pps ) == -1 ) )
1041                     id->psz_fmtp = NULL;
1042                 free( p_64_sps );
1043                 free( p_64_pps );
1044             }
1045             if( !id->psz_fmtp )
1046                 id->psz_fmtp = strdup( "packetization-mode=1" );
1047             break;
1048
1049         case VLC_FOURCC( 'm', 'p', '4', 'v' ):
1050         {
1051             char hexa[2*p_fmt->i_extra +1];
1052
1053             id->psz_enc = "MP4V-ES";
1054             id->pf_packetize = rtp_packetize_split;
1055             if( p_fmt->i_extra > 0 )
1056             {
1057                 sprintf_hexa( hexa, p_fmt->p_extra, p_fmt->i_extra );
1058                 if( asprintf( &id->psz_fmtp,
1059                               "profile-level-id=3; config=%s;", hexa ) == -1 )
1060                     id->psz_fmtp = NULL;
1061             }
1062             break;
1063         }
1064         case VLC_FOURCC( 'm', 'p', '4', 'a' ):
1065         {
1066             if(!p_sys->b_latm)
1067             {
1068                 char hexa[2*p_fmt->i_extra +1];
1069
1070                 id->psz_enc = "mpeg4-generic";
1071                 id->pf_packetize = rtp_packetize_mp4a;
1072                 sprintf_hexa( hexa, p_fmt->p_extra, p_fmt->i_extra );
1073                 if( asprintf( &id->psz_fmtp,
1074                               "streamtype=5; profile-level-id=15; "
1075                               "mode=AAC-hbr; config=%s; SizeLength=13; "
1076                               "IndexLength=3; IndexDeltaLength=3; Profile=1;",
1077                               hexa ) == -1 )
1078                     id->psz_fmtp = NULL;
1079             }
1080             else
1081             {
1082                 char hexa[13];
1083                 int i;
1084                 unsigned char config[6];
1085                 unsigned int aacsrates[15] = {
1086                     96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
1087                     16000, 12000, 11025, 8000, 7350, 0, 0 };
1088
1089                 for( i = 0; i < 15; i++ )
1090                     if( p_fmt->audio.i_rate == aacsrates[i] )
1091                         break;
1092
1093                 config[0]=0x40;
1094                 config[1]=0;
1095                 config[2]=0x20|i;
1096                 config[3]=p_fmt->audio.i_channels<<4;
1097                 config[4]=0x3f;
1098                 config[5]=0xc0;
1099
1100                 id->psz_enc = "MP4A-LATM";
1101                 id->pf_packetize = rtp_packetize_mp4a_latm;
1102                 sprintf_hexa( hexa, config, 6 );
1103                 if( asprintf( &id->psz_fmtp, "profile-level-id=15; "
1104                               "object=2; cpresent=0; config=%s", hexa ) == -1 )
1105                     id->psz_fmtp = NULL;
1106             }
1107             break;
1108         }
1109         case VLC_FOURCC( 's', 'a', 'm', 'r' ):
1110             id->psz_enc = "AMR";
1111             id->psz_fmtp = strdup( "octet-align=1" );
1112             id->pf_packetize = rtp_packetize_amr;
1113             break;
1114         case VLC_FOURCC( 's', 'a', 'w', 'b' ):
1115             id->psz_enc = "AMR-WB";
1116             id->psz_fmtp = strdup( "octet-align=1" );
1117             id->pf_packetize = rtp_packetize_amr;
1118             break;
1119         case VLC_FOURCC( 's', 'p', 'x', ' ' ):
1120             id->i_payload_type = p_sys->i_payload_type++;
1121             id->psz_enc = "SPEEX";
1122             id->pf_packetize = rtp_packetize_spx;
1123             break;
1124         case VLC_FOURCC( 't', '1', '4', '0' ):
1125             id->psz_enc = "t140" ;
1126             id->i_clock_rate = 1000;
1127             id->pf_packetize = rtp_packetize_t140;
1128             break;
1129
1130         default:
1131             msg_Err( p_stream, "cannot add this stream (unsupported "
1132                      "codec:%4.4s)", (char*)&p_fmt->i_codec );
1133             goto error;
1134     }
1135
1136     if( cscov != -1 )
1137         cscov += 8 /* UDP */ + 12 /* RTP */;
1138     if( id->sinkc > 0 )
1139         net_SetCSCov( id->sinkv[0].rtp_fd, cscov, -1 );
1140
1141     if( id->i_payload_type == p_sys->i_payload_type )
1142         p_sys->i_payload_type++;
1143
1144     if( p_sys->rtsp != NULL )
1145         id->rtsp_id = RtspAddId( p_sys->rtsp, id, p_sys->i_es,
1146                                  GetDWBE( id->ssrc ),
1147                                  p_sys->psz_destination,
1148                                  p_sys->i_ttl, id->i_port, id->i_port + 1 );
1149
1150     id->p_fifo = block_FifoNew( p_stream );
1151     if( vlc_thread_create( id, "RTP send thread", ThreadSend,
1152                            VLC_THREAD_PRIORITY_HIGHEST, VLC_FALSE ) )
1153         goto error;
1154
1155     /* Update p_sys context */
1156     vlc_mutex_lock( &p_sys->lock_es );
1157     TAB_APPEND( p_sys->i_es, p_sys->es, id );
1158     vlc_mutex_unlock( &p_sys->lock_es );
1159
1160     psz_sdp = SDPGenerate( p_stream, NULL );
1161
1162     vlc_mutex_lock( &p_sys->lock_sdp );
1163     free( p_sys->psz_sdp );
1164     p_sys->psz_sdp = psz_sdp;
1165     vlc_mutex_unlock( &p_sys->lock_sdp );
1166
1167     msg_Dbg( p_stream, "sdp=\n%s", p_sys->psz_sdp );
1168
1169     /* Update SDP (sap/file) */
1170     if( p_sys->b_export_sap ) SapSetup( p_stream );
1171     if( p_sys->b_export_sdp_file ) FileSetup( p_stream );
1172
1173     return id;
1174
1175 error:
1176     Del( p_stream, id );
1177     return NULL;
1178 }
1179
1180 static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
1181 {
1182     sout_stream_sys_t *p_sys = p_stream->p_sys;
1183
1184     if( id->p_fifo != NULL )
1185     {
1186         vlc_object_kill( id );
1187         block_FifoWake( id->p_fifo );
1188         vlc_thread_join( id );
1189         block_FifoRelease( id->p_fifo );
1190     }
1191
1192     vlc_mutex_lock( &p_sys->lock_es );
1193     TAB_REMOVE( p_sys->i_es, p_sys->es, id );
1194     vlc_mutex_unlock( &p_sys->lock_es );
1195
1196     /* Release port */
1197     if( id->i_port > 0 )
1198     {
1199         if( id->i_cat == AUDIO_ES && p_sys->i_port_audio == 0 )
1200             p_sys->i_port_audio = id->i_port;
1201         else if( id->i_cat == VIDEO_ES && p_sys->i_port_video == 0 )
1202             p_sys->i_port_video = id->i_port;
1203     }
1204
1205     free( id->psz_fmtp );
1206
1207     if( id->rtsp_id )
1208         RtspDelId( p_sys->rtsp, id->rtsp_id );
1209     if( id->sinkc > 0 )
1210         rtp_del_sink( id, id->sinkv[0].rtp_fd ); /* sink for explicit dst= */
1211     if( id->listen_fd != NULL )
1212         net_ListenClose( id->listen_fd );
1213
1214     vlc_mutex_destroy( &id->lock_sink );
1215
1216     /* Update SDP (sap/file) */
1217     if( p_sys->b_export_sap && !p_sys->p_mux ) SapSetup( p_stream );
1218     if( p_sys->b_export_sdp_file ) FileSetup( p_stream );
1219
1220     vlc_object_detach( id );
1221     vlc_object_destroy( id );
1222     return VLC_SUCCESS;
1223 }
1224
1225 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
1226                  block_t *p_buffer )
1227 {
1228     block_t *p_next;
1229
1230     assert( p_stream->p_sys->p_mux == NULL );
1231
1232     while( p_buffer != NULL )
1233     {
1234         p_next = p_buffer->p_next;
1235         if( id->pf_packetize( p_stream, id, p_buffer ) )
1236             break;
1237
1238         block_Release( p_buffer );
1239         p_buffer = p_next;
1240     }
1241     return VLC_SUCCESS;
1242 }
1243
1244 /****************************************************************************
1245  * SAP:
1246  ****************************************************************************/
1247 static int SapSetup( sout_stream_t *p_stream )
1248 {
1249     sout_stream_sys_t *p_sys = p_stream->p_sys;
1250     sout_instance_t   *p_sout = p_stream->p_sout;
1251
1252     /* Remove the previous session */
1253     if( p_sys->p_session != NULL)
1254     {
1255         sout_AnnounceUnRegister( p_sout, p_sys->p_session);
1256         p_sys->p_session = NULL;
1257     }
1258
1259     if( ( p_sys->i_es > 0 || p_sys->p_mux ) && p_sys->psz_sdp && *p_sys->psz_sdp )
1260     {
1261         announce_method_t *p_method = sout_SAPMethod();
1262         p_sys->p_session = sout_AnnounceRegisterSDP( p_sout, SOUT_CFG_PREFIX,
1263                                                      p_sys->psz_sdp,
1264                                                      p_sys->psz_destination,
1265                                                      p_method );
1266         sout_MethodRelease( p_method );
1267     }
1268
1269     return VLC_SUCCESS;
1270 }
1271
1272 /****************************************************************************
1273 * File:
1274 ****************************************************************************/
1275 static int FileSetup( sout_stream_t *p_stream )
1276 {
1277     sout_stream_sys_t *p_sys = p_stream->p_sys;
1278     FILE            *f;
1279
1280     if( ( f = utf8_fopen( p_sys->psz_sdp_file, "wt" ) ) == NULL )
1281     {
1282         msg_Err( p_stream, "cannot open file '%s' (%m)",
1283                  p_sys->psz_sdp_file );
1284         return VLC_EGENERIC;
1285     }
1286
1287     fputs( p_sys->psz_sdp, f );
1288     fclose( f );
1289
1290     return VLC_SUCCESS;
1291 }
1292
1293 /****************************************************************************
1294  * HTTP:
1295  ****************************************************************************/
1296 static int  HttpCallback( httpd_file_sys_t *p_args,
1297                           httpd_file_t *, uint8_t *p_request,
1298                           uint8_t **pp_data, int *pi_data );
1299
1300 static int HttpSetup( sout_stream_t *p_stream, vlc_url_t *url)
1301 {
1302     sout_stream_sys_t *p_sys = p_stream->p_sys;
1303
1304     p_sys->p_httpd_host = httpd_HostNew( VLC_OBJECT(p_stream), url->psz_host,
1305                                          url->i_port > 0 ? url->i_port : 80 );
1306     if( p_sys->p_httpd_host )
1307     {
1308         p_sys->p_httpd_file = httpd_FileNew( p_sys->p_httpd_host,
1309                                              url->psz_path ? url->psz_path : "/",
1310                                              "application/sdp",
1311                                              NULL, NULL, NULL,
1312                                              HttpCallback, (void*)p_sys );
1313     }
1314     if( p_sys->p_httpd_file == NULL )
1315     {
1316         return VLC_EGENERIC;
1317     }
1318     return VLC_SUCCESS;
1319 }
1320
1321 static int  HttpCallback( httpd_file_sys_t *p_args,
1322                           httpd_file_t *f, uint8_t *p_request,
1323                           uint8_t **pp_data, int *pi_data )
1324 {
1325     sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_args;
1326
1327     vlc_mutex_lock( &p_sys->lock_sdp );
1328     if( p_sys->psz_sdp && *p_sys->psz_sdp )
1329     {
1330         *pi_data = strlen( p_sys->psz_sdp );
1331         *pp_data = malloc( *pi_data );
1332         memcpy( *pp_data, p_sys->psz_sdp, *pi_data );
1333     }
1334     else
1335     {
1336         *pp_data = NULL;
1337         *pi_data = 0;
1338     }
1339     vlc_mutex_unlock( &p_sys->lock_sdp );
1340
1341     return VLC_SUCCESS;
1342 }
1343
1344 /****************************************************************************
1345  * RTP send
1346  ****************************************************************************/
1347 static void ThreadSend( vlc_object_t *p_this )
1348 {
1349     sout_stream_id_t *id = (sout_stream_id_t *)p_this;
1350     unsigned i_caching = id->i_caching;
1351 #ifdef HAVE_TEE
1352     int fd[5] = { -1, -1, -1, -1, -1 };
1353
1354     if( pipe( fd ) )
1355         fd[0] = fd[1] = -1;
1356     else
1357     if( pipe( fd ) )
1358         fd[2] = fd[3] = -1;
1359     else
1360         fd[4] = open( "/dev/null", O_WRONLY );
1361 #endif
1362
1363     while( !id->b_die )
1364     {
1365         block_t *out = block_FifoGet( id->p_fifo );
1366         if( out == NULL )
1367             continue; /* Forced wakeup */
1368
1369         mtime_t  i_date = out->i_dts + i_caching;
1370         ssize_t  len = out->i_buffer;
1371
1372 #ifdef HAVE_TEE
1373         if( fd[4] != -1 )
1374             len = write( fd[1], out->p_buffer, len);
1375         if( len == -1 )
1376             continue; /* Uho - should not happen */
1377 #endif
1378         mwait( i_date );
1379
1380         vlc_mutex_lock( &id->lock_sink );
1381         unsigned deadc = 0; /* How many dead sockets? */
1382         int deadv[id->sinkc]; /* Dead sockets list */
1383
1384         for( int i = 0; i < id->sinkc; i++ )
1385         {
1386             SendRTCP( id->sinkv[i].rtcp, out );
1387
1388 #ifdef HAVE_TEE
1389             tee( fd[0], fd[3], len, 0 );
1390             if( splice( fd[2], NULL, id->sinkv[i].rtp_fd, NULL, len,
1391                         SPLICE_F_NONBLOCK ) >= 0 )
1392                 continue;
1393             if( errno == EAGAIN )
1394                 continue;
1395
1396             /* splice failed */
1397             splice( fd[2], NULL, fd[4], NULL, len, 0 );
1398 #else
1399             if( send( id->sinkv[i].rtp_fd, out->p_buffer, len, 0 ) >= 0 )
1400                 continue;
1401 #endif
1402             /* Retry sending to root out soft-errors */
1403             if( send( id->sinkv[i].rtp_fd, out->p_buffer, len, 0 ) >= 0 )
1404                 continue;
1405
1406             deadv[deadc++] = id->sinkv[i].rtp_fd;
1407         }
1408         vlc_mutex_unlock( &id->lock_sink );
1409
1410         block_Release( out );
1411 #ifdef HAVE_TEE
1412         splice( fd[0], NULL, fd[4], NULL, len, 0 );
1413 #endif
1414
1415         for( unsigned i = 0; i < deadc; i++ )
1416         {
1417             msg_Dbg( id, "removing socket %d", deadv[i] );
1418             rtp_del_sink( id, deadv[i] );
1419         }
1420
1421         /* Hopefully we won't overflow the SO_MAXCONN accept queue */
1422         while( id->listen_fd != NULL )
1423         {
1424             int fd = net_Accept( id, id->listen_fd, 0 );
1425             if( fd == -1 )
1426                 break;
1427             msg_Dbg( id, "adding socket %d", fd );
1428             rtp_add_sink( id, fd, VLC_TRUE );
1429         }
1430     }
1431
1432 #ifdef HAVE_TEE
1433     for( unsigned i = 0; i < 5; i++ )
1434         close( fd[i] );
1435 #endif
1436 }
1437
1438 static inline void rtp_packetize_send( sout_stream_id_t *id, block_t *out )
1439 {
1440     block_FifoPut( id->p_fifo, out );
1441 }
1442
1443 int rtp_add_sink( sout_stream_id_t *id, int fd, vlc_bool_t rtcp_mux )
1444 {
1445     rtp_sink_t sink = { fd, NULL };
1446     sink.rtcp = OpenRTCP( VLC_OBJECT( id->p_stream ), fd, IPPROTO_UDP,
1447                           rtcp_mux );
1448     if( sink.rtcp == NULL )
1449         msg_Err( id, "RTCP failed!" );
1450
1451     vlc_mutex_lock( &id->lock_sink );
1452     INSERT_ELEM( id->sinkv, id->sinkc, id->sinkc, sink );
1453     vlc_mutex_unlock( &id->lock_sink );
1454     return VLC_SUCCESS;
1455 }
1456
1457 void rtp_del_sink( sout_stream_id_t *id, int fd )
1458 {
1459     rtp_sink_t sink = { fd, NULL };
1460
1461     /* NOTE: must be safe to use if fd is not included */
1462     vlc_mutex_lock( &id->lock_sink );
1463     for( int i = 0; i < id->sinkc; i++ )
1464     {
1465         if (id->sinkv[i].rtp_fd == fd)
1466         {
1467             sink = id->sinkv[i];
1468             REMOVE_ELEM( id->sinkv, id->sinkc, i );
1469             break;
1470         }
1471     }
1472     vlc_mutex_unlock( &id->lock_sink );
1473
1474     CloseRTCP( sink.rtcp );
1475     net_Close( sink.rtp_fd );
1476 }
1477
1478 uint16_t rtp_get_seq( const sout_stream_id_t *id )
1479 {
1480     /* This will return values for the next packet.
1481      * Accounting for caching would not be totally trivial. */
1482     return id->i_sequence;
1483 }
1484
1485 /* FIXME: this is pretty bad - if we remove and then insert an ES
1486  * the number will get unsynched from inside RTSP */
1487 unsigned rtp_get_num( const sout_stream_id_t *id )
1488 {
1489     sout_stream_sys_t *p_sys = id->p_stream->p_sys;
1490     int i;
1491
1492     vlc_mutex_lock( &p_sys->lock_es );
1493     for( i = 0; i < p_sys->i_es; i++ )
1494     {
1495         if( id == p_sys->es[i] )
1496             break;
1497     }
1498     vlc_mutex_unlock( &p_sys->lock_es );
1499
1500     return i;
1501 }
1502
1503
1504 /****************************************************************************
1505  * rtp_packetize_*:
1506  ****************************************************************************/
1507 static void rtp_packetize_common( sout_stream_id_t *id, block_t *out,
1508                                   int b_marker, int64_t i_pts )
1509 {
1510     uint32_t i_timestamp = i_pts * (int64_t)id->i_clock_rate / I64C(1000000);
1511
1512     out->p_buffer[0] = 0x80;
1513     out->p_buffer[1] = (b_marker?0x80:0x00)|id->i_payload_type;
1514     out->p_buffer[2] = ( id->i_sequence >> 8)&0xff;
1515     out->p_buffer[3] = ( id->i_sequence     )&0xff;
1516     out->p_buffer[4] = ( i_timestamp >> 24 )&0xff;
1517     out->p_buffer[5] = ( i_timestamp >> 16 )&0xff;
1518     out->p_buffer[6] = ( i_timestamp >>  8 )&0xff;
1519     out->p_buffer[7] = ( i_timestamp       )&0xff;
1520
1521     memcpy( out->p_buffer + 8, id->ssrc, 4 );
1522
1523     out->i_buffer = 12;
1524     id->i_sequence++;
1525 }
1526
1527 static int rtp_packetize_mpa( sout_stream_t *p_stream, sout_stream_id_t *id,
1528                               block_t *in )
1529 {
1530     int     i_max   = id->i_mtu - 12 - 4; /* payload max in one packet */
1531     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1532
1533     uint8_t *p_data = in->p_buffer;
1534     int     i_data  = in->i_buffer;
1535     int     i;
1536
1537     for( i = 0; i < i_count; i++ )
1538     {
1539         int           i_payload = __MIN( i_max, i_data );
1540         block_t *out = block_New( p_stream, 16 + i_payload );
1541
1542         /* rtp common header */
1543         rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts );
1544         /* mbz set to 0 */
1545         out->p_buffer[12] = 0;
1546         out->p_buffer[13] = 0;
1547         /* fragment offset in the current frame */
1548         out->p_buffer[14] = ( (i*i_max) >> 8 )&0xff;
1549         out->p_buffer[15] = ( (i*i_max)      )&0xff;
1550         memcpy( &out->p_buffer[16], p_data, i_payload );
1551
1552         out->i_buffer   = 16 + i_payload;
1553         out->i_dts    = in->i_dts + i * in->i_length / i_count;
1554         out->i_length = in->i_length / i_count;
1555
1556         rtp_packetize_send( id, out );
1557
1558         p_data += i_payload;
1559         i_data -= i_payload;
1560     }
1561
1562     return VLC_SUCCESS;
1563 }
1564
1565 /* rfc2250 */
1566 static int rtp_packetize_mpv( sout_stream_t *p_stream, sout_stream_id_t *id,
1567                               block_t *in )
1568 {
1569     int     i_max   = id->i_mtu - 12 - 4; /* payload max in one packet */
1570     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1571
1572     uint8_t *p_data = in->p_buffer;
1573     int     i_data  = in->i_buffer;
1574     int     i;
1575     int     b_sequence_start = 0;
1576     int     i_temporal_ref = 0;
1577     int     i_picture_coding_type = 0;
1578     int     i_fbv = 0, i_bfc = 0, i_ffv = 0, i_ffc = 0;
1579     int     b_start_slice = 0;
1580
1581     /* preparse this packet to get some info */
1582     if( in->i_buffer > 4 )
1583     {
1584         uint8_t *p = p_data;
1585         int      i_rest = in->i_buffer;
1586
1587         for( ;; )
1588         {
1589             while( i_rest > 4 &&
1590                    ( p[0] != 0x00 || p[1] != 0x00 || p[2] != 0x01 ) )
1591             {
1592                 p++;
1593                 i_rest--;
1594             }
1595             if( i_rest <= 4 )
1596             {
1597                 break;
1598             }
1599             p += 3;
1600             i_rest -= 4;
1601
1602             if( *p == 0xb3 )
1603             {
1604                 /* sequence start code */
1605                 b_sequence_start = 1;
1606             }
1607             else if( *p == 0x00 && i_rest >= 4 )
1608             {
1609                 /* picture */
1610                 i_temporal_ref = ( p[1] << 2) |((p[2]>>6)&0x03);
1611                 i_picture_coding_type = (p[2] >> 3)&0x07;
1612
1613                 if( i_rest >= 4 && ( i_picture_coding_type == 2 ||
1614                                     i_picture_coding_type == 3 ) )
1615                 {
1616                     i_ffv = (p[3] >> 2)&0x01;
1617                     i_ffc = ((p[3]&0x03) << 1)|((p[4]>>7)&0x01);
1618                     if( i_rest > 4 && i_picture_coding_type == 3 )
1619                     {
1620                         i_fbv = (p[4]>>6)&0x01;
1621                         i_bfc = (p[4]>>3)&0x07;
1622                     }
1623                 }
1624             }
1625             else if( *p <= 0xaf )
1626             {
1627                 b_start_slice = 1;
1628             }
1629         }
1630     }
1631
1632     for( i = 0; i < i_count; i++ )
1633     {
1634         int           i_payload = __MIN( i_max, i_data );
1635         block_t *out = block_New( p_stream,
1636                                              16 + i_payload );
1637         uint32_t      h = ( i_temporal_ref << 16 )|
1638                           ( b_sequence_start << 13 )|
1639                           ( b_start_slice << 12 )|
1640                           ( i == i_count - 1 ? 1 << 11 : 0 )|
1641                           ( i_picture_coding_type << 8 )|
1642                           ( i_fbv << 7 )|( i_bfc << 4 )|( i_ffv << 3 )|i_ffc;
1643
1644         /* rtp common header */
1645         rtp_packetize_common( id, out, (i == i_count - 1)?1:0,
1646                               in->i_pts > 0 ? in->i_pts : in->i_dts );
1647
1648         /* MBZ:5 T:1 TR:10 AN:1 N:1 S:1 B:1 E:1 P:3 FBV:1 BFC:3 FFV:1 FFC:3 */
1649         out->p_buffer[12] = ( h >> 24 )&0xff;
1650         out->p_buffer[13] = ( h >> 16 )&0xff;
1651         out->p_buffer[14] = ( h >>  8 )&0xff;
1652         out->p_buffer[15] = ( h       )&0xff;
1653
1654         memcpy( &out->p_buffer[16], p_data, i_payload );
1655
1656         out->i_buffer   = 16 + i_payload;
1657         out->i_dts    = in->i_dts + i * in->i_length / i_count;
1658         out->i_length = in->i_length / i_count;
1659
1660         rtp_packetize_send( id, out );
1661
1662         p_data += i_payload;
1663         i_data -= i_payload;
1664     }
1665
1666     return VLC_SUCCESS;
1667 }
1668
1669 static int rtp_packetize_ac3( sout_stream_t *p_stream, sout_stream_id_t *id,
1670                               block_t *in )
1671 {
1672     int     i_max   = id->i_mtu - 12 - 2; /* payload max in one packet */
1673     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1674
1675     uint8_t *p_data = in->p_buffer;
1676     int     i_data  = in->i_buffer;
1677     int     i;
1678
1679     for( i = 0; i < i_count; i++ )
1680     {
1681         int           i_payload = __MIN( i_max, i_data );
1682         block_t *out = block_New( p_stream, 14 + i_payload );
1683
1684         /* rtp common header */
1685         rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts );
1686         /* unit count */
1687         out->p_buffer[12] = 1;
1688         /* unit header */
1689         out->p_buffer[13] = 0x00;
1690         /* data */
1691         memcpy( &out->p_buffer[14], p_data, i_payload );
1692
1693         out->i_buffer   = 14 + i_payload;
1694         out->i_dts    = in->i_dts + i * in->i_length / i_count;
1695         out->i_length = in->i_length / i_count;
1696
1697         rtp_packetize_send( id, out );
1698
1699         p_data += i_payload;
1700         i_data -= i_payload;
1701     }
1702
1703     return VLC_SUCCESS;
1704 }
1705
1706 static int rtp_packetize_split( sout_stream_t *p_stream, sout_stream_id_t *id,
1707                                 block_t *in )
1708 {
1709     int     i_max   = id->i_mtu - 12; /* payload max in one packet */
1710     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1711
1712     uint8_t *p_data = in->p_buffer;
1713     int     i_data  = in->i_buffer;
1714     int     i;
1715
1716     for( i = 0; i < i_count; i++ )
1717     {
1718         int           i_payload = __MIN( i_max, i_data );
1719         block_t *out = block_New( p_stream, 12 + i_payload );
1720
1721         /* rtp common header */
1722         rtp_packetize_common( id, out, ((i == i_count - 1)?1:0),
1723                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
1724         memcpy( &out->p_buffer[12], p_data, i_payload );
1725
1726         out->i_buffer   = 12 + i_payload;
1727         out->i_dts    = in->i_dts + i * in->i_length / i_count;
1728         out->i_length = in->i_length / i_count;
1729
1730         rtp_packetize_send( id, out );
1731
1732         p_data += i_payload;
1733         i_data -= i_payload;
1734     }
1735
1736     return VLC_SUCCESS;
1737 }
1738
1739 /* rfc3016 */
1740 static int rtp_packetize_mp4a_latm( sout_stream_t *p_stream, sout_stream_id_t *id,
1741                                 block_t *in )
1742 {
1743     int     i_max   = id->i_mtu - 14;              /* payload max in one packet */
1744     int     latmhdrsize = in->i_buffer / 0xff + 1;
1745     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1746
1747     uint8_t *p_data = in->p_buffer, *p_header = NULL;
1748     int     i_data  = in->i_buffer;
1749     int     i;
1750
1751     for( i = 0; i < i_count; i++ )
1752     {
1753         int     i_payload = __MIN( i_max, i_data );
1754         block_t *out;
1755
1756         if( i != 0 )
1757             latmhdrsize = 0;
1758         out = block_New( p_stream, 12 + latmhdrsize + i_payload );
1759
1760         /* rtp common header */
1761         rtp_packetize_common( id, out, ((i == i_count - 1) ? 1 : 0),
1762                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
1763
1764         if( i == 0 )
1765         {
1766             int tmp = in->i_buffer;
1767
1768             p_header=out->p_buffer+12;
1769             while( tmp > 0xfe )
1770             {
1771                 *p_header = 0xff;
1772                 p_header++;
1773                 tmp -= 0xff;
1774             }
1775             *p_header = tmp;
1776         }
1777
1778         memcpy( &out->p_buffer[12+latmhdrsize], p_data, i_payload );
1779
1780         out->i_buffer   = 12 + latmhdrsize + i_payload;
1781         out->i_dts    = in->i_dts + i * in->i_length / i_count;
1782         out->i_length = in->i_length / i_count;
1783
1784         rtp_packetize_send( id, out );
1785
1786         p_data += i_payload;
1787         i_data -= i_payload;
1788     }
1789
1790     return VLC_SUCCESS;
1791 }
1792
1793 static int rtp_packetize_l16( sout_stream_t *p_stream, sout_stream_id_t *id,
1794                               block_t *in )
1795 {
1796     const uint8_t *p_data = in->p_buffer;
1797     size_t i_data  = in->i_buffer;
1798     /* ptime=20ms -> 50Hz */
1799     size_t i_plen = 2 * id->i_channels * ( ( id->i_clock_rate + 49 ) / 50 );
1800
1801     for( unsigned i_packet = 0; i_data > 0; i_packet++ )
1802     {
1803         int           i_payload = __MIN( i_plen, i_data );
1804         block_t *out = block_New( p_stream, 12 + i_payload );
1805
1806         /* rtp common header */
1807         rtp_packetize_common( id, out, 0,
1808                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
1809         memcpy( &out->p_buffer[12], p_data, i_payload );
1810
1811         out->i_buffer = 12 + i_payload;
1812         out->i_dts    = in->i_dts + i_packet * 20000;
1813         out->i_length = i_payload * 20000 / i_plen;
1814
1815         rtp_packetize_send( id, out );
1816
1817         p_data += i_payload;
1818         i_data -= i_payload;
1819     }
1820
1821     return VLC_SUCCESS;
1822 }
1823
1824 static int rtp_packetize_l8( sout_stream_t *p_stream, sout_stream_id_t *id,
1825                              block_t *in )
1826 {
1827     const uint8_t *p_data = in->p_buffer;
1828     size_t i_data  = in->i_buffer;
1829     /* ptime=20ms -> 50Hz */
1830     size_t i_plen = id->i_channels * ( ( id->i_clock_rate + 49 ) / 50 );
1831
1832     for( unsigned i_packet = 0; i_data > 0; i_packet++ )
1833     {
1834         int           i_payload = __MIN( i_plen, i_data );
1835         block_t *out = block_New( p_stream, 12 + i_payload );
1836
1837         /* rtp common header */
1838         rtp_packetize_common( id, out, 0,
1839                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
1840         memcpy( &out->p_buffer[12], p_data, i_payload );
1841
1842         out->i_buffer = 12 + i_payload;
1843         out->i_dts    = in->i_dts + i_packet * 20000;
1844         out->i_length = i_payload * 20000 / i_plen;
1845
1846         rtp_packetize_send( id, out );
1847
1848         p_data += i_payload;
1849         i_data -= i_payload;
1850     }
1851
1852     return VLC_SUCCESS;
1853 }
1854
1855 static int rtp_packetize_mp4a( sout_stream_t *p_stream, sout_stream_id_t *id,
1856                                block_t *in )
1857 {
1858     int     i_max   = id->i_mtu - 16; /* payload max in one packet */
1859     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1860
1861     uint8_t *p_data = in->p_buffer;
1862     int     i_data  = in->i_buffer;
1863     int     i;
1864
1865     for( i = 0; i < i_count; i++ )
1866     {
1867         int           i_payload = __MIN( i_max, i_data );
1868         block_t *out = block_New( p_stream, 16 + i_payload );
1869
1870         /* rtp common header */
1871         rtp_packetize_common( id, out, ((i == i_count - 1)?1:0),
1872                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
1873         /* AU headers */
1874         /* AU headers length (bits) */
1875         out->p_buffer[12] = 0;
1876         out->p_buffer[13] = 2*8;
1877         /* for each AU length 13 bits + idx 3bits, */
1878         out->p_buffer[14] = ( in->i_buffer >> 5 )&0xff;
1879         out->p_buffer[15] = ( (in->i_buffer&0xff)<<3 )|0;
1880
1881         memcpy( &out->p_buffer[16], p_data, i_payload );
1882
1883         out->i_buffer   = 16 + i_payload;
1884         out->i_dts    = in->i_dts + i * in->i_length / i_count;
1885         out->i_length = in->i_length / i_count;
1886
1887         rtp_packetize_send( id, out );
1888
1889         p_data += i_payload;
1890         i_data -= i_payload;
1891     }
1892
1893     return VLC_SUCCESS;
1894 }
1895
1896
1897 /* rfc2429 */
1898 #define RTP_H263_HEADER_SIZE (2)  // plen = 0
1899 #define RTP_H263_PAYLOAD_START (14)  // plen = 0
1900 static int rtp_packetize_h263( sout_stream_t *p_stream, sout_stream_id_t *id,
1901                                block_t *in )
1902 {
1903     uint8_t *p_data = in->p_buffer;
1904     int     i_data  = in->i_buffer;
1905     int     i;
1906     int     i_max   = id->i_mtu - 12 - RTP_H263_HEADER_SIZE; /* payload max in one packet */
1907     int     i_count;
1908     int     b_p_bit;
1909     int     b_v_bit = 0; // no pesky error resilience
1910     int     i_plen = 0; // normally plen=0 for PSC packet
1911     int     i_pebit = 0; // because plen=0
1912     uint16_t h;
1913
1914     if( i_data < 2 )
1915     {
1916         return VLC_EGENERIC;
1917     }
1918     if( p_data[0] || p_data[1] )
1919     {
1920         return VLC_EGENERIC;
1921     }
1922     /* remove 2 leading 0 bytes */
1923     p_data += 2;
1924     i_data -= 2;
1925     i_count = ( i_data + i_max - 1 ) / i_max;
1926
1927     for( i = 0; i < i_count; i++ )
1928     {
1929         int      i_payload = __MIN( i_max, i_data );
1930         block_t *out = block_New( p_stream,
1931                                   RTP_H263_PAYLOAD_START + i_payload );
1932         b_p_bit = (i == 0) ? 1 : 0;
1933         h = ( b_p_bit << 10 )|
1934             ( b_v_bit << 9  )|
1935             ( i_plen  << 3  )|
1936               i_pebit;
1937
1938         /* rtp common header */
1939         //b_m_bit = 1; // always contains end of frame
1940         rtp_packetize_common( id, out, (i == i_count - 1)?1:0,
1941                               in->i_pts > 0 ? in->i_pts : in->i_dts );
1942
1943         /* h263 header */
1944         out->p_buffer[12] = ( h >>  8 )&0xff;
1945         out->p_buffer[13] = ( h       )&0xff;
1946         memcpy( &out->p_buffer[RTP_H263_PAYLOAD_START], p_data, i_payload );
1947
1948         out->i_buffer = RTP_H263_PAYLOAD_START + i_payload;
1949         out->i_dts    = in->i_dts + i * in->i_length / i_count;
1950         out->i_length = in->i_length / i_count;
1951
1952         rtp_packetize_send( id, out );
1953
1954         p_data += i_payload;
1955         i_data -= i_payload;
1956     }
1957
1958     return VLC_SUCCESS;
1959 }
1960
1961 /* rfc3984 */
1962 static int
1963 rtp_packetize_h264_nal( sout_stream_t *p_stream, sout_stream_id_t *id,
1964                         const uint8_t *p_data, int i_data, int64_t i_pts,
1965                         int64_t i_dts, vlc_bool_t b_last, int64_t i_length )
1966 {
1967     const int i_max = id->i_mtu - 12; /* payload max in one packet */
1968     int i_nal_hdr;
1969     int i_nal_type;
1970
1971     if( i_data < 5 )
1972         return VLC_SUCCESS;
1973
1974     i_nal_hdr = p_data[3];
1975     i_nal_type = i_nal_hdr&0x1f;
1976
1977     /* Skip start code */
1978     p_data += 3;
1979     i_data -= 3;
1980
1981     /* */
1982     if( i_data <= i_max )
1983     {
1984         /* Single NAL unit packet */
1985         block_t *out = block_New( p_stream, 12 + i_data );
1986         out->i_dts    = i_dts;
1987         out->i_length = i_length;
1988
1989         /* */
1990         rtp_packetize_common( id, out, b_last, i_pts );
1991         out->i_buffer = 12 + i_data;
1992
1993         memcpy( &out->p_buffer[12], p_data, i_data );
1994
1995         rtp_packetize_send( id, out );
1996     }
1997     else
1998     {
1999         /* FU-A Fragmentation Unit without interleaving */
2000         const int i_count = ( i_data-1 + i_max-2 - 1 ) / (i_max-2);
2001         int i;
2002
2003         p_data++;
2004         i_data--;
2005
2006         for( i = 0; i < i_count; i++ )
2007         {
2008             const int i_payload = __MIN( i_data, i_max-2 );
2009             block_t *out = block_New( p_stream, 12 + 2 + i_payload );
2010             out->i_dts    = i_dts + i * i_length / i_count;
2011             out->i_length = i_length / i_count;
2012
2013             /* */
2014             rtp_packetize_common( id, out, (b_last && i_payload == i_data), i_pts );
2015             out->i_buffer = 14 + i_payload;
2016
2017             /* FU indicator */
2018             out->p_buffer[12] = 0x00 | (i_nal_hdr & 0x60) | 28;
2019             /* FU header */
2020             out->p_buffer[13] = ( i == 0 ? 0x80 : 0x00 ) | ( (i == i_count-1) ? 0x40 : 0x00 )  | i_nal_type;
2021             memcpy( &out->p_buffer[14], p_data, i_payload );
2022
2023             rtp_packetize_send( id, out );
2024
2025             i_data -= i_payload;
2026             p_data += i_payload;
2027         }
2028     }
2029     return VLC_SUCCESS;
2030 }
2031
2032 static int rtp_packetize_h264( sout_stream_t *p_stream, sout_stream_id_t *id,
2033                                block_t *in )
2034 {
2035     const uint8_t *p_buffer = in->p_buffer;
2036     int i_buffer = in->i_buffer;
2037
2038     while( i_buffer > 4 && ( p_buffer[0] != 0 || p_buffer[1] != 0 || p_buffer[2] != 1 ) )
2039     {
2040         i_buffer--;
2041         p_buffer++;
2042     }
2043
2044     /* Split nal units */
2045     while( i_buffer > 4 )
2046     {
2047         int i_offset;
2048         int i_size = i_buffer;
2049         int i_skip = i_buffer;
2050
2051         /* search nal end */
2052         for( i_offset = 4; i_offset+2 < i_buffer ; i_offset++)
2053         {
2054             if( p_buffer[i_offset] == 0 && p_buffer[i_offset+1] == 0 && p_buffer[i_offset+2] == 1 )
2055             {
2056                 /* we found another startcode */
2057                 i_size = i_offset - ( p_buffer[i_offset-1] == 0 ? 1 : 0);
2058                 i_skip = i_offset;
2059                 break;
2060             }
2061         }
2062         /* TODO add STAP-A to remove a lot of overhead with small slice/sei/... */
2063         rtp_packetize_h264_nal( p_stream, id, p_buffer, i_size,
2064                                 (in->i_pts > 0 ? in->i_pts : in->i_dts), in->i_dts,
2065                                 (i_size >= i_buffer), in->i_length * i_size / in->i_buffer );
2066
2067         i_buffer -= i_skip;
2068         p_buffer += i_skip;
2069     }
2070     return VLC_SUCCESS;
2071 }
2072
2073 static int rtp_packetize_amr( sout_stream_t *p_stream, sout_stream_id_t *id,
2074                               block_t *in )
2075 {
2076     int     i_max   = id->i_mtu - 14; /* payload max in one packet */
2077     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
2078
2079     uint8_t *p_data = in->p_buffer;
2080     int     i_data  = in->i_buffer;
2081     int     i;
2082
2083     /* Only supports octet-aligned mode */
2084     for( i = 0; i < i_count; i++ )
2085     {
2086         int           i_payload = __MIN( i_max, i_data );
2087         block_t *out = block_New( p_stream, 14 + i_payload );
2088
2089         /* rtp common header */
2090         rtp_packetize_common( id, out, ((i == i_count - 1)?1:0),
2091                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
2092         /* Payload header */
2093         out->p_buffer[12] = 0xF0; /* CMR */
2094         out->p_buffer[13] = p_data[0]&0x7C; /* ToC */ /* FIXME: frame type */
2095
2096         /* FIXME: are we fed multiple frames ? */
2097         memcpy( &out->p_buffer[14], p_data+1, i_payload-1 );
2098
2099         out->i_buffer   = 14 + i_payload-1;
2100         out->i_dts    = in->i_dts + i * in->i_length / i_count;
2101         out->i_length = in->i_length / i_count;
2102
2103         rtp_packetize_send( id, out );
2104
2105         p_data += i_payload;
2106         i_data -= i_payload;
2107     }
2108
2109     return VLC_SUCCESS;
2110 }
2111
2112 static int rtp_packetize_t140( sout_stream_t *p_stream, sout_stream_id_t *id,
2113                                block_t *in )
2114 {
2115     const size_t   i_max  = id->i_mtu - 12;
2116     const uint8_t *p_data = in->p_buffer;
2117     size_t         i_data = in->i_buffer;
2118
2119     for( unsigned i_packet = 0; i_data > 0; i_packet++ )
2120     {
2121         size_t i_payload = i_data;
2122
2123         /* Make sure we stop on an UTF-8 character boundary
2124          * (assuming the input is valid UTF-8) */
2125         if( i_data > i_max )
2126         {
2127             i_payload = i_max;
2128
2129             while( ( p_data[i_payload] & 0xC0 ) == 0x80 )
2130             {
2131                 if( i_payload == 0 )
2132                     return VLC_SUCCESS; /* fishy input! */
2133
2134                 i_payload--;
2135             }
2136         }
2137
2138         block_t *out = block_New( p_stream, 12 + i_payload );
2139         if( out == NULL )
2140             return VLC_SUCCESS;
2141
2142         rtp_packetize_common( id, out, 0, in->i_pts + i_packet );
2143         memcpy( out->p_buffer + 12, p_data, i_payload );
2144
2145         out->i_buffer = 12 + i_payload;
2146         out->i_dts    = out->i_pts;
2147         out->i_length = 0;
2148
2149         rtp_packetize_send( id, out );
2150
2151         p_data += i_payload;
2152         i_data -= i_payload;
2153     }
2154
2155     return VLC_SUCCESS;
2156 }
2157
2158 /*****************************************************************************
2159  * Non-RTP mux
2160  *****************************************************************************/
2161
2162 /** Add an ES to a non-RTP muxed stream */
2163 static sout_stream_id_t *MuxAdd( sout_stream_t *p_stream, es_format_t *p_fmt )
2164 {
2165     sout_input_t      *p_input;
2166     sout_mux_t *p_mux = p_stream->p_sys->p_mux;
2167     assert( p_mux != NULL );
2168
2169     p_input = sout_MuxAddStream( p_mux, p_fmt );
2170     if( p_input == NULL )
2171     {
2172         msg_Err( p_stream, "cannot add this stream to the muxer" );
2173         return NULL;
2174     }
2175
2176     return (sout_stream_id_t *)p_input;
2177 }
2178
2179
2180 static int MuxSend( sout_stream_t *p_stream, sout_stream_id_t *id,
2181                     block_t *p_buffer )
2182 {
2183     sout_mux_t *p_mux = p_stream->p_sys->p_mux;
2184     assert( p_mux != NULL );
2185
2186     sout_MuxSendBuffer( p_mux, (sout_input_t *)id, p_buffer );
2187     return VLC_SUCCESS;
2188 }
2189
2190
2191 /** Remove an ES from a non-RTP muxed stream */
2192 static int MuxDel( sout_stream_t *p_stream, sout_stream_id_t *id )
2193 {
2194     sout_mux_t *p_mux = p_stream->p_sys->p_mux;
2195     assert( p_mux != NULL );
2196
2197     sout_MuxDeleteStream( p_mux, (sout_input_t *)id );
2198     return VLC_SUCCESS;
2199 }
2200
2201
2202 static int AccessOutGrabberWriteBuffer( sout_stream_t *p_stream,
2203                                         const block_t *p_buffer )
2204 {
2205     sout_stream_sys_t *p_sys = p_stream->p_sys;
2206     sout_stream_id_t *id = p_sys->es[0];
2207
2208     int64_t  i_dts = p_buffer->i_dts;
2209
2210     uint8_t         *p_data = p_buffer->p_buffer;
2211     unsigned int    i_data  = p_buffer->i_buffer;
2212     unsigned int    i_max   = id->i_mtu - 12;
2213
2214     unsigned i_packet = ( p_buffer->i_buffer + i_max - 1 ) / i_max;
2215
2216     while( i_data > 0 )
2217     {
2218         unsigned int i_size;
2219
2220         /* output complete packet */
2221         if( p_sys->packet &&
2222             p_sys->packet->i_buffer + i_data > i_max )
2223         {
2224             rtp_packetize_send( id, p_sys->packet );
2225             p_sys->packet = NULL;
2226         }
2227
2228         if( p_sys->packet == NULL )
2229         {
2230             /* allocate a new packet */
2231             p_sys->packet = block_New( p_stream, id->i_mtu );
2232             rtp_packetize_common( id, p_sys->packet, 1, i_dts );
2233             p_sys->packet->i_dts = i_dts;
2234             p_sys->packet->i_length = p_buffer->i_length / i_packet;
2235             i_dts += p_sys->packet->i_length;
2236         }
2237
2238         i_size = __MIN( i_data,
2239                         (unsigned)(id->i_mtu - p_sys->packet->i_buffer) );
2240
2241         memcpy( &p_sys->packet->p_buffer[p_sys->packet->i_buffer],
2242                 p_data, i_size );
2243
2244         p_sys->packet->i_buffer += i_size;
2245         p_data += i_size;
2246         i_data -= i_size;
2247     }
2248
2249     return VLC_SUCCESS;
2250 }
2251
2252
2253 static int AccessOutGrabberWrite( sout_access_out_t *p_access,
2254                                   block_t *p_buffer )
2255 {
2256     sout_stream_t *p_stream = (sout_stream_t*)p_access->p_sys;
2257
2258     while( p_buffer )
2259     {
2260         block_t *p_next;
2261
2262         AccessOutGrabberWriteBuffer( p_stream, p_buffer );
2263
2264         p_next = p_buffer->p_next;
2265         block_Release( p_buffer );
2266         p_buffer = p_next;
2267     }
2268
2269     return VLC_SUCCESS;
2270 }
2271
2272
2273 static sout_access_out_t *GrabberCreate( sout_stream_t *p_stream )
2274 {
2275     sout_access_out_t *p_grab;
2276
2277     p_grab = vlc_object_create( p_stream->p_sout, sizeof( *p_grab ) );
2278     if( p_grab == NULL )
2279         return NULL;
2280
2281     p_grab->p_module    = NULL;
2282     p_grab->p_sout      = p_stream->p_sout;
2283     p_grab->psz_access  = strdup( "grab" );
2284     p_grab->p_cfg       = NULL;
2285     p_grab->psz_path    = strdup( "" );
2286     p_grab->p_sys       = (sout_access_out_sys_t *)p_stream;
2287     p_grab->pf_seek     = NULL;
2288     p_grab->pf_write    = AccessOutGrabberWrite;
2289     return p_grab;
2290 }
2291
2292 static int rtp_packetize_spx( sout_stream_t *p_stream, sout_stream_id_t *id,
2293                               block_t *in )
2294 {
2295     uint8_t *p_buffer = in->p_buffer;
2296     int i_data_size, i_payload_size, i_payload_padding;
2297     i_data_size = i_payload_size = in->i_buffer;
2298     i_payload_padding = 0;
2299     block_t *p_out;
2300
2301     if ( in->i_buffer + 12 > id->i_mtu )
2302     {
2303         msg_Warn( p_stream, "Cannot send packet larger than output MTU" );
2304         return VLC_SUCCESS;
2305     }
2306
2307     /*
2308       RFC for Speex in RTP says that each packet must end on an octet 
2309       boundary. So, we check to see if the number of bytes % 4 is zero.
2310       If not, we have to add some padding. 
2311
2312       This MAY be overkill since packetization is handled elsewhere and 
2313       appears to ensure the octet boundary. However, better safe than
2314       sorry.
2315     */
2316     if ( i_payload_size % 4 )
2317     {
2318         i_payload_padding = 4 - ( i_payload_size % 4 );
2319         i_payload_size += i_payload_padding;
2320     }
2321
2322     /* 
2323       Allocate a new RTP p_output block of the appropriate size. 
2324       Allow for 12 extra bytes of RTP header. 
2325     */
2326     p_out = block_New( p_stream, 12 + i_payload_size );
2327
2328     if ( i_payload_padding )
2329     {
2330         /* 
2331           The padding is required to be a zero followed by all 1s.
2332         */
2333         char c_first_pad, c_remaining_pad;
2334         c_first_pad = 0x7F;
2335         c_remaining_pad = 0xFF;
2336
2337         /* 
2338           Allow for 12 bytes before the i_data_size because
2339           of the expected RTP header added during
2340           rtp_packetize_common.
2341         */
2342         p_out->p_buffer[12 + i_data_size] = c_first_pad; 
2343         switch (i_payload_padding)
2344         {
2345             case 2:
2346                 p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad; 
2347                 break;
2348             case 3:
2349                 p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad; 
2350                 p_out->p_buffer[12 + i_data_size + 2] = c_remaining_pad; 
2351                 break;
2352         }
2353     } 
2354
2355     /* Add the RTP header to our p_output buffer. */
2356     rtp_packetize_common( id, p_out, 0, (in->i_pts > 0 ? in->i_pts : in->i_dts) );
2357     /* Copy the Speex payload to the p_output buffer */
2358     memcpy( &p_out->p_buffer[12], p_buffer, i_data_size );
2359
2360     p_out->i_buffer = 12 + i_payload_size;
2361     p_out->i_dts = in->i_dts;
2362     p_out->i_length = in->i_length;
2363
2364     /* Queue the buffer for actual transmission. */
2365     rtp_packetize_send( id, p_out );
2366     return VLC_SUCCESS;
2367 }