Update of /cvsroot/xine/xine-lib/src/xine-engine In directory usw-pr-cvs1:/tmp/cvs-serv19763/src/xine-engine Modified Files: audio_decoder.c buffer.h metronom.c osd.c video_decoder.c video_out.c xine.c xine_internal.h Log Message: - new (fast) demuxer seeking scheme - updated decoder api to allow reseting internal state on seeks Index: audio_decoder.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/xine-engine/audio_decoder.c,v retrieving revision 1.69 retrieving revision 1.70 diff -u -r1.69 -r1.70 --- audio_decoder.c 6 Apr 2002 02:56:04 -0000 1.69 +++ audio_decoder.c 9 Apr 2002 03:38:01 -0000 1.70 @@ -70,7 +70,7 @@ if (buf->input_time) this->cur_input_time = buf->input_time; - + switch (buf->type) { case BUF_CONTROL_START: @@ -128,20 +128,16 @@ case BUF_CONTROL_NOP: break; - case BUF_CONTROL_DISCONTINUITY: - /* reseting decoder on discontinuities is needed to make sure there will - * be no held back pts values. it's unlikely that it would do any harm - * given metronom's in_discontinuity counter but, at least in theory, - * we might have problems with still frame + audio dvd menus. - */ + case BUF_CONTROL_RESET_DECODER: if (this->cur_audio_decoder_plugin) - this->cur_audio_decoder_plugin->reset (this->cur_audio_decoder_plugin); + this->cur_audio_decoder_plugin->reset (this->cur_audio_decoder_plugin); + break; + + case BUF_CONTROL_DISCONTINUITY: this->metronom->handle_audio_discontinuity (this->metronom, DISC_RELATIVE, buf->disc_off); break; case BUF_CONTROL_NEWPTS: - if (this->cur_audio_decoder_plugin) - this->cur_audio_decoder_plugin->reset (this->cur_audio_decoder_plugin); this->metronom->handle_audio_discontinuity (this->metronom, DISC_ABSOLUTE, buf->disc_off); break; Index: buffer.h =================================================================== RCS file: /cvsroot/xine/xine-lib/src/xine-engine/buffer.h,v retrieving revision 1.38 retrieving revision 1.39 diff -u -r1.38 -r1.39 --- buffer.h 24 Mar 2002 14:15:37 -0000 1.38 +++ buffer.h 9 Apr 2002 03:38:01 -0000 1.39 @@ -70,7 +70,7 @@ #define BUF_CONTROL_AUDIO_CHANNEL 0x01050000 #define BUF_CONTROL_SPU_CHANNEL 0x01060000 #define BUF_CONTROL_NEWPTS 0x01070000 -#define BUF_CONTROL_SEEK 0x01080000 +#define BUF_CONTROL_RESET_DECODER 0x01080000 /* video buffer types: (please keep in sync with buffer_types.c) */ Index: metronom.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/xine-engine/metronom.c,v retrieving revision 1.79 retrieving revision 1.80 diff -u -r1.79 -r1.80 --- metronom.c 7 Apr 2002 12:09:38 -0000 1.79 +++ metronom.c 9 Apr 2002 03:38:01 -0000 1.80 @@ -368,14 +368,12 @@ #endif if (abs (diff) > VIDEO_DRIFT_TOLERANCE) { - + this->video_vpts = vpts; this->video_drift = 0; - -#ifdef LOG + printf ("metronom: video jump\n"); -#endif - + } else { this->video_drift = diff; Index: osd.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/xine-engine/osd.c,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- osd.c 14 Mar 2002 13:57:15 -0000 1.15 +++ osd.c 9 Apr 2002 03:38:01 -0000 1.16 @@ -252,12 +252,6 @@ this->event.vpts = vpts; this->video_overlay->add_event(this->video_overlay,(void *)&this->event); - this->event.event_type = EVENT_FREE_HANDLE; - this->event.vpts = vpts+1; - this->video_overlay->add_event(this->video_overlay,(void *)&this->event); - - osd->handle = -1; /* handle will be freed */ - pthread_mutex_unlock (&this->osd_mutex); return 1; @@ -777,6 +771,16 @@ if( osd_to_close->handle >= 0 ) { osd_hide(osd_to_close,0); + + this->event.object.handle = osd_to_close->handle; + + /* not really needed this, but good pratice to clean it up */ + memset( this->event.object.overlay, 0, sizeof(this->event.object.overlay) ); + this->event.event_type = EVENT_FREE_HANDLE; + this->event.vpts = 0; + this->video_overlay->add_event(this->video_overlay,(void *)&this->event); + + osd_to_close->handle = -1; /* handle will be freed */ } pthread_mutex_lock (&this->osd_mutex); Index: video_decoder.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/xine-engine/video_decoder.c,v retrieving revision 1.80 retrieving revision 1.81 diff -u -r1.80 -r1.81 --- video_decoder.c 27 Mar 2002 15:30:16 -0000 1.80 +++ video_decoder.c 9 Apr 2002 03:38:01 -0000 1.81 @@ -181,13 +181,19 @@ running = 0; break; + case BUF_CONTROL_RESET_DECODER: + if (this->cur_video_decoder_plugin) { + this->cur_video_decoder_plugin->reset (this->cur_video_decoder_plugin); + } + break; + case BUF_CONTROL_DISCONTINUITY: printf ("video_decoder: discontinuity ahead\n"); this->video_in_discontinuity = 1; this->metronom->handle_video_discontinuity (this->metronom, DISC_RELATIVE, buf->disc_off); - + this->video_in_discontinuity = 0; break; @@ -197,7 +203,7 @@ this->video_in_discontinuity = 1; this->metronom->handle_video_discontinuity (this->metronom, DISC_ABSOLUTE, buf->disc_off); - + this->video_in_discontinuity = 0; break; @@ -301,8 +307,5 @@ this->video_fifo->put (this->video_fifo, buf); pthread_join (this->video_thread, &p); - - this->video_out->exit (this->video_out); - this->video_fifo->dispose (this->video_fifo); } Index: video_out.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/xine-engine/video_out.c,v retrieving revision 1.92 retrieving revision 1.93 diff -u -r1.92 -r1.93 --- video_out.c 2 Apr 2002 19:29:09 -0000 1.92 +++ video_out.c 9 Apr 2002 03:38:01 -0000 1.93 @@ -666,11 +666,14 @@ diff = vpts - this->last_delivery_pts; if (diff > 30000 && !this->display_img_buf_queue->first) { if (this->xine->cur_video_decoder_plugin) { - this->xine->cur_video_decoder_plugin->flush(this->xine->cur_video_decoder_plugin); #ifdef LOG - printf ("video_out: flushing current video decoder plugin\n"); + printf ("video_out: flushing current video decoder plugin (%d %d)\n", + this->display_img_buf_queue->num_buffers, + this->free_img_buf_queue->num_buffers); #endif + + this->xine->cur_video_decoder_plugin->flush(this->xine->cur_video_decoder_plugin); } this->last_delivery_pts = vpts; } @@ -700,6 +703,10 @@ usec_to_sleep, vpts); #endif + if ( (next_frame_vpts - vpts) > 2*90000 ) + printf("video_out: vpts/clock error, next_vpts=%lld cur_vpts=%lld\n", + next_frame_vpts,vpts); + if (usec_to_sleep>0) xine_usec_sleep (usec_to_sleep); Index: xine.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/xine-engine/xine.c,v retrieving revision 1.113 retrieving revision 1.114 diff -u -r1.113 -r1.114 --- xine.c 24 Mar 2002 14:15:37 -0000 1.113 +++ xine.c 9 Apr 2002 03:38:01 -0000 1.114 @@ -92,6 +92,33 @@ } } +/* internal use only - called from demuxers on seek/stop + * warning: after clearing decoders fifos an absolute discontinuity + * indication must be sent. relative discontinuities are likely + * to cause "jumps" on metronom. + */ +void xine_flush_engine (xine_t *this) { + + buf_element_t *buf; + + this->video_fifo->clear(this->video_fifo); + if( this->audio_fifo ) + this->audio_fifo->clear(this->audio_fifo); + + buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); + buf->type = BUF_CONTROL_RESET_DECODER; + this->video_fifo->put (this->video_fifo, buf); + + if(this->audio_fifo) { + buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); + buf->type = BUF_CONTROL_RESET_DECODER; + this->audio_fifo->put (this->audio_fifo, buf); + } + + this->metronom->adjust_clock(this->metronom, + this->metronom->get_current_time(this->metronom) + 30 * 90000 ); +} + static void xine_internal_osd (xine_t *this, char *str, uint32_t start_time, uint32_t duration) { @@ -282,10 +309,10 @@ pthread_mutex_lock (&this->xine_lock); /* - * stop engine? + * stop engine only for different mrl */ - if (this->status == XINE_PLAY) { + if (this->status == XINE_PLAY && strcmp (mrl, this->cur_mrl) ) { if(this->cur_demuxer_plugin) { this->cur_demuxer_plugin->stop (this->cur_demuxer_plugin); @@ -305,76 +332,82 @@ this->status = XINE_STOP; } - /* - * find input plugin - */ - - this->cur_input_plugin = NULL; + if (this->status == XINE_STOP ) { + /* + * find input plugin + */ + this->cur_input_plugin = NULL; - for (i = 0; i < this->num_input_plugins; i++) { - if (this->input_plugins[i]->open(this->input_plugins[i], mrl)) { - this->cur_input_plugin = this->input_plugins[i]; - break; + for (i = 0; i < this->num_input_plugins; i++) { + if (this->input_plugins[i]->open(this->input_plugins[i], mrl)) { + this->cur_input_plugin = this->input_plugins[i]; + break; + } } - } - if (!this->cur_input_plugin) { - xine_log (this, XINE_LOG_FORMAT, - _("xine: cannot find input plugin for this MRL\n")); - this->cur_demuxer_plugin = NULL; - this->err = XINE_ERROR_NO_INPUT_PLUGIN; - pthread_mutex_unlock (&this->xine_lock); + if (!this->cur_input_plugin) { + xine_log (this, XINE_LOG_FORMAT, + _("xine: cannot find input plugin for this MRL\n")); + this->cur_demuxer_plugin = NULL; + this->err = XINE_ERROR_NO_INPUT_PLUGIN; + pthread_mutex_unlock (&this->xine_lock); - return 0; - } + return 0; + } - printf ("xine: using input plugin >%s< for this MRL (%s).\n", - this->cur_input_plugin->get_identifier(this->cur_input_plugin), mrl); + printf ("xine: using input plugin >%s< for this MRL (%s).\n", + this->cur_input_plugin->get_identifier(this->cur_input_plugin), mrl); - xine_log (this, XINE_LOG_FORMAT, - _("using input plugin '%s' for MRL '%s'\n"), - this->cur_input_plugin->get_identifier(this->cur_input_plugin), - mrl); + xine_log (this, XINE_LOG_FORMAT, + _("using input plugin '%s' for MRL '%s'\n"), + this->cur_input_plugin->get_identifier(this->cur_input_plugin), + mrl); - /* - * find demuxer plugin - */ + /* + * find demuxer plugin + */ - if (!find_demuxer(this, mrl)) { - xine_log (this, XINE_LOG_FORMAT, - _("xine: couldn't find demuxer for >%s<\n"), mrl); - this->err = XINE_ERROR_NO_DEMUXER_PLUGIN; - pthread_mutex_unlock (&this->xine_lock); - return 0; - } + if (!find_demuxer(this, mrl)) { + xine_log (this, XINE_LOG_FORMAT, + _("xine: couldn't find demuxer for >%s<\n"), mrl); + this->err = XINE_ERROR_NO_DEMUXER_PLUGIN; + pthread_mutex_unlock (&this->xine_lock); + return 0; + } - xine_log (this, XINE_LOG_FORMAT, - _("system layer format '%s' detected.\n"), - this->cur_demuxer_plugin->get_identifier()); - + xine_log (this, XINE_LOG_FORMAT, + _("system layer format '%s' detected.\n"), + this->cur_demuxer_plugin->get_identifier()); + } + /* * start demuxer */ if (start_pos) { + /* FIXME: do we need to protect concurrent access to input plugin here? */ len = this->cur_input_plugin->get_length (this->cur_input_plugin); share = (double) start_pos / 65535; pos = (off_t) (share * len) ; } else pos = 0; - - this->cur_demuxer_plugin->start (this->cur_demuxer_plugin, - this->video_fifo, - this->audio_fifo, - pos, start_time); + + if( this->status == XINE_STOP ) + this->cur_demuxer_plugin->start (this->cur_demuxer_plugin, + this->video_fifo, + this->audio_fifo, + pos, start_time); + else + this->cur_demuxer_plugin->seek (this->cur_demuxer_plugin, + pos, start_time); if (this->cur_demuxer_plugin->get_status(this->cur_demuxer_plugin) != DEMUX_OK) { xine_log (this, XINE_LOG_MSG, _("xine_play: demuxer failed to start\n")); - this->cur_input_plugin->close(this->cur_input_plugin); - - this->status = XINE_STOP; + if( this->status == XINE_STOP ) + this->cur_input_plugin->close(this->cur_input_plugin); + } else { this->status = XINE_PLAY; @@ -383,6 +416,7 @@ xine_set_speed_internal (this, SPEED_NORMAL); /* osd */ + xine_usec_sleep(100000); /* FIXME: how do we assure an updated cur_input_time? */ xine_internal_osd (this, ">", this->metronom->get_current_time (this->metronom), 300000); } @@ -426,6 +460,8 @@ video_decoder_shutdown (this); this->osd_renderer->close( this->osd_renderer ); + this->video_out->exit (this->video_out); + this->video_fifo->dispose (this->video_fifo); this->status = XINE_QUIT; Index: xine_internal.h =================================================================== RCS file: /cvsroot/xine/xine-lib/src/xine-engine/xine_internal.h,v retrieving revision 1.74 retrieving revision 1.75 diff -u -r1.74 -r1.75 --- xine_internal.h 18 Mar 2002 19:34:17 -0000 1.74 +++ xine_internal.h 9 Apr 2002 03:38:01 -0000 1.75 @@ -55,7 +55,7 @@ #define INPUT_PLUGIN_MAX 50 #define DEMUXER_PLUGIN_MAX 50 #define DECODER_PLUGIN_MAX 256 -#define DECODER_PLUGIN_IFACE_VERSION 5 +#define DECODER_PLUGIN_IFACE_VERSION 6 #define AUDIO_OUT_PLUGIN_MAX 50 #define VIDEO_OUT_PLUGIN_MAX 50 #define XINE_MAX_EVENT_LISTENERS 50 @@ -80,6 +80,8 @@ void (*decode_data) (video_decoder_t *this, buf_element_t *buf); + void (*reset) (video_decoder_t *this); + void (*flush) (video_decoder_t *this); void (*close) (video_decoder_t *this); @@ -407,6 +409,7 @@ */ void xine_notify_stream_finished (xine_t *this); +void xine_flush_engine (xine_t *this); /* * video decoder stuff |