]> git.sesse.net Git - vlc/commitdiff
Use plain sockets rather than the UDP access output for RTSP.
authorRémi Denis-Courmont <rem@videolan.org>
Fri, 7 Sep 2007 15:57:38 +0000 (15:57 +0000)
committerRémi Denis-Courmont <rem@videolan.org>
Fri, 7 Sep 2007 15:57:38 +0000 (15:57 +0000)
This saves:
 - one malloc() per packet per client } due to
 - one memcpy() per packet per client } block_Duplicate()
 - one mwait() per packet per client, and
 - one thread per client per track

So it should really help scale RTSP broadcast up.
However, in its current state, it removes the pts synchronization,
which might not be such a great idea. I will re-add it later.

modules/stream_out/rtp.c
modules/stream_out/rtp.h
modules/stream_out/rtsp.c

index 5aca6493230befc9adf7962c0f5616b41de05d0b..5e34a867195024e23f806d0fcba463f61a48e058 100644 (file)
@@ -240,13 +240,13 @@ struct sout_stream_id_t
     pf_rtp_packetizer_t pf_packetize;
     int          i_mtu;
 
-    /* for sending the packets */
+    /* Packets sinks */
     sout_access_out_t *p_access;
 
     vlc_mutex_t       lock_sink;
-    int               i_sink;
-    sout_access_out_t **sink;
-    rtsp_stream_id_t  *rtsp_id;
+    int               fdc;
+    int              *fdv;
+    rtsp_stream_id_t *rtsp_id;
 };
 
 
@@ -322,7 +322,7 @@ static int Open( vlc_object_t *p_this )
     {
         if( !b_rtsp )
         {
-            msg_Err( p_stream, "missing destination and not in rtsp mode" );
+            msg_Err( p_stream, "missing destination and not in RTSP mode" );
             free( p_sys );
             return VLC_EGENERIC;
         }
@@ -387,8 +387,8 @@ static int Open( vlc_object_t *p_this )
         id->p_stream = p_stream;
 
         vlc_mutex_init( p_stream, &id->lock_sink );
-        id->i_sink = 0;
-        id->sink = NULL;
+        id->fdc = 0;
+        id->fdv = NULL;
         id->rtsp_id = NULL;
 
         /* Check muxer type */
@@ -918,8 +918,8 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
     id->rtsp_id    = NULL;
 
     vlc_mutex_init( p_stream, &id->lock_sink );
-    id->i_sink = 0;
-    id->sink = NULL;
+    id->fdc = 0;
+    id->fdv = NULL;
 
     switch( p_fmt->i_codec )
     {
@@ -1206,7 +1206,7 @@ static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
         RtspDelId( p_sys->rtsp, id->rtsp_id );
 
     vlc_mutex_destroy( &id->lock_sink );
-    free( id->sink );
+    free( id->fdv );
 
     /* Update SDP (sap/file) */
     if( p_sys->b_export_sap && !p_sys->p_mux ) SapSetup( p_stream );
@@ -1362,9 +1362,9 @@ static void rtp_packetize_send( sout_stream_id_t *id, block_t *out )
 {
     int i;
     vlc_mutex_lock( &id->lock_sink );
-    for( i = 0; i < id->i_sink; i++ )
+    for( i = 0; i < id->fdc; i++ )
     {
-        sout_AccessOutWrite( id->sink[i], block_Duplicate( out ) );
+        send( id->fdv[i], out->p_buffer, out->i_buffer, 0 );
     }
     vlc_mutex_unlock( &id->lock_sink );
 
@@ -1378,20 +1378,21 @@ static void rtp_packetize_send( sout_stream_id_t *id, block_t *out )
     }
 }
 
-int rtp_add_sink( sout_stream_id_t *id, sout_access_out_t *access )
+int rtp_add_sink( sout_stream_id_t *id, int fd )
 {
     vlc_mutex_lock( &id->lock_sink );
-    TAB_APPEND( id->i_sink, id->sink, access );
+    TAB_APPEND( id->fdc, id->fdv, fd );
     vlc_mutex_unlock( &id->lock_sink );
     return VLC_SUCCESS;
 }
 
-void rtp_del_sink( sout_stream_id_t *id, sout_access_out_t *access )
+void rtp_del_sink( sout_stream_id_t *id, int fd )
 {
-    /* NOTE: must be safe to use if access is not a sink to id */
+    /* NOTE: must be safe to use if fd is not included */
     vlc_mutex_lock( &id->lock_sink );
-    TAB_REMOVE( id->i_sink, id->sink, access );
+    TAB_REMOVE( id->fdc, id->fdv, fd );
     vlc_mutex_unlock( &id->lock_sink );
+    net_Close( fd );
 }
 
 static int rtp_packetize_mpa( sout_stream_t *p_stream, sout_stream_id_t *id,
index c660a0ba017728c1e7192b98ed836d8b6fd59d72..228c066ae1239c9b24307d08c817dd8505d2c352 100644 (file)
@@ -36,6 +36,6 @@ void RtspDelId( rtsp_stream_t *rtsp, rtsp_stream_id_t * );
 
 char *SDPGenerate( const sout_stream_t *p_stream, const char *rtsp_url );
 
-int rtp_add_sink( sout_stream_id_t *id, sout_access_out_t *access );
-void rtp_del_sink( sout_stream_id_t *id, sout_access_out_t *access );
+int rtp_add_sink( sout_stream_id_t *id, int fd );
+void rtp_del_sink( sout_stream_id_t *id, int fd );
 
index 534e5f8ffabfff78fbef06313c84b7988a16cbd4..1147847fc6f990cdc4f7b6aab1c6d2c1fd700373 100644 (file)
@@ -154,7 +154,7 @@ struct rtsp_session_t
 struct rtsp_strack_t
 {
     sout_stream_id_t  *id;
-    sout_access_out_t *access;
+    int                fd;
     vlc_bool_t         playing;
 };
 
@@ -217,9 +217,8 @@ void RtspDelId( rtsp_stream_t *rtsp, rtsp_stream_id_t *id )
             if( ses->trackv[j].id == id->sout_id )
             {
                 rtsp_strack_t *tr = ses->trackv + j;
-                sout_AccessOutDelete( tr->access );
+                net_Close( tr->fd );
                 REMOVE_ELEM( ses->trackv, ses->trackc, j );
-                /* FIXME: are we supposed to notify the client? */
             }
         }
     }
