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