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