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