Commit eceaf0fd authored by Jean-Paul Saman's avatar Jean-Paul Saman

Respond to x-playNow option in RTSP SETUP request. Did some indentation fixes too.

parent e8fb0d3d
...@@ -48,6 +48,7 @@ static void Close( vlc_object_t * ); ...@@ -48,6 +48,7 @@ static void Close( vlc_object_t * );
"You can set the address, port and path the rtsp interface will bind to." \ "You can set the address, port and path the rtsp interface will bind to." \
"\nSyntax is address:port/path. Default is to bind to any address "\ "\nSyntax is address:port/path. Default is to bind to any address "\
"on port 554, with no path." ) "on port 554, with no path." )
vlc_module_begin(); vlc_module_begin();
set_shortname( _("RTSP VoD" ) ); set_shortname( _("RTSP VoD" ) );
set_description( _("RTSP VoD server") ); set_description( _("RTSP VoD server") );
...@@ -294,6 +295,8 @@ static vod_media_t *MediaNew( vod_t *p_vod, const char *psz_name, ...@@ -294,6 +295,8 @@ static vod_media_t *MediaNew( vod_t *p_vod, const char *psz_name,
"a=control:rtsp://[%%s]:%d%s/trackid=%%d\r\n", "a=control:rtsp://[%%s]:%d%s/trackid=%%d\r\n",
p_sys->i_port, p_media->psz_rtsp_path ); p_sys->i_port, p_media->psz_rtsp_path );
httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_SETUP,
RtspCallback, (void*)p_media );
httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_DESCRIBE, httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_DESCRIBE,
RtspCallback, (void*)p_media ); RtspCallback, (void*)p_media );
httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_PLAY, httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_PLAY,
...@@ -385,7 +388,6 @@ static int MediaAddES( vod_t *p_vod, vod_media_t *p_media, es_format_t *p_fmt ) ...@@ -385,7 +388,6 @@ static int MediaAddES( vod_t *p_vod, vod_media_t *p_media, es_format_t *p_fmt )
{ {
p_es->i_payload_type = p_media->i_payload_type++; p_es->i_payload_type = p_media->i_payload_type++;
} }
p_es->psz_rtpmap = malloc( strlen( "L16/*/*" ) + 20+1 ); p_es->psz_rtpmap = malloc( strlen( "L16/*/*" ) + 20+1 );
sprintf( p_es->psz_rtpmap, "L16/%d/%d", p_fmt->audio.i_rate, sprintf( p_es->psz_rtpmap, "L16/%d/%d", p_fmt->audio.i_rate,
p_fmt->audio.i_channels ); p_fmt->audio.i_channels );
...@@ -620,12 +622,13 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, ...@@ -620,12 +622,13 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl,
{ {
vod_media_t *p_media = (vod_media_t*)p_args; vod_media_t *p_media = (vod_media_t*)p_args;
vod_t *p_vod = p_media->p_vod; vod_t *p_vod = p_media->p_vod;
char *psz_transport = NULL;
char *psz_session = NULL; char *psz_session = NULL;
rtsp_client_t *p_rtsp; rtsp_client_t *p_rtsp;
if( answer == NULL || query == NULL ) return VLC_SUCCESS; if( answer == NULL || query == NULL ) return VLC_SUCCESS;
msg_Info( p_vod, "RtspCallback query: type=%d\n", query->i_type ); msg_Info( p_vod, "RtspCallback query: type=%d", query->i_type );
answer->i_proto = HTTPD_PROTO_RTSP; answer->i_proto = HTTPD_PROTO_RTSP;
answer->i_version = query->i_version; answer->i_version = query->i_version;
...@@ -633,6 +636,69 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, ...@@ -633,6 +636,69 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl,
switch( query->i_type ) switch( query->i_type )
{ {
case HTTPD_MSG_SETUP:
{
psz_transport = httpd_MsgGet( query, "Transport" );
msg_Dbg( p_vod, "HTTPD_MSG_SETUP: transport=%s", psz_transport );
if( strstr( psz_transport, "unicast" ) &&
strstr( psz_transport, "client_port=" ) )
{
rtsp_client_t *p_rtsp;
char ip[NI_MAXNUMERICHOST];
int i_port = atoi( strstr( psz_transport, "client_port=" ) +
strlen("client_port=") );
if( httpd_ClientIP( cl, ip ) == NULL )
{
answer->i_status = 500;
answer->psz_status = strdup( "Internal server error" );
answer->i_body = 0;
answer->p_body = NULL;
break;
}
msg_Dbg( p_vod, "HTTPD_MSG_SETUP: unicast ip=%s port=%d",
ip, i_port );
psz_session = httpd_MsgGet( query, "Session" );
if( !psz_session || !*psz_session )
{
asprintf( &psz_session, "%d", rand() );
p_rtsp = RtspClientNew( p_media, psz_session );
}
else
{
p_rtsp = RtspClientGet( p_media, psz_session );
if( !p_rtsp )
{
/* FIXME right error code */
answer->i_status = 454;
answer->psz_status = strdup( "Unknown session id" );
answer->i_body = 0;
answer->p_body = NULL;
break;
}
}
answer->i_status = 200;
answer->psz_status = strdup( "OK" );
answer->i_body = 0;
answer->p_body = NULL;
httpd_MsgAdd( answer, "Transport", "RTP/AVP/UDP;client_port=%d-%d",
i_port, i_port + 1 );
}
else /* TODO strstr( psz_transport, "interleaved" ) ) */
{
answer->i_status = 461;
answer->psz_status = strdup( "Unsupported Transport" );
answer->i_body = 0;
answer->p_body = NULL;
}
break;
}
case HTTPD_MSG_DESCRIBE: case HTTPD_MSG_DESCRIBE:
{ {
char *psz_sdp = char *psz_sdp =
...@@ -771,14 +837,15 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl, ...@@ -771,14 +837,15 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl,
vod_media_t *p_media = p_es->p_media; vod_media_t *p_media = p_es->p_media;
vod_t *p_vod = p_media->p_vod; vod_t *p_vod = p_media->p_vod;
rtsp_client_t *p_rtsp = NULL; rtsp_client_t *p_rtsp = NULL;
char *psz_session = NULL;
char *psz_transport = NULL; char *psz_transport = NULL;
char *psz_playnow = NULL; /* support option: x-playNow */
char *psz_session = NULL;
char *psz_position = NULL; char *psz_position = NULL;
int i; int i;
if( answer == NULL || query == NULL ) return VLC_SUCCESS; if( answer == NULL || query == NULL ) return VLC_SUCCESS;
msg_Info( p_vod, "RtspCallback query: type=%d\n", query->i_type ); msg_Info( p_vod, "RtspCallback query: type=%d", query->i_type );
answer->i_proto = HTTPD_PROTO_RTSP; answer->i_proto = HTTPD_PROTO_RTSP;
answer->i_version = query->i_version; answer->i_version = query->i_version;
...@@ -787,8 +854,10 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl, ...@@ -787,8 +854,10 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl,
switch( query->i_type ) switch( query->i_type )
{ {
case HTTPD_MSG_SETUP: case HTTPD_MSG_SETUP:
psz_playnow = httpd_MsgGet( query, "x-playNow" );
psz_transport = httpd_MsgGet( query, "Transport" ); psz_transport = httpd_MsgGet( query, "Transport" );
msg_Dbg( p_vod, "HTTPD_MSG_SETUP: transport=%s\n", psz_transport );
msg_Dbg( p_vod, "HTTPD_MSG_SETUP: transport=%s", psz_transport );
if( strstr( psz_transport, "unicast" ) && if( strstr( psz_transport, "unicast" ) &&
strstr( psz_transport, "client_port=" ) ) strstr( psz_transport, "client_port=" ) )
...@@ -808,7 +877,7 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl, ...@@ -808,7 +877,7 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl,
break; break;
} }
msg_Dbg( p_vod, "HTTPD_MSG_SETUP: unicast ip=%s port=%d\n", msg_Dbg( p_vod, "HTTPD_MSG_SETUP: unicast ip=%s port=%d",
ip, i_port ); ip, i_port );
psz_session = httpd_MsgGet( query, "Session" ); psz_session = httpd_MsgGet( query, "Session" );
...@@ -827,7 +896,6 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl, ...@@ -827,7 +896,6 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl,
answer->psz_status = strdup( "Unknown session id" ); answer->psz_status = strdup( "Unknown session id" );
answer->i_body = 0; answer->i_body = 0;
answer->p_body = NULL; answer->p_body = NULL;
free( ip );
break; break;
} }
} }
...@@ -838,6 +906,9 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl, ...@@ -838,6 +906,9 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl,
p_rtsp_es->p_media_es = p_es; p_rtsp_es->p_media_es = p_es;
TAB_APPEND( p_rtsp->i_es, p_rtsp->es, p_rtsp_es ); TAB_APPEND( p_rtsp->i_es, p_rtsp->es, p_rtsp_es );
if( psz_playnow ) /* support option: x-playNow */
goto rtsp_play_now;
answer->i_status = 200; answer->i_status = 200;
answer->psz_status = strdup( "OK" ); answer->psz_status = strdup( "OK" );
answer->i_body = 0; answer->i_body = 0;
...@@ -886,6 +957,9 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl, ...@@ -886,6 +957,9 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl,
break; break;
case HTTPD_MSG_PLAY: case HTTPD_MSG_PLAY:
/* This avoids code duplications although it is ugly. */
rtsp_play_now:
/* This is kind of a kludge. Should we only support Aggregate /* This is kind of a kludge. Should we only support Aggregate
* Operations ? */ * Operations ? */
psz_session = httpd_MsgGet( query, "Session" ); psz_session = httpd_MsgGet( query, "Session" );
...@@ -946,9 +1020,7 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl, ...@@ -946,9 +1020,7 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl,
httpd_MsgAdd( answer, "Cache-Control", "%s", "no-cache" ); httpd_MsgAdd( answer, "Cache-Control", "%s", "no-cache" );
if( psz_session ) if( psz_session )
{
httpd_MsgAdd( answer, "Session", "%s"/*;timeout=5*/, psz_session ); httpd_MsgAdd( answer, "Session", "%s"/*;timeout=5*/, psz_session );
}
return VLC_SUCCESS; return VLC_SUCCESS;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment