summaryrefslogtreecommitdiff
path: root/src/xine-engine
diff options
context:
space:
mode:
authorGuenter Bartsch <guenter@users.sourceforge.net>2002-03-20 23:12:58 +0000
committerGuenter Bartsch <guenter@users.sourceforge.net>2002-03-20 23:12:58 +0000
commitd1eca278036b0abedb86545257a7c1b026d1d0d8 (patch)
tree6340dbab0f37669ddf38f02f09729d6863bf7d7d /src/xine-engine
parentf461a6cb075255690fcab513648911110b63dca6 (diff)
downloadxine-lib-d1eca278036b0abedb86545257a7c1b026d1d0d8.tar.gz
xine-lib-d1eca278036b0abedb86545257a7c1b026d1d0d8.tar.bz2
steps towards dvd playback:
- cleanup / more types of discontinuity handling in metronom - disc detection based on nav-packets small video_out fix to make exiting xine easier in case it gets stuck CVS patchset: 1599 CVS date: 2002/03/20 23:12:58
Diffstat (limited to 'src/xine-engine')
-rw-r--r--src/xine-engine/audio_decoder.c10
-rw-r--r--src/xine-engine/buffer.h4
-rw-r--r--src/xine-engine/metronom.c45
-rw-r--r--src/xine-engine/metronom.h41
-rw-r--r--src/xine-engine/video_decoder.c16
-rw-r--r--src/xine-engine/video_out.c15
6 files changed, 75 insertions, 56 deletions
diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c
index 2ed4c0522..e85aa40a1 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.66 2002/03/18 22:45:53 guenter Exp $
+ * $Id: audio_decoder.c,v 1.67 2002/03/20 23:12:58 guenter Exp $
*
*
* functions that implement audio decoding
@@ -84,7 +84,7 @@ void *audio_decoder_loop (void *this_gen) {
this->audio_finished = 0;
pthread_mutex_unlock (&this->finished_lock);
- this->metronom->audio_stream_start (this->metronom);
+ this->metronom->handle_audio_discontinuity (this->metronom, DISC_STREAMSTART, 0);
break;
@@ -129,9 +129,11 @@ void *audio_decoder_loop (void *this_gen) {
break;
case BUF_CONTROL_DISCONTINUITY:
- printf ("audio_decoder: discontinuity ahead\n");
+ this->metronom->handle_audio_discontinuity (this->metronom, DISC_RELATIVE, buf->disc_off);
+ break;
- this->metronom->expect_audio_discontinuity (this->metronom, buf->disc_off);
+ case BUF_CONTROL_NEWPTS:
+ this->metronom->handle_audio_discontinuity (this->metronom, DISC_ABSOLUTE, buf->disc_off);
break;
case BUF_CONTROL_AUDIO_CHANNEL:
diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h
index e818d9cbf..e0a0a6630 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.36 2002/03/16 20:53:50 guenter Exp $
+ * $Id: buffer.h,v 1.37 2002/03/20 23:12:58 guenter Exp $
*
*
* contents:
@@ -69,6 +69,8 @@ extern "C" {
#define BUF_CONTROL_NOP 0x01040000
#define BUF_CONTROL_AUDIO_CHANNEL 0x01050000
#define BUF_CONTROL_SPU_CHANNEL 0x01060000
+#define BUF_CONTROL_NEWPTS 0x01070000
+#define BUF_CONTROL_SEEK 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 80745a727..f589a9554 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.70 2002/03/12 22:23:14 guenter Exp $
+ * $Id: metronom.c,v 1.71 2002/03/20 23:12:58 guenter Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -274,7 +274,7 @@ static int64_t metronom_got_spu_packet (metronom_t *this, int64_t pts,
return vpts;
}
-static void metronom_handle_video_discontinuity (metronom_t *this, int is_stream_start,
+static void metronom_handle_video_discontinuity (metronom_t *this, int type,
int64_t disc_off) {
pthread_mutex_lock (&this->lock);
@@ -282,8 +282,8 @@ static void metronom_handle_video_discontinuity (metronom_t *this, int is_stream
this->video_discontinuity_count++;
pthread_cond_signal (&this->video_discontinuity_reached);
- printf ("metronom: video discontinuity #%d, disc_off is %lld\n",
- this->video_discontinuity_count, disc_off);
+ printf ("metronom: video discontinuity #%d, type is %d, disc_off is %lld\n",
+ this->video_discontinuity_count, type, disc_off);
if (this->have_audio) {
while (this->audio_discontinuity_count <
@@ -304,24 +304,23 @@ static void metronom_handle_video_discontinuity (metronom_t *this, int is_stream
if (this->in_discontinuity)
this->vpts_offset = this->next_vpts_offset;
- if (is_stream_start) {
- this->vpts_offset = this->video_vpts;
+ switch (type) {
+ case DISC_STREAMSTART:
+ this->vpts_offset = this->video_vpts;
this->in_discontinuity = 0;
- } else {
+ break;
+ case DISC_ABSOLUTE:
+ this->next_vpts_offset = this->video_vpts - disc_off;
+ this->in_discontinuity = 30;
+ break;
+ case DISC_RELATIVE:
this->next_vpts_offset = this->vpts_offset - disc_off;
this->in_discontinuity = 30;
+ break;
}
pthread_mutex_unlock (&this->lock);
}
-static void metronom_video_stream_start (metronom_t *this) {
- metronom_handle_video_discontinuity (this, 1, 0);
-}
-
-static void metronom_expect_video_discontinuity (metronom_t *this, int64_t disc_off) {
- metronom_handle_video_discontinuity (this, 0, disc_off);
-}
-
static void metronom_got_video_frame (metronom_t *this, vo_frame_t *img) {
int64_t vpts;
@@ -399,7 +398,7 @@ static void metronom_got_video_frame (metronom_t *this, vo_frame_t *img) {
pthread_mutex_unlock (&this->lock);
}
-static void metronom_expect_audio_discontinuity (metronom_t *this,
+static void metronom_handle_audio_discontinuity (metronom_t *this, int type,
int64_t disc_off) {
pthread_mutex_lock (&this->lock);
@@ -407,8 +406,8 @@ static void metronom_expect_audio_discontinuity (metronom_t *this,
this->audio_discontinuity_count++;
pthread_cond_signal (&this->audio_discontinuity_reached);
- printf ("metronom: audio discontinuity #%d, disc_off %lld\n",
- this->audio_discontinuity_count, disc_off);
+ printf ("metronom: audio discontinuity #%d, type is %d, disc_off %lld\n",
+ this->audio_discontinuity_count, type, disc_off);
while ( this->audio_discontinuity_count >
this->video_discontinuity_count ) {
@@ -429,10 +428,6 @@ static void metronom_expect_audio_discontinuity (metronom_t *this,
pthread_mutex_unlock (&this->lock);
}
-static void metronom_audio_stream_start (metronom_t *this) {
- metronom_expect_audio_discontinuity (this, 0);
-}
-
static int64_t metronom_got_audio_samples (metronom_t *this, int64_t pts,
int nsamples) {
@@ -587,10 +582,8 @@ metronom_t * metronom_init (int have_audio, void *xine) {
this->got_video_frame = metronom_got_video_frame;
this->got_audio_samples = metronom_got_audio_samples;
this->got_spu_packet = metronom_got_spu_packet;
- this->audio_stream_start = metronom_audio_stream_start;
- this->video_stream_start = metronom_video_stream_start;
- this->expect_audio_discontinuity = metronom_expect_audio_discontinuity;
- this->expect_video_discontinuity = metronom_expect_video_discontinuity;
+ this->handle_audio_discontinuity = metronom_handle_audio_discontinuity;
+ this->handle_video_discontinuity = metronom_handle_video_discontinuity;
this->set_av_offset = metronom_set_av_offset;
this->get_av_offset = metronom_get_av_offset;
this->start_clock = metronom_start_clock;
diff --git a/src/xine-engine/metronom.h b/src/xine-engine/metronom.h
index 9e486a222..08b64eb57 100644
--- a/src/xine-engine/metronom.h
+++ b/src/xine-engine/metronom.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: metronom.h,v 1.22 2002/03/12 19:51:29 guenter Exp $
+ * $Id: metronom.h,v 1.23 2002/03/20 23:12:58 guenter Exp $
*
* metronom: general pts => virtual calculation/assoc
*
@@ -55,6 +55,11 @@ extern "C" {
typedef struct metronom_s metronom_t ;
typedef struct scr_plugin_s scr_plugin_t;
+ /* see below */
+#define DISC_STREAMSTART 0
+#define DISC_RELATIVE 1
+#define DISC_ABSOLUTE 2
+
struct metronom_s {
/*
@@ -116,27 +121,27 @@ struct metronom_s {
* tell metronom about discontinuities.
*
* these functions are called due to a discontinuity detected at
- * demux stage from SCR values. As SCR are not guarateed to happen with
- * any regularity, we can not correct the xxx_wrap_offset right now.
+ * demux stage.
*
- * we will instead prepare both audio and video to correct the
- * discontinuity at the first new PTS value (got_video_frame or
- * got_audio_samples). As we can predict with reasonably accuracy what
- * the old PTS would have being the calculated wrap_offset should be
- * good.
+ * there are different types of discontinuities:
*
- * (the time between discontinuity is detected to where it is corrected
- * may be called "discontinuity window". Inside this window we cannot
- * use the xxx_wrap_offset for any pts -> vpts calculation as the result
- * would be wrong. The vpts values will be predicted for pts == 0 and
- * whenever we get a new pts we can calculate the new xxx_wrap_offset)
+ * DISC_STREAMSTART : new stream starts, expect pts values to start
+ * from zero immediately
+ * DISC_RELATIVE : typically a wrap-around, expect pts with
+ * a specified offset from the former ones soon
+ * DISC_ABSOLUTE : typically a new menu stream (nav packets)
+ * pts will start from given value soon
*
+ * for DISC_RELATIVE and DISC_ABSOLUTE metronom will enter a
+ * special discontinuity mode which means that it will ignore
+ * pts values for some time (about 1sec) to ignore any held-back
+ * reference frames that are flushed out of decoders containing
+ * pts values that do not mach the new offset. Then it will
+ * just switch to the new disc_offset and resume synced operation.
+ *
*/
- void (*expect_audio_discontinuity) (metronom_t *this, int64_t disc_off);
- void (*expect_video_discontinuity) (metronom_t *this, int64_t disc_off);
-
- void (*audio_stream_start) (metronom_t *this);
- void (*video_stream_start) (metronom_t *this);
+ void (*handle_audio_discontinuity) (metronom_t *this, int type, int64_t disc_off);
+ void (*handle_video_discontinuity) (metronom_t *this, int type, int64_t disc_off);
/*
* manually correct audio <-> video sync
diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c
index 6604d2c33..cf6eccb43 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.78 2002/03/16 20:53:50 guenter Exp $
+ * $Id: video_decoder.c,v 1.79 2002/03/20 23:12:58 guenter Exp $
*
*/
@@ -106,7 +106,7 @@ void *video_decoder_loop (void *this_gen) {
pthread_mutex_unlock (&this->finished_lock);
- this->metronom->video_stream_start (this->metronom);
+ this->metronom->handle_video_discontinuity (this->metronom, DISC_STREAMSTART, 0);
break;
@@ -186,7 +186,17 @@ void *video_decoder_loop (void *this_gen) {
this->video_in_discontinuity = 1;
- this->metronom->expect_video_discontinuity (this->metronom, buf->disc_off);
+ this->metronom->handle_video_discontinuity (this->metronom, DISC_RELATIVE, buf->disc_off);
+
+ this->video_in_discontinuity = 0;
+ break;
+
+ case BUF_CONTROL_NEWPTS:
+ printf ("video_decoder: new pts %lld\n", buf->disc_off);
+
+ this->video_in_discontinuity = 1;
+
+ this->metronom->handle_video_discontinuity (this->metronom, DISC_ABSOLUTE, buf->disc_off);
this->video_in_discontinuity = 0;
break;
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index 2850f3616..4af47c3c3 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.80 2002/03/14 04:31:49 miguelfreitas Exp $
+ * $Id: video_out.c,v 1.81 2002/03/20 23:12:58 guenter Exp $
*
* frame allocation / queuing / scheduling / output functions
*/
@@ -258,9 +258,12 @@ static int vo_frame_draw (vo_frame_t *img) {
diff = pic_vpts - cur_vpts;
frames_to_skip = ((-1 * diff) / img->duration + 3) * 2;
+ if (frames_to_skip<0)
+ frames_to_skip = 0;
+
#ifdef LOG
- printf ("video_out: delivery diff : %lld, current vpts is %lld\n",
- diff, cur_vpts);
+ printf ("video_out: delivery diff : %lld, current vpts is %lld, %d frames to skip\n",
+ diff, cur_vpts, frames_to_skip);
#endif
if (img->display_locked) {
@@ -286,6 +289,10 @@ static int vo_frame_draw (vo_frame_t *img) {
vo_append_to_img_buf_queue (this->display_img_buf_queue, img);
} else {
+#ifdef LOG
+ printf ("video_out: bad_frame\n");
+#endif
+
this->num_frames_skipped++;
pthread_mutex_lock (&img->mutex);
@@ -669,7 +676,7 @@ static void *video_out_loop (void *this_gen) {
if (usec_to_sleep>0)
xine_usec_sleep (usec_to_sleep);
- } while (usec_to_sleep > 0);
+ } while ( (usec_to_sleep > 0) && this->video_loop_running);
}