X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fmisc%2Frtsp.c;h=10708f7ea1752e658f14f518f727dd80d5f4f63f;hb=de587c237065de4696d9d035d0504cdf34990d87;hp=d8d9c808263802c043c52d1d237eec11d2564b45;hpb=6da90a1716250d282f16dc6bc9dacec5b9514caf;p=vlc diff --git a/modules/misc/rtsp.c b/modules/misc/rtsp.c index d8d9c80826..10708f7ea1 100644 --- a/modules/misc/rtsp.c +++ b/modules/misc/rtsp.c @@ -30,7 +30,8 @@ # include "config.h" #endif -#include +#include +#include #include #include #include @@ -44,6 +45,14 @@ #include +#ifndef WIN32 +# include +#endif + +#ifdef HAVE_XLOCALE_H +# include +#endif + /***************************************************************************** * Module descriptor *****************************************************************************/ @@ -71,8 +80,8 @@ static void Close( vlc_object_t * ); "those made by HansunTech) which get confused by it. The default is 5." ) vlc_module_begin(); - set_shortname( _("RTSP VoD" ) ); - set_description( _("RTSP VoD server") ); + set_shortname( N_("RTSP VoD" ) ); + set_description( N_("RTSP VoD server") ); set_category( CAT_SOUT ); set_subcategory( SUBCAT_SOUT_VOD ); set_capability( "vod server", 1 ); @@ -364,10 +373,7 @@ static vod_media_t *MediaNew( vod_t *p_vod, const char *psz_name, int i; if( !p_media ) - { - msg_Err( p_vod, "not enough memory" ); return NULL; - } memset( p_media, 0, sizeof(vod_media_t) ); p_media->id = p_sys->i_media_id++; @@ -494,7 +500,10 @@ static int MediaAddES( vod_t *p_vod, vod_media_t *p_media, es_format_t *p_fmt ) /* TODO: update SDP, etc... */ if( asprintf( &psz_urlc, "%s/trackID=%d", p_media->psz_rtsp_path, p_media->i_es ) < 0 ) + { + free( p_es ); return VLC_ENOMEM; + } msg_Dbg( p_vod, " - ES %4.4s (%s)", (char *)&p_fmt->i_codec, psz_urlc ); switch( p_fmt->i_codec ) @@ -524,6 +533,7 @@ static int MediaAddES( vod_t *p_vod, vod_media_t *p_media, es_format_t *p_fmt ) p_fmt->audio.i_channels ); break; case VLC_FOURCC( 'm', 'p', 'g', 'a' ): + case VLC_FOURCC( 'm', 'p', '3', ' ' ): p_es->i_payload_type = 14; p_es->psz_rtpmap = strdup( "MPA/90000" ); break; @@ -533,7 +543,7 @@ 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++; - p_es->psz_rtpmap = strdup( "ac3/90000" ); + asprintf( &p_es->psz_rtpmap, "ac3/%d", p_fmt->audio.i_rate ); break; case VLC_FOURCC( 'H', '2', '6', '3' ): p_es->i_payload_type = p_media->i_payload_type++; @@ -584,11 +594,19 @@ static int MediaAddES( vod_t *p_vod, vod_media_t *p_media, es_format_t *p_fmt ) } /* */ if( p_64_sps && p_64_pps ) + { if( asprintf( &p_es->psz_fmtp, "packetization-mode=1;profile-level-id=%s;" "sprop-parameter-sets=%s,%s;", hexa, p_64_sps, p_64_pps ) < 0 ) + { + free( p_64_sps ); + free( p_64_pps ); + free( psz_urlc ); + free( p_es ); return VLC_ENOMEM; + } + } free( p_64_sps ); free( p_64_pps ); } @@ -650,6 +668,7 @@ static int MediaAddES( vod_t *p_vod, vod_media_t *p_media, es_format_t *p_fmt ) default: msg_Err( p_vod, "cannot add this stream (unsupported " "codec: %4.4s)", (char*)&p_fmt->i_codec ); + free( psz_urlc ); free( p_es ); return VLC_EGENERIC; } @@ -787,7 +806,7 @@ 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; @@ -908,6 +927,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 ) { @@ -1018,19 +1060,19 @@ static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, if( strstr( psz_transport, "MP2T/H2221/UDP" ) ) { httpd_MsgAdd( answer, "Transport", - "MP2T/H2221/UDP;client_port=%d-%d", + "MP2T/H2221/UDP;unicast;client_port=%d-%d", i_port, i_port + 1 ); } else if( strstr( psz_transport, "RAW/RAW/UDP" ) ) { httpd_MsgAdd( answer, "Transport", - "RAW/RAW/UDP;client_port=%d-%d", + "RAW/RAW/UDP;unicast;client_port=%d-%d", i_port, i_port + 1 ); } } else httpd_MsgAdd( answer, "Transport", - "RTP/AVP/UDP;client_port=%d-%d", + "RTP/AVP/UDP;unicast;client_port=%d-%d", i_port, i_port + 1 ); } else /* TODO strstr( psz_transport, "interleaved" ) ) */ @@ -1079,19 +1121,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 ) @@ -1412,20 +1446,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 )