[vlc-devel] rtsp source ports

Pierre Ynard linkfanel at yahoo.fr
Thu Jun 25 17:38:33 CEST 2009


>Hey Pierre
> 
> You said you wanted to share. I already send you a mail requesting the  
> patch but without respons. Maybe you overlooked it? Could you still  
> provide we with the path code? Thanks a lot.

No I haven't overlooked it :) Sorry, I was rewriting that patch in a
little more resilient way, and I missed a bit... I'm not finished and I
won't be able to test this tonight, but here's what I have for now, it
should work.


--- modules/stream_out/rtp.c	2009-06-25 10:55:59.000000000 +0200
+++ modules/stream_out/rtp.c	2009-06-25 15:22:46.000000000 +0200
@@ -116,6 +116,19 @@
 #define PORT_VIDEO_LONGTEXT N_( \
     "This allows you to specify the default video port for the RTP streaming." )
 
+#define SOCKET_TEXT N_("Socket file descriptor")
+#define SOCKET_LONGTEXT N_( \
+    "This allows to pass the file descriptor of an already connected socket " \
+    "to use for the RTP streaming.\nWarning: this option will work only " \
+    "with one Elementary Stream, and is not error-safe (it might leak the " \
+    "socket)." )
+#define CBPIPE_TEXT N_("Callback pipe file descriptor")
+#define CBPIPE_LONGTEXT N_( \
+    "This allows to pass the file descriptor of an open writing pipe to " \
+    "send back the RTP sequence number and timestamp to the calling RTSP " \
+    "module (typically VoD).\nWarning: this option will work only with one " \
+    "Elementary Stream, is not error-safe, etc..." )
+
 #define TTL_TEXT N_("Hop limit (TTL)")
 #define TTL_LONGTEXT N_( \
     "This is the hop limit (also known as \"Time-To-Live\" or TTL) of " \
@@ -196,6 +209,11 @@
     add_integer( SOUT_CFG_PREFIX "port-video", 0, NULL, PORT_VIDEO_TEXT,
                  PORT_VIDEO_LONGTEXT, true )
 
+    add_integer( SOUT_CFG_PREFIX "socket", -1, NULL, SOCKET_TEXT,
+                 SOCKET_LONGTEXT, true )
+    add_integer( SOUT_CFG_PREFIX "cbpipe", -1, NULL, CBPIPE_TEXT,
+                 CBPIPE_LONGTEXT, true )
+
     add_integer( SOUT_CFG_PREFIX "ttl", -1, NULL, TTL_TEXT,
                  TTL_LONGTEXT, true )
     add_bool( SOUT_CFG_PREFIX "rtcp-mux", false, NULL,
@@ -216,7 +234,8 @@
  * Exported prototypes
  *****************************************************************************/
 static const char *const ppsz_sout_options[] = {
-    "dst", "name", "port", "port-audio", "port-video", "*sdp", "ttl", "mux",
+    "dst", "name", "port", "port-audio", "port-video", 
+    "socket", "cbpipe", "*sdp", "ttl", "mux",
     "sap", "description", "url", "email", "phone",
     "proto", "rtcp-mux", "key", "salt",
     "mp4a-latm", NULL
@@ -271,6 +290,8 @@
     bool      rtcp_mux;
     int       i_ttl:9;
     bool      b_latm;
+    int       socket;
+    int       cbpipe;
 
     /* in case we do TS/PS over rtp */
     sout_mux_t        *p_mux;
@@ -300,6 +321,7 @@
     uint16_t    i_sequence;
     uint8_t     i_payload_type;
     uint8_t     ssrc[4];
+    int         cbpipe;
 
     /* for sdp */
     const char  *psz_enc;
@@ -350,6 +372,9 @@
     p_sys->i_port       = var_GetInteger( p_stream, SOUT_CFG_PREFIX "port" );
     p_sys->i_port_audio = var_GetInteger( p_stream, SOUT_CFG_PREFIX "port-audio" );
     p_sys->i_port_video = var_GetInteger( p_stream, SOUT_CFG_PREFIX "port-video" );
+    /* FIXME: close socket and cbpipe on error and on Close() */
+    p_sys->socket       = var_GetInteger( p_stream, SOUT_CFG_PREFIX "socket" );
+    p_sys->cbpipe       = var_GetInteger( p_stream, SOUT_CFG_PREFIX "cbpipe" );
     p_sys->rtcp_mux     = var_GetBool( p_stream, SOUT_CFG_PREFIX "rtcp-mux" );
 
     p_sys->psz_sdp_file = NULL;
@@ -910,6 +933,9 @@
     vlc_rand_bytes (&id->i_sequence, sizeof (id->i_sequence));
     vlc_rand_bytes (id->ssrc, sizeof (id->ssrc));
 
+    id->cbpipe = p_sys->cbpipe;
+    p_sys->cbpipe = -1;
+
     id->psz_enc    = NULL;
     id->psz_fmtp   = NULL;
     id->i_clock_rate = 90000; /* most common case for video */
@@ -1000,13 +1026,22 @@
 
             default:
             {
-                int ttl = (p_sys->i_ttl >= 0) ? p_sys->i_ttl : -1;
-                int fd = net_ConnectDgram( p_stream, p_sys->psz_destination,
-                                           i_port, ttl, p_sys->proto );
-                if( fd == -1 )
+                int fd;
+                if( p_sys->socket != -1 )
                 {
-                    msg_Err( p_stream, "cannot create RTP socket" );
-                    goto error;
+                    fd = p_sys->socket;
+                    p_sys->socket = -1;
+                }
+                else
+                {
+                    int ttl = (p_sys->i_ttl >= 0) ? p_sys->i_ttl : -1;
+                    fd = net_ConnectDgram( p_stream, p_sys->psz_destination,
+                                               i_port, ttl, p_sys->proto );
+                    if( fd == -1 )
+                    {
+                        msg_Err( p_stream, "cannot create RTP socket" );
+                        goto error;
+                    }
                 }
                 rtp_add_sink( id, fd, p_sys->rtcp_mux );
             }
@@ -1641,6 +1676,14 @@
 {
     uint32_t i_timestamp = i_pts * (int64_t)id->i_clock_rate / INT64_C(1000000);
 
+    if( id->cbpipe != -1 )
+    {
+        write( id->cbpipe, &id->i_sequence, sizeof( id->i_sequence ) );
+        write( id->cbpipe, &i_timestamp, sizeof( i_timestamp ) );
+        close( id->cbpipe );
+        id->cbpipe = -1;
+    }
+
     out->p_buffer[0] = 0x80;
     out->p_buffer[1] = (b_marker?0x80:0x00)|id->i_payload_type;
     out->p_buffer[2] = ( id->i_sequence >> 8)&0xff;
--- modules/misc/rtsp.c	2009-05-29 11:37:22.000000000 +0200
+++ modules/misc/rtsp.c	2009-06-25 16:32:12.000000000 +0200
@@ -107,6 +107,8 @@
     media_es_t *p_media_es;
     char *psz_ip;
     int i_port;
+    int socket;
+    int cbpipe;
 
 } rtsp_client_es_t;
 
@@ -1237,6 +1239,8 @@
                     i_port_video = p_rtsp->es[i]->i_port;
             }
 
+            int read_cbpipe = -1;
+
             if( p_media->psz_mux )
             {
                 if( p_media->b_raw )
@@ -1256,15 +1260,55 @@
             }
             else
             {
+                /* FIXME: If the socket fails to be consumed here, it will
+                 * be leaked! */
+                int socket = (p_rtsp->i_es > 0) ? p_rtsp->es[0]->socket : -1;
+
+                int write_cbpipe = -1;
+                /* We only support RTP-Info for one ES. */
+                if( p_rtsp->i_es == 1 )
+                {
+                    int cbpipe[2];
+                    if( pipe( cbpipe ) == -1 )
+                    {
+                        msg_Err( p_vod,
+                                 "cannot create RTSP callback pipe: %m" );
+                    }
+                    else
+                    {
+                        read_cbpipe = cbpipe[0];
+                        write_cbpipe = cbpipe[1];
+                    }
+                }
+                /* FIXME: if asprintf fails, we also leak the socket and
+                 * cbpipes... */
                 if( asprintf( &psz_output,
-                              "rtp{dst=%s,port-video=%i,port-audio=%i}",
-                              ip, i_port_video, i_port_audio ) < 0 )
+                "rtp{dst=%s,port-video=%i,port-audio=%i,socket=%i,cbpipe=%i}",
+                              ip, i_port_video, i_port_audio, socket,
+                              write_cbpipe ) < 0 )
                     return VLC_ENOMEM;
             }
 
             CommandPush( p_vod, RTSP_CMD_TYPE_PLAY, p_media, psz_session,
                          0, psz_output );
             free( psz_output );
