<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, ×tamp, 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>