summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/demuxers/demux_mpeg_block.c157
-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
7 files changed, 190 insertions, 98 deletions
diff --git a/src/demuxers/demux_mpeg_block.c b/src/demuxers/demux_mpeg_block.c
index ee1348dc0..b590102fa 100644
--- a/src/demuxers/demux_mpeg_block.c
+++ b/src/demuxers/demux_mpeg_block.c
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2000, 2001 the xine project
+ * Copyright (C) 2000-2002 the xine project
*
- * This file is part of xine, a unix video player.
+ * This file is part of xine, a free video player.
*
* xine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -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: demux_mpeg_block.c,v 1.79 2002/03/12 02:55:37 miguelfreitas Exp $
+ * $Id: demux_mpeg_block.c,v 1.80 2002/03/20 23:12:58 guenter Exp $
*
* demultiplexer for mpeg 1/2 program streams
*
@@ -75,6 +75,7 @@ typedef struct demux_mpeg_block_s {
uint8_t *scratch;
int64_t last_scr;
+ int64_t nav_last_end_pts;
} demux_mpeg_block_t ;
@@ -91,10 +92,16 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
buf = this->input->read_block (this->input, this->video_fifo, this->blocksize);
+#ifdef LOG
+ printf ("demux_mpeg_block: read_block\n");
+#endif
+
if (buf==NULL) {
xine_next_mrl_event_t event;
+#ifdef LOG
printf ("demux_mpeg_block: read_block failed\n");
+#endif
/*
* check if seamless branching is possible
@@ -107,13 +114,17 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
if (event.handled) {
char *next_mrl = event.mrl;
-
+
+#ifdef LOG
printf ("demux_mpeg_block: checking if we can branch to %s\n", next_mrl);
+#endif
if (next_mrl && this->input->is_branch_possible
&& this->input->is_branch_possible (this->input, next_mrl)) {
+#ifdef LOG
printf ("demux_mpeg_block: branching\n");
+#endif
this->input->close (this->input);
this->input->open (this->input, next_mrl);
@@ -139,7 +150,7 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
/* If this is not a block for the demuxer, pass it
* straight through. */
- if(buf->type != BUF_DEMUX_BLOCK) {
+ if (buf->type != BUF_DEMUX_BLOCK) {
buf_element_t *cbuf;
this->video_fifo->put (this->video_fifo, buf);
@@ -153,6 +164,13 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
this->audio_fifo->put (this->audio_fifo, cbuf);
}
+#ifdef LOG
+ printf ("demux_mpeg_block: type %08x != BUF_DEMUX_BLOCK\n", buf->type);
+#endif
+ /*
+ if (buf->type == BUF_CONTROL_NOP)
+ this->send_disc = 1;
+ */
return;
}
@@ -210,10 +228,14 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
scr |= p[7] << 5;
scr |= (p[8] & 0xF8) >> 3;
/* optional - decode extension:
- scr *=300;
- scr += ( (p[8] & 0x03 << 7) | (p[9] & 0xFE >> 1) );
+ scr *=300;
+ scr += ( (p[8] & 0x03 << 7) | (p[9] & 0xFE >> 1) );
*/
+#ifdef LOG
+ printf ("demux_mpeg_block: SCR=%lld\n", scr);
+#endif
+
/* buf->scr = scr; */
/* mux_rate */
@@ -228,8 +250,7 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
p += 14 + num_stuffing_bytes;
}
- }
-
+ }
if (p[3] == 0xbb) { /* program stream system header */
@@ -257,9 +278,70 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
return;
}
+ packet_len = p[4] << 8 | p[5];
+ stream_id = p[3];
+
+ if (stream_id == 0xbf) { /* NAV Packet */
+
+ int64_t start_pts, end_pts;
+
+ start_pts = (p[7+12] << 24);
+ start_pts |= (p[7+13] << 16);
+ start_pts |= (p[7+14] << 8);
+ start_pts |= p[7+15];
+
+ end_pts = (p[7+16] << 24);
+ end_pts |= (p[7+17] << 16);
+ end_pts |= (p[7+18] << 8);
+ end_pts |= p[7+19];
+
+ buf->content = p;
+ buf->size = packet_len;
+ buf->type = BUF_SPU_NAV;
+ buf->pts = 0; /* NAV packets do not have PES values */
+ buf->input_pos = this->input->get_current_pos(this->input);
+ this->video_fifo->put (this->video_fifo, buf);
+
+#ifdef LOG
+ printf ("demux_mpeg_block: NAV packet, start pts = %lld, end_pts = %lld\n",
+ start_pts, end_pts);
+#endif
+
+ if (this->nav_last_end_pts != start_pts) {
+
+#ifdef LOG
+ printf ("demux_mpeg_block: informing metronom about new start pts\n");
+#endif
+
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf->type = BUF_CONTROL_NEWPTS;
+ buf->disc_off = start_pts;
+ 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_NEWPTS;
+ buf->disc_off = start_pts;
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
+
+ }
+
+ this->nav_last_end_pts = end_pts;
+ this->last_scr = end_pts;
+
+ /*
+ for (i=0; i<120; i++)
+ printf ("%02x ", p[i]);
+ printf ("\n");
+ */
+
+ return ;
+ }
+
+#if 0
/* discontinuity ? */
- if( scr )
- {
+ if (scr) {
int64_t scr_diff = scr - this->last_scr;
#ifdef LOG
@@ -267,12 +349,12 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
scr, this->last_scr, scr_diff);
#endif
- if (abs(scr_diff) > DISC_TRESHOLD && !preview_mode) {
+ if ((abs(scr_diff) > DISC_TRESHOLD) && !preview_mode) {
buf_element_t *buf;
#ifdef LOG
- printf ("demux_mpeg_block: DISCONTINUITY!\n");
+ printf ("demux_mpeg_block: DISCONTINUITY/NEWPTS!\n");
#endif
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
@@ -289,19 +371,8 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
}
this->last_scr = scr;
}
+#endif
- packet_len = p[4] << 8 | p[5];
- stream_id = p[3];
-
- if (stream_id == 0xbf) { /* NAV Packet */
- buf->content = p;
- buf->size = packet_len;
- buf->type = BUF_SPU_NAV;
- buf->pts = 0; /* NAV packets do not have PES values */
- buf->input_pos = this->input->get_current_pos(this->input);
- this->video_fifo->put (this->video_fifo, buf);
- return ;
- }
if (bMpeg1) {
@@ -340,11 +411,11 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
PTS |= p[ 3] << 7 ;
PTS |= (p[ 4] & 0xFE) >> 1 ;
/* DTS decoding code is working, but not used in xine
- DTS = (p[ 5] & 0x0E) << 29 ;
- DTS |= p[ 6] << 22 ;
- DTS |= (p[ 7] & 0xFE) << 14 ;
- DTS |= p[ 8] << 7 ;
- DTS |= (p[ 9] & 0xFE) >> 1 ;
+ DTS = (p[ 5] & 0x0E) << 29 ;
+ DTS |= p[ 6] << 22 ;
+ DTS |= (p[ 7] & 0xFE) << 14 ;
+ DTS |= p[ 8] << 7 ;
+ DTS |= (p[ 9] & 0xFE) >> 1 ;
*/
p += 10;
packet_len -= 10;
@@ -371,20 +442,24 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
PTS |= p[12] << 7 ;
PTS |= (p[13] & 0xFE) >> 1 ;
+#ifdef LOG
+ printf ("demux_mpeg_block: pts = %lld\n", PTS);
+#endif
+
} else
PTS = 0;
/* code is working but not used in xine
- if (p[7] & 0x40) {
+ if (p[7] & 0x40) {
- DTS = (p[14] & 0x0E) << 29 ;
- DTS |= p[15] << 22 ;
- DTS |= (p[16] & 0xFE) << 14 ;
- DTS |= p[17] << 7 ;
- DTS |= (p[18] & 0xFE) >> 1 ;
+ DTS = (p[14] & 0x0E) << 29 ;
+ DTS |= p[15] << 22 ;
+ DTS |= (p[16] & 0xFE) << 14 ;
+ DTS |= p[17] << 7 ;
+ DTS |= (p[18] & 0xFE) >> 1 ;
- } else
- DTS = 0;
+ } else
+ DTS = 0;
*/
@@ -394,8 +469,6 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
packet_len -= header_len + 3;
}
- PTS &= 0x7FFFFFFF ; /* 31 bit only (for signed calculations) */
-
if (stream_id == 0xbd) {
int track, spu_id;
@@ -534,7 +607,6 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
return ;
}
-
buf->free_buffer (buf);
return ;
@@ -797,7 +869,8 @@ static void demux_mpeg_block_start (demux_plugin_t *this_gen,
this->rate = demux_mpeg_block_estimate_rate (this);
- this->last_scr = 0;
+ this->last_scr = 0;
+ this->nav_last_end_pts = 0;
if((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) {
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);
}