From 925407b099b381f2cd5137b82e92b864e63eca5c Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Mon, 10 Mar 2008 00:06:48 -0300 Subject: Support # stream parameter separator in raw filenames as well as in full MRLs. Changeset 8ffe18290ba5 fixed bug 1784272 (opening raw filenames with # character, like "show #1.mpg") but at the cost of killing # separator in raw filenames completely. Although this might be a valid requirement in a new devel branch, imho, such change in stable branch should be considered a regression. The original idea of passing partial MRL for the input plugins to try doesn't work because plugin will generate error messages for every failed attempt to open the file (like "show " above), even thought the complete MRL is valid and will be played. So, since raw filenames are an exception for the MRL scheme anyway, we try stat'ing the partial filenames to determine what user means with the #. --- src/xine-engine/xine.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) (limited to 'src/xine-engine') diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index e9251267b..841f966d1 100644 --- a/src/xine-engine/xine.c +++ b/src/xine-engine/xine.c @@ -36,6 +36,7 @@ #include #include #include +#include #if defined (__linux__) || defined (__GLIBC__) #include #elif defined (__FreeBSD__) @@ -796,6 +797,7 @@ static inline int _x_path_looks_like_mrl (const char *path) /*static*/ int open_internal (xine_stream_t *stream, const char *mrl) { const char *stream_setup = NULL; + const char *mrl_proto = NULL; int no_cache = 0; if (!mrl) { @@ -819,16 +821,31 @@ static inline int _x_path_looks_like_mrl (const char *path) /* * look for a stream_setup in MRL and try finding an input plugin */ + stream_setup = strchr (mrl, '#'); if (isalpha (*mrl)) { - stream_setup = mrl + 1; - while (isalnum (*stream_setup) || *stream_setup == '+' || *stream_setup == '-' || *stream_setup == '.') - ++stream_setup; - if (stream_setup[0] == ':' && stream_setup[1] == '/') - stream_setup = strchr (mrl, '#'); - else - stream_setup = NULL; + mrl_proto = mrl + 1; + while (isalnum (*mrl_proto) || *mrl_proto == '+' || *mrl_proto == '-' || *mrl_proto == '.') + ++mrl_proto; + if (!mrl_proto[0] || mrl_proto[0] != ':' || mrl_proto[1] != '/') + mrl_proto = NULL; + } + + /* for raw filenames we must try every '#' checking if it is part of the filename */ + if( !mrl_proto && stream_setup) { + struct stat stat_buf; + int res; + + while( stream_setup ) { + char *raw_filename = strndup (mrl, stream_setup - mrl); + + res = stat(raw_filename, &stat_buf); + free(raw_filename); + if( !res ) + break; + stream_setup = strchr(stream_setup + 1, '#'); + } } { @@ -837,8 +854,10 @@ static inline int _x_path_looks_like_mrl (const char *path) /* * find an input plugin */ - - if ((stream->input_plugin = _x_find_input_plugin (stream, input_source))) { + stream->input_plugin = _x_find_input_plugin (stream, input_source); + free(input_source); + + if ( stream->input_plugin ) { int res; xine_log (stream->xine, XINE_LOG_MSG, _("xine: found input plugin : %s\n"), @@ -853,7 +872,6 @@ static inline int _x_path_looks_like_mrl (const char *path) case 1: /* Open successfull */ break; case -1: /* Open unsuccessfull, but correct plugin */ - free(input_source); stream->err = XINE_ERROR_INPUT_FAILED; _x_flush_events_queues (stream); return 0; @@ -864,8 +882,6 @@ static inline int _x_path_looks_like_mrl (const char *path) stream->err = XINE_ERROR_INPUT_FAILED; } } - - free(input_source); } if (!stream->input_plugin) { -- cgit v1.2.3 From d3572a729ae098dba38d27a2b1914b6ca17c4de1 Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Mon, 10 Mar 2008 23:11:49 -0300 Subject: Fixed long delay when closing stream on dual core systems [Bug #33] --- src/xine-engine/demux.c | 15 ++++++++++----- src/xine-engine/xine.c | 3 +++ src/xine-engine/xine_internal.h | 1 + 3 files changed, 14 insertions(+), 5 deletions(-) (limited to 'src/xine-engine') diff --git a/src/xine-engine/demux.c b/src/xine-engine/demux.c index f33397256..24ee1b86d 100644 --- a/src/xine-engine/demux.c +++ b/src/xine-engine/demux.c @@ -198,6 +198,7 @@ void _x_demux_control_headers_done (xine_stream_t *stream) { } stream->demux_action_pending = 0; + pthread_cond_signal(&stream->demux_resume); lprintf ("headers processed.\n"); @@ -284,12 +285,14 @@ static void *demux_loop (void *stream_gen) { /* someone may want to interrupt us */ if( stream->demux_action_pending ) { - pthread_mutex_unlock( &stream->demux_lock ); + struct timeval tv; + struct timespec ts; - lprintf ("sched_yield\n"); - - sched_yield(); - pthread_mutex_lock( &stream->demux_lock ); + gettimeofday(&tv, NULL); + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = (tv.tv_usec + 100000) * 1000; + + pthread_cond_timedwait (&stream->demux_resume, &stream->demux_lock, &ts); } } @@ -365,6 +368,7 @@ int _x_demux_start_thread (xine_stream_t *stream) { stream->demux_action_pending = 1; pthread_mutex_lock( &stream->demux_lock ); stream->demux_action_pending = 0; + pthread_cond_signal(&stream->demux_resume); if( !stream->demux_thread_running ) { @@ -396,6 +400,7 @@ int _x_demux_stop_thread (xine_stream_t *stream) { pthread_mutex_lock( &stream->demux_lock ); stream->demux_thread_running = 0; stream->demux_action_pending = 0; + pthread_cond_signal(&stream->demux_resume); /* At that point, the demuxer has sent the last audio/video buffer, * so it's a safe place to flush the engine. diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index 841f966d1..c207680e6 100644 --- a/src/xine-engine/xine.c +++ b/src/xine-engine/xine.c @@ -629,6 +629,7 @@ xine_stream_t *xine_stream_new (xine_t *this, pthread_mutex_init (&stream->meta_mutex, NULL); pthread_mutex_init (&stream->demux_lock, NULL); pthread_mutex_init (&stream->demux_mutex, NULL); + pthread_cond_init (&stream->demux_resume, NULL); pthread_mutex_init (&stream->event_queues_lock, NULL); pthread_mutex_init (&stream->counter_lock, NULL); pthread_cond_init (&stream->counter_changed, NULL); @@ -1322,6 +1323,7 @@ static int play_internal (xine_stream_t *stream, int start_pos, int start_time) pthread_mutex_lock( &stream->demux_lock ); /* demux_lock taken. now demuxer is suspended */ stream->demux_action_pending = 0; + pthread_cond_signal(&stream->demux_resume); /* set normal speed again (now that demuxer/input pair is suspended) * some input plugin may have changed speed by itself, we must ensure @@ -1448,6 +1450,7 @@ void xine_dispose_internal (xine_stream_t *stream) { pthread_mutex_destroy (&stream->current_extra_info_lock); pthread_cond_destroy (&stream->counter_changed); pthread_mutex_destroy (&stream->demux_mutex); + pthread_cond_destroy (&stream->demux_resume); pthread_mutex_destroy (&stream->demux_lock); pthread_mutex_destroy (&stream->first_frame_lock); pthread_cond_destroy (&stream->first_frame_reached); diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h index 9b69f16f1..8fb4723a5 100644 --- a/src/xine-engine/xine_internal.h +++ b/src/xine-engine/xine_internal.h @@ -333,6 +333,7 @@ struct xine_stream_s { int demux_thread_running; pthread_mutex_t demux_lock; int demux_action_pending; + pthread_cond_t demux_resume; pthread_mutex_t demux_mutex; /* used in _x_demux_... functions to synchronize order of pairwise A/V buffer operations */ extra_info_t *current_extra_info; -- cgit v1.2.3