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