@@ -283,10 +282,7 @@ void RtspClientDel( rtsp_stream_t *rtsp, rtsp_session_t *session )
     TAB_REMOVE( rtsp->sessionc, rtsp->sessionv, session );
 
     for( i = 0; i < session->trackc; i++ )
-    {
-        rtp_del_sink( session->trackv[i].id, session->trackv[i].access );
-        sout_AccessOutDelete( session->trackv[i].access );
-    }
+        rtp_del_sink( session->trackv[i].id, session->trackv[i].fd );
 
     free( session->trackv );
     free( session );
@@ -491,10 +487,10 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
                 }
                 else
                 {
-                    char ip[NI_MAXNUMERICHOST], url[NI_MAXNUMERICHOST + 8];
-                    static const char access[] = "udp{raw,rtcp}";
+                    char ip[NI_MAXNUMERICHOST], src[NI_MAXNUMERICHOST];
                     rtsp_session_t *ses = NULL;
-                    rtsp_strack_t track = { id->sout_id, NULL, VLC_FALSE };
+                    rtsp_strack_t track = { id->sout_id, -1, VLC_FALSE };
+                    int sport;
 
                     if( httpd_ClientIP( cl, ip ) == NULL )
                     {
@@ -502,25 +498,18 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
                         continue;
                     }
 
-                    snprintf( url, sizeof( url ),
-                              ( strchr( ip, ':' ) != NULL )
-                                  ? "[%s]:%d" : "%s:%d",
-                              ip, loport );
-
-                    track.access = sout_AccessOutNew( p_stream->p_sout,
-                                                      access, url );
-                    if( track.access == NULL )
+                    track.fd = net_ConnectDgram( p_stream, ip, loport, -1,
+                                                 IPPROTO_UDP );
+                    if( track.fd == -1 )
                     {
                         msg_Err( p_stream,
-                                 "cannot create access output for %s://%s",
-                                 access, url );
+                                 "cannot create RTP socket for %s port %u",
+                                 ip, loport );
                         answer->i_status = 500;
                         continue;
                     }
 
-                    char *src = var_GetNonEmptyString( track.access,
-                                                       "src-addr" );
-                    int sport = var_GetInteger( track.access, "src-port" );
+                    net_GetSockAddress( track.fd, src, &sport );
 
                     vlc_mutex_lock( &rtsp->lock );
                     if( psz_session == NULL )
@@ -549,7 +538,7 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
 
                     httpd_ServerIP( cl, ip );
 
-                    if( ( src != NULL ) && strcmp( src, ip ) )
+                    if( strcmp( src, ip ) )
                     {
                         /* Specify source IP if it is different from the RTSP
                          * control connection server address */
@@ -573,7 +562,6 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
                     }
 
                     answer->i_status = 200;
-                    free( src );
                 }
                 break;
             }
@@ -602,7 +590,7 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
                      && ( ( id == NULL ) || ( tr->id == id->sout_id ) ) )
                     {
                         tr->playing = VLC_TRUE;
-                        rtp_add_sink( tr->id, tr->access );
+                        rtp_add_sink( tr->id, tr->fd );
                     }
                 }
             }
@@ -650,8 +638,7 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
                 {
                     if( ses->trackv[i].id == id->sout_id )
                     {
-                        rtp_del_sink( id->sout_id, ses->trackv[i].access );
-                        sout_AccessOutDelete( ses->trackv[i].access );
+                        rtp_del_sink( id->sout_id, ses->trackv[i].fd );
                         REMOVE_ELEM( ses->trackv, ses->trackc, i );
                     }
                 }