]> git.sesse.net Git - vlc/blob - modules/stream_out/rtp.c
80831f5465de226f6acd3da6fd4c76b87aecefe3
[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_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_rtpmap, id->psz_fmtp);
747
748         if( rtsp_url != NULL )
749         {
750             assert( strlen( rtsp_url ) > 0 );
751             vlc_bool_t addslash = ( rtsp_url[strlen( rtsp_url ) - 1] != '/' );
752             sdp_AddAttribute ( &psz_sdp, "control",
753                                addslash ? "%s/trackID=%u" : "%strackID=%u",
754                                rtsp_url, i );
755         }
756         else
757         {
758             if( id->listen_fd != NULL )
759                 sdp_AddAttribute( &psz_sdp, "setup", "passive" );
760 #if 0
761             if( p_sys->proto == IPPROTO_DCCP )
762                 sdp_AddAttribute( &psz_sdp, "dccp-service-code", 
763                                   "SC:RTP%c", toupper( mime_major[0] ) );
764 #endif
765         }
766     }
767
768     return psz_sdp;
769 }
770
771 /*****************************************************************************
772  * RTP mux
773  *****************************************************************************/
774 static int rtp_packetize_l16  ( sout_stream_t *, sout_stream_id_t *, block_t * );
775 static int rtp_packetize_l8   ( sout_stream_t *, sout_stream_id_t *, block_t * );
776 static int rtp_packetize_mpa  ( sout_stream_t *, sout_stream_id_t *, block_t * );
777 static int rtp_packetize_mpv  ( sout_stream_t *, sout_stream_id_t *, block_t * );
778 static int rtp_packetize_ac3  ( sout_stream_t *, sout_stream_id_t *, block_t * );
779 static int rtp_packetize_split( sout_stream_t *, sout_stream_id_t *, block_t * );
780 static int rtp_packetize_mp4a ( sout_stream_t *, sout_stream_id_t *, block_t * );
781 static int rtp_packetize_mp4a_latm ( sout_stream_t *, sout_stream_id_t *, block_t * );
782 static int rtp_packetize_h263 ( sout_stream_t *, sout_stream_id_t *, block_t * );
783 static int rtp_packetize_h264 ( sout_stream_t *, sout_stream_id_t *, block_t * );
784 static int rtp_packetize_amr  ( sout_stream_t *, sout_stream_id_t *, block_t * );
785 static int rtp_packetize_spx  ( sout_stream_t *, sout_stream_id_t *, block_t * );
786 static int rtp_packetize_t140 ( sout_stream_t *, sout_stream_id_t *, block_t * );
787
788 static void sprintf_hexa( char *s, uint8_t *p_data, int i_data )
789 {
790     static const char hex[16] = "0123456789abcdef";
791     int i;
792
793     for( i = 0; i < i_data; i++ )
794     {
795         s[2*i+0] = hex[(p_data[i]>>4)&0xf];
796         s[2*i+1] = hex[(p_data[i]   )&0xf];
797     }
798     s[2*i_data] = '\0';
799 }
800
801
802 /** Add an ES as a new RTP stream */
803 static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
804 {
805     /* NOTE: As a special case, if we use a non-RTP
806      * mux (TS/PS), then p_fmt is NULL. */
807     sout_stream_sys_t *p_sys = p_stream->p_sys;
808     sout_stream_id_t  *id;
809     int               i_port, cscov = -1;
810     char              *psz_sdp;
811
812     id = vlc_object_create( p_stream, sizeof( sout_stream_id_t ) );
813     if( id == NULL )
814         return NULL;
815     vlc_object_attach( id, p_stream );
816
817     /* Choose the port */
818     i_port = 0;
819     if( p_fmt == NULL )
820         ;
821     else
822     if( p_fmt->i_cat == AUDIO_ES && p_sys->i_port_audio > 0 )
823     {
824         i_port = p_sys->i_port_audio;
825         p_sys->i_port_audio = 0;
826     }
827     else
828     if( p_fmt->i_cat == VIDEO_ES && p_sys->i_port_video > 0 )
829     {
830         i_port = p_sys->i_port_video;
831         p_sys->i_port_video = 0;
832     }
833
834     while( i_port == 0 )
835     {
836         if( p_sys->i_port != p_sys->i_port_audio
837          && p_sys->i_port != p_sys->i_port_video )
838         {
839             i_port = p_sys->i_port;
840             p_sys->i_port += 2;
841             break;
842         }
843         p_sys->i_port += 2;
844     }
845
846     id->p_stream   = p_stream;
847
848     id->i_sequence = rand()&0xffff;
849     id->i_payload_type = p_sys->i_payload_type;
850     id->ssrc[0] = rand()&0xff;
851     id->ssrc[1] = rand()&0xff;
852     id->ssrc[2] = rand()&0xff;
853     id->ssrc[3] = rand()&0xff;
854
855     id->psz_rtpmap = NULL;
856     id->psz_fmtp   = NULL;
857     id->i_clock_rate = 90000; /* most common case for video */
858     id->i_channels = 0;
859     id->i_port     = i_port;
860     if( p_fmt != NULL )
861     {
862         id->i_cat  = p_fmt->i_cat;
863         if( p_fmt->i_cat == AUDIO_ES )
864         {
865             id->i_clock_rate = p_fmt->audio.i_rate;
866             id->i_channels = p_fmt->audio.i_channels;
867         }
868         id->i_bitrate = p_fmt->i_bitrate/1000; /* Stream bitrate in kbps */
869     }
870     else
871     {
872         id->i_cat  = VIDEO_ES;
873         id->i_bitrate = 0;
874     }
875
876     id->pf_packetize = NULL;
877     id->i_mtu = config_GetInt( p_stream, "mtu" );
878     if( id->i_mtu <= 12 + 16 )
879         id->i_mtu = 576 - 20 - 8; /* pessimistic */
880
881     msg_Dbg( p_stream, "maximum RTP packet size: %d bytes", id->i_mtu );
882
883     vlc_mutex_init( p_stream, &id->lock_sink );
884     id->sinkc = 0;
885     id->sinkv = NULL;
886     id->rtsp_id = NULL;
887     id->p_fifo = NULL;
888     id->listen_fd = NULL;
889
890     id->i_caching =
891         (int64_t)1000 * var_GetInteger( p_stream, SOUT_CFG_PREFIX "caching");
892
893     if( p_sys->psz_destination != NULL )
894         switch( p_sys->proto )
895         {
896             case IPPROTO_TCP:
897             case IPPROTO_DCCP:
898                 id->listen_fd = net_Listen( VLC_OBJECT(p_stream),
899                                             p_sys->psz_destination, i_port,
900                                             p_sys->proto );
901                 if( id->listen_fd == NULL )
902                 {
903                     msg_Err( p_stream, "passive COMEDIA RTP socket failed" );
904                     goto error;
905                 }
906                 break;
907
908             default:
909             {
910                 int ttl = (p_sys->i_ttl > 0) ? p_sys->i_ttl : -1;
911                 int fd = net_ConnectDgram( p_stream, p_sys->psz_destination,
912                                            i_port, ttl, p_sys->proto );
913                 if( fd == -1 )
914                 {
915                     msg_Err( p_stream, "cannot create RTP socket" );
916                     goto error;
917                 }
918                 rtp_add_sink( id, fd, p_sys->rtcp_mux );
919             }
920         }
921
922     if( p_fmt == NULL )
923     {
924         char *psz = var_GetNonEmptyString( p_stream, SOUT_CFG_PREFIX "mux" );
925
926         if( psz == NULL ) /* Uho! */
927             ;
928         else
929         if( strncmp( psz, "ts", 2 ) == 0 )
930         {
931             id->i_payload_type = 33;
932             id->psz_rtpmap = strdup( "MP2T/90000" );
933         }
934         else
935         {
936             id->psz_rtpmap = strdup( "MP2P/90000" );
937         }
938     }
939     else
940     switch( p_fmt->i_codec )
941     {
942         case VLC_FOURCC( 'u', 'l', 'a', 'w' ):
943             if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 8000 )
944                 id->i_payload_type = 0;
945             if( asprintf( &id->psz_rtpmap, "PCMU/%d/%d", p_fmt->audio.i_rate,
946                           p_fmt->audio.i_channels ) == -1 )
947                 id->psz_rtpmap = NULL;
948             id->pf_packetize = rtp_packetize_l8;
949             break;
950         case VLC_FOURCC( 'a', 'l', 'a', 'w' ):
951             if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 8000 )
952                 id->i_payload_type = 8;
953             if( asprintf( &id->psz_rtpmap, "PCMA/%d/%d", p_fmt->audio.i_rate,
954                           p_fmt->audio.i_channels ) == -1 )
955                 id->psz_rtpmap = NULL;
956             id->pf_packetize = rtp_packetize_l8;
957             break;
958         case VLC_FOURCC( 's', '1', '6', 'b' ):
959             if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 44100 )
960             {
961                 id->i_payload_type = 11;
962             }
963             else if( p_fmt->audio.i_channels == 2 &&
964                      p_fmt->audio.i_rate == 44100 )
965             {
966                 id->i_payload_type = 10;
967             }
968             if( asprintf( &id->psz_rtpmap, "L16/%d/%d", p_fmt->audio.i_rate,
969                           p_fmt->audio.i_channels ) == -1 )
970                 id->psz_rtpmap = NULL;
971             id->pf_packetize = rtp_packetize_l16;
972             break;
973         case VLC_FOURCC( 'u', '8', ' ', ' ' ):
974             if( asprintf( &id->psz_rtpmap, "L8/%d/%d", p_fmt->audio.i_rate,
975                           p_fmt->audio.i_channels ) == -1 )
976                 id->psz_rtpmap = NULL;
977             id->pf_packetize = rtp_packetize_l8;
978             break;
979         case VLC_FOURCC( 'm', 'p', 'g', 'a' ):
980             id->i_payload_type = 14;
981             id->psz_rtpmap = strdup( "MPA/90000" );
982             id->pf_packetize = rtp_packetize_mpa;
983             break;
984         case VLC_FOURCC( 'm', 'p', 'g', 'v' ):
985             id->i_payload_type = 32;
986             id->psz_rtpmap = strdup( "MPV/90000" );
987             id->pf_packetize = rtp_packetize_mpv;
988             break;
989         case VLC_FOURCC( 'a', '5', '2', ' ' ):
990             id->psz_rtpmap = strdup( "ac3/90000" );
991             id->pf_packetize = rtp_packetize_ac3;
992             break;
993         case VLC_FOURCC( 'H', '2', '6', '3' ):
994             id->psz_rtpmap = strdup( "H263-1998/90000" );
995             id->pf_packetize = rtp_packetize_h263;
996             break;
997         case VLC_FOURCC( 'h', '2', '6', '4' ):
998             id->psz_rtpmap = strdup( "H264/90000" );
999             id->pf_packetize = rtp_packetize_h264;
1000             id->psz_fmtp = NULL;
1001
1002             if( p_fmt->i_extra > 0 )
1003             {
1004                 uint8_t *p_buffer = p_fmt->p_extra;
1005                 int     i_buffer = p_fmt->i_extra;
1006                 char    *p_64_sps = NULL;
1007                 char    *p_64_pps = NULL;
1008                 char    hexa[6+1];
1009
1010                 while( i_buffer > 4 &&
1011                        p_buffer[0] == 0 && p_buffer[1] == 0 &&
1012                        p_buffer[2] == 0 && p_buffer[3] == 1 )
1013                 {
1014                     const int i_nal_type = p_buffer[4]&0x1f;
1015                     int i_offset;
1016                     int i_size      = 0;
1017
1018                     msg_Dbg( p_stream, "we found a startcode for NAL with TYPE:%d", i_nal_type );
1019
1020                     i_size = i_buffer;
1021                     for( i_offset = 4; i_offset+3 < i_buffer ; i_offset++)
1022                     {
1023                         if( !memcmp (p_buffer + i_offset, "\x00\x00\x00\x01", 4 ) )
1024                         {
1025                             /* we found another startcode */
1026                             i_size = i_offset;
1027                             break;
1028                         }
1029                     }
1030                     if( i_nal_type == 7 )
1031                     {
1032                         p_64_sps = vlc_b64_encode_binary( &p_buffer[4], i_size - 4 );
1033                         sprintf_hexa( hexa, &p_buffer[5], 3 );
1034                     }
1035                     else if( i_nal_type == 8 )
1036                     {
1037                         p_64_pps = vlc_b64_encode_binary( &p_buffer[4], i_size - 4 );
1038                     }
1039                     i_buffer -= i_size;
1040                     p_buffer += i_size;
1041                 }
1042                 /* */
1043                 if( p_64_sps && p_64_pps &&
1044                     ( asprintf( &id->psz_fmtp,
1045                                 "packetization-mode=1;profile-level-id=%s;"
1046                                 "sprop-parameter-sets=%s,%s;", hexa, p_64_sps,
1047                                 p_64_pps ) == -1 ) )
1048                     id->psz_fmtp = NULL;
1049                 free( p_64_sps );
1050                 free( p_64_pps );
1051             }
1052             if( !id->psz_fmtp )
1053                 id->psz_fmtp = strdup( "packetization-mode=1" );
1054             break;
1055
1056         case VLC_FOURCC( 'm', 'p', '4', 'v' ):
1057         {
1058             char hexa[2*p_fmt->i_extra +1];
1059
1060             id->psz_rtpmap = strdup( "MP4V-ES/90000" );
1061             id->pf_packetize = rtp_packetize_split;
1062             if( p_fmt->i_extra > 0 )
1063             {
1064                 sprintf_hexa( hexa, p_fmt->p_extra, p_fmt->i_extra );
1065                 if( asprintf( &id->psz_fmtp,
1066                               "profile-level-id=3; config=%s;", hexa ) == -1 )
1067                     id->psz_fmtp = NULL;
1068             }
1069             break;
1070         }
1071         case VLC_FOURCC( 'm', 'p', '4', 'a' ):
1072         {
1073             if(!p_sys->b_latm)
1074             {
1075                 char hexa[2*p_fmt->i_extra +1];
1076
1077                 if( asprintf( &id->psz_rtpmap, "mpeg4-generic/%d",
1078                               p_fmt->audio.i_rate ) == -1 )
1079                     id->psz_rtpmap = NULL;
1080                 id->pf_packetize = rtp_packetize_mp4a;
1081                 sprintf_hexa( hexa, p_fmt->p_extra, p_fmt->i_extra );
1082                 if( asprintf( &id->psz_fmtp,
1083                               "streamtype=5; profile-level-id=15; "
1084                               "mode=AAC-hbr; config=%s; SizeLength=13; "
1085                               "IndexLength=3; IndexDeltaLength=3; Profile=1;",
1086                               hexa ) == -1 )
1087                     id->psz_fmtp = NULL;
1088             }
1089             else
1090             {
1091                 char hexa[13];
1092                 int i;
1093                 unsigned char config[6];
1094                 unsigned int aacsrates[15] = {
1095                     96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
1096                     16000, 12000, 11025, 8000, 7350, 0, 0 };
1097
1098                 for( i = 0; i < 15; i++ )
1099                     if( p_fmt->audio.i_rate == aacsrates[i] )
1100                         break;
1101
1102                 config[0]=0x40;
1103                 config[1]=0;
1104                 config[2]=0x20|i;
1105                 config[3]=p_fmt->audio.i_channels<<4;
1106                 config[4]=0x3f;
1107                 config[5]=0xc0;
1108
1109                 if( asprintf( &id->psz_rtpmap, "MP4A-LATM/%d/%d",
1110                               p_fmt->audio.i_rate,
1111                               p_fmt->audio.i_channels ) == -1)
1112                     id->psz_rtpmap = NULL;
1113                 id->pf_packetize = rtp_packetize_mp4a_latm;
1114                 sprintf_hexa( hexa, config, 6 );
1115                 if( asprintf( &id->psz_fmtp, "profile-level-id=15; "
1116                               "object=2; cpresent=0; config=%s", hexa ) == -1 )
1117                     id->psz_fmtp = NULL;
1118             }
1119             break;
1120         }
1121         case VLC_FOURCC( 's', 'a', 'm', 'r' ):
1122             id->psz_rtpmap = strdup( p_fmt->audio.i_channels == 2 ?
1123                                      "AMR/8000/2" : "AMR/8000" );
1124             id->psz_fmtp = strdup( "octet-align=1" );
1125             id->pf_packetize = rtp_packetize_amr;
1126             break;
1127         case VLC_FOURCC( 's', 'a', 'w', 'b' ):
1128             id->psz_rtpmap = strdup( p_fmt->audio.i_channels == 2 ?
1129                                      "AMR-WB/16000/2" : "AMR-WB/16000" );
1130             id->psz_fmtp = strdup( "octet-align=1" );
1131             id->pf_packetize = rtp_packetize_amr;
1132             break;
1133         case VLC_FOURCC( 's', 'p', 'x', ' ' ):
1134             id->i_payload_type = p_sys->i_payload_type++;
1135             if( asprintf( &id->psz_rtpmap, "SPEEX/%d",
1136                           p_fmt->audio.i_rate ) == -1)
1137                 id->psz_rtpmap = NULL;
1138             id->pf_packetize = rtp_packetize_spx;
1139             break;
1140         case VLC_FOURCC( 't', '1', '4', '0' ):
1141             id->psz_rtpmap = strdup( "t140/1000" );
1142             id->i_clock_rate = 1000;
1143             id->pf_packetize = rtp_packetize_t140;
1144             break;
1145
1146         default:
1147             msg_Err( p_stream, "cannot add this stream (unsupported "
1148                      "codec:%4.4s)", (char*)&p_fmt->i_codec );
1149             goto error;
1150     }
1151
1152     if( cscov != -1 )
1153         cscov += 8 /* UDP */ + 12 /* RTP */;
1154     if( id->sinkc > 0 )
1155         net_SetCSCov( id->sinkv[0].rtp_fd, cscov, -1 );
1156
1157     if( id->i_payload_type == p_sys->i_payload_type )
1158         p_sys->i_payload_type++;
1159
1160     if( p_sys->rtsp != NULL )
1161         id->rtsp_id = RtspAddId( p_sys->rtsp, id, p_sys->i_es,
1162                                  GetDWBE( id->ssrc ),
1163                                  p_sys->psz_destination,
1164                                  p_sys->i_ttl, id->i_port, id->i_port + 1 );
1165
1166     id->p_fifo = block_FifoNew( p_stream );
1167     if( vlc_thread_create( id, "RTP send thread", ThreadSend,
1168                            VLC_THREAD_PRIORITY_HIGHEST, VLC_FALSE ) )
1169         goto error;
1170
1171     /* Update p_sys context */
1172     vlc_mutex_lock( &p_sys->lock_es );
1173     TAB_APPEND( p_sys->i_es, p_sys->es, id );
1174     vlc_mutex_unlock( &p_sys->lock_es );
1175
1176     psz_sdp = SDPGenerate( p_stream, NULL );
1177
1178     vlc_mutex_lock( &p_sys->lock_sdp );
1179     free( p_sys->psz_sdp );
1180     p_sys->psz_sdp = psz_sdp;
1181     vlc_mutex_unlock( &p_sys->lock_sdp );
1182
1183     msg_Dbg( p_stream, "sdp=\n%s", p_sys->psz_sdp );
1184
1185     /* Update SDP (sap/file) */
1186     if( p_sys->b_export_sap ) SapSetup( p_stream );
1187     if( p_sys->b_export_sdp_file ) FileSetup( p_stream );
1188
1189     return id;
1190
1191 error:
1192     Del( p_stream, id );
1193     return NULL;
1194 }
1195
1196 static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
1197 {
1198     sout_stream_sys_t *p_sys = p_stream->p_sys;
1199
1200     if( id->p_fifo != NULL )
1201     {
1202         vlc_object_kill( id );
1203         block_FifoWake( id->p_fifo );
1204         vlc_thread_join( id );
1205         block_FifoRelease( id->p_fifo );
1206     }
1207
1208     vlc_mutex_lock( &p_sys->lock_es );
1209     TAB_REMOVE( p_sys->i_es, p_sys->es, id );
1210     vlc_mutex_unlock( &p_sys->lock_es );
1211
1212     /* Release port */
1213     if( id->i_port > 0 )
1214     {
1215         if( id->i_cat == AUDIO_ES && p_sys->i_port_audio == 0 )
1216             p_sys->i_port_audio = id->i_port;
1217         else if( id->i_cat == VIDEO_ES && p_sys->i_port_video == 0 )
1218             p_sys->i_port_video = id->i_port;
1219     }
1220
1221     free( id->psz_rtpmap );
1222     free( id->psz_fmtp );
1223
1224     if( id->rtsp_id )
1225         RtspDelId( p_sys->rtsp, id->rtsp_id );
1226     if( id->sinkc > 0 )
1227         rtp_del_sink( id, id->sinkv[0].rtp_fd ); /* sink for explicit dst= */
1228     if( id->listen_fd != NULL )
1229         net_ListenClose( id->listen_fd );
1230
1231     vlc_mutex_destroy( &id->lock_sink );
1232
1233     /* Update SDP (sap/file) */
1234     if( p_sys->b_export_sap && !p_sys->p_mux ) SapSetup( p_stream );
1235     if( p_sys->b_export_sdp_file ) FileSetup( p_stream );
1236
1237     vlc_object_detach( id );
1238     vlc_object_destroy( id );
1239     return VLC_SUCCESS;
1240 }
1241
1242 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
1243                  block_t *p_buffer )
1244 {
1245     block_t *p_next;
1246
1247     assert( p_stream->p_sys->p_mux == NULL );
1248
1249     while( p_buffer != NULL )
1250     {
1251         p_next = p_buffer->p_next;
1252         if( id->pf_packetize( p_stream, id, p_buffer ) )
1253             break;
1254
1255         block_Release( p_buffer );
1256         p_buffer = p_next;
1257     }
1258     return VLC_SUCCESS;
1259 }
1260
1261 /****************************************************************************
1262  * SAP:
1263  ****************************************************************************/
1264 static int SapSetup( sout_stream_t *p_stream )
1265 {
1266     sout_stream_sys_t *p_sys = p_stream->p_sys;
1267     sout_instance_t   *p_sout = p_stream->p_sout;
1268
1269     /* Remove the previous session */
1270     if( p_sys->p_session != NULL)
1271     {
1272         sout_AnnounceUnRegister( p_sout, p_sys->p_session);
1273         p_sys->p_session = NULL;
1274     }
1275
1276     if( ( p_sys->i_es > 0 || p_sys->p_mux ) && p_sys->psz_sdp && *p_sys->psz_sdp )
1277     {
1278         announce_method_t *p_method = sout_SAPMethod();
1279         p_sys->p_session = sout_AnnounceRegisterSDP( p_sout, SOUT_CFG_PREFIX,
1280                                                      p_sys->psz_sdp,
1281                                                      p_sys->psz_destination,
1282                                                      p_method );
1283         sout_MethodRelease( p_method );
1284     }
1285
1286     return VLC_SUCCESS;
1287 }
1288
1289 /****************************************************************************
1290 * File:
1291 ****************************************************************************/
1292 static int FileSetup( sout_stream_t *p_stream )
1293 {
1294     sout_stream_sys_t *p_sys = p_stream->p_sys;
1295     FILE            *f;
1296
1297     if( ( f = utf8_fopen( p_sys->psz_sdp_file, "wt" ) ) == NULL )
1298     {
1299         msg_Err( p_stream, "cannot open file '%s' (%m)",
1300                  p_sys->psz_sdp_file );
1301         return VLC_EGENERIC;
1302     }
1303
1304     fputs( p_sys->psz_sdp, f );
1305     fclose( f );
1306
1307     return VLC_SUCCESS;
1308 }
1309
1310 /****************************************************************************
1311  * HTTP:
1312  ****************************************************************************/
1313 static int  HttpCallback( httpd_file_sys_t *p_args,
1314                           httpd_file_t *, uint8_t *p_request,
1315                           uint8_t **pp_data, int *pi_data );
1316
1317 static int HttpSetup( sout_stream_t *p_stream, vlc_url_t *url)
1318 {
1319     sout_stream_sys_t *p_sys = p_stream->p_sys;
1320
1321     p_sys->p_httpd_host = httpd_HostNew( VLC_OBJECT(p_stream), url->psz_host,
1322                                          url->i_port > 0 ? url->i_port : 80 );
1323     if( p_sys->p_httpd_host )
1324     {
1325         p_sys->p_httpd_file = httpd_FileNew( p_sys->p_httpd_host,
1326                                              url->psz_path ? url->psz_path : "/",
1327                                              "application/sdp",
1328                                              NULL, NULL, NULL,
1329                                              HttpCallback, (void*)p_sys );
1330     }
1331     if( p_sys->p_httpd_file == NULL )
1332     {
1333         return VLC_EGENERIC;
1334     }
1335     return VLC_SUCCESS;
1336 }
1337
1338 static int  HttpCallback( httpd_file_sys_t *p_args,
1339                           httpd_file_t *f, uint8_t *p_request,
1340                           uint8_t **pp_data, int *pi_data )
1341 {
1342     sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_args;
1343
1344     vlc_mutex_lock( &p_sys->lock_sdp );
1345     if( p_sys->psz_sdp && *p_sys->psz_sdp )
1346     {
1347         *pi_data = strlen( p_sys->psz_sdp );
1348         *pp_data = malloc( *pi_data );
1349         memcpy( *pp_data, p_sys->psz_sdp, *pi_data );
1350     }
1351     else
1352     {
1353         *pp_data = NULL;
1354         *pi_data = 0;
1355     }
1356     vlc_mutex_unlock( &p_sys->lock_sdp );
1357
1358     return VLC_SUCCESS;
1359 }
1360
1361 /****************************************************************************
1362  * RTP send
1363  ****************************************************************************/
1364 static void ThreadSend( vlc_object_t *p_this )
1365 {
1366     sout_stream_id_t *id = (sout_stream_id_t *)p_this;
1367     unsigned i_caching = id->i_caching;
1368 #ifdef HAVE_TEE
1369     int fd[5] = { -1, -1, -1, -1, -1 };
1370
1371     if( pipe( fd ) )
1372         fd[0] = fd[1] = -1;
1373     else
1374     if( pipe( fd ) )
1375         fd[2] = fd[3] = -1;
1376     else
1377         fd[4] = open( "/dev/null", O_WRONLY );
1378 #endif
1379
1380     while( !id->b_die )
1381     {
1382         block_t *out = block_FifoGet( id->p_fifo );
1383         if( out == NULL )
1384             continue; /* Forced wakeup */
1385
1386         mtime_t  i_date = out->i_dts + i_caching;
1387         ssize_t  len = out->i_buffer;
1388
1389 #ifdef HAVE_TEE
1390         if( fd[4] != -1 )
1391             len = write( fd[1], out->p_buffer, len);
1392         if( len == -1 )
1393             continue; /* Uho - should not happen */
1394 #endif
1395         mwait( i_date );
1396
1397         vlc_mutex_lock( &id->lock_sink );
1398         unsigned deadc = 0; /* How many dead sockets? */
1399         int deadv[id->sinkc]; /* Dead sockets list */
1400
1401         for( int i = 0; i < id->sinkc; i++ )
1402         {
1403             SendRTCP( id->sinkv[i].rtcp, out );
1404
1405 #ifdef HAVE_TEE
1406             tee( fd[0], fd[3], len, 0 );
1407             if( splice( fd[2], NULL, id->sinkv[i].rtp_fd, NULL, len,
1408                         SPLICE_F_NONBLOCK ) >= 0 )
1409                 continue;
1410             if( errno == EAGAIN )
1411                 continue;
1412
1413             /* splice failed */
1414             splice( fd[2], NULL, fd[4], NULL, len, 0 );
1415 #else
1416             if( send( id->sinkv[i].rtp_fd, out->p_buffer, len, 0 ) >= 0 )
1417                 continue;
1418 #endif
1419             /* Retry sending to root out soft-errors */
1420             if( send( id->sinkv[i].rtp_fd, out->p_buffer, len, 0 ) >= 0 )
1421                 continue;
1422
1423             deadv[deadc++] = id->sinkv[i].rtp_fd;
1424         }
1425         vlc_mutex_unlock( &id->lock_sink );
1426
1427         block_Release( out );
1428 #ifdef HAVE_TEE
1429         splice( fd[0], NULL, fd[4], NULL, len, 0 );
1430 #endif
1431
1432         for( unsigned i = 0; i < deadc; i++ )
1433         {
1434             msg_Dbg( id, "removing socket %d", deadv[i] );
1435             rtp_del_sink( id, deadv[i] );
1436         }
1437
1438         /* Hopefully we won't overflow the SO_MAXCONN accept queue */
1439         while( id->listen_fd != NULL )
1440         {
1441             int fd = net_Accept( id, id->listen_fd, 0 );
1442             if( fd == -1 )
1443                 break;
1444             msg_Dbg( id, "adding socket %d", fd );
1445             rtp_add_sink( id, fd, VLC_TRUE );
1446         }
1447     }
1448
1449 #ifdef HAVE_TEE
1450     for( unsigned i = 0; i < 5; i++ )
1451         close( fd[i] );
1452 #endif
1453 }
1454
1455 static inline void rtp_packetize_send( sout_stream_id_t *id, block_t *out )
1456 {
1457     block_FifoPut( id->p_fifo, out );
1458 }
1459
1460 int rtp_add_sink( sout_stream_id_t *id, int fd, vlc_bool_t rtcp_mux )
1461 {
1462     rtp_sink_t sink = { fd, NULL };
1463     sink.rtcp = OpenRTCP( VLC_OBJECT( id->p_stream ), fd, IPPROTO_UDP,
1464                           rtcp_mux );
1465     if( sink.rtcp == NULL )
1466         msg_Err( id, "RTCP failed!" );
1467
1468     vlc_mutex_lock( &id->lock_sink );
1469     INSERT_ELEM( id->sinkv, id->sinkc, id->sinkc, sink );
1470     vlc_mutex_unlock( &id->lock_sink );
1471     return VLC_SUCCESS;
1472 }
1473
1474 void rtp_del_sink( sout_stream_id_t *id, int fd )
1475 {
1476     rtp_sink_t sink = { fd, NULL };
1477
1478     /* NOTE: must be safe to use if fd is not included */
1479     vlc_mutex_lock( &id->lock_sink );
1480     for( int i = 0; i < id->sinkc; i++ )
1481     {
1482         if (id->sinkv[i].rtp_fd == fd)
1483         {
1484             sink = id->sinkv[i];
1485             REMOVE_ELEM( id->sinkv, id->sinkc, i );
1486             break;
1487         }
1488     }
1489     vlc_mutex_unlock( &id->lock_sink );
1490
1491     CloseRTCP( sink.rtcp );
1492     net_Close( sink.rtp_fd );
1493 }
1494
1495 uint16_t rtp_get_seq( const sout_stream_id_t *id )
1496 {
1497     /* This will return values for the next packet.
1498      * Accounting for caching would not be totally trivial. */
1499     return id->i_sequence;
1500 }
1501
1502 /* FIXME: this is pretty bad - if we remove and then insert an ES
1503  * the number will get unsynched from inside RTSP */
1504 unsigned rtp_get_num( const sout_stream_id_t *id )
1505 {
1506     sout_stream_sys_t *p_sys = id->p_stream->p_sys;
1507     int i;
1508
1509     vlc_mutex_lock( &p_sys->lock_es );
1510     for( i = 0; i < p_sys->i_es; i++ )
1511     {
1512         if( id == p_sys->es[i] )
1513             break;
1514     }
1515     vlc_mutex_unlock( &p_sys->lock_es );
1516
1517     return i;
1518 }
1519
1520
1521 /****************************************************************************
1522  * rtp_packetize_*:
1523  ****************************************************************************/
1524 static void rtp_packetize_common( sout_stream_id_t *id, block_t *out,
1525                                   int b_marker, int64_t i_pts )
1526 {
1527     uint32_t i_timestamp = i_pts * (int64_t)id->i_clock_rate / I64C(1000000);
1528
1529     out->p_buffer[0] = 0x80;
1530     out->p_buffer[1] = (b_marker?0x80:0x00)|id->i_payload_type;
1531     out->p_buffer[2] = ( id->i_sequence >> 8)&0xff;
1532     out->p_buffer[3] = ( id->i_sequence     )&0xff;
1533     out->p_buffer[4] = ( i_timestamp >> 24 )&0xff;
1534     out->p_buffer[5] = ( i_timestamp >> 16 )&0xff;
1535     out->p_buffer[6] = ( i_timestamp >>  8 )&0xff;
1536     out->p_buffer[7] = ( i_timestamp       )&0xff;
1537
1538     memcpy( out->p_buffer + 8, id->ssrc, 4 );
1539
1540     out->i_buffer = 12;
1541     id->i_sequence++;
1542 }
1543
1544 static int rtp_packetize_mpa( sout_stream_t *p_stream, sout_stream_id_t *id,
1545                               block_t *in )
1546 {
1547     int     i_max   = id->i_mtu - 12 - 4; /* payload max in one packet */
1548     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1549
1550     uint8_t *p_data = in->p_buffer;
1551     int     i_data  = in->i_buffer;
1552     int     i;
1553
1554     for( i = 0; i < i_count; i++ )
1555     {
1556         int           i_payload = __MIN( i_max, i_data );
1557         block_t *out = block_New( p_stream, 16 + i_payload );
1558
1559         /* rtp common header */
1560         rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts );
1561         /* mbz set to 0 */
1562         out->p_buffer[12] = 0;
1563         out->p_buffer[13] = 0;
1564         /* fragment offset in the current frame */
1565         out->p_buffer[14] = ( (i*i_max) >> 8 )&0xff;
1566         out->p_buffer[15] = ( (i*i_max)      )&0xff;
1567         memcpy( &out->p_buffer[16], p_data, i_payload );
1568
1569         out->i_buffer   = 16 + i_payload;
1570         out->i_dts    = in->i_dts + i * in->i_length / i_count;
1571         out->i_length = in->i_length / i_count;
1572
1573         rtp_packetize_send( id, out );
1574
1575         p_data += i_payload;
1576         i_data -= i_payload;
1577     }
1578
1579     return VLC_SUCCESS;
1580 }
1581
1582 /* rfc2250 */
1583 static int rtp_packetize_mpv( sout_stream_t *p_stream, sout_stream_id_t *id,
1584                               block_t *in )
1585 {
1586     int     i_max   = id->i_mtu - 12 - 4; /* payload max in one packet */
1587     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1588
1589     uint8_t *p_data = in->p_buffer;
1590     int     i_data  = in->i_buffer;
1591     int     i;
1592     int     b_sequence_start = 0;
1593     int     i_temporal_ref = 0;
1594     int     i_picture_coding_type = 0;
1595     int     i_fbv = 0, i_bfc = 0, i_ffv = 0, i_ffc = 0;
1596     int     b_start_slice = 0;
1597
1598     /* preparse this packet to get some info */
1599     if( in->i_buffer > 4 )
1600     {
1601         uint8_t *p = p_data;
1602         int      i_rest = in->i_buffer;
1603
1604         for( ;; )
1605         {
1606             while( i_rest > 4 &&
1607                    ( p[0] != 0x00 || p[1] != 0x00 || p[2] != 0x01 ) )
1608             {
1609                 p++;
1610                 i_rest--;
1611             }
1612             if( i_rest <= 4 )
1613             {
1614                 break;
1615             }
1616             p += 3;
1617             i_rest -= 4;
1618
1619             if( *p == 0xb3 )
1620             {
1621                 /* sequence start code */
1622                 b_sequence_start = 1;
1623             }
1624             else if( *p == 0x00 && i_rest >= 4 )
1625             {
1626                 /* picture */
1627                 i_temporal_ref = ( p[1] << 2) |((p[2]>>6)&0x03);
1628                 i_picture_coding_type = (p[2] >> 3)&0x07;
1629
1630                 if( i_rest >= 4 && ( i_picture_coding_type == 2 ||
1631                                     i_picture_coding_type == 3 ) )
1632                 {
1633                     i_ffv = (p[3] >> 2)&0x01;
1634                     i_ffc = ((p[3]&0x03) << 1)|((p[4]>>7)&0x01);
1635                     if( i_rest > 4 && i_picture_coding_type == 3 )
1636                     {
1637                         i_fbv = (p[4]>>6)&0x01;
1638                         i_bfc = (p[4]>>3)&0x07;
1639                     }
1640                 }
1641             }
1642             else if( *p <= 0xaf )
1643             {
1644                 b_start_slice = 1;
1645             }
1646         }
1647     }
1648
1649     for( i = 0; i < i_count; i++ )
1650     {
1651         int           i_payload = __MIN( i_max, i_data );
1652         block_t *out = block_New( p_stream,
1653                                              16 + i_payload );
1654         uint32_t      h = ( i_temporal_ref << 16 )|
1655                           ( b_sequence_start << 13 )|
1656                           ( b_start_slice << 12 )|
1657                           ( i == i_count - 1 ? 1 << 11 : 0 )|
1658                           ( i_picture_coding_type << 8 )|
1659                           ( i_fbv << 7 )|( i_bfc << 4 )|( i_ffv << 3 )|i_ffc;
1660
1661         /* rtp common header */
1662         rtp_packetize_common( id, out, (i == i_count - 1)?1:0,
1663                               in->i_pts > 0 ? in->i_pts : in->i_dts );
1664
1665         /* 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 */
1666         out->p_buffer[12] = ( h >> 24 )&0xff;
1667         out->p_buffer[13] = ( h >> 16 )&0xff;
1668         out->p_buffer[14] = ( h >>  8 )&0xff;
1669         out->p_buffer[15] = ( h       )&0xff;
1670
1671         memcpy( &out->p_buffer[16], p_data, i_payload );
1672
1673         out->i_buffer   = 16 + i_payload;
1674         out->i_dts    = in->i_dts + i * in->i_length / i_count;
1675         out->i_length = in->i_length / i_count;
1676
1677         rtp_packetize_send( id, out );
1678
1679         p_data += i_payload;
1680         i_data -= i_payload;
1681     }
1682
1683     return VLC_SUCCESS;
1684 }
1685
1686 static int rtp_packetize_ac3( sout_stream_t *p_stream, sout_stream_id_t *id,
1687                               block_t *in )
1688 {
1689     int     i_max   = id->i_mtu - 12 - 2; /* payload max in one packet */
1690     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1691
1692     uint8_t *p_data = in->p_buffer;
1693     int     i_data  = in->i_buffer;
1694     int     i;
1695
1696     for( i = 0; i < i_count; i++ )
1697     {
1698         int           i_payload = __MIN( i_max, i_data );
1699         block_t *out = block_New( p_stream, 14 + i_payload );
1700
1701         /* rtp common header */
1702         rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts );
1703         /* unit count */
1704         out->p_buffer[12] = 1;
1705         /* unit header */
1706         out->p_buffer[13] = 0x00;
1707         /* data */
1708         memcpy( &out->p_buffer[14], p_data, i_payload );
1709
1710         out->i_buffer   = 14 + i_payload;
1711         out->i_dts    = in->i_dts + i * in->i_length / i_count;
1712         out->i_length = in->i_length / i_count;
1713
1714         rtp_packetize_send( id, out );
1715
1716         p_data += i_payload;
1717         i_data -= i_payload;
1718     }
1719
1720     return VLC_SUCCESS;
1721 }
1722
1723 static int rtp_packetize_split( sout_stream_t *p_stream, sout_stream_id_t *id,
1724                                 block_t *in )
1725 {
1726     int     i_max   = id->i_mtu - 12; /* payload max in one packet */
1727     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1728
1729     uint8_t *p_data = in->p_buffer;
1730     int     i_data  = in->i_buffer;
1731     int     i;
1732
1733     for( i = 0; i < i_count; i++ )
1734     {
1735         int           i_payload = __MIN( i_max, i_data );
1736         block_t *out = block_New( p_stream, 12 + i_payload );
1737
1738         /* rtp common header */
1739         rtp_packetize_common( id, out, ((i == i_count - 1)?1:0),
1740                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
1741         memcpy( &out->p_buffer[12], p_data, i_payload );
1742
1743         out->i_buffer   = 12 + i_payload;
1744         out->i_dts    = in->i_dts + i * in->i_length / i_count;
1745         out->i_length = in->i_length / i_count;
1746
1747         rtp_packetize_send( id, out );
1748
1749         p_data += i_payload;
1750         i_data -= i_payload;
1751     }
1752
1753     return VLC_SUCCESS;
1754 }
1755
1756 /* rfc3016 */
1757 static int rtp_packetize_mp4a_latm( sout_stream_t *p_stream, sout_stream_id_t *id,
1758                                 block_t *in )
1759 {
1760     int     i_max   = id->i_mtu - 14;              /* payload max in one packet */
1761     int     latmhdrsize = in->i_buffer / 0xff + 1;
1762     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1763
1764     uint8_t *p_data = in->p_buffer, *p_header = NULL;
1765     int     i_data  = in->i_buffer;
1766     int     i;
1767
1768     for( i = 0; i < i_count; i++ )
1769     {
1770         int     i_payload = __MIN( i_max, i_data );
1771         block_t *out;
1772
1773         if( i != 0 )
1774             latmhdrsize = 0;
1775         out = block_New( p_stream, 12 + latmhdrsize + i_payload );
1776
1777         /* rtp common header */
1778         rtp_packetize_common( id, out, ((i == i_count - 1) ? 1 : 0),
1779                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
1780
1781         if( i == 0 )
1782         {
1783             int tmp = in->i_buffer;
1784
1785             p_header=out->p_buffer+12;
1786             while( tmp > 0xfe )
1787             {
1788                 *p_header = 0xff;
1789                 p_header++;
1790                 tmp -= 0xff;
1791             }
1792             *p_header = tmp;
1793         }
1794
1795         memcpy( &out->p_buffer[12+latmhdrsize], p_data, i_payload );
1796
1797         out->i_buffer   = 12 + latmhdrsize + i_payload;
1798         out->i_dts    = in->i_dts + i * in->i_length / i_count;
1799         out->i_length = in->i_length / i_count;
1800
1801         rtp_packetize_send( id, out );
1802
1803         p_data += i_payload;
1804         i_data -= i_payload;
1805     }
1806
1807     return VLC_SUCCESS;
1808 }
1809
1810 static int rtp_packetize_l16( sout_stream_t *p_stream, sout_stream_id_t *id,
1811                               block_t *in )
1812 {
1813     int     i_max   = id->i_mtu - 12; /* payload max in one packet */
1814     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1815
1816     uint8_t *p_data = in->p_buffer;
1817     int     i_data  = in->i_buffer;
1818     int     i_packet = 0;
1819
1820     while( i_data > 0 )
1821     {
1822         int           i_payload = (__MIN( i_max, i_data )/4)*4;
1823         block_t *out = block_New( p_stream, 12 + i_payload );
1824
1825         /* rtp common header */
1826         rtp_packetize_common( id, out, 0,
1827                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
1828         memcpy( &out->p_buffer[12], p_data, i_payload );
1829
1830         out->i_buffer   = 12 + i_payload;
1831         out->i_dts    = in->i_dts + i_packet * in->i_length / i_count;
1832         out->i_length = in->i_length / i_count;
1833
1834         rtp_packetize_send( id, out );
1835
1836         p_data += i_payload;
1837         i_data -= i_payload;
1838         i_packet++;
1839     }
1840
1841     return VLC_SUCCESS;
1842 }
1843
1844 static int rtp_packetize_l8( sout_stream_t *p_stream, sout_stream_id_t *id,
1845                              block_t *in )
1846 {
1847     int     i_max   = id->i_mtu - 12; /* payload max in one packet */
1848     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1849
1850     uint8_t *p_data = in->p_buffer;
1851     int     i_data  = in->i_buffer;
1852     int     i_packet = 0;
1853
1854     while( i_data > 0 )
1855     {
1856         int           i_payload = (__MIN( i_max, i_data )/2)*2;
1857         block_t *out = block_New( p_stream, 12 + i_payload );
1858
1859         /* rtp common header */
1860         rtp_packetize_common( id, out, 0,
1861                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
1862         memcpy( &out->p_buffer[12], p_data, i_payload );
1863
1864         out->i_buffer   = 12 + i_payload;
1865         out->i_dts    = in->i_dts + i_packet * in->i_length / i_count;
1866         out->i_length = in->i_length / i_count;
1867
1868         rtp_packetize_send( id, out );
1869
1870         p_data += i_payload;
1871         i_data -= i_payload;
1872         i_packet++;
1873     }
1874
1875     return VLC_SUCCESS;
1876 }
1877
1878 static int rtp_packetize_mp4a( sout_stream_t *p_stream, sout_stream_id_t *id,
1879                                block_t *in )
1880 {
1881     int     i_max   = id->i_mtu - 16; /* payload max in one packet */
1882     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1883
1884     uint8_t *p_data = in->p_buffer;
1885     int     i_data  = in->i_buffer;
1886     int     i;
1887
1888     for( i = 0; i < i_count; i++ )
1889     {
1890         int           i_payload = __MIN( i_max, i_data );
1891         block_t *out = block_New( p_stream, 16 + i_payload );
1892
1893         /* rtp common header */
1894         rtp_packetize_common( id, out, ((i == i_count - 1)?1:0),
1895                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
1896         /* AU headers */
1897         /* AU headers length (bits) */
1898         out->p_buffer[12] = 0;
1899         out->p_buffer[13] = 2*8;
1900         /* for each AU length 13 bits + idx 3bits, */
1901         out->p_buffer[14] = ( in->i_buffer >> 5 )&0xff;
1902         out->p_buffer[15] = ( (in->i_buffer&0xff)<<3 )|0;
1903
1904         memcpy( &out->p_buffer[16], p_data, i_payload );
1905
1906         out->i_buffer   = 16 + i_payload;
1907         out->i_dts    = in->i_dts + i * in->i_length / i_count;
1908         out->i_length = in->i_length / i_count;
1909
1910         rtp_packetize_send( id, out );
1911
1912         p_data += i_payload;
1913         i_data -= i_payload;
1914     }
1915
1916     return VLC_SUCCESS;
1917 }
1918
1919
1920 /* rfc2429 */
1921 #define RTP_H263_HEADER_SIZE (2)  // plen = 0
1922 #define RTP_H263_PAYLOAD_START (14)  // plen = 0
1923 static int rtp_packetize_h263( sout_stream_t *p_stream, sout_stream_id_t *id,
1924                                block_t *in )
1925 {
1926     uint8_t *p_data = in->p_buffer;
1927     int     i_data  = in->i_buffer;
1928     int     i;
1929     int     i_max   = id->i_mtu - 12 - RTP_H263_HEADER_SIZE; /* payload max in one packet */
1930     int     i_count;
1931     int     b_p_bit;
1932     int     b_v_bit = 0; // no pesky error resilience
1933     int     i_plen = 0; // normally plen=0 for PSC packet
1934     int     i_pebit = 0; // because plen=0
1935     uint16_t h;
1936
1937     if( i_data < 2 )
1938     {
1939         return VLC_EGENERIC;
1940     }
1941     if( p_data[0] || p_data[1] )
1942     {
1943         return VLC_EGENERIC;
1944     }
1945     /* remove 2 leading 0 bytes */
1946     p_data += 2;
1947     i_data -= 2;
1948     i_count = ( i_data + i_max - 1 ) / i_max;
1949
1950     for( i = 0; i < i_count; i++ )
1951     {
1952         int      i_payload = __MIN( i_max, i_data );
1953         block_t *out = block_New( p_stream,
1954                                   RTP_H263_PAYLOAD_START + i_payload );
1955         b_p_bit = (i == 0) ? 1 : 0;
1956         h = ( b_p_bit << 10 )|
1957             ( b_v_bit << 9  )|
1958             ( i_plen  << 3  )|
1959               i_pebit;
1960
1961         /* rtp common header */
1962         //b_m_bit = 1; // always contains end of frame
1963         rtp_packetize_common( id, out, (i == i_count - 1)?1:0,
1964                               in->i_pts > 0 ? in->i_pts : in->i_dts );
1965
1966         /* h263 header */
1967         out->p_buffer[12] = ( h >>  8 )&0xff;
1968         out->p_buffer[13] = ( h       )&0xff;
1969         memcpy( &out->p_buffer[RTP_H263_PAYLOAD_START], p_data, i_payload );
1970
1971         out->i_buffer = RTP_H263_PAYLOAD_START + i_payload;
1972         out->i_dts    = in->i_dts + i * in->i_length / i_count;
1973         out->i_length = in->i_length / i_count;
1974
1975         rtp_packetize_send( id, out );
1976
1977         p_data += i_payload;
1978         i_data -= i_payload;
1979     }
1980
1981     return VLC_SUCCESS;
1982 }
1983
1984 /* rfc3984 */
1985 static int
1986 rtp_packetize_h264_nal( sout_stream_t *p_stream, sout_stream_id_t *id,
1987                         const uint8_t *p_data, int i_data, int64_t i_pts,
1988                         int64_t i_dts, vlc_bool_t b_last, int64_t i_length )
1989 {
1990     const int i_max = id->i_mtu - 12; /* payload max in one packet */
1991     int i_nal_hdr;
1992     int i_nal_type;
1993
1994     if( i_data < 5 )
1995         return VLC_SUCCESS;
1996
1997     i_nal_hdr = p_data[3];
1998     i_nal_type = i_nal_hdr&0x1f;
1999
2000     /* Skip start code */
2001     p_data += 3;
2002     i_data -= 3;
2003
2004     /* */
2005     if( i_data <= i_max )
2006     {
2007         /* Single NAL unit packet */
2008         block_t *out = block_New( p_stream, 12 + i_data );
2009         out->i_dts    = i_dts;
2010         out->i_length = i_length;
2011
2012         /* */
2013         rtp_packetize_common( id, out, b_last, i_pts );
2014         out->i_buffer = 12 + i_data;
2015
2016         memcpy( &out->p_buffer[12], p_data, i_data );
2017
2018         rtp_packetize_send( id, out );
2019     }
2020     else
2021     {
2022         /* FU-A Fragmentation Unit without interleaving */
2023         const int i_count = ( i_data-1 + i_max-2 - 1 ) / (i_max-2);
2024         int i;
2025
2026         p_data++;
2027         i_data--;
2028
2029         for( i = 0; i < i_count; i++ )
2030         {
2031             const int i_payload = __MIN( i_data, i_max-2 );
2032             block_t *out = block_New( p_stream, 12 + 2 + i_payload );
2033             out->i_dts    = i_dts + i * i_length / i_count;
2034             out->i_length = i_length / i_count;
2035
2036             /* */
2037             rtp_packetize_common( id, out, (b_last && i_payload == i_data), i_pts );
2038             out->i_buffer = 14 + i_payload;
2039
2040             /* FU indicator */
2041             out->p_buffer[12] = 0x00 | (i_nal_hdr & 0x60) | 28;
2042             /* FU header */
2043             out->p_buffer[13] = ( i == 0 ? 0x80 : 0x00 ) | ( (i == i_count-1) ? 0x40 : 0x00 )  | i_nal_type;
2044             memcpy( &out->p_buffer[14], p_data, i_payload );
2045
2046             rtp_packetize_send( id, out );
2047
2048             i_data -= i_payload;
2049             p_data += i_payload;
2050         }
2051     }
2052     return VLC_SUCCESS;
2053 }
2054
2055 static int rtp_packetize_h264( sout_stream_t *p_stream, sout_stream_id_t *id,
2056                                block_t *in )
2057 {
2058     const uint8_t *p_buffer = in->p_buffer;
2059     int i_buffer = in->i_buffer;
2060
2061     while( i_buffer > 4 && ( p_buffer[0] != 0 || p_buffer[1] != 0 || p_buffer[2] != 1 ) )
2062     {
2063         i_buffer--;
2064         p_buffer++;
2065     }
2066
2067     /* Split nal units */
2068     while( i_buffer > 4 )
2069     {
2070         int i_offset;
2071         int i_size = i_buffer;
2072         int i_skip = i_buffer;
2073
2074         /* search nal end */
2075         for( i_offset = 4; i_offset+2 < i_buffer ; i_offset++)
2076         {
2077             if( p_buffer[i_offset] == 0 && p_buffer[i_offset+1] == 0 && p_buffer[i_offset+2] == 1 )
2078             {
2079                 /* we found another startcode */
2080                 i_size = i_offset - ( p_buffer[i_offset-1] == 0 ? 1 : 0);
2081                 i_skip = i_offset;
2082                 break;
2083             }
2084         }
2085         /* TODO add STAP-A to remove a lot of overhead with small slice/sei/... */
2086         rtp_packetize_h264_nal( p_stream, id, p_buffer, i_size,
2087                                 (in->i_pts > 0 ? in->i_pts : in->i_dts), in->i_dts,
2088                                 (i_size >= i_buffer), in->i_length * i_size / in->i_buffer );
2089
2090         i_buffer -= i_skip;
2091         p_buffer += i_skip;
2092     }
2093     return VLC_SUCCESS;
2094 }
2095
2096 static int rtp_packetize_amr( sout_stream_t *p_stream, sout_stream_id_t *id,
2097                               block_t *in )
2098 {
2099     int     i_max   = id->i_mtu - 14; /* payload max in one packet */
2100     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
2101
2102     uint8_t *p_data = in->p_buffer;
2103     int     i_data  = in->i_buffer;
2104     int     i;
2105
2106     /* Only supports octet-aligned mode */
2107     for( i = 0; i < i_count; i++ )
2108     {
2109         int           i_payload = __MIN( i_max, i_data );
2110         block_t *out = block_New( p_stream, 14 + i_payload );
2111
2112         /* rtp common header */
2113         rtp_packetize_common( id, out, ((i == i_count - 1)?1:0),
2114                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
2115         /* Payload header */
2116         out->p_buffer[12] = 0xF0; /* CMR */
2117         out->p_buffer[13] = p_data[0]&0x7C; /* ToC */ /* FIXME: frame type */
2118
2119         /* FIXME: are we fed multiple frames ? */
2120         memcpy( &out->p_buffer[14], p_data+1, i_payload-1 );
2121
2122         out->i_buffer   = 14 + i_payload-1;
2123         out->i_dts    = in->i_dts + i * in->i_length / i_count;
2124         out->i_length = in->i_length / i_count;
2125
2126         rtp_packetize_send( id, out );
2127
2128         p_data += i_payload;
2129         i_data -= i_payload;
2130     }
2131
2132     return VLC_SUCCESS;
2133 }
2134
2135 static int rtp_packetize_t140( sout_stream_t *p_stream, sout_stream_id_t *id,
2136                                block_t *in )
2137 {
2138     const size_t   i_max  = id->i_mtu - 12;
2139     const uint8_t *p_data = in->p_buffer;
2140     size_t         i_data = in->i_buffer;
2141
2142     for( unsigned i_packet = 0; i_data > 0; i_packet++ )
2143     {
2144         size_t i_payload = i_data;
2145
2146         /* Make sure we stop on an UTF-8 character boundary
2147          * (assuming the input is valid UTF-8) */
2148         if( i_data > i_max )
2149         {
2150             i_payload = i_max;
2151
2152             while( ( p_data[i_payload] & 0xC0 ) == 0x80 )
2153             {
2154                 if( i_payload == 0 )
2155                     return VLC_SUCCESS; /* fishy input! */
2156
2157                 i_payload--;
2158             }
2159         }
2160
2161         block_t *out = block_New( p_stream, 12 + i_payload );
2162         if( out == NULL )
2163             return VLC_SUCCESS;
2164
2165         rtp_packetize_common( id, out, 0, in->i_pts + i_packet );
2166         memcpy( out->p_buffer + 12, p_data, i_payload );
2167
2168         out->i_buffer = 12 + i_payload;
2169         out->i_dts    = out->i_pts;
2170         out->i_length = 0;
2171
2172         rtp_packetize_send( id, out );
2173
2174         p_data += i_payload;
2175         i_data -= i_payload;
2176     }
2177
2178     return VLC_SUCCESS;
2179 }
2180
2181 /*****************************************************************************
2182  * Non-RTP mux
2183  *****************************************************************************/
2184
2185 /** Add an ES to a non-RTP muxed stream */
2186 static sout_stream_id_t *MuxAdd( sout_stream_t *p_stream, es_format_t *p_fmt )
2187 {
2188     sout_input_t      *p_input;
2189     sout_mux_t *p_mux = p_stream->p_sys->p_mux;
2190     assert( p_mux != NULL );
2191
2192     p_input = sout_MuxAddStream( p_mux, p_fmt );
2193     if( p_input == NULL )
2194     {
2195         msg_Err( p_stream, "cannot add this stream to the muxer" );
2196         return NULL;
2197     }
2198
2199     return (sout_stream_id_t *)p_input;
2200 }
2201
2202
2203 static int MuxSend( sout_stream_t *p_stream, sout_stream_id_t *id,
2204                     block_t *p_buffer )
2205 {
2206     sout_mux_t *p_mux = p_stream->p_sys->p_mux;
2207     assert( p_mux != NULL );
2208
2209     sout_MuxSendBuffer( p_mux, (sout_input_t *)id, p_buffer );
2210     return VLC_SUCCESS;
2211 }
2212
2213
2214 /** Remove an ES from a non-RTP muxed stream */
2215 static int MuxDel( sout_stream_t *p_stream, sout_stream_id_t *id )
2216 {
2217     sout_mux_t *p_mux = p_stream->p_sys->p_mux;
2218     assert( p_mux != NULL );
2219
2220     sout_MuxDeleteStream( p_mux, (sout_input_t *)id );
2221     return VLC_SUCCESS;
2222 }
2223
2224
2225 static int AccessOutGrabberWriteBuffer( sout_stream_t *p_stream,
2226                                         const block_t *p_buffer )
2227 {
2228     sout_stream_sys_t *p_sys = p_stream->p_sys;
2229     sout_stream_id_t *id = p_sys->es[0];
2230
2231     int64_t  i_dts = p_buffer->i_dts;
2232
2233     uint8_t         *p_data = p_buffer->p_buffer;
2234     unsigned int    i_data  = p_buffer->i_buffer;
2235     unsigned int    i_max   = id->i_mtu - 12;
2236
2237     unsigned i_packet = ( p_buffer->i_buffer + i_max - 1 ) / i_max;
2238
2239     while( i_data > 0 )
2240     {
2241         unsigned int i_size;
2242
2243         /* output complete packet */
2244         if( p_sys->packet &&
2245             p_sys->packet->i_buffer + i_data > i_max )
2246         {
2247             rtp_packetize_send( id, p_sys->packet );
2248             p_sys->packet = NULL;
2249         }
2250
2251         if( p_sys->packet == NULL )
2252         {
2253             /* allocate a new packet */
2254             p_sys->packet = block_New( p_stream, id->i_mtu );
2255             rtp_packetize_common( id, p_sys->packet, 1, i_dts );
2256             p_sys->packet->i_dts = i_dts;
2257             p_sys->packet->i_length = p_buffer->i_length / i_packet;
2258             i_dts += p_sys->packet->i_length;
2259         }
2260
2261         i_size = __MIN( i_data,
2262                         (unsigned)(id->i_mtu - p_sys->packet->i_buffer) );
2263
2264         memcpy( &p_sys->packet->p_buffer[p_sys->packet->i_buffer],
2265                 p_data, i_size );
2266
2267         p_sys->packet->i_buffer += i_size;
2268         p_data += i_size;
2269         i_data -= i_size;
2270     }
2271
2272     return VLC_SUCCESS;
2273 }
2274
2275
2276 static int AccessOutGrabberWrite( sout_access_out_t *p_access,
2277                                   block_t *p_buffer )
2278 {
2279     sout_stream_t *p_stream = (sout_stream_t*)p_access->p_sys;
2280
2281     while( p_buffer )
2282     {
2283         block_t *p_next;
2284
2285         AccessOutGrabberWriteBuffer( p_stream, p_buffer );
2286
2287         p_next = p_buffer->p_next;
2288         block_Release( p_buffer );
2289         p_buffer = p_next;
2290     }
2291
2292     return VLC_SUCCESS;
2293 }
2294
2295
2296 static sout_access_out_t *GrabberCreate( sout_stream_t *p_stream )
2297 {
2298     sout_access_out_t *p_grab;
2299
2300     p_grab = vlc_object_create( p_stream->p_sout, sizeof( *p_grab ) );
2301     if( p_grab == NULL )
2302         return NULL;
2303
2304     p_grab->p_module    = NULL;
2305     p_grab->p_sout      = p_stream->p_sout;
2306     p_grab->psz_access  = strdup( "grab" );
2307     p_grab->p_cfg       = NULL;
2308     p_grab->psz_path    = strdup( "" );
2309     p_grab->p_sys       = (sout_access_out_sys_t *)p_stream;
2310     p_grab->pf_seek     = NULL;
2311     p_grab->pf_write    = AccessOutGrabberWrite;
2312     return p_grab;
2313 }
2314
2315 static int rtp_packetize_spx( sout_stream_t *p_stream, sout_stream_id_t *id,
2316                               block_t *in )
2317 {
2318     uint8_t *p_buffer = in->p_buffer;
2319     int i_data_size, i_payload_size, i_payload_padding;
2320     i_data_size = i_payload_size = in->i_buffer;
2321     i_payload_padding = 0;
2322     block_t *p_out;
2323
2324     if ( in->i_buffer + 12 > id->i_mtu )
2325     {
2326         msg_Warn( p_stream, "Cannot send packet larger than output MTU" );
2327         return VLC_SUCCESS;
2328     }
2329
2330     /*
2331       RFC for Speex in RTP says that each packet must end on an octet 
2332       boundary. So, we check to see if the number of bytes % 4 is zero.
2333       If not, we have to add some padding. 
2334
2335       This MAY be overkill since packetization is handled elsewhere and 
2336       appears to ensure the octet boundary. However, better safe than
2337       sorry.
2338     */
2339     if ( i_payload_size % 4 )
2340     {
2341         i_payload_padding = 4 - ( i_payload_size % 4 );
2342         i_payload_size += i_payload_padding;
2343     }
2344
2345     /* 
2346       Allocate a new RTP p_output block of the appropriate size. 
2347       Allow for 12 extra bytes of RTP header. 
2348     */
2349     p_out = block_New( p_stream, 12 + i_payload_size );
2350
2351     if ( i_payload_padding )
2352     {
2353         /* 
2354           The padding is required to be a zero followed by all 1s.
2355         */
2356         char c_first_pad, c_remaining_pad;
2357         c_first_pad = 0x7F;
2358         c_remaining_pad = 0xFF;
2359
2360         /* 
2361           Allow for 12 bytes before the i_data_size because
2362           of the expected RTP header added during
2363           rtp_packetize_common.
2364         */
2365         p_out->p_buffer[12 + i_data_size] = c_first_pad; 
2366         switch (i_payload_padding)
2367         {
2368             case 2:
2369                 p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad; 
2370                 break;
2371             case 3:
2372                 p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad; 
2373                 p_out->p_buffer[12 + i_data_size + 2] = c_remaining_pad; 
2374                 break;
2375         }
2376     } 
2377
2378     /* Add the RTP header to our p_output buffer. */
2379     rtp_packetize_common( id, p_out, 0, (in->i_pts > 0 ? in->i_pts : in->i_dts) );
2380     /* Copy the Speex payload to the p_output buffer */
2381     memcpy( &p_out->p_buffer[12], p_buffer, i_data_size );
2382
2383     p_out->i_buffer = 12 + i_payload_size;
2384     p_out->i_dts = in->i_dts;
2385     p_out->i_length = in->i_length;
2386
2387     /* Queue the buffer for actual transmission. */
2388     rtp_packetize_send( id, p_out );
2389     return VLC_SUCCESS;
2390 }