X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=modules%2Fmisc%2Frtsp.c;h=561e110cae0a647b6a087abcd47642e3bfef78f6;hb=ffbd92724a257d0c92eb59032901803109100d26;hp=ae7e27754ca80d9f696871d82b9dae1048624f8b;hpb=5cf39390c0d9a4c9ef2860746126f0bbad3370b6;p=vlc diff --git a/modules/misc/rtsp.c b/modules/misc/rtsp.c index ae7e27754c..561e110cae 100644 --- a/modules/misc/rtsp.c +++ b/modules/misc/rtsp.c @@ -45,6 +45,14 @@ #include +#ifndef WIN32 +# include +#endif + +#ifdef HAVE_XLOCALE_H +# include +#endif + /***************************************************************************** * Module descriptor *****************************************************************************/ @@ -218,9 +226,9 @@ static void MediaDel( vod_t *, vod_media_t * ); static int MediaAddES( vod_t *, vod_media_t *, es_format_t * ); static void MediaDelES( vod_t *, vod_media_t *, es_format_t * ); -static void CommandThread( vlc_object_t *p_this ); -static void CommandPush( vod_t *, rtsp_cmd_type_t, vod_media_t *, const char *psz_session, - double f_arg, const char *psz_arg ); +static void* CommandThread( vlc_object_t *p_this ); +static void CommandPush( vod_t *, rtsp_cmd_type_t, vod_media_t *, const char *psz_session, + double f_arg, const char *psz_arg ); static rtsp_client_t *RtspClientNew( vod_media_t *, char * ); static rtsp_client_t *RtspClientGet( vod_media_t *, const char * ); @@ -394,11 +402,21 @@ static vod_media_t *MediaNew( vod_t *p_vod, const char *psz_name, if( asprintf( &p_media->psz_rtsp_control_v4, "a=control:rtsp://%%s:%d%s/trackID=%%d\r\n", p_sys->i_port, p_media->psz_rtsp_path ) < 0 ) + { + httpd_UrlDelete( p_media->p_rtsp_url ); + free( p_media->psz_rtsp_path ); + free( p_media ); return NULL; + } if( asprintf( &p_media->psz_rtsp_control_v6, "a=control:rtsp://[%%s]:%d%s/trackID=%%d\r\n", p_sys->i_port, p_media->psz_rtsp_path ) < 0 ) + { + httpd_UrlDelete( p_media->p_rtsp_url ); + free( p_media->psz_rtsp_path ); + free( p_media ); return NULL; + } httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_SETUP, RtspCallback, (void*)p_media ); @@ -514,15 +532,15 @@ 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->psz_rtpmap = malloc( strlen( "L16/*/*" ) + 20+1 ); - sprintf( p_es->psz_rtpmap, "L16/%d/%d", p_fmt->audio.i_rate, - p_fmt->audio.i_channels ); + if( asprintf( &p_es->psz_rtpmap, "L16/%d/%d", p_fmt->audio.i_rate, + p_fmt->audio.i_channels ) == -1 ) + p_es->psz_rtpmap = NULL; break; case VLC_FOURCC( 'u', '8', ' ', ' ' ): p_es->i_payload_type = p_media->i_payload_type++; - p_es->psz_rtpmap = malloc( strlen( "L8/*/*" ) + 20+1 ); - sprintf( p_es->psz_rtpmap, "L8/%d/%d", p_fmt->audio.i_rate, - p_fmt->audio.i_channels ); + if( asprintf( &p_es->psz_rtpmap, "L8/%d/%d", p_fmt->audio.i_rate, + p_fmt->audio.i_channels ) == -1 ) + p_es->psz_rtpmap = NULL; break; case VLC_FOURCC( 'm', 'p', 'g', 'a' ): case VLC_FOURCC( 'm', 'p', '3', ' ' ): @@ -535,7 +553,8 @@ static int MediaAddES( vod_t *p_vod, vod_media_t *p_media, es_format_t *p_fmt ) break; case VLC_FOURCC( 'a', '5', '2', ' ' ): p_es->i_payload_type = p_media->i_payload_type++; - asprintf( &p_es->psz_rtpmap, "ac3/%d", p_fmt->audio.i_rate ); + if( asprintf( &p_es->psz_rtpmap, "ac3/%d", p_fmt->audio.i_rate ) == -1 ) + p_es->psz_rtpmap = NULL; break; case VLC_FOURCC( 'H', '2', '6', '3' ): p_es->i_payload_type = p_media->i_payload_type++; @@ -611,26 +630,26 @@ static int MediaAddES( vod_t *p_vod, vod_media_t *p_media, es_format_t *p_fmt ) if( p_fmt->i_extra > 0 ) { char *p_hexa = malloc( 2 * p_fmt->i_extra + 1 ); - p_es->psz_fmtp = malloc( 100 + 2 * p_fmt->i_extra ); sprintf_hexa( p_hexa, p_fmt->p_extra, p_fmt->i_extra ); - sprintf( p_es->psz_fmtp, - "profile-level-id=3; config=%s;", p_hexa ); + if( asprintf( &p_es->psz_fmtp, + "profile-level-id=3; config=%s;", p_hexa ) == -1 ) + p_es->psz_fmtp = NULL; free( p_hexa ); } break; case VLC_FOURCC( 'm', 'p', '4', 'a' ): p_es->i_payload_type = p_media->i_payload_type++; - p_es->psz_rtpmap = malloc( strlen( "mpeg4-generic/" ) + 12 ); - sprintf( p_es->psz_rtpmap, "mpeg4-generic/%d", p_fmt->audio.i_rate ); + if( asprintf( &p_es->psz_rtpmap, "mpeg4-generic/%d", p_fmt->audio.i_rate ) == -1 ) + p_es->psz_rtpmap = NULL; if( p_fmt->i_extra > 0 ) { char *p_hexa = malloc( 2 * p_fmt->i_extra + 1 ); - p_es->psz_fmtp = malloc( 200 + 2 * p_fmt->i_extra ); sprintf_hexa( p_hexa, p_fmt->p_extra, p_fmt->i_extra ); - sprintf( p_es->psz_fmtp, - "streamtype=5; profile-level-id=15; mode=AAC-hbr; " - "config=%s; SizeLength=13;IndexLength=3; " - "IndexDeltaLength=3; Profile=1;", p_hexa ); + if( asprintf( &p_es->psz_fmtp, + "streamtype=5; profile-level-id=15; mode=AAC-hbr; " + "config=%s; SizeLength=13;IndexLength=3; " + "IndexDeltaLength=3; Profile=1;", p_hexa ) == -1 ) + p_es->psz_fmtp = NULL; free( p_hexa ); } break; @@ -793,12 +812,12 @@ static void CommandPush( vod_t *p_vod, rtsp_cmd_type_t i_type, vod_media_t *p_me block_FifoPut( p_vod->p_sys->p_fifo_cmd, p_cmd ); } -static void CommandThread( vlc_object_t *p_this ) +static void* CommandThread( vlc_object_t *p_this ) { vod_t *p_vod = (vod_t*)p_this; vod_sys_t *p_sys = p_vod->p_sys; - while( !p_vod->b_die ) + while( vlc_object_alive (p_vod) ) { block_t *p_block_cmd = block_FifoGet( p_sys->p_fifo_cmd ); rtsp_cmd_t cmd; @@ -864,6 +883,7 @@ static void CommandThread( vlc_object_t *p_this ) free( cmd.psz_session ); free( cmd.psz_arg ); } + return NULL; } /**************************************************************************** @@ -919,6 +939,29 @@ static void RtspClientDel( vod_media_t *p_media, rtsp_client_t *p_rtsp ) free( p_rtsp ); } + +static float ParseNPT (const char *str) +{ + locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL); + locale_t oldloc = uselocale (loc); + unsigned hour, min; + float sec; + + if (sscanf (str, "%u:%u:%f", &hour, &min, &sec) == 3) + sec += ((hour * 60) + min) * 60; + else + if (sscanf (str, "%f", &sec) != 1) + sec = 0.; + + if (loc != (locale_t)0) + { + uselocale (oldloc); + freelocale (loc); + } + return sec; +} + + static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, httpd_message_t *answer, const httpd_message_t *query ) { @@ -1090,19 +1133,11 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, psz_position = strstr( psz_position, "npt=" ); if( psz_position && !psz_scale ) { - double f_pos; - char *end; - + double f_pos = ParseNPT (psz_position + 4); msg_Dbg( p_vod, "seeking request: %s", psz_position ); - psz_position += 4; - /* FIXME: npt= is not necessarily formatted as a float */ - f_pos = us_strtod( psz_position, &end ); - if( end > psz_position ) - { - f_pos /= ((double)(p_media->i_length))/1000 /1000 / 100; - CommandPush( p_vod, RTSP_CMD_TYPE_SEEK, p_media, - psz_session, f_pos, NULL ); - } + f_pos /= ((double)(p_media->i_length))/1000 /1000 / 100; + CommandPush( p_vod, RTSP_CMD_TYPE_SEEK, p_media, + psz_session, f_pos, NULL ); break; } if( psz_scale ) @@ -1423,20 +1458,11 @@ static int RtspCallbackES( httpd_callback_sys_t *p_args, httpd_client_t *cl, if( psz_position ) psz_position = strstr( psz_position, "npt=" ); if( psz_position ) { - double f_pos; - char *end; - + double f_pos = ParseNPT (psz_position + 4); msg_Dbg( p_vod, "seeking request: %s", psz_position ); - - psz_position += 4; - /* FIXME: npt= is not necessarily formatted as a float */ - f_pos = us_strtod( psz_position, &end ); - if( end > psz_position ) - { - f_pos /= ((double)(p_media->i_length))/1000 /1000 / 100; - CommandPush( p_vod, RTSP_CMD_TYPE_SEEK, p_media, - psz_session, f_pos, NULL ); - } + f_pos /= ((double)(p_media->i_length))/1000 /1000 / 100; + CommandPush( p_vod, RTSP_CMD_TYPE_SEEK, p_media, + psz_session, f_pos, NULL ); } if( !psz_playnow )