diff options
author | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2003-04-23 14:33:01 +0000 |
---|---|---|
committer | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2003-04-23 14:33:01 +0000 |
commit | a3a060c862eafe9e8e204a3d208a585457246879 (patch) | |
tree | b72599d8b0db4691b1fd9ed3bb2cafddc3b87783 /src/xine-engine/xine.c | |
parent | 774c7546d0e1308abda154de9279c3e4f8a4537b (diff) | |
download | xine-lib-a3a060c862eafe9e8e204a3d208a585457246879.tar.gz xine-lib-a3a060c862eafe9e8e204a3d208a585457246879.tar.bz2 |
faster seeking (heavily based on Thibaut's patch)
rework xine_play_internal, wait for first frame after seek
CVS patchset: 4660
CVS date: 2003/04/23 14:33:01
Diffstat (limited to 'src/xine-engine/xine.c')
-rw-r--r-- | src/xine-engine/xine.c | 81 |
1 files changed, 47 insertions, 34 deletions
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index 5bba920cd..373541243 100644 --- a/src/xine-engine/xine.c +++ b/src/xine-engine/xine.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine.c,v 1.244 2003/04/22 23:30:55 tchamp Exp $ + * $Id: xine.c,v 1.245 2003/04/23 14:33:05 miguelfreitas Exp $ * * top-level xine functions * @@ -903,21 +903,25 @@ static int xine_play_internal (xine_stream_t *stream, int start_pos, int start_t if (stream->xine->clock->speed != XINE_SPEED_NORMAL) xine_set_speed_internal (stream, XINE_SPEED_NORMAL); - /* Wait until the first frame produced by the previous - * xine_play call is pushed into the video_out fifo - * see video_out.c - */ - pthread_mutex_lock (&stream->first_frame_lock); - /* FIXME: howto detect if video frames will be produced */ - if (stream->first_frame_flag && stream->video_decoder_plugin) { - struct timeval tv; - struct timespec ts; - gettimeofday(&tv, NULL); - ts.tv_sec = tv.tv_sec + 2; - ts.tv_nsec = tv.tv_usec * 1000; - pthread_cond_timedwait(&stream->first_frame_reached, &stream->first_frame_lock, &ts); + if (!stream->demux_plugin) { + xine_log (stream->xine, XINE_LOG_MSG, + _("xine_play: no demux available\n")); + stream->err = XINE_ERROR_NO_DEMUX_PLUGIN; + + return 0; } - pthread_mutex_unlock (&stream->first_frame_lock); + + /* hint demuxer thread we want to interrupt it */ + stream->demux_action_pending = 1; + + /* discard audio/video buffers to get engine going and take the lock faster */ + if (stream->audio_out) + stream->audio_out->set_property(stream->audio_out, AO_PROP_DISCARD_BUFFERS, 1); + if (stream->video_out) + stream->video_out->set_property(stream->video_out, VO_PROP_DISCARD_FRAMES, 1); + + pthread_mutex_lock( &stream->demux_lock ); + /* demux_lock taken. now demuxer is suspended */ /* * start/seek demux @@ -926,7 +930,6 @@ static int xine_play_internal (xine_stream_t *stream, int start_pos, int start_t pthread_mutex_lock( &stream->current_extra_info_lock ); len = stream->current_extra_info->input_length; pthread_mutex_unlock( &stream->current_extra_info_lock ); - /* FIXME: do we need to protect concurrent access to input plugin here? */ if ((len == 0) && stream->input_plugin) len = stream->input_plugin->get_length (stream->input_plugin); share = (double) start_pos / 65535; @@ -934,30 +937,28 @@ static int xine_play_internal (xine_stream_t *stream, int start_pos, int start_t } else pos = 0; - if (!stream->demux_plugin) { - xine_log (stream->xine, XINE_LOG_MSG, - _("xine_play: no demux available\n")); - stream->err = XINE_ERROR_NO_DEMUX_PLUGIN; - - return 0; - } - - stream->demux_action_pending = 1; - if (stream->audio_out) - stream->audio_out->set_property(stream->audio_out, AO_PROP_DISCARD_BUFFERS, 1); - if (stream->video_out) - stream->video_out->set_property(stream->video_out, VO_PROP_DISCARD_FRAMES, 1); - pthread_mutex_lock( &stream->demux_lock ); + /* seek to new position (no data is sent to decoders yet) */ demux_status = stream->demux_plugin->seek (stream->demux_plugin, pos, start_time); + stream->demux_action_pending = 0; + if (stream->audio_out) stream->audio_out->set_property(stream->audio_out, AO_PROP_DISCARD_BUFFERS, 0); if (stream->video_out) stream->video_out->set_property(stream->video_out, VO_PROP_DISCARD_FRAMES, 0); + + /* before resuming the demuxer, set first_frame_flag */ pthread_mutex_lock (&stream->first_frame_lock); - stream->first_frame_flag = 1; + stream->first_frame_flag = 2; pthread_mutex_unlock (&stream->first_frame_lock); + + /* before resuming the demuxer, reset current position information */ + pthread_mutex_lock( &stream->current_extra_info_lock ); + extra_info_reset( stream->current_extra_info ); + pthread_mutex_unlock( &stream->current_extra_info_lock ); + + /* now resume demuxer thread if it is running already */ pthread_mutex_unlock( &stream->demux_lock ); if (demux_status != DEMUX_OK) { @@ -973,9 +974,21 @@ static int xine_play_internal (xine_stream_t *stream, int start_pos, int start_t stream->status = XINE_STATUS_PLAY; } - pthread_mutex_lock( &stream->current_extra_info_lock ); - extra_info_reset( stream->current_extra_info ); - pthread_mutex_unlock( &stream->current_extra_info_lock ); + + /* Wait until the first frame produced is displayed + * see video_out.c + */ + pthread_mutex_lock (&stream->first_frame_lock); + /* FIXME: howto detect if video frames will be produced */ + if (stream->first_frame_flag && stream->video_decoder_plugin) { + struct timeval tv; + struct timespec ts; + gettimeofday(&tv, NULL); + ts.tv_sec = tv.tv_sec + 2; + ts.tv_nsec = tv.tv_usec * 1000; + pthread_cond_timedwait(&stream->first_frame_reached, &stream->first_frame_lock, &ts); + } + pthread_mutex_unlock (&stream->first_frame_lock); if (stream->xine->verbosity >= XINE_VERBOSITY_DEBUG) printf ("xine: xine_play_internal ...done\n"); |