]> git.sesse.net Git - vlc/blob - modules/stream_out/rtp.c
0e65085cf2a9b7cf79f63a2d9f08aa5d6a83ab72
[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-2008 Rémi Denis-Courmont
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_sout.h>
35 #include <vlc_block.h>
36
37 #include <vlc_httpd.h>
38 #include <vlc_url.h>
39 #include <vlc_network.h>
40 #include <vlc_charset.h>
41 #include <vlc_strings.h>
42 #include <vlc_rand.h>
43 #ifdef HAVE_SRTP
44 # include <srtp.h>
45 #endif
46
47 #include "rtp.h"
48
49 #ifdef HAVE_UNISTD_H
50 #   include <sys/types.h>
51 #   include <unistd.h>
52 #   include <fcntl.h>
53 #   include <sys/stat.h>
54 #endif
55 #ifdef HAVE_ARPA_INET_H
56 #   include <arpa/inet.h>
57 #endif
58 #ifdef HAVE_LINUX_DCCP_H
59 #   include <linux/dccp.h>
60 #endif
61 #ifndef IPPROTO_DCCP
62 # define IPPROTO_DCCP 33
63 #endif
64 #ifndef IPPROTO_UDPLITE
65 # define IPPROTO_UDPLITE 136
66 #endif
67
68 #include <errno.h>
69
70 #include <assert.h>
71
72 /*****************************************************************************
73  * Module descriptor
74  *****************************************************************************/
75
76 #define DEST_TEXT N_("Destination")
77 #define DEST_LONGTEXT N_( \
78     "This is the output URL that will be used." )
79 #define SDP_TEXT N_("SDP")
80 #define SDP_LONGTEXT N_( \
81     "This allows you to specify how the SDP (Session Descriptor) for this RTP "\
82     "session will be made available. You must use an url: http://location to " \
83     "access the SDP via HTTP, rtsp://location for RTSP access, and sap:// " \
84     "for the SDP to be announced via SAP." )
85 #define SAP_TEXT N_("SAP announcing")
86 #define SAP_LONGTEXT N_("Announce this session with SAP.")
87 #define MUX_TEXT N_("Muxer")
88 #define MUX_LONGTEXT N_( \
89     "This allows you to specify the muxer used for the streaming output. " \
90     "Default is to use no muxer (standard RTP stream)." )
91
92 #define NAME_TEXT N_("Session name")
93 #define NAME_LONGTEXT N_( \
94     "This is the name of the session that will be announced in the SDP " \
95     "(Session Descriptor)." )
96 #define DESC_TEXT N_("Session description")
97 #define DESC_LONGTEXT N_( \
98     "This allows you to give a short description with details about the stream, " \
99     "that will be announced in the SDP (Session Descriptor)." )
100 #define URL_TEXT N_("Session URL")
101 #define URL_LONGTEXT N_( \
102     "This allows you to give an URL with more details about the stream " \
103     "(often the website of the streaming organization), that will " \
104     "be announced in the SDP (Session Descriptor)." )
105 #define EMAIL_TEXT N_("Session email")
106 #define EMAIL_LONGTEXT N_( \
107     "This allows you to give a contact mail address for the stream, that will " \
108     "be announced in the SDP (Session Descriptor)." )
109 #define PHONE_TEXT N_("Session phone number")
110 #define PHONE_LONGTEXT N_( \
111     "This allows you to give a contact telephone number for the stream, that will " \
112     "be announced in the SDP (Session Descriptor)." )
113
114 #define PORT_TEXT N_("Port")
115 #define PORT_LONGTEXT N_( \
116     "This allows you to specify the base port for the RTP streaming." )
117 #define PORT_AUDIO_TEXT N_("Audio port")
118 #define PORT_AUDIO_LONGTEXT N_( \
119     "This allows you to specify the default audio port for the RTP streaming." )
120 #define PORT_VIDEO_TEXT N_("Video port")
121 #define PORT_VIDEO_LONGTEXT N_( \
122     "This allows you to specify the default video port for the RTP streaming." )
123
124 #define TTL_TEXT N_("Hop limit (TTL)")
125 #define TTL_LONGTEXT N_( \
126     "This is the hop limit (also known as \"Time-To-Live\" or TTL) of " \
127     "the multicast packets sent by the stream output (-1 = use operating " \
128     "system built-in default).")
129
130 #define RTCP_MUX_TEXT N_("RTP/RTCP multiplexing")
131 #define RTCP_MUX_LONGTEXT N_( \
132     "This sends and receives RTCP packet multiplexed over the same port " \
133     "as RTP packets." )
134
135 #define CACHING_TEXT N_("Caching value (ms)")
136 #define CACHING_LONGTEXT N_( \
137     "Default caching value for outbound RTP streams. This " \
138     "value should be set in milliseconds." )
139
140 #define PROTO_TEXT N_("Transport protocol")
141 #define PROTO_LONGTEXT N_( \
142     "This selects which transport protocol to use for RTP." )
143
144 #define SRTP_KEY_TEXT N_("SRTP key (hexadecimal)")
145 #define SRTP_KEY_LONGTEXT N_( \
146     "RTP packets will be integrity-protected and ciphered "\
147     "with this Secure RTP master shared secret key.")
148
149 #define SRTP_SALT_TEXT N_("SRTP salt (hexadecimal)")
150 #define SRTP_SALT_LONGTEXT N_( \
151     "Secure RTP requires a (non-secret) master salt value.")
152
153 static const char *const ppsz_protos[] = {
154     "dccp", "sctp", "tcp", "udp", "udplite",
155 };
156
157 static const char *const ppsz_protocols[] = {
158     "DCCP", "SCTP", "TCP", "UDP", "UDP-Lite",
159 };
160
161 #define RFC3016_TEXT N_("MP4A LATM")
162 #define RFC3016_LONGTEXT N_( \
163     "This allows you to stream MPEG4 LATM audio streams (see RFC3016)." )
164
165 static int  Open ( vlc_object_t * );
166 static void Close( vlc_object_t * );
167
168 #define SOUT_CFG_PREFIX "sout-rtp-"
169 #define MAX_EMPTY_BLOCKS 200
170
171 vlc_module_begin ()
172     set_shortname( N_("RTP"))
173     set_description( N_("RTP stream output") )
174     set_capability( "sout stream", 0 )
175     add_shortcut( "rtp" )
176     set_category( CAT_SOUT )
177     set_subcategory( SUBCAT_SOUT_STREAM )
178
179     add_string( SOUT_CFG_PREFIX "dst", "", NULL, DEST_TEXT,
180                 DEST_LONGTEXT, true )
181     add_string( SOUT_CFG_PREFIX "sdp", "", NULL, SDP_TEXT,
182                 SDP_LONGTEXT, true )
183     add_string( SOUT_CFG_PREFIX "mux", "", NULL, MUX_TEXT,
184                 MUX_LONGTEXT, true )
185     add_bool( SOUT_CFG_PREFIX "sap", false, NULL, SAP_TEXT, SAP_LONGTEXT,
186               true )
187
188     add_string( SOUT_CFG_PREFIX "name", "", NULL, NAME_TEXT,
189                 NAME_LONGTEXT, true )
190     add_string( SOUT_CFG_PREFIX "description", "", NULL, DESC_TEXT,
191                 DESC_LONGTEXT, true )
192     add_string( SOUT_CFG_PREFIX "url", "", NULL, URL_TEXT,
193                 URL_LONGTEXT, true )
194     add_string( SOUT_CFG_PREFIX "email", "", NULL, EMAIL_TEXT,
195                 EMAIL_LONGTEXT, true )
196     add_string( SOUT_CFG_PREFIX "phone", "", NULL, PHONE_TEXT,
197                 PHONE_LONGTEXT, true )
198
199     add_string( SOUT_CFG_PREFIX "proto", "udp", NULL, PROTO_TEXT,
200                 PROTO_LONGTEXT, false )
201         change_string_list( ppsz_protos, ppsz_protocols, NULL )
202     add_integer( SOUT_CFG_PREFIX "port", 5004, NULL, PORT_TEXT,
203                  PORT_LONGTEXT, true )
204     add_integer( SOUT_CFG_PREFIX "port-audio", 0, NULL, PORT_AUDIO_TEXT,
205                  PORT_AUDIO_LONGTEXT, true )
206     add_integer( SOUT_CFG_PREFIX "port-video", 0, NULL, PORT_VIDEO_TEXT,
207                  PORT_VIDEO_LONGTEXT, true )
208
209     add_integer( SOUT_CFG_PREFIX "ttl", -1, NULL, TTL_TEXT,
210                  TTL_LONGTEXT, true )
211     add_bool( SOUT_CFG_PREFIX "rtcp-mux", false, NULL,
212               RTCP_MUX_TEXT, RTCP_MUX_LONGTEXT, false )
213     add_integer( SOUT_CFG_PREFIX "caching", DEFAULT_PTS_DELAY / 1000, NULL,
214                  CACHING_TEXT, CACHING_LONGTEXT, true )
215
216 #ifdef HAVE_SRTP
217     add_string( SOUT_CFG_PREFIX "key", "", NULL,
218                 SRTP_KEY_TEXT, SRTP_KEY_LONGTEXT, false )
219     add_string( SOUT_CFG_PREFIX "salt", "", NULL,
220                 SRTP_SALT_TEXT, SRTP_SALT_LONGTEXT, false )
221 #endif
222
223     add_bool( SOUT_CFG_PREFIX "mp4a-latm", false, NULL, RFC3016_TEXT,
224                  RFC3016_LONGTEXT, false )
225
226     set_callbacks( Open, Close )
227 vlc_module_end ()
228
229 /*****************************************************************************
230  * Exported prototypes
231  *****************************************************************************/
232 static const char *const ppsz_sout_options[] = {
233     "dst", "name", "port", "port-audio", "port-video", "*sdp", "ttl", "mux",
234     "sap", "description", "url", "email", "phone",
235     "proto", "rtcp-mux", "caching", "key", "salt",
236     "mp4a-latm", NULL
237 };
238
239 static sout_stream_id_t *Add ( sout_stream_t *, es_format_t * );
240 static int               Del ( sout_stream_t *, sout_stream_id_t * );
241 static int               Send( sout_stream_t *, sout_stream_id_t *,
242                                block_t* );
243 static sout_stream_id_t *MuxAdd ( sout_stream_t *, es_format_t * );
244 static int               MuxDel ( sout_stream_t *, sout_stream_id_t * );
245 static int               MuxSend( sout_stream_t *, sout_stream_id_t *,
246                                   block_t* );
247
248 static sout_access_out_t *GrabberCreate( sout_stream_t *p_sout );
249 static void* ThreadSend( vlc_object_t *p_this );
250 static void *rtp_listen_thread( void * );
251
252 static void SDPHandleUrl( sout_stream_t *, const char * );
253
254 static int SapSetup( sout_stream_t *p_stream );
255 static int FileSetup( sout_stream_t *p_stream );
256 static int HttpSetup( sout_stream_t *p_stream, const vlc_url_t * );
257
258 struct sout_stream_sys_t
259 {
260     /* SDP */
261     char    *psz_sdp;
262     vlc_mutex_t  lock_sdp;
263
264     /* SDP to disk */
265     char *psz_sdp_file;
266
267     /* SDP via SAP */
268     bool b_export_sap;
269     session_descriptor_t *p_session;
270
271     /* SDP via HTTP */
272     httpd_host_t *p_httpd_host;
273     httpd_file_t *p_httpd_file;
274
275     /* RTSP */
276     rtsp_stream_t *rtsp;
277
278     /* */
279     char     *psz_destination;
280     uint32_t  payload_bitmap;
281     uint16_t  i_port;
282     uint16_t  i_port_audio;
283     uint16_t  i_port_video;
284     uint8_t   proto;
285     bool      rtcp_mux;
286     int       i_ttl:9;
287     bool      b_latm;
288
289     /* in case we do TS/PS over rtp */
290     sout_mux_t        *p_mux;
291     sout_access_out_t *p_grab;
292     block_t           *packet;
293
294     /* */
295     vlc_mutex_t      lock_es;
296     int              i_es;
297     sout_stream_id_t **es;
298 };
299
300 typedef int (*pf_rtp_packetizer_t)( sout_stream_id_t *, block_t * );
301
302 typedef struct rtp_sink_t
303 {
304     int rtp_fd;
305     rtcp_sender_t *rtcp;
306 } rtp_sink_t;
307
308 struct sout_stream_id_t
309 {
310     VLC_COMMON_MEMBERS
311
312     sout_stream_t *p_stream;
313     /* rtp field */
314     uint16_t    i_sequence;
315     uint8_t     i_payload_type;
316     uint8_t     ssrc[4];
317
318     /* for rtsp */
319     uint16_t    i_seq_sent_next;
320
321     /* for sdp */
322     const char  *psz_enc;
323     char        *psz_fmtp;
324     int          i_clock_rate;
325     int          i_port;
326     int          i_cat;
327     int          i_channels;
328     int          i_bitrate;
329
330     /* Packetizer specific fields */
331     int                 i_mtu;
332 #ifdef HAVE_SRTP
333     srtp_session_t     *srtp;
334 #endif
335     pf_rtp_packetizer_t pf_packetize;
336
337     /* Packets sinks */
338     vlc_mutex_t       lock_sink;
339     int               sinkc;
340     rtp_sink_t       *sinkv;
341     rtsp_stream_id_t *rtsp_id;
342     struct {
343         int          *fd;
344         vlc_thread_t  thread;
345     } listen;
346
347     block_fifo_t     *p_fifo;
348     int64_t           i_caching;
349 };
350
351 /*****************************************************************************
352  * Open:
353  *****************************************************************************/
354 static int Open( vlc_object_t *p_this )
355 {
356     sout_stream_t       *p_stream = (sout_stream_t*)p_this;
357     sout_instance_t     *p_sout = p_stream->p_sout;
358     sout_stream_sys_t   *p_sys = NULL;
359     config_chain_t      *p_cfg = NULL;
360     char                *psz;
361     bool          b_rtsp = false;
362
363     config_ChainParse( p_stream, SOUT_CFG_PREFIX,
364                        ppsz_sout_options, p_stream->p_cfg );
365
366     p_sys = malloc( sizeof( sout_stream_sys_t ) );
367     if( p_sys == NULL )
368         return VLC_ENOMEM;
369
370     p_sys->psz_destination = var_GetNonEmptyString( p_stream, SOUT_CFG_PREFIX "dst" );
371
372     p_sys->i_port       = var_GetInteger( p_stream, SOUT_CFG_PREFIX "port" );
373     p_sys->i_port_audio = var_GetInteger( p_stream, SOUT_CFG_PREFIX "port-audio" );
374     p_sys->i_port_video = var_GetInteger( p_stream, SOUT_CFG_PREFIX "port-video" );
375     p_sys->rtcp_mux     = var_GetBool( p_stream, SOUT_CFG_PREFIX "rtcp-mux" );
376
377     if( p_sys->i_port_audio && p_sys->i_port_video == p_sys->i_port_audio )
378     {
379         msg_Err( p_stream, "audio and video RTP port must be distinct" );
380         free( p_sys->psz_destination );
381         free( p_sys );
382         return VLC_EGENERIC;
383     }
384
385     for( p_cfg = p_stream->p_cfg; p_cfg != NULL; p_cfg = p_cfg->p_next )
386     {
387         if( !strcmp( p_cfg->psz_name, "sdp" )
388          && ( p_cfg->psz_value != NULL )
389          && !strncasecmp( p_cfg->psz_value, "rtsp:", 5 ) )
390         {
391             b_rtsp = true;
392             break;
393         }
394     }
395     if( !b_rtsp )
396     {
397         psz = var_GetNonEmptyString( p_stream, SOUT_CFG_PREFIX "sdp" );
398         if( psz != NULL )
399         {
400             if( !strncasecmp( psz, "rtsp:", 5 ) )
401                 b_rtsp = true;
402             free( psz );
403         }
404     }
405
406     /* Transport protocol */
407     p_sys->proto = IPPROTO_UDP;
408     psz = var_GetNonEmptyString (p_stream, SOUT_CFG_PREFIX"proto");
409
410     if ((psz == NULL) || !strcasecmp (psz, "udp"))
411         (void)0; /* default */
412     else
413     if (!strcasecmp (psz, "dccp"))
414     {
415         p_sys->proto = IPPROTO_DCCP;
416         p_sys->rtcp_mux = true; /* Force RTP/RTCP mux */
417     }
418 #if 0
419     else
420     if (!strcasecmp (psz, "sctp"))
421     {
422         p_sys->proto = IPPROTO_TCP;
423         p_sys->rtcp_mux = true; /* Force RTP/RTCP mux */
424     }
425 #endif
426 #if 0
427     else
428     if (!strcasecmp (psz, "tcp"))
429     {
430         p_sys->proto = IPPROTO_TCP;
431         p_sys->rtcp_mux = true; /* Force RTP/RTCP mux */
432     }
433 #endif
434     else
435     if (!strcasecmp (psz, "udplite") || !strcasecmp (psz, "udp-lite"))
436         p_sys->proto = IPPROTO_UDPLITE;
437     else
438         msg_Warn (p_this, "unknown or unsupported transport protocol \"%s\"",
439                   psz);
440     free (psz);
441     var_Create (p_this, "dccp-service", VLC_VAR_STRING);
442
443     if( ( p_sys->psz_destination == NULL ) && !b_rtsp )
444     {
445         msg_Err( p_stream, "missing destination and not in RTSP mode" );
446         free( p_sys );
447         return VLC_EGENERIC;
448     }
449
450     p_sys->i_ttl = var_GetInteger( p_stream, SOUT_CFG_PREFIX "ttl" );
451     if( p_sys->i_ttl == -1 )
452     {
453         /* Normally, we should let the default hop limit up to the core,
454          * but we have to know it to build our SDP properly, which is why
455          * we ask the core. FIXME: broken when neither sout-rtp-ttl nor
456          * ttl are set. */
457         p_sys->i_ttl = config_GetInt( p_stream, "ttl" );
458     }
459
460     p_sys->b_latm = var_GetBool( p_stream, SOUT_CFG_PREFIX "mp4a-latm" );
461
462     p_sys->payload_bitmap = 0;
463     p_sys->i_es = 0;
464     p_sys->es   = NULL;
465     p_sys->rtsp = NULL;
466     p_sys->psz_sdp = NULL;
467
468     p_sys->b_export_sap = false;
469     p_sys->p_session = NULL;
470     p_sys->psz_sdp_file = NULL;
471
472     p_sys->p_httpd_host = NULL;
473     p_sys->p_httpd_file = NULL;
474
475     p_stream->p_sys     = p_sys;
476
477     vlc_mutex_init( &p_sys->lock_sdp );
478     vlc_mutex_init( &p_sys->lock_es );
479
480     psz = var_GetNonEmptyString( p_stream, SOUT_CFG_PREFIX "mux" );
481     if( psz != NULL )
482     {
483         sout_stream_id_t *id;
484
485         /* Check muxer type */
486         if( strncasecmp( psz, "ps", 2 )
487          && strncasecmp( psz, "mpeg1", 5 )
488          && strncasecmp( psz, "ts", 2 ) )
489         {
490             msg_Err( p_stream, "unsupported muxer type for RTP (only TS/PS)" );
491             free( psz );
492             vlc_mutex_destroy( &p_sys->lock_sdp );
493             vlc_mutex_destroy( &p_sys->lock_es );
494             free( p_sys->psz_destination );
495             free( p_sys );
496             return VLC_EGENERIC;
497         }
498
499         p_sys->p_grab = GrabberCreate( p_stream );
500         p_sys->p_mux = sout_MuxNew( p_sout, psz, p_sys->p_grab );
501         free( psz );
502
503         if( p_sys->p_mux == NULL )
504         {
505             msg_Err( p_stream, "cannot create muxer" );
506             sout_AccessOutDelete( p_sys->p_grab );
507             vlc_mutex_destroy( &p_sys->lock_sdp );
508             vlc_mutex_destroy( &p_sys->lock_es );
509             free( p_sys->psz_destination );
510             free( p_sys );
511             return VLC_EGENERIC;
512         }
513
514         id = Add( p_stream, NULL );
515         if( id == NULL )
516         {
517             sout_MuxDelete( p_sys->p_mux );
518             sout_AccessOutDelete( p_sys->p_grab );
519             vlc_mutex_destroy( &p_sys->lock_sdp );
520             vlc_mutex_destroy( &p_sys->lock_es );
521             free( p_sys->psz_destination );
522             free( p_sys );
523             return VLC_EGENERIC;
524         }
525
526         p_sys->packet = NULL;
527
528         p_stream->pf_add  = MuxAdd;
529         p_stream->pf_del  = MuxDel;
530         p_stream->pf_send = MuxSend;
531     }
532     else
533     {
534         p_sys->p_mux    = NULL;
535         p_sys->p_grab   = NULL;
536
537         p_stream->pf_add    = Add;
538         p_stream->pf_del    = Del;
539         p_stream->pf_send   = Send;
540     }
541
542     if( var_GetBool( p_stream, SOUT_CFG_PREFIX"sap" ) )
543         SDPHandleUrl( p_stream, "sap" );
544
545     psz = var_GetNonEmptyString( p_stream, SOUT_CFG_PREFIX "sdp" );
546     if( psz != NULL )
547     {
548         config_chain_t *p_cfg;
549
550         SDPHandleUrl( p_stream, psz );
551
552         for( p_cfg = p_stream->p_cfg; p_cfg != NULL; p_cfg = p_cfg->p_next )
553         {
554             if( !strcmp( p_cfg->psz_name, "sdp" ) )
555             {
556                 if( p_cfg->psz_value == NULL || *p_cfg->psz_value == '\0' )
557                     continue;
558
559                 /* needed both :sout-rtp-sdp= and rtp{sdp=} can be used */
560                 if( !strcmp( p_cfg->psz_value, psz ) )
561                     continue;
562
563                 SDPHandleUrl( p_stream, p_cfg->psz_value );
564             }
565         }
566         free( psz );
567     }
568
569     /* update p_sout->i_out_pace_nocontrol */
570     p_stream->p_sout->i_out_pace_nocontrol++;
571
572     return VLC_SUCCESS;
573 }
574
575 /*****************************************************************************
576  * Close:
577  *****************************************************************************/
578 static void Close( vlc_object_t * p_this )
579 {
580     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
581     sout_stream_sys_t *p_sys = p_stream->p_sys;
582
583     /* update p_sout->i_out_pace_nocontrol */
584     p_stream->p_sout->i_out_pace_nocontrol--;
585
586     if( p_sys->p_mux )
587     {
588         assert( p_sys->i_es == 1 );
589
590         sout_MuxDelete( p_sys->p_mux );
591         Del( p_stream, p_sys->es[0] );
592         sout_AccessOutDelete( p_sys->p_grab );
593
594         if( p_sys->packet )
595         {
596             block_Release( p_sys->packet );
597         }
598         if( p_sys->b_export_sap )
599         {
600             p_sys->p_mux = NULL;
601             SapSetup( p_stream );
602         }
603     }
604
605     if( p_sys->rtsp != NULL )
606         RtspUnsetup( p_sys->rtsp );
607
608     vlc_mutex_destroy( &p_sys->lock_sdp );
609     vlc_mutex_destroy( &p_sys->lock_es );
610
611     if( p_sys->p_httpd_file )
612         httpd_FileDelete( p_sys->p_httpd_file );
613
614     if( p_sys->p_httpd_host )
615         httpd_HostDelete( p_sys->p_httpd_host );
616
617     free( p_sys->psz_sdp );
618
619     if( p_sys->psz_sdp_file != NULL )
620     {
621 #ifdef HAVE_UNISTD_H
622         unlink( p_sys->psz_sdp_file );
623 #endif
624         free( p_sys->psz_sdp_file );
625     }
626     free( p_sys->psz_destination );
627     free( p_sys );
628 }
629
630 /*****************************************************************************
631  * SDPHandleUrl:
632  *****************************************************************************/
633 static void SDPHandleUrl( sout_stream_t *p_stream, const char *psz_url )
634 {
635     sout_stream_sys_t *p_sys = p_stream->p_sys;
636     vlc_url_t url;
637
638     vlc_UrlParse( &url, psz_url, 0 );
639     if( url.psz_protocol && !strcasecmp( url.psz_protocol, "http" ) )
640     {
641         if( p_sys->p_httpd_file )
642         {
643             msg_Err( p_stream, "you can use sdp=http:// only once" );
644             goto out;
645         }
646
647         if( HttpSetup( p_stream, &url ) )
648         {
649             msg_Err( p_stream, "cannot export SDP as HTTP" );
650         }
651     }
652     else if( url.psz_protocol && !strcasecmp( url.psz_protocol, "rtsp" ) )
653     {
654         if( p_sys->rtsp != NULL )
655         {
656             msg_Err( p_stream, "you can use sdp=rtsp:// only once" );
657             goto out;
658         }
659
660         /* FIXME test if destination is multicast or no destination at all */
661         p_sys->rtsp = RtspSetup( p_stream, &url );
662         if( p_sys->rtsp == NULL )
663             msg_Err( p_stream, "cannot export SDP as RTSP" );
664         else
665         if( p_sys->p_mux != NULL )
666         {
667             sout_stream_id_t *id = p_sys->es[0];
668             id->rtsp_id = RtspAddId( p_sys->rtsp, id, 0, GetDWBE( id->ssrc ),
669                                      p_sys->psz_destination, p_sys->i_ttl,
670                                      id->i_port, id->i_port + 1 );
671         }
672     }
673     else if( ( url.psz_protocol && !strcasecmp( url.psz_protocol, "sap" ) ) ||
674              ( url.psz_host && !strcasecmp( url.psz_host, "sap" ) ) )
675     {
676         p_sys->b_export_sap = true;
677         SapSetup( p_stream );
678     }
679     else if( url.psz_protocol && !strcasecmp( url.psz_protocol, "file" ) )
680     {
681         if( p_sys->psz_sdp_file != NULL )
682         {
683             msg_Err( p_stream, "you can use sdp=file:// only once" );
684             goto out;
685         }
686         psz_url = &psz_url[5];
687         if( psz_url[0] == '/' && psz_url[1] == '/' )
688             psz_url += 2;
689         p_sys->psz_sdp_file = strdup( psz_url );
690         if( p_sys->psz_sdp_file == NULL )
691             goto out;
692         decode_URI( p_sys->psz_sdp_file ); /* FIXME? */
693         FileSetup( p_stream );
694     }
695     else
696     {
697         msg_Warn( p_stream, "unknown protocol for SDP (%s)",
698                   url.psz_protocol );
699     }
700
701 out:
702     vlc_UrlClean( &url );
703 }
704
705 /*****************************************************************************
706  * SDPGenerate
707  *****************************************************************************/
708 /*static*/
709 char *SDPGenerate( const sout_stream_t *p_stream, const char *rtsp_url )
710 {
711     const sout_stream_sys_t *p_sys = p_stream->p_sys;
712     char *psz_sdp;
713     struct sockaddr_storage dst;
714     socklen_t dstlen;
715     int i;
716     /*
717      * When we have a fixed destination (typically when we do multicast),
718      * we need to put the actual port numbers in the SDP.
719      * When there is no fixed destination, we only support RTSP unicast
720      * on-demand setup, so we should rather let the clients decide which ports
721      * to use.
722      * When there is both a fixed destination and RTSP unicast, we need to
723      * put port numbers used by the fixed destination, otherwise the SDP would
724      * become totally incorrect for multicast use. It should be noted that
725      * port numbers from SDP with RTSP are only "recommendation" from the
726      * server to the clients (per RFC2326), so only broken clients will fail
727      * to handle this properly. There is no solution but to use two differents
728      * output chain with two different RTSP URLs if you need to handle this
729      * scenario.
730      */
731     int inclport;
732
733     if( p_sys->psz_destination != NULL )
734     {
735         inclport = 1;
736
737         /* Oh boy, this is really ugly! (+ race condition on lock_es) */
738         dstlen = sizeof( dst );
739         if( p_sys->es[0]->listen.fd != NULL )
740             getsockname( p_sys->es[0]->listen.fd[0],
741                          (struct sockaddr *)&dst, &dstlen );
742         else
743             getpeername( p_sys->es[0]->sinkv[0].rtp_fd,
744                          (struct sockaddr *)&dst, &dstlen );
745     }
746     else
747     {
748         inclport = 0;
749
750         /* Dummy destination address for RTSP */
751         memset (&dst, 0, sizeof( struct sockaddr_in ) );
752         dst.ss_family = AF_INET;
753 #ifdef HAVE_SA_LEN
754         dst.ss_len =
755 #endif
756         dstlen = sizeof( struct sockaddr_in );
757     }
758
759     psz_sdp = vlc_sdp_Start( VLC_OBJECT( p_stream ), SOUT_CFG_PREFIX,
760                              NULL, 0, (struct sockaddr *)&dst, dstlen );
761     if( psz_sdp == NULL )
762         return NULL;
763
764     /* TODO: a=source-filter */
765     if( p_sys->rtcp_mux )
766         sdp_AddAttribute( &psz_sdp, "rtcp-mux", NULL );
767
768     if( rtsp_url != NULL )
769         sdp_AddAttribute ( &psz_sdp, "control", "%s", rtsp_url );
770
771     /* FIXME: locking?! */
772     for( i = 0; i < p_sys->i_es; i++ )
773     {
774         sout_stream_id_t *id = p_sys->es[i];
775         const char *mime_major; /* major MIME type */
776         const char *proto = "RTP/AVP"; /* protocol */
777
778         switch( id->i_cat )
779         {
780             case VIDEO_ES:
781                 mime_major = "video";
782                 break;
783             case AUDIO_ES:
784                 mime_major = "audio";
785                 break;
786             case SPU_ES:
787                 mime_major = "text";
788                 break;
789             default:
790                 continue;
791         }
792
793         if( rtsp_url == NULL )
794         {
795             switch( p_sys->proto )
796             {
797                 case IPPROTO_UDP:
798                     break;
799                 case IPPROTO_TCP:
800                     proto = "TCP/RTP/AVP";
801                     break;
802                 case IPPROTO_DCCP:
803                     proto = "DCCP/RTP/AVP";
804                     break;
805                 case IPPROTO_UDPLITE:
806                     continue;
807             }
808         }
809
810         sdp_AddMedia( &psz_sdp, mime_major, proto, inclport * id->i_port,
811                       id->i_payload_type, false, id->i_bitrate,
812                       id->psz_enc, id->i_clock_rate, id->i_channels,
813                       id->psz_fmtp);
814
815         if( !p_sys->rtcp_mux && (id->i_port & 1) ) /* cf RFC4566 §5.14 */
816             sdp_AddAttribute ( &psz_sdp, "rtcp", "%u", id->i_port + 1 );
817
818         if( rtsp_url != NULL )
819         {
820             assert( strlen( rtsp_url ) > 0 );
821             bool addslash = ( rtsp_url[strlen( rtsp_url ) - 1] != '/' );
822             sdp_AddAttribute ( &psz_sdp, "control",
823                                addslash ? "%s/trackID=%u" : "%strackID=%u",
824                                rtsp_url, i );
825         }
826         else
827         {
828             if( id->listen.fd != NULL )
829                 sdp_AddAttribute( &psz_sdp, "setup", "passive" );
830             if( p_sys->proto == IPPROTO_DCCP )
831                 sdp_AddAttribute( &psz_sdp, "dccp-service-code",
832                                   "SC:RTP%c", toupper( mime_major[0] ) );
833         }
834     }
835
836     return psz_sdp;
837 }
838
839 /*****************************************************************************
840  * RTP mux
841  *****************************************************************************/
842
843 static void sprintf_hexa( char *s, uint8_t *p_data, int i_data )
844 {
845     static const char hex[16] = "0123456789abcdef";
846     int i;
847
848     for( i = 0; i < i_data; i++ )
849     {
850         s[2*i+0] = hex[(p_data[i]>>4)&0xf];
851         s[2*i+1] = hex[(p_data[i]   )&0xf];
852     }
853     s[2*i_data] = '\0';
854 }
855
856 /**
857  * Shrink the MTU down to a fixed packetization time (for audio).
858  */
859 static void
860 rtp_set_ptime (sout_stream_id_t *id, unsigned ptime_ms, size_t bytes)
861 {
862     /* Samples per second */
863     size_t spl = (id->i_clock_rate - 1) * ptime_ms / 1000 + 1;
864     bytes *= id->i_channels;
865     spl *= bytes;
866
867     if (spl < rtp_mtu (id)) /* MTU is big enough for ptime */
868         id->i_mtu = 12 + spl;
869     else /* MTU is too small for ptime, align to a sample boundary */
870         id->i_mtu = 12 + (((id->i_mtu - 12) / bytes) * bytes);
871 }
872
873 /** Add an ES as a new RTP stream */
874 static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
875 {
876     /* NOTE: As a special case, if we use a non-RTP
877      * mux (TS/PS), then p_fmt is NULL. */
878     sout_stream_sys_t *p_sys = p_stream->p_sys;
879     sout_stream_id_t  *id;
880     char              *psz_sdp;
881
882     if (0xffffffff == p_sys->payload_bitmap)
883     {
884         msg_Err (p_stream, "too many RTP elementary streams");
885         return NULL;
886     }
887
888     /* Choose the port */
889     uint16_t i_port = 0;
890     if( p_fmt == NULL )
891         ;
892     else
893     if( p_fmt->i_cat == AUDIO_ES && p_sys->i_port_audio > 0 )
894         i_port = p_sys->i_port_audio;
895     else
896     if( p_fmt->i_cat == VIDEO_ES && p_sys->i_port_video > 0 )
897         i_port = p_sys->i_port_video;
898
899     /* We do not need the ES lock (p_sys->lock_es) here, because this is the
900      * only one thread that can *modify* the ES table. The ES lock protects
901      * the other threads from our modifications (TAB_APPEND, TAB_REMOVE). */
902     for (int i = 0; i_port && (i < p_sys->i_es); i++)
903          if (i_port == p_sys->es[i]->i_port)
904              i_port = 0; /* Port already in use! */
905     for (uint16_t p = p_sys->i_port; i_port == 0; p += 2)
906     {
907         if (p == 0)
908         {
909             msg_Err (p_stream, "too many RTP elementary streams");
910             return NULL;
911         }
912         i_port = p;
913         for (int i = 0; i_port && (i < p_sys->i_es); i++)
914              if (p == p_sys->es[i]->i_port)
915                  i_port = 0;
916     }
917
918     id = vlc_object_create( p_stream, sizeof( sout_stream_id_t ) );
919     if( id == NULL )
920         return NULL;
921     vlc_object_attach( id, p_stream );
922
923     id->p_stream   = p_stream;
924
925     /* Look for free dymanic payload type */
926     id->i_payload_type = 96;
927     while (p_sys->payload_bitmap & (1 << (id->i_payload_type - 96)))
928         id->i_payload_type++;
929     assert (id->i_payload_type < 128);
930
931     vlc_rand_bytes (&id->i_sequence, sizeof (id->i_sequence));
932     vlc_rand_bytes (id->ssrc, sizeof (id->ssrc));
933
934     id->i_seq_sent_next = id->i_sequence;
935
936     id->psz_enc    = NULL;
937     id->psz_fmtp   = NULL;
938     id->i_clock_rate = 90000; /* most common case for video */
939     id->i_channels = 0;
940     id->i_port     = i_port;
941     if( p_fmt != NULL )
942     {
943         id->i_cat  = p_fmt->i_cat;
944         if( p_fmt->i_cat == AUDIO_ES )
945         {
946             id->i_clock_rate = p_fmt->audio.i_rate;
947             id->i_channels = p_fmt->audio.i_channels;
948         }
949         id->i_bitrate = p_fmt->i_bitrate/1000; /* Stream bitrate in kbps */
950     }
951     else
952     {
953         id->i_cat  = VIDEO_ES;
954         id->i_bitrate = 0;
955     }
956
957     id->i_mtu = config_GetInt( p_stream, "mtu" );
958     if( id->i_mtu <= 12 + 16 )
959         id->i_mtu = 576 - 20 - 8; /* pessimistic */
960     msg_Dbg( p_stream, "maximum RTP packet size: %d bytes", id->i_mtu );
961
962     id->pf_packetize = NULL;
963
964 #ifdef HAVE_SRTP
965     id->srtp = NULL;
966
967     char *key = var_CreateGetNonEmptyString (p_stream, SOUT_CFG_PREFIX"key");
968     if (key)
969     {
970         id->srtp = srtp_create (SRTP_ENCR_AES_CM, SRTP_AUTH_HMAC_SHA1, 10,
971                                    SRTP_PRF_AES_CM, SRTP_RCC_MODE1);
972         if (id->srtp == NULL)
973         {
974             free (key);
975             goto error;
976         }
977
978         char *salt = var_CreateGetNonEmptyString (p_stream, SOUT_CFG_PREFIX"salt");
979         errno = srtp_setkeystring (id->srtp, key, salt ? salt : "");
980         free (salt);
981         free (key);
982         if (errno)
983         {
984             msg_Err (p_stream, "bad SRTP key/salt combination (%m)");
985             goto error;
986         }
987         id->i_sequence = 0; /* FIXME: awful hack for libvlc_srtp */
988     }
989 #endif
990
991     vlc_mutex_init( &id->lock_sink );
992     id->sinkc = 0;
993     id->sinkv = NULL;
994     id->rtsp_id = NULL;
995     id->p_fifo = NULL;
996     id->listen.fd = NULL;
997
998     id->i_caching =
999         (int64_t)1000 * var_GetInteger( p_stream, SOUT_CFG_PREFIX "caching");
1000
1001     if( p_sys->psz_destination != NULL )
1002         switch( p_sys->proto )
1003         {
1004             case IPPROTO_DCCP:
1005             {
1006                 const char *code;
1007                 switch (id->i_cat)
1008                 {
1009                     case VIDEO_ES: code = "RTPV";     break;
1010                     case AUDIO_ES: code = "RTPARTPV"; break;
1011                     case SPU_ES:   code = "RTPTRTPV"; break;
1012                     default:       code = "RTPORTPV"; break;
1013                 }
1014                 var_SetString (p_stream, "dccp-service", code);
1015             }   /* fall through */
1016             case IPPROTO_TCP:
1017                 id->listen.fd = net_Listen( VLC_OBJECT(p_stream),
1018                                             p_sys->psz_destination, i_port,
1019                                             p_sys->proto );
1020                 if( id->listen.fd == NULL )
1021                 {
1022                     msg_Err( p_stream, "passive COMEDIA RTP socket failed" );
1023                     goto error;
1024                 }
1025                 if( vlc_clone( &id->listen.thread, rtp_listen_thread, id,
1026                                VLC_THREAD_PRIORITY_LOW ) )
1027                 {
1028                     net_ListenClose( id->listen.fd );
1029                     id->listen.fd = NULL;
1030                     goto error;
1031                 }
1032                 break;
1033
1034             default:
1035             {
1036                 int ttl = (p_sys->i_ttl >= 0) ? p_sys->i_ttl : -1;
1037                 int fd = net_ConnectDgram( p_stream, p_sys->psz_destination,
1038                                            i_port, ttl, p_sys->proto );
1039                 if( fd == -1 )
1040                 {
1041                     msg_Err( p_stream, "cannot create RTP socket" );
1042                     goto error;
1043                 }
1044                 /* Ignore any unexpected incoming packet (including RTCP-RR
1045                  * packets in case of rtcp-mux) */
1046                 setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &(int){ 0 },
1047                             sizeof (int));
1048                 rtp_add_sink( id, fd, p_sys->rtcp_mux, NULL );
1049             }
1050         }
1051
1052     if( p_fmt == NULL )
1053     {
1054         char *psz = var_GetNonEmptyString( p_stream, SOUT_CFG_PREFIX "mux" );
1055
1056         if( psz == NULL ) /* Uho! */
1057             ;
1058         else
1059         if( strncmp( psz, "ts", 2 ) == 0 )
1060         {
1061             id->i_payload_type = 33;
1062             id->psz_enc = "MP2T";
1063         }
1064         else
1065         {
1066             id->psz_enc = "MP2P";
1067         }
1068         free( psz );
1069     }
1070     else
1071     switch( p_fmt->i_codec )
1072     {
1073         case VLC_CODEC_MULAW:
1074             if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 8000 )
1075                 id->i_payload_type = 0;
1076             id->psz_enc = "PCMU";
1077             id->pf_packetize = rtp_packetize_split;
1078             rtp_set_ptime (id, 20, 1);
1079             break;
1080         case VLC_CODEC_ALAW:
1081             if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 8000 )
1082                 id->i_payload_type = 8;
1083             id->psz_enc = "PCMA";
1084             id->pf_packetize = rtp_packetize_split;
1085             rtp_set_ptime (id, 20, 1);
1086             break;
1087         case VLC_CODEC_S16B:
1088         case VLC_CODEC_S16L:
1089             if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 44100 )
1090             {
1091                 id->i_payload_type = 11;
1092             }
1093             else if( p_fmt->audio.i_channels == 2 &&
1094                      p_fmt->audio.i_rate == 44100 )
1095             {
1096                 id->i_payload_type = 10;
1097             }
1098             id->psz_enc = "L16";
1099             if( p_fmt->i_codec == VLC_CODEC_S16B )
1100                 id->pf_packetize = rtp_packetize_split;
1101             else
1102                 id->pf_packetize = rtp_packetize_swab;
1103             rtp_set_ptime (id, 20, 2);
1104             break;
1105         case VLC_CODEC_U8:
1106             id->psz_enc = "L8";
1107             id->pf_packetize = rtp_packetize_split;
1108             rtp_set_ptime (id, 20, 1);
1109             break;
1110         case VLC_CODEC_MPGA:
1111             id->i_payload_type = 14;
1112             id->psz_enc = "MPA";
1113             id->i_clock_rate = 90000; /* not 44100 */
1114             id->pf_packetize = rtp_packetize_mpa;
1115             break;
1116         case VLC_CODEC_MPGV:
1117             id->i_payload_type = 32;
1118             id->psz_enc = "MPV";
1119             id->pf_packetize = rtp_packetize_mpv;
1120             break;
1121         case VLC_CODEC_ADPCM_G726:
1122             switch( p_fmt->i_bitrate / 1000 )
1123             {
1124             case 16:
1125                 id->psz_enc = "G726-16";
1126                 id->pf_packetize = rtp_packetize_g726_16;
1127                 break;
1128             case 24:
1129                 id->psz_enc = "G726-24";
1130                 id->pf_packetize = rtp_packetize_g726_24;
1131                 break;
1132             case 32:
1133                 id->psz_enc = "G726-32";
1134                 id->pf_packetize = rtp_packetize_g726_32;
1135                 break;
1136             case 40:
1137                 id->psz_enc = "G726-40";
1138                 id->pf_packetize = rtp_packetize_g726_40;
1139                 break;
1140             default:
1141                 msg_Err( p_stream, "cannot add this stream (unsupported "
1142                          "G.726 bit rate: %u)", p_fmt->i_bitrate );
1143                 goto error;
1144             }
1145             break;
1146         case VLC_CODEC_A52:
1147             id->psz_enc = "ac3";
1148             id->pf_packetize = rtp_packetize_ac3;
1149             break;
1150         case VLC_CODEC_H263:
1151             id->psz_enc = "H263-1998";
1152             id->pf_packetize = rtp_packetize_h263;
1153             break;
1154         case VLC_CODEC_H264:
1155             id->psz_enc = "H264";
1156             id->pf_packetize = rtp_packetize_h264;
1157             id->psz_fmtp = NULL;
1158
1159             if( p_fmt->i_extra > 0 )
1160             {
1161                 uint8_t *p_buffer = p_fmt->p_extra;
1162                 int     i_buffer = p_fmt->i_extra;
1163                 char    *p_64_sps = NULL;
1164                 char    *p_64_pps = NULL;
1165                 char    hexa[6+1];
1166
1167                 while( i_buffer > 4 &&
1168                        p_buffer[0] == 0 && p_buffer[1] == 0 &&
1169                        p_buffer[2] == 0 && p_buffer[3] == 1 )
1170                 {
1171                     const int i_nal_type = p_buffer[4]&0x1f;
1172                     int i_offset;
1173                     int i_size      = 0;
1174
1175                     msg_Dbg( p_stream, "we found a startcode for NAL with TYPE:%d", i_nal_type );
1176
1177                     i_size = i_buffer;
1178                     for( i_offset = 4; i_offset+3 < i_buffer ; i_offset++)
1179                     {
1180                         if( !memcmp (p_buffer + i_offset, "\x00\x00\x00\x01", 4 ) )
1181                         {
1182                             /* we found another startcode */
1183                             i_size = i_offset;
1184                             break;
1185                         }
1186                     }
1187                     if( i_nal_type == 7 )
1188                     {
1189                         p_64_sps = vlc_b64_encode_binary( &p_buffer[4], i_size - 4 );
1190                         sprintf_hexa( hexa, &p_buffer[5], 3 );
1191                     }
1192                     else if( i_nal_type == 8 )
1193                     {
1194                         p_64_pps = vlc_b64_encode_binary( &p_buffer[4], i_size - 4 );
1195                     }
1196                     i_buffer -= i_size;
1197                     p_buffer += i_size;
1198                 }
1199                 /* */
1200                 if( p_64_sps && p_64_pps &&
1201                     ( asprintf( &id->psz_fmtp,
1202                                 "packetization-mode=1;profile-level-id=%s;"
1203                                 "sprop-parameter-sets=%s,%s;", hexa, p_64_sps,
1204                                 p_64_pps ) == -1 ) )
1205                     id->psz_fmtp = NULL;
1206                 free( p_64_sps );
1207                 free( p_64_pps );
1208             }
1209             if( !id->psz_fmtp )
1210                 id->psz_fmtp = strdup( "packetization-mode=1" );
1211             break;
1212
1213         case VLC_CODEC_MP4V:
1214         {
1215             char hexa[2*p_fmt->i_extra +1];
1216
1217             id->psz_enc = "MP4V-ES";
1218             id->pf_packetize = rtp_packetize_split;
1219             if( p_fmt->i_extra > 0 )
1220             {
1221                 sprintf_hexa( hexa, p_fmt->p_extra, p_fmt->i_extra );
1222                 if( asprintf( &id->psz_fmtp,
1223                               "profile-level-id=3; config=%s;", hexa ) == -1 )
1224                     id->psz_fmtp = NULL;
1225             }
1226             break;
1227         }
1228         case VLC_CODEC_MP4A:
1229         {
1230             if(!p_sys->b_latm)
1231             {
1232                 char hexa[2*p_fmt->i_extra +1];
1233
1234                 id->psz_enc = "mpeg4-generic";
1235                 id->pf_packetize = rtp_packetize_mp4a;
1236                 sprintf_hexa( hexa, p_fmt->p_extra, p_fmt->i_extra );
1237                 if( asprintf( &id->psz_fmtp,
1238                               "streamtype=5; profile-level-id=15; "
1239                               "mode=AAC-hbr; config=%s; SizeLength=13; "
1240                               "IndexLength=3; IndexDeltaLength=3; Profile=1;",
1241                               hexa ) == -1 )
1242                     id->psz_fmtp = NULL;
1243             }
1244             else
1245             {
1246                 char hexa[13];
1247                 int i;
1248                 unsigned char config[6];
1249                 unsigned int aacsrates[15] = {
1250                     96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
1251                     16000, 12000, 11025, 8000, 7350, 0, 0 };
1252
1253                 for( i = 0; i < 15; i++ )
1254                     if( p_fmt->audio.i_rate == aacsrates[i] )
1255                         break;
1256
1257                 config[0]=0x40;
1258                 config[1]=0;
1259                 config[2]=0x20|i;
1260                 config[3]=p_fmt->audio.i_channels<<4;
1261                 config[4]=0x3f;
1262                 config[5]=0xc0;
1263
1264                 id->psz_enc = "MP4A-LATM";
1265                 id->pf_packetize = rtp_packetize_mp4a_latm;
1266                 sprintf_hexa( hexa, config, 6 );
1267                 if( asprintf( &id->psz_fmtp, "profile-level-id=15; "
1268                               "object=2; cpresent=0; config=%s", hexa ) == -1 )
1269                     id->psz_fmtp = NULL;
1270             }
1271             break;
1272         }
1273         case VLC_CODEC_AMR_NB:
1274             id->psz_enc = "AMR";
1275             id->psz_fmtp = strdup( "octet-align=1" );
1276             id->pf_packetize = rtp_packetize_amr;
1277             break;
1278         case VLC_CODEC_AMR_WB:
1279             id->psz_enc = "AMR-WB";
1280             id->psz_fmtp = strdup( "octet-align=1" );
1281             id->pf_packetize = rtp_packetize_amr;
1282             break;
1283         case VLC_CODEC_SPEEX:
1284             id->psz_enc = "SPEEX";
1285             id->pf_packetize = rtp_packetize_spx;
1286             break;
1287         case VLC_CODEC_ITU_T140:
1288             id->psz_enc = "t140" ;
1289             id->i_clock_rate = 1000;
1290             id->pf_packetize = rtp_packetize_t140;
1291             break;
1292
1293         default:
1294             msg_Err( p_stream, "cannot add this stream (unsupported "
1295                      "codec: %4.4s)", (char*)&p_fmt->i_codec );
1296             goto error;
1297     }
1298     if (id->i_payload_type >= 96)
1299         /* Mark dynamic payload type in use */
1300         p_sys->payload_bitmap |= 1 << (id->i_payload_type - 96);
1301
1302 #if 0 /* No payload formats sets this at the moment */
1303     int cscov = -1;
1304     if( cscov != -1 )
1305         cscov += 8 /* UDP */ + 12 /* RTP */;
1306     if( id->sinkc > 0 )
1307         net_SetCSCov( id->sinkv[0].rtp_fd, cscov, -1 );
1308 #endif
1309
1310     if( p_sys->rtsp != NULL )
1311         id->rtsp_id = RtspAddId( p_sys->rtsp, id, p_sys->i_es,
1312                                  GetDWBE( id->ssrc ),
1313                                  p_sys->psz_destination,
1314                                  p_sys->i_ttl, id->i_port, id->i_port + 1 );
1315
1316     id->p_fifo = block_FifoNew();
1317     if( vlc_thread_create( id, "RTP send thread", ThreadSend,
1318                            VLC_THREAD_PRIORITY_HIGHEST ) )
1319         goto error;
1320
1321     /* Update p_sys context */
1322     vlc_mutex_lock( &p_sys->lock_es );
1323     TAB_APPEND( p_sys->i_es, p_sys->es, id );
1324     vlc_mutex_unlock( &p_sys->lock_es );
1325
1326     psz_sdp = SDPGenerate( p_stream, NULL );
1327
1328     vlc_mutex_lock( &p_sys->lock_sdp );
1329     free( p_sys->psz_sdp );
1330     p_sys->psz_sdp = psz_sdp;
1331     vlc_mutex_unlock( &p_sys->lock_sdp );
1332
1333     msg_Dbg( p_stream, "sdp=\n%s", p_sys->psz_sdp );
1334
1335     /* Update SDP (sap/file) */
1336     if( p_sys->b_export_sap ) SapSetup( p_stream );
1337     if( p_sys->psz_sdp_file != NULL ) FileSetup( p_stream );
1338
1339     return id;
1340
1341 error:
1342     Del( p_stream, id );
1343     return NULL;
1344 }
1345
1346 static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
1347 {
1348     sout_stream_sys_t *p_sys = p_stream->p_sys;
1349
1350     if( id->p_fifo != NULL )
1351     {
1352         vlc_object_kill( id );
1353         vlc_thread_join( id );
1354         block_FifoRelease( id->p_fifo );
1355     }
1356
1357     vlc_mutex_lock( &p_sys->lock_es );
1358     TAB_REMOVE( p_sys->i_es, p_sys->es, id );
1359     vlc_mutex_unlock( &p_sys->lock_es );
1360
1361     /* Release dynamic payload type */
1362     if (id->i_payload_type >= 96)
1363         p_sys->payload_bitmap &= ~(1 << (id->i_payload_type - 96));
1364
1365     free( id->psz_fmtp );
1366
1367     if( id->rtsp_id )
1368         RtspDelId( p_sys->rtsp, id->rtsp_id );
1369     if( id->sinkc > 0 )
1370         rtp_del_sink( id, id->sinkv[0].rtp_fd ); /* sink for explicit dst= */
1371     if( id->listen.fd != NULL )
1372     {
1373         vlc_cancel( id->listen.thread );
1374         vlc_join( id->listen.thread, NULL );
1375         net_ListenClose( id->listen.fd );
1376     }
1377 #ifdef HAVE_SRTP
1378     if( id->srtp != NULL )
1379         srtp_destroy( id->srtp );
1380 #endif
1381
1382     vlc_mutex_destroy( &id->lock_sink );
1383
1384     /* Update SDP (sap/file) */
1385     if( p_sys->b_export_sap && !p_sys->p_mux ) SapSetup( p_stream );
1386     if( p_sys->psz_sdp_file != NULL ) FileSetup( p_stream );
1387
1388     vlc_object_detach( id );
1389     vlc_object_release( id );
1390     return VLC_SUCCESS;
1391 }
1392
1393 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
1394                  block_t *p_buffer )
1395 {
1396     block_t *p_next;
1397
1398     assert( p_stream->p_sys->p_mux == NULL );
1399     (void)p_stream;
1400
1401     while( p_buffer != NULL )
1402     {
1403         p_next = p_buffer->p_next;
1404         if( id->pf_packetize( id, p_buffer ) )
1405             break;
1406
1407         block_Release( p_buffer );
1408         p_buffer = p_next;
1409     }
1410     return VLC_SUCCESS;
1411 }
1412
1413 /****************************************************************************
1414  * SAP:
1415  ****************************************************************************/
1416 static int SapSetup( sout_stream_t *p_stream )
1417 {
1418     sout_stream_sys_t *p_sys = p_stream->p_sys;
1419     sout_instance_t   *p_sout = p_stream->p_sout;
1420
1421     /* Remove the previous session */
1422     if( p_sys->p_session != NULL)
1423     {
1424         sout_AnnounceUnRegister( p_sout, p_sys->p_session);
1425         p_sys->p_session = NULL;
1426     }
1427
1428     if( ( p_sys->i_es > 0 || p_sys->p_mux ) && p_sys->psz_sdp && *p_sys->psz_sdp )
1429     {
1430         announce_method_t *p_method = sout_SAPMethod();
1431         p_sys->p_session = sout_AnnounceRegisterSDP( p_sout,
1432                                                      p_sys->psz_sdp,
1433                                                      p_sys->psz_destination,
1434                                                      p_method );
1435         sout_MethodRelease( p_method );
1436     }
1437
1438     return VLC_SUCCESS;
1439 }
1440
1441 /****************************************************************************
1442 * File:
1443 ****************************************************************************/
1444 static int FileSetup( sout_stream_t *p_stream )
1445 {
1446     sout_stream_sys_t *p_sys = p_stream->p_sys;
1447     FILE            *f;
1448
1449     if( p_sys->psz_sdp == NULL )
1450         return VLC_EGENERIC; /* too early */
1451
1452     if( ( f = utf8_fopen( p_sys->psz_sdp_file, "wt" ) ) == NULL )
1453     {
1454         msg_Err( p_stream, "cannot open file '%s' (%m)",
1455                  p_sys->psz_sdp_file );
1456         return VLC_EGENERIC;
1457     }
1458
1459     fputs( p_sys->psz_sdp, f );
1460     fclose( f );
1461
1462     return VLC_SUCCESS;
1463 }
1464
1465 /****************************************************************************
1466  * HTTP:
1467  ****************************************************************************/
1468 static int  HttpCallback( httpd_file_sys_t *p_args,
1469                           httpd_file_t *, uint8_t *p_request,
1470                           uint8_t **pp_data, int *pi_data );
1471
1472 static int HttpSetup( sout_stream_t *p_stream, const vlc_url_t *url)
1473 {
1474     sout_stream_sys_t *p_sys = p_stream->p_sys;
1475
1476     p_sys->p_httpd_host = httpd_HostNew( VLC_OBJECT(p_stream), url->psz_host,
1477                                          url->i_port > 0 ? url->i_port : 80 );
1478     if( p_sys->p_httpd_host )
1479     {
1480         p_sys->p_httpd_file = httpd_FileNew( p_sys->p_httpd_host,
1481                                              url->psz_path ? url->psz_path : "/",
1482                                              "application/sdp",
1483                                              NULL, NULL, NULL,
1484                                              HttpCallback, (void*)p_sys );
1485     }
1486     if( p_sys->p_httpd_file == NULL )
1487     {
1488         return VLC_EGENERIC;
1489     }
1490     return VLC_SUCCESS;
1491 }
1492
1493 static int  HttpCallback( httpd_file_sys_t *p_args,
1494                           httpd_file_t *f, uint8_t *p_request,
1495                           uint8_t **pp_data, int *pi_data )
1496 {
1497     VLC_UNUSED(f); VLC_UNUSED(p_request);
1498     sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_args;
1499
1500     vlc_mutex_lock( &p_sys->lock_sdp );
1501     if( p_sys->psz_sdp && *p_sys->psz_sdp )
1502     {
1503         *pi_data = strlen( p_sys->psz_sdp );
1504         *pp_data = malloc( *pi_data );
1505         memcpy( *pp_data, p_sys->psz_sdp, *pi_data );
1506     }
1507     else
1508     {
1509         *pp_data = NULL;
1510         *pi_data = 0;
1511     }
1512     vlc_mutex_unlock( &p_sys->lock_sdp );
1513
1514     return VLC_SUCCESS;
1515 }
1516
1517 /****************************************************************************
1518  * RTP send
1519  ****************************************************************************/
1520 static void* ThreadSend( vlc_object_t *p_this )
1521 {
1522 #ifdef WIN32
1523 # define ECONNREFUSED WSAECONNREFUSED
1524 # define ENOPROTOOPT  WSAENOPROTOOPT
1525 # define EHOSTUNREACH WSAEHOSTUNREACH
1526 # define ENETUNREACH  WSAENETUNREACH
1527 # define ENETDOWN     WSAENETDOWN
1528 # define ENOBUFS      WSAENOBUFS
1529 # define EAGAIN       WSAEWOULDBLOCK
1530 # define EWOULDBLOCK  WSAEWOULDBLOCK
1531 #endif
1532     sout_stream_id_t *id = (sout_stream_id_t *)p_this;
1533     unsigned i_caching = id->i_caching;
1534
1535     for (;;)
1536     {
1537         block_t *out = block_FifoGet( id->p_fifo );
1538         block_cleanup_push (out);
1539
1540 #ifdef HAVE_SRTP
1541         if( id->srtp )
1542         {   /* FIXME: this is awfully inefficient */
1543             size_t len = out->i_buffer;
1544             out = block_Realloc( out, 0, len + 10 );
1545             out->i_buffer = len;
1546
1547             int canc = vlc_savecancel ();
1548             int val = srtp_send( id->srtp, out->p_buffer, &len, len + 10 );
1549             vlc_restorecancel (canc);
1550             if( val )
1551             {
1552                 errno = val;
1553                 msg_Dbg( id, "SRTP sending error: %m" );
1554                 block_Release( out );
1555                 out = NULL;
1556             }
1557             else
1558                 out->i_buffer = len;
1559         }
1560         if (out)
1561 #endif
1562             mwait (out->i_dts + i_caching);
1563         vlc_cleanup_pop ();
1564         if (out == NULL)
1565             continue;
1566
1567         ssize_t len = out->i_buffer;
1568         int canc = vlc_savecancel ();
1569
1570         vlc_mutex_lock( &id->lock_sink );
1571         unsigned deadc = 0; /* How many dead sockets? */
1572         int deadv[id->sinkc]; /* Dead sockets list */
1573
1574         for( int i = 0; i < id->sinkc; i++ )
1575         {
1576 #ifdef HAVE_SRTP
1577             if( !id->srtp ) /* FIXME: SRTCP support */
1578 #endif
1579                 SendRTCP( id->sinkv[i].rtcp, out );
1580
1581             if( send( id->sinkv[i].rtp_fd, out->p_buffer, len, 0 ) >= 0 )
1582                 continue;
1583             switch( net_errno )
1584             {
1585                 /* Soft errors (e.g. ICMP): */
1586                 case ECONNREFUSED: /* Port unreachable */
1587                 case ENOPROTOOPT:
1588 #ifdef EPROTO
1589                 case EPROTO:       /* Protocol unreachable */
1590 #endif
1591                 case EHOSTUNREACH: /* Host unreachable */
1592                 case ENETUNREACH:  /* Network unreachable */
1593                 case ENETDOWN:     /* Entire network down */
1594                     send( id->sinkv[i].rtp_fd, out->p_buffer, len, 0 );
1595                 /* Transient congestion: */
1596                 case ENOMEM: /* out of socket buffers */
1597                 case ENOBUFS:
1598                 case EAGAIN:
1599 #if (EAGAIN != EWOULDBLOCK)
1600                 case EWOULDBLOCK:
1601 #endif
1602                     continue;
1603             }
1604
1605             deadv[deadc++] = id->sinkv[i].rtp_fd;
1606         }
1607         id->i_seq_sent_next = ntohs(((uint16_t *) out->p_buffer)[1]) + 1;
1608         vlc_mutex_unlock( &id->lock_sink );
1609         block_Release( out );
1610
1611         for( unsigned i = 0; i < deadc; i++ )
1612         {
1613             msg_Dbg( id, "removing socket %d", deadv[i] );
1614             rtp_del_sink( id, deadv[i] );
1615         }
1616         vlc_restorecancel (canc);
1617     }
1618     return NULL;
1619 }
1620
1621
1622 /* This thread dequeues incoming connections (DCCP streaming) */
1623 static void *rtp_listen_thread( void *data )
1624 {
1625     sout_stream_id_t *id = data;
1626
1627     assert( id->listen.fd != NULL );
1628
1629     for( ;; )
1630     {
1631         int fd = net_Accept( id, id->listen.fd );
1632         if( fd == -1 )
1633             continue;
1634         int canc = vlc_savecancel( );
1635         rtp_add_sink( id, fd, true, NULL );
1636         vlc_restorecancel( canc );
1637     }
1638
1639     assert( 0 );
1640 }
1641
1642
1643 int rtp_add_sink( sout_stream_id_t *id, int fd, bool rtcp_mux, uint16_t *seq )
1644 {
1645     rtp_sink_t sink = { fd, NULL };
1646     sink.rtcp = OpenRTCP( VLC_OBJECT( id->p_stream ), fd, IPPROTO_UDP,
1647                           rtcp_mux );
1648     if( sink.rtcp == NULL )
1649         msg_Err( id, "RTCP failed!" );
1650
1651     vlc_mutex_lock( &id->lock_sink );
1652     INSERT_ELEM( id->sinkv, id->sinkc, id->sinkc, sink );
1653     if( seq != NULL )
1654         *seq = id->i_seq_sent_next;
1655     vlc_mutex_unlock( &id->lock_sink );
1656     return VLC_SUCCESS;
1657 }
1658
1659 void rtp_del_sink( sout_stream_id_t *id, int fd )
1660 {
1661     rtp_sink_t sink = { fd, NULL };
1662
1663     /* NOTE: must be safe to use if fd is not included */
1664     vlc_mutex_lock( &id->lock_sink );
1665     for( int i = 0; i < id->sinkc; i++ )
1666     {
1667         if (id->sinkv[i].rtp_fd == fd)
1668         {
1669             sink = id->sinkv[i];
1670             REMOVE_ELEM( id->sinkv, id->sinkc, i );
1671             break;
1672         }
1673     }
1674     vlc_mutex_unlock( &id->lock_sink );
1675
1676     CloseRTCP( sink.rtcp );
1677     net_Close( sink.rtp_fd );
1678 }
1679
1680 uint16_t rtp_get_seq( sout_stream_id_t *id )
1681 {
1682     /* This will return values for the next packet. */
1683     uint16_t seq;
1684
1685     vlc_mutex_lock( &id->lock_sink );
1686     seq = id->i_seq_sent_next;
1687     vlc_mutex_unlock( &id->lock_sink );
1688
1689     return seq;
1690 }
1691
1692 /* FIXME: this is pretty bad - if we remove and then insert an ES
1693  * the number will get unsynched from inside RTSP */
1694 unsigned rtp_get_num( const sout_stream_id_t *id )
1695 {
1696     sout_stream_sys_t *p_sys = id->p_stream->p_sys;
1697     int i;
1698
1699     vlc_mutex_lock( &p_sys->lock_es );
1700     for( i = 0; i < p_sys->i_es; i++ )
1701     {
1702         if( id == p_sys->es[i] )
1703             break;
1704     }
1705     vlc_mutex_unlock( &p_sys->lock_es );
1706
1707     return i;
1708 }
1709
1710
1711 void rtp_packetize_common( sout_stream_id_t *id, block_t *out,
1712                            int b_marker, int64_t i_pts )
1713 {
1714     uint32_t i_timestamp = i_pts * (int64_t)id->i_clock_rate / CLOCK_FREQ;
1715
1716     out->p_buffer[0] = 0x80;
1717     out->p_buffer[1] = (b_marker?0x80:0x00)|id->i_payload_type;
1718     out->p_buffer[2] = ( id->i_sequence >> 8)&0xff;
1719     out->p_buffer[3] = ( id->i_sequence     )&0xff;
1720     out->p_buffer[4] = ( i_timestamp >> 24 )&0xff;
1721     out->p_buffer[5] = ( i_timestamp >> 16 )&0xff;
1722     out->p_buffer[6] = ( i_timestamp >>  8 )&0xff;
1723     out->p_buffer[7] = ( i_timestamp       )&0xff;
1724
1725     memcpy( out->p_buffer + 8, id->ssrc, 4 );
1726
1727     out->i_buffer = 12;
1728     id->i_sequence++;
1729 }
1730
1731 void rtp_packetize_send( sout_stream_id_t *id, block_t *out )
1732 {
1733     block_FifoPut( id->p_fifo, out );
1734 }
1735
1736 /**
1737  * @return configured max RTP payload size (including payload type-specific
1738  * headers, excluding RTP and transport headers)
1739  */
1740 size_t rtp_mtu (const sout_stream_id_t *id)
1741 {
1742     return id->i_mtu - 12;
1743 }
1744
1745 /*****************************************************************************
1746  * Non-RTP mux
1747  *****************************************************************************/
1748
1749 /** Add an ES to a non-RTP muxed stream */
1750 static sout_stream_id_t *MuxAdd( sout_stream_t *p_stream, es_format_t *p_fmt )
1751 {
1752     sout_input_t      *p_input;
1753     sout_mux_t *p_mux = p_stream->p_sys->p_mux;
1754     assert( p_mux != NULL );
1755
1756     p_input = sout_MuxAddStream( p_mux, p_fmt );
1757     if( p_input == NULL )
1758     {
1759         msg_Err( p_stream, "cannot add this stream to the muxer" );
1760         return NULL;
1761     }
1762
1763     return (sout_stream_id_t *)p_input;
1764 }
1765
1766
1767 static int MuxSend( sout_stream_t *p_stream, sout_stream_id_t *id,
1768                     block_t *p_buffer )
1769 {
1770     sout_mux_t *p_mux = p_stream->p_sys->p_mux;
1771     assert( p_mux != NULL );
1772
1773     sout_MuxSendBuffer( p_mux, (sout_input_t *)id, p_buffer );
1774     return VLC_SUCCESS;
1775 }
1776
1777
1778 /** Remove an ES from a non-RTP muxed stream */
1779 static int MuxDel( sout_stream_t *p_stream, sout_stream_id_t *id )
1780 {
1781     sout_mux_t *p_mux = p_stream->p_sys->p_mux;
1782     assert( p_mux != NULL );
1783
1784     sout_MuxDeleteStream( p_mux, (sout_input_t *)id );
1785     return VLC_SUCCESS;
1786 }
1787
1788
1789 static ssize_t AccessOutGrabberWriteBuffer( sout_stream_t *p_stream,
1790                                             const block_t *p_buffer )
1791 {
1792     sout_stream_sys_t *p_sys = p_stream->p_sys;
1793     sout_stream_id_t *id = p_sys->es[0];
1794
1795     int64_t  i_dts = p_buffer->i_dts;
1796
1797     uint8_t         *p_data = p_buffer->p_buffer;
1798     size_t          i_data  = p_buffer->i_buffer;
1799     size_t          i_max   = id->i_mtu - 12;
1800
1801     size_t i_packet = ( p_buffer->i_buffer + i_max - 1 ) / i_max;
1802
1803     while( i_data > 0 )
1804     {
1805         size_t i_size;
1806
1807         /* output complete packet */
1808         if( p_sys->packet &&
1809             p_sys->packet->i_buffer + i_data > i_max )
1810         {
1811             rtp_packetize_send( id, p_sys->packet );
1812             p_sys->packet = NULL;
1813         }
1814
1815         if( p_sys->packet == NULL )
1816         {
1817             /* allocate a new packet */
1818             p_sys->packet = block_New( p_stream, id->i_mtu );
1819             rtp_packetize_common( id, p_sys->packet, 1, i_dts );
1820             p_sys->packet->i_dts = i_dts;
1821             p_sys->packet->i_length = p_buffer->i_length / i_packet;
1822             i_dts += p_sys->packet->i_length;
1823         }
1824
1825         i_size = __MIN( i_data,
1826                         (unsigned)(id->i_mtu - p_sys->packet->i_buffer) );
1827
1828         memcpy( &p_sys->packet->p_buffer[p_sys->packet->i_buffer],
1829                 p_data, i_size );
1830
1831         p_sys->packet->i_buffer += i_size;
1832         p_data += i_size;
1833         i_data -= i_size;
1834     }
1835
1836     return VLC_SUCCESS;
1837 }
1838
1839
1840 static ssize_t AccessOutGrabberWrite( sout_access_out_t *p_access,
1841                                       block_t *p_buffer )
1842 {
1843     sout_stream_t *p_stream = (sout_stream_t*)p_access->p_sys;
1844
1845     while( p_buffer )
1846     {
1847         block_t *p_next;
1848
1849         AccessOutGrabberWriteBuffer( p_stream, p_buffer );
1850
1851         p_next = p_buffer->p_next;
1852         block_Release( p_buffer );
1853         p_buffer = p_next;
1854     }
1855
1856     return VLC_SUCCESS;
1857 }
1858
1859
1860 static sout_access_out_t *GrabberCreate( sout_stream_t *p_stream )
1861 {
1862     sout_access_out_t *p_grab;
1863
1864     p_grab = vlc_object_create( p_stream->p_sout, sizeof( *p_grab ) );
1865     if( p_grab == NULL )
1866         return NULL;
1867
1868     p_grab->p_module    = NULL;
1869     p_grab->psz_access  = strdup( "grab" );
1870     p_grab->p_cfg       = NULL;
1871     p_grab->psz_path    = strdup( "" );
1872     p_grab->p_sys       = (sout_access_out_sys_t *)p_stream;
1873     p_grab->pf_seek     = NULL;
1874     p_grab->pf_write    = AccessOutGrabberWrite;
1875     vlc_object_attach( p_grab, p_stream );
1876     return p_grab;
1877 }