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