summaryrefslogtreecommitdiff
path: root/src/xine-engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/xine-engine')
-rw-r--r--src/xine-engine/audio_decoder.c18
-rw-r--r--src/xine-engine/buffer.h4
-rw-r--r--src/xine-engine/metronom.c10
-rw-r--r--src/xine-engine/osd.c16
-rw-r--r--src/xine-engine/video_decoder.c15
-rw-r--r--src/xine-engine/video_out.c13
-rw-r--r--src/xine-engine/xine.c134
-rw-r--r--src/xine-engine/xine_internal.h7
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