+
+            if( read_cbpipe != -1 )
+            {
+                uint16_t sequence;
+                uint32_t timestamp;
+                read( read_cbpipe, &sequence, sizeof( sequence ) );
+                read( read_cbpipe, &timestamp, sizeof( timestamp ) );
+                close( read_cbpipe );
+
+                httpd_ServerIP( cl, ip );
+
+                /* FIXME: pass RTSP server port if it's not the default */
+                httpd_MsgAdd( answer, "RTP-Info",
+                              "url=rtsp://%s%s/trackID=0;seq=%u;rtptime=%u",
+                              ip, p_media->psz_rtsp_path, sequence, timestamp );
+            }
+
             break;
         }
 
@@ -1448,6 +1492,7 @@
                 p_rtsp_es->i_port = i_port;
                 p_rtsp_es->psz_ip = strdup( ip );
                 p_rtsp_es->p_media_es = p_es;
+                p_rtsp_es->socket = -1;
                 TAB_APPEND( p_rtsp->i_es, p_rtsp->es, p_rtsp_es );
 
                 answer->i_status = 200;
@@ -1471,9 +1516,31 @@
                 }
                 else
                 {
+                    char server_port[sizeof( ";server_port=65536-65536" ) + 1]
+                        = "";
+                    if( p_rtsp->i_es == 1 )
+                    {
+                        p_rtsp_es->socket = net_ConnectDgram( p_vod,
+                                        p_rtsp_es->psz_ip, p_rtsp_es->i_port,
+                                        -1, IPPROTO_UDP );
+                        if( p_rtsp_es->socket != -1 )
+                        {
+                            int sport;
+                            net_GetSockAddress( p_rtsp_es->socket, NULL,
+                                                &sport );
+                            sprintf( server_port, ";server_port=%d-%d", sport,
+                                     sport + 1 );
+                        }
+                        else
+                        {
+                            msg_Err( p_vod, "cannot prepare RTP socket" );
+                        }
+                    }
+
                     httpd_MsgAdd( answer, "Transport",
-                                  "RTP/AVP/UDP;client_port=%d-%d",
-                                  p_rtsp_es->i_port, p_rtsp_es->i_port + 1 );
+                                  "RTP/AVP/UDP;client_port=%d-%d%s",
+                                  p_rtsp_es->i_port, p_rtsp_es->i_port + 1,
+                                  server_port );
                 }
             }
             else /* TODO  strstr( psz_transport, "interleaved" ) ) */


Regards,

-- 
Pierre Ynard
"Une âme dans un corps, c'est comme un dessin sur une feuille de papier."



More information about the vlc-devel mailing list