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