diff options
Diffstat (limited to 'src/xine-engine')
-rw-r--r-- | src/xine-engine/audio_decoder.c | 18 | ||||
-rw-r--r-- | src/xine-engine/buffer.h | 4 | ||||
-rw-r--r-- | src/xine-engine/metronom.c | 10 | ||||
-rw-r--r-- | src/xine-engine/osd.c | 16 | ||||
-rw-r--r-- | src/xine-engine/video_decoder.c | 15 | ||||
-rw-r--r-- | src/xine-engine/video_out.c | 13 | ||||
-rw-r--r-- | src/xine-engine/xine.c | 134 | ||||
-rw-r--r-- | src/xine-engine/xine_internal.h | 7 |
8 files changed, 132 insertions, 85 deletions
diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c index 172557345..04139231d 100644 --- a/src/xine-engine/audio_decoder.c +++ b/src/xine-engine/audio_decoder.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: audio_decoder.c,v 1.69 2002/04/06 02:56:04 miguelfreitas Exp $ + * $Id: audio_decoder.c,v 1.70 2002/04/09 03:38:01 miguelfreitas Exp $ * * * functions that implement audio decoding @@ -70,7 +70,7 @@ void *audio_decoder_loop (void *this_gen) { if (buf->input_time) this->cur_input_time = buf->input_time; - + switch (buf->type) { case BUF_CONTROL_START: @@ -128,20 +128,16 @@ void *audio_decoder_loop (void *this_gen) { 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; diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h index e4be9b9bb..3d70f54c6 100644 --- a/src/xine-engine/buffer.h +++ b/src/xine-engine/buffer.h @@ -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: buffer.h,v 1.38 2002/03/24 14:15:37 guenter Exp $ + * $Id: buffer.h,v 1.39 2002/04/09 03:38:01 miguelfreitas Exp $ * * * contents: @@ -70,7 +70,7 @@ extern "C" { #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) */ diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c index 5e00d273d..62abe76b3 100644 --- a/src/xine-engine/metronom.c +++ b/src/xine-engine/metronom.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: metronom.c,v 1.79 2002/04/07 12:09:38 miguelfreitas Exp $ + * $Id: metronom.c,v 1.80 2002/04/09 03:38:01 miguelfreitas Exp $ */ #ifdef HAVE_CONFIG_H @@ -368,14 +368,12 @@ static void metronom_got_video_frame (metronom_t *this, vo_frame_t *img) { #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; diff --git a/src/xine-engine/osd.c b/src/xine-engine/osd.c index 69c06bbff..d0c5ef4a6 100644 --- a/src/xine-engine/osd.c +++ b/src/xine-engine/osd.c @@ -252,12 +252,6 @@ static int osd_hide (osd_object_t *osd, int64_t vpts) { 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 @@ static void osd_free_object (osd_object_t *osd_to_close) { 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); diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c index 035326005..359c28274 100644 --- a/src/xine-engine/video_decoder.c +++ b/src/xine-engine/video_decoder.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: video_decoder.c,v 1.80 2002/03/27 15:30:16 miguelfreitas Exp $ + * $Id: video_decoder.c,v 1.81 2002/04/09 03:38:01 miguelfreitas Exp $ * */ @@ -181,13 +181,19 @@ void *video_decoder_loop (void *this_gen) { 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 @@ void *video_decoder_loop (void *this_gen) { 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 @@ void video_decoder_shutdown (xine_t *this) { 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); } diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c index b090cddeb..43ccff317 100644 --- a/src/xine-engine/video_out.c +++ b/src/xine-engine/video_out.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: video_out.c,v 1.92 2002/04/02 19:29:09 esnel Exp $ + * $Id: video_out.c,v 1.93 2002/04/09 03:38:01 miguelfreitas Exp $ * * frame allocation / queuing / scheduling / output functions */ @@ -666,11 +666,14 @@ static void *video_out_loop (void *this_gen) { 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 @@ static void *video_out_loop (void *this_gen) { 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); diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index abe7d9db9..f6694dcd9 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.113 2002/03/24 14:15:37 guenter Exp $ + * $Id: xine.c,v 1.114 2002/04/09 03:38:01 miguelfreitas Exp $ * * top-level xine functions * @@ -92,6 +92,33 @@ void xine_notify_stream_finished (xine_t *this) { } } +/* 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 @@ int xine_play (xine_t *this, char *mrl, 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 @@ int xine_play (xine_t *this, char *mrl, 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 @@ int xine_play (xine_t *this, char *mrl, 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 @@ void xine_exit (xine_t *this) { 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; diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h index 7e7f375b1..8afb1d402 100644 --- a/src/xine-engine/xine_internal.h +++ b/src/xine-engine/xine_internal.h @@ -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_internal.h,v 1.74 2002/03/18 19:34:17 guenter Exp $ + * $Id: xine_internal.h,v 1.75 2002/04/09 03:38:01 miguelfreitas Exp $ * */ @@ -55,7 +55,7 @@ extern "C" { #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 @@ struct video_decoder_s { 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 @@ char **xine_get_autoplay_mrls (xine_t *this, char *plugin_id, int *num_mrls); */ void xine_notify_stream_finished (xine_t *this); +void xine_flush_engine (xine_t *this); /* * video decoder stuff |