X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fdemux%2Flive555.cpp;h=4e7f3035e05d075115c62d60646d477bdb7962b3;hb=7aca939ab1ed52290efac498101ad4faa6c6e32c;hp=ffed8fe809a7824148c697fb5b0fefc646c69a4c;hpb=daf35d71d9c0a2a1a984f6da341566da8dada431;p=vlc diff --git a/modules/demux/live555.cpp b/modules/demux/live555.cpp index ffed8fe809..4e7f3035e0 100644 --- a/modules/demux/live555.cpp +++ b/modules/demux/live555.cpp @@ -27,14 +27,18 @@ * Preamble *****************************************************************************/ +/* For inttypes.h + * Note: config.h may include inttypes.h, so make sure we define this option + * early enough. */ +#define __STDC_CONSTANT_MACROS 1 + #ifdef HAVE_CONFIG_H # include "config.h" #endif -#define __STDC_CONSTANT_MACROS 1 #include -#include +#include #include #include @@ -44,6 +48,7 @@ #include #include +#include #if defined( WIN32 ) @@ -106,6 +111,9 @@ vlc_module_begin(); add_integer( "rtp-client-port", -1, NULL, N_("Client port"), N_("Port to use for the RTP source of the session"), true ); + add_bool( "rtsp-mcast", false, NULL, + N_("Force multicast RTP via RTSP"), + N_("Force multicast RTP via RTSP"), true ); add_bool( "rtsp-http", 0, NULL, N_("Tunnel RTSP and RTP over HTTP"), N_("Tunnel RTSP and RTP over HTTP"), true ); @@ -136,28 +144,26 @@ typedef struct es_format_t fmt; es_out_id_t *p_es; - bool b_muxed; - bool b_quicktime; - bool b_asf; + bool b_muxed; + bool b_quicktime; + bool b_asf; stream_t *p_out_muxed; /* for muxed stream */ uint8_t *p_buffer; unsigned int i_buffer; - bool b_rtcp_sync; + bool b_rtcp_sync; char waiting; int64_t i_pts; - u_int32_t i_start_seq; + float i_npt; } live_track_t; struct timeout_thread_t { - VLC_COMMON_MEMBERS - - int64_t i_remain; - bool b_handle_keep_alive; demux_sys_t *p_sys; + vlc_thread_t handle; + bool b_handle_keep_alive; }; struct demux_sys_t @@ -178,25 +184,28 @@ struct demux_sys_t /* Weird formats */ asf_header_t asfh; stream_t *p_out_asf; - bool b_real; + bool b_real; /* */ int64_t i_pcr; /* The clock */ - int64_t i_npt; /* The current time in the stream */ - int64_t i_npt_length; - int64_t i_npt_start; + float i_npt; + float i_npt_length; + float i_npt_start; /* timeout thread information */ int i_timeout; /* session timeout value in seconds */ - bool b_timeout_call;/* mark to send an RTSP call to prevent server timeout */ + bool b_timeout_call;/* mark to send an RTSP call to prevent server timeout */ timeout_thread_t *p_timeout; /* the actual thread that makes sure we don't timeout */ /* */ - bool b_multicast; /* true if one of the tracks is multicasted */ - bool b_no_data; /* true if we never receive any data */ + bool b_force_mcast; + bool b_multicast; /* if one of the tracks is multicasted */ + bool b_no_data; /* if we never received any data */ int i_no_data_ti; /* consecutive number of TaskInterrupt */ char event; + + bool b_get_param; /* Does the server support GET_PARAMETER */ }; static int Demux ( demux_t * ); @@ -213,7 +222,7 @@ static void StreamRead ( void *, unsigned int, unsigned int, static void StreamClose ( void * ); static void TaskInterrupt( void * ); -static void TimeoutPrevention( timeout_thread_t * ); +static void* TimeoutPrevention( void * ); static unsigned char* parseH264ConfigStr( char const* configStr, unsigned int& configSize ); @@ -263,9 +272,9 @@ static int Open ( vlc_object_t *p_this ) p_sys->i_track = 0; p_sys->track = NULL; p_sys->i_pcr = 0; - p_sys->i_npt = 0; - p_sys->i_npt_start = 0; - p_sys->i_npt_length = 0; + p_sys->i_npt = 0.; + p_sys->i_npt_start = 0.; + p_sys->i_npt_length = 0.; p_sys->p_out_asf = NULL; p_sys->b_no_data = true; p_sys->i_no_data_ti = 0; @@ -275,6 +284,8 @@ static int Open ( vlc_object_t *p_this ) p_sys->b_multicast = false; p_sys->b_real = false; p_sys->psz_path = strdup( p_demux->psz_path ); + p_sys->b_force_mcast = var_CreateGetBool( p_demux, "rtsp-mcast" ); + p_sys->b_get_param = false; /* parse URL for rtsp://[user:[passwd]@]serverip:port/options */ vlc_UrlParse( &p_sys->url, p_sys->psz_path, 0 ); @@ -314,7 +325,7 @@ static int Open ( vlc_object_t *p_this ) int i_read = stream_Read( p_demux->s, &p_sdp[i_sdp], i_sdp_max - i_sdp - 1 ); - if( p_demux->b_die || p_demux->b_error ) + if( !vlc_object_alive (p_demux) || p_demux->b_error ) { free( p_sdp ); goto error; @@ -396,16 +407,15 @@ error: if( p_sys->i_track ) free( p_sys->track ); if( p_sys->p_out_asf ) stream_DemuxDelete( p_sys->p_out_asf ); if( p_sys->rtsp && p_sys->ms ) p_sys->rtsp->teardownMediaSession( *p_sys->ms ); - if( p_sys->ms ) Medium::close( p_sys->ms ); - if( p_sys->rtsp ) RTSPClient::close( p_sys->rtsp ); - if( p_sys->env ) p_sys->env->reclaim(); if( p_sys->p_timeout ) { - vlc_object_kill( p_sys->p_timeout ); - vlc_thread_join( p_sys->p_timeout ); - vlc_object_detach( p_sys->p_timeout ); - vlc_object_release( p_sys->p_timeout ); + vlc_cancel( p_sys->p_timeout->handle ); + vlc_join( p_sys->p_timeout->handle, NULL ); + free( p_sys->p_timeout ); } + if( p_sys->ms ) Medium::close( p_sys->ms ); + if( p_sys->rtsp ) RTSPClient::close( p_sys->rtsp ); + if( p_sys->env ) p_sys->env->reclaim(); delete p_sys->scheduler; free( p_sys->p_sdp ); free( p_sys->psz_path ); @@ -438,16 +448,15 @@ static void Close( vlc_object_t *p_this ) if( p_sys->i_track ) free( p_sys->track ); if( p_sys->p_out_asf ) stream_DemuxDelete( p_sys->p_out_asf ); if( p_sys->rtsp && p_sys->ms ) p_sys->rtsp->teardownMediaSession( *p_sys->ms ); - if( p_sys->ms ) Medium::close( p_sys->ms ); - if( p_sys->rtsp ) RTSPClient::close( p_sys->rtsp ); - if( p_sys->env ) p_sys->env->reclaim(); if( p_sys->p_timeout ) { - vlc_object_kill( p_sys->p_timeout ); - vlc_thread_join( p_sys->p_timeout ); - vlc_object_detach( p_sys->p_timeout ); - vlc_object_release( p_sys->p_timeout ); + vlc_cancel( p_sys->p_timeout->handle ); + vlc_join( p_sys->p_timeout->handle, NULL ); + free( p_sys->p_timeout ); } + if( p_sys->ms ) Medium::close( p_sys->ms ); + if( p_sys->rtsp ) RTSPClient::close( p_sys->rtsp ); + if( p_sys->env ) p_sys->env->reclaim(); delete p_sys->scheduler; free( p_sys->p_sdp ); free( p_sys->psz_path ); @@ -498,7 +507,7 @@ static int Connect( demux_t *p_demux ) i_lefttries = 3; createnew: i_lefttries--; - if( p_demux->b_die || p_demux->b_error ) + if( !vlc_object_alive (p_demux) || p_demux->b_error ) { free( psz_user ); free( psz_pwd ); @@ -530,9 +539,7 @@ createnew: */ if( var_CreateGetBool( p_demux, "rtsp-kasenna" )) { -#if LIVEMEDIA_LIBRARY_VERSION_INT > 1130457500 p_sys->rtsp->setUserAgentString( "VLC_MEDIA_PLAYER_KA" ); -#endif } describe: @@ -541,6 +548,8 @@ describe: psz_options = p_sys->rtsp->sendOptionsCmd( psz_url, psz_user, psz_pwd, &authenticator ); + if( psz_options ) + p_sys->b_get_param = strstr( psz_options, "GET_PARAMETER" ) ? true : false ; delete [] psz_options; p_sdp = p_sys->rtsp->describeURL( psz_url, &authenticator, @@ -635,7 +644,7 @@ static int SessionsSetup( demux_t *p_demux ) MediaSubsessionIterator *iter = NULL; MediaSubsession *sub = NULL; - bool b_rtsp_tcp = false; + bool b_rtsp_tcp = false; int i_client_port; int i_return = VLC_SUCCESS; unsigned int i_buffer = 0; @@ -660,7 +669,7 @@ static int SessionsSetup( demux_t *p_demux ) Boolean bInit; live_track_t *tk; - if( p_demux->b_die || p_demux->b_error ) + if( !vlc_object_alive (p_demux) || p_demux->b_error ) { delete iter; return VLC_EGENERIC; @@ -716,13 +725,15 @@ static int SessionsSetup( demux_t *p_demux ) /* Issue the SETUP */ if( p_sys->rtsp ) { - if( !( p_sys->rtsp->setupMediaSubsession( *sub, False, - b_rtsp_tcp ? True : False ) ) ) + if( !p_sys->rtsp->setupMediaSubsession( *sub, False, + b_rtsp_tcp ? True : False, + ( p_sys->b_force_mcast && !b_rtsp_tcp ) ? True : False ) ) { /* if we get an unsupported transport error, toggle TCP use and try again */ if( !strstr(p_sys->env->getResultMsg(), "461 Unsupported Transport") - || !( p_sys->rtsp->setupMediaSubsession( *sub, False, - b_rtsp_tcp ? False : True ) ) ) + || !p_sys->rtsp->setupMediaSubsession( *sub, False, + b_rtsp_tcp ? False : True, + False ) ) { msg_Err( p_demux, "SETUP of'%s/%s' failed %s", sub->mediumName(), sub->codecName(), p_sys->env->getResultMsg() ); @@ -755,6 +766,7 @@ static int SessionsSetup( demux_t *p_demux ) tk->waiting = 0; tk->b_rtcp_sync = false; tk->i_pts = 0; + tk->i_npt = 0.; tk->i_buffer = 65536; tk->p_buffer = (uint8_t *)malloc( 65536 ); if( !tk->p_buffer ) @@ -993,25 +1005,13 @@ static int SessionsSetup( demux_t *p_demux ) delete iter; if( p_sys->i_track <= 0 ) i_return = VLC_EGENERIC; -#if (LIVEMEDIA_LIBRARY_VERSION_INT >= 1199404800) /* Retrieve the starttime if possible */ - p_sys->i_npt_start = (int64_t)( p_sys->ms->playStartTime() * (double)1000000.0 ); -#else - p_sys->i_npt_start = (int64_t) -1; -#endif - if( p_sys->i_npt_start < 0 ) - p_sys->i_npt_start = -1; + p_sys->i_npt_start = p_sys->ms->playStartTime(); -#if (LIVEMEDIA_LIBRARY_VERSION_INT >= 1199404800) /* Retrieve the duration if possible */ - p_sys->i_npt_length = (int64_t)( p_sys->ms->playEndTime() * (double)1000000.0 ); -#else - p_sys->i_npt_length = (int64_t) -1; -#endif - if( p_sys->i_npt_length < 0 ) - p_sys->i_npt_length = -1; + p_sys->i_npt_length = p_sys->ms->playEndTime(); - msg_Dbg( p_demux, "setup start: %lld stop:%lld", p_sys->i_npt_start, p_sys->i_npt_length ); + msg_Dbg( p_demux, "setup start: %f stop:%f", p_sys->i_npt_start, p_sys->i_npt_length ); return i_return; } @@ -1037,60 +1037,36 @@ static int Play( demux_t *p_demux ) if( p_sys->i_timeout <= 0 ) p_sys->i_timeout = 60; /* default value from RFC2326 */ - /* start timeout-thread only on x-asf streams (wms), it has rtcp support but doesn't - * seem to use it for liveness/keep-alive, get_parameter seems to work for it. get_parameter - * doesn't work with dss 5.5.4 & 5.5.5, they seems to work with rtcp */ - if( !p_sys->p_timeout && p_sys->p_out_asf ) + /* start timeout-thread only if GET_PARAMETER is supported by the server */ + if( !p_sys->p_timeout && p_sys->b_get_param ) { msg_Dbg( p_demux, "We have a timeout of %d seconds", p_sys->i_timeout ); - p_sys->p_timeout = (timeout_thread_t *)vlc_object_create( p_demux, sizeof(timeout_thread_t) ); - p_sys->p_timeout->p_sys = p_demux->p_sys; /* lol, object recursion :D */ - if( vlc_thread_create( p_sys->p_timeout, "liveMedia-timeout", TimeoutPrevention, - VLC_THREAD_PRIORITY_LOW, true ) ) + p_sys->p_timeout = (timeout_thread_t *)malloc( sizeof(timeout_thread_t) ); + if( p_sys->p_timeout ) { - msg_Err( p_demux, "cannot spawn liveMedia timeout thread" ); - vlc_object_release( p_sys->p_timeout ); + memset( p_sys->p_timeout, 0, sizeof(timeout_thread_t) ); + p_sys->p_timeout->p_sys = p_demux->p_sys; /* lol, object recursion :D */ + if( vlc_clone( &p_sys->p_timeout->handle, TimeoutPrevention, + p_sys->p_timeout, VLC_THREAD_PRIORITY_LOW ) ) + { + msg_Err( p_demux, "cannot spawn liveMedia timeout thread" ); + free( p_sys->p_timeout ); + p_sys->p_timeout = NULL; + } + else + msg_Dbg( p_demux, "spawned timeout thread" ); } - msg_Dbg( p_demux, "spawned timeout thread" ); - vlc_object_attach( p_sys->p_timeout, p_demux ); + else + msg_Err( p_demux, "cannot spawn liveMedia timeout thread" ); } } p_sys->i_pcr = 0; -#if (LIVEMEDIA_LIBRARY_VERSION_INT >= 1195257600) - for( i = 0; i < p_sys->i_track; i++ ) - { - if( !p_sys->track[i]->b_rtcp_sync ) - p_sys->track[i]->i_pts = (int64_t) ( p_sys->track[i]->sub->rtpInfo.timestamp * (double)1000000.0 ); - p_sys->track[i]->i_start_seq = (int)p_sys->track[i]->sub->rtpInfo.seqNum; - msg_Info( p_demux, "set startseq: %u", p_sys->track[i]->i_start_seq ); - } -#endif - -#if (LIVEMEDIA_LIBRARY_VERSION_INT >= 1199404800) /* Retrieve the starttime if possible */ - p_sys->i_npt_start = (int64_t)( p_sys->ms->playStartTime() * (double)1000000.0 ); -#else - p_sys->i_npt_start = -1; -#endif - if( p_sys->i_npt_start < 0 ) - { - p_sys->i_npt_start = -1; - p_sys->i_npt = 0; - } - else - p_sys->i_npt = p_sys->i_npt_start; + p_sys->i_npt_start = p_sys->ms->playStartTime(); + p_sys->i_npt_length = p_sys->ms->playEndTime(); -#if (LIVEMEDIA_LIBRARY_VERSION_INT >= 1199404800) - /* Retrieve the duration if possible */ - p_sys->i_npt_length = (int64_t)( p_sys->ms->playEndTime() * (double)1000000.0 ); -#else - p_sys->i_npt_length = -1; -#endif - if( p_sys->i_npt_length < 0 ) - p_sys->i_npt_length = -1; - - msg_Dbg( p_demux, "play start: %lld stop:%lld", p_sys->i_npt_start, p_sys->i_npt_length ); + msg_Dbg( p_demux, "play start: %f stop:%f", p_sys->i_npt_start, p_sys->i_npt_length ); return VLC_SUCCESS; } @@ -1103,7 +1079,7 @@ static int Demux( demux_t *p_demux ) demux_sys_t *p_sys = p_demux->p_sys; TaskToken task; - bool b_send_pcr = true; + bool b_send_pcr = true; int64_t i_pcr = 0; int i; @@ -1115,7 +1091,6 @@ static int Demux( demux_t *p_demux ) p_sys->b_timeout_call = false; } - for( i = 0; i < p_sys->i_track; i++ ) { live_track_t *tk = p_sys->track[i]; @@ -1175,7 +1150,9 @@ static int Demux( demux_t *p_demux ) tk->b_rtcp_sync = true; /* reset PCR */ tk->i_pts = 0; + tk->i_npt = 0.; p_sys->i_pcr = 0; + p_sys->i_npt = 0.; i_pcr = 0; } } @@ -1202,14 +1179,12 @@ static int Demux( demux_t *p_demux ) msg_Err( p_demux, "TCP rollover failed, aborting" ); return 0; } + return 1; } - else if( p_sys->i_no_data_ti > 34 ) - { - msg_Err( p_demux, "no data received in 10s, aborting" ); - return 0; - } + msg_Err( p_demux, "no data received in 10s, aborting" ); + return 0; } - else if( !p_sys->b_multicast && p_sys->b_no_data && p_sys->i_no_data_ti > 34 ) + else if( !p_sys->b_multicast && p_sys->i_no_data_ti > 34 ) { /* EOF ? */ msg_Warn( p_demux, "no data received in 10s, eof ?" ); @@ -1224,7 +1199,7 @@ static int Demux( demux_t *p_demux ) static int Control( demux_t *p_demux, int i_query, va_list args ) { demux_sys_t *p_sys = p_demux->p_sys; - int64_t *pi64; + int64_t *pi64, i64; double *pf, f; bool *pb, *pb2, b_bool; int *pi_int; @@ -1235,7 +1210,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) pi64 = (int64_t*)va_arg( args, int64_t * ); if( p_sys->i_npt > 0 ) { - *pi64 = p_sys->i_npt; + *pi64 = (int64_t)(p_sys->i_npt * 1000000.); return VLC_SUCCESS; } return VLC_EGENERIC; @@ -1244,81 +1219,71 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) pi64 = (int64_t*)va_arg( args, int64_t * ); if( p_sys->i_npt_length > 0 ) { - *pi64 = p_sys->i_npt_length; + *pi64 = p_sys->i_npt_length * 1000000.0; return VLC_SUCCESS; } return VLC_EGENERIC; case DEMUX_GET_POSITION: pf = (double*)va_arg( args, double* ); - if( p_sys->i_npt_length > 0 && p_sys->i_npt > 0 ) + if( p_sys->i_npt_length > 0 && p_sys->i_npt > 0) { - *pf = (double)p_sys->i_npt / (double)p_sys->i_npt_length; + *pf = ( (double)p_sys->i_npt / (double)p_sys->i_npt_length ); return VLC_SUCCESS; } return VLC_EGENERIC; case DEMUX_SET_POSITION: - { - float time; - - f = (double)va_arg( args, double ); + case DEMUX_SET_TIME: if( p_sys->rtsp && p_sys->i_npt_length > 0 ) { int i; - time = f * (double)p_sys->i_npt_length / (double)1000000.0; /* in second */ + float time; + + if( i_query == DEMUX_SET_TIME && p_sys->i_npt > 0 ) + { + i64 = (int64_t)va_arg( args, int64_t ); + time = (float)((double)i64 / (double)1000000.0); /* in second */ + } + else if( i_query == DEMUX_SET_TIME ) + return VLC_EGENERIC; + else + { + f = (double)va_arg( args, double ); + time = f * (double)p_sys->i_npt_length; /* in second */ + } + if( !p_sys->rtsp->playMediaSession( *p_sys->ms, time, -1, 1 ) ) { msg_Err( p_demux, "PLAY failed %s", p_sys->env->getResultMsg() ); return VLC_EGENERIC; } - es_out_Control( p_demux->out, ES_OUT_RESET_PCR ); p_sys->i_pcr = 0; -#if (LIVEMEDIA_LIBRARY_VERSION_INT >= 1195257600) + /* Retrieve RTP-Info values */ for( i = 0; i < p_sys->i_track; i++ ) { - //if( !p_sys->track[i]->b_rtcp_sync ) p_sys->track[i]->b_rtcp_sync = false; - p_sys->track[i]->i_pts = (int64_t) ( p_sys->track[i]->sub->rtpInfo.timestamp * (double)1000000.0 ); - p_sys->track[i]->i_start_seq = p_sys->track[i]->sub->rtpInfo.seqNum; - msg_Info( p_demux, "set pos startseq: %u", p_sys->track[i]->i_start_seq ); + p_sys->track[i]->i_pts = 0; } -#endif -#if (LIVEMEDIA_LIBRARY_VERSION_INT >= 1199404800) + /* Retrieve the starttime if possible */ - p_sys->i_npt_start = (int64_t)( p_sys->ms->playStartTime() * (double)1000000.0 ); -#else - p_sys->i_npt_start = -1; -#endif - if( p_sys->i_npt_start < 0 ) - { - p_sys->i_npt_start = -1; - p_sys->i_npt = 0; - } - else - p_sys->i_npt = p_sys->i_npt_start; + p_sys->i_npt = p_sys->i_npt_start = p_sys->ms->playStartTime(); -#if (LIVEMEDIA_LIBRARY_VERSION_INT >= 1199404800) /* Retrieve the duration if possible */ - p_sys->i_npt_length = (int64_t)( p_sys->ms->playEndTime() * (double)1000000.0 ); -#else - p_sys->i_npt_length = -1; -#endif - if( p_sys->i_npt_length < 0 ) - p_sys->i_npt_length = -1; + p_sys->i_npt_length = p_sys->ms->playEndTime(); - msg_Dbg( p_demux, "seek start: %lld stop:%lld", p_sys->i_npt_start, p_sys->i_npt_length ); + msg_Dbg( p_demux, "seek start: %f stop:%f", p_sys->i_npt_start, p_sys->i_npt_length ); return VLC_SUCCESS; } return VLC_EGENERIC; - } + /* Special for access_demux */ case DEMUX_CAN_PAUSE: case DEMUX_CAN_SEEK: pb = (bool*)va_arg( args, bool * ); - if( p_sys->rtsp && p_sys->i_npt_length ) + if( p_sys->rtsp && p_sys->i_npt_length > 0 ) /* Not always true, but will be handled in SET_PAUSE_STATE */ *pb = true; else @@ -1378,7 +1343,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) /* ReSync the stream */ p_sys->i_npt_start = 0; p_sys->i_pcr = 0; - es_out_Control( p_demux->out, ES_OUT_RESET_PCR ); + p_sys->i_npt = 0.; *pi_int = (int)( INPUT_RATE_DEFAULT / p_sys->ms->scale() + 0.5 ); return VLC_SUCCESS; @@ -1387,7 +1352,6 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) case DEMUX_SET_PAUSE_STATE: { - double d_npt = (double) p_sys->i_npt / INT64_C(1000000); int i; b_bool = (bool)va_arg( args, int ); @@ -1397,7 +1361,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) /* FIXME */ if( ( b_bool && !p_sys->rtsp->pauseMediaSession( *p_sys->ms ) ) || ( !b_bool && !p_sys->rtsp->playMediaSession( *p_sys->ms, - d_npt > 0 ? d_npt : -1 ) ) ) + -1 ) ) ) { msg_Err( p_demux, "PLAY or PAUSE failed %s", p_sys->env->getResultMsg() ); return VLC_EGENERIC; @@ -1416,41 +1380,22 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) else if( !b_bool && p_sys->p_timeout != NULL ) p_sys->p_timeout->b_handle_keep_alive = false; - es_out_Control( p_demux->out, ES_OUT_RESET_PCR ); - p_sys->i_pcr = 0; -#if (LIVEMEDIA_LIBRARY_VERSION_INT >= 1195257600) - for( i = 0; i < p_sys->i_track; i++ ) + for( i = 0; !b_bool && i < p_sys->i_track; i++ ) { - if( !p_sys->track[i]->b_rtcp_sync ) - p_sys->track[i]->i_pts = 0; // (int64_t) ( p_sys->track[i]->sub->rtpInfo.timestamp * (double)1000000.0 ); - p_sys->track[i]->i_start_seq = p_sys->track[i]->sub->rtpInfo.seqNum; - msg_Info( p_demux, "set pause startseq: %u", p_sys->track[i]->i_start_seq ); + live_track_t *tk = p_sys->track[i]; + tk->b_rtcp_sync = false; + tk->i_pts = 0; + p_sys->i_pcr = 0; + es_out_Control( p_demux->out, ES_OUT_RESET_PCR ); } -#endif -#if (LIVEMEDIA_LIBRARY_VERSION_INT >= 1199404800) + /* Retrieve the starttime if possible */ - p_sys->i_npt_start = (int64_t)( p_sys->ms->playStartTime() * (double)1000000.0 ); -#else - p_sys->i_npt_start = -1; -#endif - if( p_sys->i_npt_start < 0 ) - { - p_sys->i_npt_start = -1; - p_sys->i_npt = 0; - } - else - p_sys->i_npt = p_sys->i_npt_start; + p_sys->i_npt = p_sys->i_npt_start = p_sys->ms->playStartTime(); -#if (LIVEMEDIA_LIBRARY_VERSION_INT >= 1199404800) /* Retrieve the duration if possible */ - p_sys->i_npt_length = (int64_t)( p_sys->ms->playEndTime() * (double)1000000.0 ); -#else - p_sys->i_npt_length = -1; -#endif - if( p_sys->i_npt_length < 0 ) - p_sys->i_npt_length = -1; + p_sys->i_npt_length = p_sys->ms->playEndTime(); - msg_Dbg( p_demux, "pause start: %lld stop:%lld", p_sys->i_npt_start, p_sys->i_npt_length ); + msg_Dbg( p_demux, "pause start: %f stop:%f", p_sys->i_npt_start, p_sys->i_npt_length ); return VLC_SUCCESS; } case DEMUX_GET_TITLE_INFO: @@ -1486,6 +1431,7 @@ static int RollOverTcp( demux_t *p_demux ) live_track_t *tk = p_sys->track[i]; if( tk->b_muxed ) stream_DemuxDelete( tk->p_out_muxed ); + if( tk->p_es ) es_out_Del( p_demux->out, tk->p_es ); es_format_Clean( &tk->fmt ); free( tk->p_buffer ); free( tk ); @@ -1503,8 +1449,7 @@ static int RollOverTcp( demux_t *p_demux ) p_sys->i_track = 0; /* Reopen rtsp client */ - if( ( p_demux->s != NULL ) && - ( i_return = Connect( p_demux ) ) != VLC_SUCCESS ) + if( ( i_return = Connect( p_demux ) ) != VLC_SUCCESS ) { msg_Err( p_demux, "Failed to connect with rtsp://%s", p_sys->psz_path ); @@ -1547,11 +1492,14 @@ static void StreamRead( void *p_private, unsigned int i_size, //msg_Dbg( p_demux, "pts: %d", pts.tv_sec ); - int64_t i_pts = (uint64_t)pts.tv_sec * UINT64_C(1000000) + - (uint64_t)pts.tv_usec; + int64_t i_pts = (int64_t)pts.tv_sec * INT64_C(1000000) + + (int64_t)pts.tv_usec; /* XXX Beurk beurk beurk Avoid having negative value XXX */ - i_pts &= UINT64_C(0x00ffffffffffffff); + i_pts &= INT64_C(0x00ffffffffffffff); + + /* Retrieve NPT for this pts */ + tk->i_npt = tk->sub->getNormalPlayTime(pts); if( tk->b_quicktime && tk->p_es == NULL ) { @@ -1652,13 +1600,8 @@ static void StreamRead( void *p_private, unsigned int i_size, } else if( tk->fmt.i_codec == VLC_FOURCC('H','2','6','1') ) { -#if LIVEMEDIA_LIBRARY_VERSION_INT >= 1081468800 H261VideoRTPSource *h261Source = (H261VideoRTPSource*)tk->sub->rtpSource(); uint32_t header = h261Source->lastSpecialHeader(); -#else - uint32_t header = 0; - msg_Warn( p_demux, "need livemedia library >= \"2004.04.09\"" ); -#endif p_block = block_New( p_demux, i_size + 4 ); memcpy( p_block->p_buffer, &header, 4 ); memcpy( p_block->p_buffer + 4, tk->p_buffer, i_size ); @@ -1692,25 +1635,20 @@ static void StreamRead( void *p_private, unsigned int i_size, memcpy( p_block->p_buffer, tk->p_buffer, i_size ); } - /* Update NPT */ - //msg_Dbg( p_demux, "current %d, start_seq %u", (int)tk->sub->rtpSource()->curPacketRTPSeqNum(), tk->i_start_seq ); - if( (tk->fmt.i_cat == VIDEO_ES) && (p_sys->i_pcr < i_pts) && - (i_pts > 0) && (p_sys->i_pcr > 0) ) - { - p_sys->i_npt += __MAX( 0, i_pts - p_sys->i_pcr ); - p_sys->i_pcr = i_pts; - //msg_Dbg( p_demux, "npt update" ); - } - else if( /*tk->fmt.i_cat == VIDEO_ES &&*/ p_sys->i_pcr < i_pts ) + if( p_sys->i_pcr < i_pts ) { p_sys->i_pcr = i_pts; } - //msg_Dbg( p_demux, "npt %lld", p_sys->i_npt ); if( (i_pts != tk->i_pts) && (!tk->b_muxed) ) { p_block->i_pts = i_pts; } + + /* Update our global npt value */ + if( tk->i_npt > 0 && tk->i_npt > p_sys->i_npt && tk->i_npt < p_sys->i_npt_length) + p_sys->i_npt = tk->i_npt; + if( !tk->b_muxed ) { /*FIXME: for h264 you should check that packetization-mode=1 in sdp-file */ @@ -1776,38 +1714,26 @@ static void TaskInterrupt( void *p_private ) /***************************************************************************** * *****************************************************************************/ -static void TimeoutPrevention( timeout_thread_t *p_timeout ) +static void* TimeoutPrevention( void *p_data ) { - p_timeout->b_die = false; - p_timeout->i_remain = (int64_t)p_timeout->p_sys->i_timeout -2; - p_timeout->i_remain *= 1000000; - - vlc_thread_ready( p_timeout ); + timeout_thread_t *p_timeout = (timeout_thread_t *)p_data; - /* Avoid lock */ - while( !p_timeout->b_die ) + for( ;; ) { - if( p_timeout->i_remain <= 0 ) + /* Voodoo (= no) thread safety here! *Ahem* */ + if( p_timeout->b_handle_keep_alive ) { char *psz_bye = NULL; - p_timeout->i_remain = (int64_t)p_timeout->p_sys->i_timeout -2; - p_timeout->i_remain *= 1000000; - msg_Dbg( p_timeout, "reset the timeout timer" ); - if( p_timeout->b_handle_keep_alive == true ) - { -#if LIVEMEDIA_LIBRARY_VERSION_INT >= 1138089600 - p_timeout->p_sys->rtsp->getMediaSessionParameter( *p_timeout->p_sys->ms, NULL, psz_bye ); -#endif - p_timeout->p_sys->b_timeout_call = false; - } - else - { - p_timeout->p_sys->b_timeout_call = true; - } + int canc = vlc_savecancel (); + + p_timeout->p_sys->rtsp->getMediaSessionParameter( *p_timeout->p_sys->ms, NULL, psz_bye ); + vlc_restorecancel (canc); } - p_timeout->i_remain -= 200000; - msleep( 200000 ); /* 200 ms */ + p_timeout->p_sys->b_timeout_call = !p_timeout->b_handle_keep_alive; + + msleep (((int64_t)p_timeout->p_sys->i_timeout - 2) * CLOCK_FREQ); } + assert(0); /* dead code */ } /*****************************************************************************