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.c14
-rw-r--r--src/xine-engine/metronom.c123
-rw-r--r--src/xine-engine/metronom.h5
-rw-r--r--src/xine-engine/video_decoder.c43
-rw-r--r--src/xine-engine/video_out.c35
-rw-r--r--src/xine-engine/video_out.h3
-rw-r--r--src/xine-engine/xine_internal.h6
7 files changed, 163 insertions, 66 deletions
diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c
index 0e920f477..797059eb5 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.51 2001/11/10 13:48:03 guenter Exp $
+ * $Id: audio_decoder.c,v 1.52 2001/11/13 21:47:59 heikos Exp $
*
*
* functions that implement audio decoding
@@ -52,14 +52,17 @@ void *audio_decoder_loop (void *this_gen) {
while (running) {
- /* printf ("audio_loop: waiting for package...\n"); */
+#ifdef AUDIO_DECODER_LOG
+ printf ("audio_loop: waiting for package...\n");
+#endif
buf = this->audio_fifo->get (this->audio_fifo);
- /*
+
+#ifdef AUDIO_DECODER_LOG
printf ("audio_loop: got package pts = %d, type = %08x\n",
buf->PTS, buf->type);
- */
+#endif
if (buf->input_pos)
this->cur_input_pos = buf->input_pos;
@@ -140,6 +143,7 @@ void *audio_decoder_loop (void *this_gen) {
if (this->cur_audio_decoder_plugin) {
this->cur_audio_decoder_plugin->close (this->cur_audio_decoder_plugin);
this->cur_audio_decoder_plugin = NULL;
+ this->audio_type = 0;
}
this->metronom->expect_audio_discontinuity (this->metronom);
@@ -274,7 +278,7 @@ void audio_decoder_init (xine_t *this) {
return;
}
- this->audio_fifo = fifo_buffer_new (1500, 8192);
+ this->audio_fifo = fifo_buffer_new (20, 8192);
this->audio_channel = -1;
this->audio_channel_suggested = -1;
this->audio_type = 0;
diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c
index 8e7d593fe..e15907cc0 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.34 2001/11/10 14:57:20 heikos Exp $
+ * $Id: metronom.c,v 1.35 2001/11/13 21:47:59 heikos Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -243,14 +243,13 @@ static void metronom_video_stream_start (metronom_t *this) {
}
this->pts_per_frame = 3000;
+ this->avg_frame_duration = 3000;
this->video_vpts = PREBUFFER_PTS_OFFSET;
- this->video_pts_delta = 0;
-
this->last_video_pts = 0;
this->last_video_scr = 0;
- this->num_video_vpts_guessed = 1;
+ this->num_video_vpts_guessed = 0;
this->video_wrap_offset = PREBUFFER_PTS_OFFSET;
this->wrap_diff_counter = 0;
@@ -362,7 +361,7 @@ static void metronom_audio_stream_end (metronom_t *this) {
/* while (this->video_stream_running) { */
if (this->video_stream_running) {
- printf ("waiting for video to end...\n");
+ printf ("metronom: waiting for video to end...\n");
pthread_cond_wait (&this->video_ended, &this->lock);
}
@@ -375,11 +374,13 @@ static void metronom_set_video_rate (metronom_t *this, uint32_t pts_per_frame) {
this->pts_per_frame = pts_per_frame;
+ this->avg_frame_duration = this->pts_per_frame;
+
pthread_mutex_unlock (&this->lock);
}
static uint32_t metronom_get_video_rate (metronom_t *this) {
- return this->pts_per_frame + this->video_pts_delta;
+ return this->avg_frame_duration;
}
static void metronom_set_audio_rate (metronom_t *this, uint32_t pts_per_smpls) {
@@ -432,8 +433,11 @@ static void metronom_expect_video_discontinuity (metronom_t *this) {
printf("metronom: video vpts adjusted to %d\n", this->video_vpts);
}
- this->num_video_vpts_guessed = 1;
+ this->num_video_vpts_guessed = 0;
this->last_video_pts = this->video_vpts - this->video_wrap_offset;
+
+ this->avg_frame_duration = this->pts_per_frame;
+ this->frames_since_start = 0;
printf ("metronom: video discontinuity => last_video_pts=%d, wrap_offset=%d, video_vpts=%d\n",
this->last_video_pts, this->video_wrap_offset, this->video_vpts);
@@ -443,8 +447,6 @@ static void metronom_expect_video_discontinuity (metronom_t *this) {
static uint32_t metronom_got_video_frame (metronom_t *this, uint32_t pts, uint32_t scr) {
- uint32_t vpts;
-
pthread_mutex_lock (&this->lock);
if (pts) {
@@ -457,19 +459,17 @@ static uint32_t metronom_got_video_frame (metronom_t *this, uint32_t pts, uint32
this->video_stream_starting = 0;
this->video_wrap_offset += this->last_video_pts - pts
- + this->num_video_vpts_guessed
- * (this->pts_per_frame + this->video_pts_delta);
+ + (this->num_video_vpts_guessed+1) * this->avg_frame_duration;
printf ("metronom: video pts discontinuity, pts is %d, last_pts is %d, wrap_offset = %d\n",
pts, this->last_video_pts, this->video_wrap_offset);
+ this->last_video_pts = 0;
}
/*
- * audio and video wrap are not allowed to differ
- * for too long
+ * audio and video wrap are not allowed to differ for too long
*/
-
if ( !this->audio_stream_starting && this->have_audio
&& (this->video_wrap_offset != this->audio_wrap_offset)) {
this->wrap_diff_counter++;
@@ -484,45 +484,100 @@ static uint32_t metronom_got_video_frame (metronom_t *this, uint32_t pts, uint32
else
this->video_wrap_offset = this->audio_wrap_offset;
- printf ("to %d\n", this->video_wrap_offset);
+ printf (" to %d\n", this->video_wrap_offset);
this->wrap_diff_counter = 0;
}
}
- vpts = pts + this->video_wrap_offset;
-
/*
- * calc delta to compensate wrong framerates
+ * calc overall average frame duration (according to pts values)
*/
-
- if (this->last_video_pts && (pts>this->last_video_pts)) {
- int32_t vpts_diff;
+ if (this->frames_since_start && this->last_video_pts) {
+ int current_avg_delta;
- vpts_diff = vpts - this->video_vpts;
+ int weight_old = 9;
+ int weight_new = 1;
- this->video_pts_delta += vpts_diff / (this->num_video_vpts_guessed);
-
- if (abs(this->video_pts_delta) >= MAX_VIDEO_DELTA)
- this->video_pts_delta = 0;
+ /*
+ printf("foo: pts %d, last pts %d\n", pts, this->last_video_pts);
+ */
+
+ if (pts > this->last_video_pts) {
+ current_avg_delta = (pts - this->last_video_pts) / (this->num_video_vpts_guessed + 1);
+
+ /*
+ printf("foo: current_avg_delta %d\n", current_avg_delta);
+ */
+
+ this->avg_frame_duration =
+ (((this->avg_frame_duration * weight_old) + (current_avg_delta * weight_new)) /
+ (weight_old + weight_new));
+ } else {
+ current_avg_delta = (this->last_video_pts - pts) / (this->num_video_vpts_guessed + 1);
+
+ /*
+ printf("foo: current_avg_delta - %d\n", current_avg_delta);
+ */
+
+ this->avg_frame_duration =
+ (((this->avg_frame_duration * weight_old) - (current_avg_delta * weight_new)) /
+ (weight_old + weight_new));
+ }
}
- this->num_video_vpts_guessed = 0;
this->last_video_pts = pts;
- this->video_vpts = vpts;
+ }
+
+ this->video_vpts += this->avg_frame_duration;
+
+ if (pts) {
+ int drift;
+ int delta = this->video_vpts - this->video_wrap_offset - pts;
+
+#ifdef METRONOM_LOG
+ printf("metronom: delta: %d\n", delta);
+#endif
+
+ /* does xine need this ?!
+ if (abs (delta) > 30000) {
+
+ discontinuity
+
+ this->video_vpts = pts + this->this->video_wrap_offset;
+
+ printf ("metronom: disc. detected\n");
+
+
+ } else {
+ */
+
+ if (this->num_video_vpts_guessed > 10)
+ this->num_video_vpts_guessed = 10;
+
+ drift = delta / 20 * (this->num_video_vpts_guessed + 1);
+#ifdef METRONOM_LOG
+ printf("metronom: compensating drift: %d\n", drift);
+#endif
+
+ this->video_vpts -= drift;
+
+ this->num_video_vpts_guessed = 0;
} else
- vpts = this->video_vpts;
+ this->num_video_vpts_guessed++;
- this->video_vpts += this->pts_per_frame + this->video_pts_delta;
- this->num_video_vpts_guessed++ ;
+ this->frames_since_start++;
#ifdef METRONOM_LOG
- printf ("metronom: video vpts for %10d : %10d\n", pts, vpts);
+ printf("metronom: stats: %d num guessed, %d avg_frame_duration. %d frames since start\n",
+ this->num_video_vpts_guessed, this->avg_frame_duration, this->frames_since_start);
+
+ printf ("metronom: video vpts for %10d : %10d\n", pts, this->video_vpts);
#endif
pthread_mutex_unlock (&this->lock);
- return vpts + this->av_offset;
+ return this->video_vpts + this->av_offset;
}
static void metronom_expect_audio_discontinuity (metronom_t *this) {
@@ -581,7 +636,7 @@ static uint32_t metronom_got_audio_samples (metronom_t *this, uint32_t pts,
+ this->num_audio_samples_guessed
* (this->audio_pts_delta + this->pts_per_smpls) / AUDIO_SAMPLE_NUM ;
- printf ("metronom: audio pts discontinuity, pts is %d, last_pts is %d, wrap_offset = %d\n",
+ printf ("metronom: audio pts discontinuity/start, pts is %d, last_pts is %d, wrap_offset = %d\n",
pts, this->last_audio_pts, this->audio_wrap_offset);
}
diff --git a/src/xine-engine/metronom.h b/src/xine-engine/metronom.h
index 097983f09..22b02f892 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.13 2001/11/10 13:48:03 guenter Exp $
+ * $Id: metronom.h,v 1.14 2001/11/13 21:47:59 heikos Exp $
*
* metronom: general pts => virtual calculation/assoc
*
@@ -198,7 +198,6 @@ struct metronom_s {
uint32_t last_video_pts;
uint32_t last_video_scr;
int num_video_vpts_guessed;
- int32_t video_pts_delta;
uint32_t last_audio_pts;
uint32_t last_audio_scr;
@@ -228,6 +227,8 @@ struct metronom_s {
pthread_cond_t video_ended;
pthread_cond_t audio_ended;
+ int frames_since_start;
+ int avg_frame_duration;
};
metronom_t *metronom_init (int have_audio);
diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c
index bd4a53caf..20a59d96b 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.62 2001/11/10 13:48:03 guenter Exp $
+ * $Id: video_decoder.c,v 1.63 2001/11/13 21:47:59 heikos Exp $
*
*/
@@ -33,6 +33,10 @@
#include "monitor.h"
#include <sched.h>
+/*
+#define VIDEO_DECODER_LOG
+*/
+
static spu_decoder_t* update_spu_decoder(xine_t *this, int type) {
int streamtype = (type>>16) & 0xFF;
spu_decoder_t *spu_decoder = this->spu_decoder_plugins [streamtype];
@@ -68,15 +72,41 @@ void *video_decoder_loop (void *this_gen) {
while (running) {
- /* printf ("video_decoder: getting buffer...\n"); */
+#ifdef VIDEO_DECODER_LOG
+ printf ("video_decoder: getting buffer...\n");
+#endif
+
+ /*
+
+ I dont know if this will ever work - highly experimental,
+ let xine itself detect when to insert still images
+
+ if (!this->video_fifo->first) {
+
+#ifdef VIDEO_DECODER_LOG
+ printf ("video_decoder: ... inserting still ...\n");
+#endif
+
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+
+ buf->type = BUF_VIDEO_FILL ;
+ buf->PTS = 0;
+ buf->SCR = 0;
+ this->cur_input_pos = 0;
+ this->cur_input_time = 0;
+
+ } else */
buf = this->video_fifo->get (this->video_fifo);
+
if (buf->input_pos)
this->cur_input_pos = buf->input_pos;
if (buf->input_time)
this->cur_input_time = buf->input_time;
- /* printf ("video_decoder: got buffer 0x%08x\n", buf->type); */
+#ifdef VIDEO_DECODER_LOG
+ printf ("video_decoder: got buffer 0x%08x\n", buf->type);
+#endif
switch (buf->type & 0xffff0000) {
case BUF_CONTROL_START:
@@ -166,11 +196,8 @@ void *video_decoder_loop (void *this_gen) {
case BUF_CONTROL_AVSYNC_RESET:
printf ("video_decoder: discontinuity ahead\n");
- /* fixme ? */
- if (this->cur_video_decoder_plugin) {
- this->cur_video_decoder_plugin->close (this->cur_video_decoder_plugin);
- this->cur_video_decoder_plugin = NULL;
- }
+ if (this->cur_video_decoder_plugin)
+ this->cur_video_decoder_plugin->flush (this->cur_video_decoder_plugin);
this->metronom->expect_video_discontinuity (this->metronom);
break;
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index cd274d291..c13b34583 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.52 2001/11/10 13:48:03 guenter Exp $
+ * $Id: video_out.c,v 1.53 2001/11/13 21:47:59 heikos Exp $
*
*/
@@ -36,6 +36,10 @@
#include "utils.h"
#include "monitor.h"
+/*
+#define VIDEO_OUT_LOG
+*/
+
#define NUM_FRAME_BUFFERS 15
struct img_buf_fifo_s {
@@ -201,8 +205,10 @@ static void *video_out_loop (void *this_gen) {
cur_pts = this->metronom->get_current_time (this->metronom);
xprintf (VERBOSE|VIDEO, "video_out : video loop iteration at audio pts %d\n", cur_pts);
- /*printf ("video_out : video loop iteration at audio pts %d\n", cur_pts);
- fflush (stdout); */
+
+#ifdef VIDEO_OUT_LOG
+ printf ("video_out : video loop iteration at audio pts %d\n", cur_pts);
+#endif
img = this->display_img_buf_queue->first;
@@ -226,12 +232,9 @@ static void *video_out_loop (void *this_gen) {
"it's too old (diff : %d > %d).\n",pts,diff,
this->pts_per_half_frame);
- /*
- fprintf (stderr,
- "video_out : throwing away image with pts %d because "
+ printf ( "video_out : throwing away image with pts %d because "
"it's too old (diff : %d > %d).\n",pts,diff,
this->pts_per_half_frame);
- */
this->num_frames_discarded++;
@@ -256,10 +259,9 @@ static void *video_out_loop (void *this_gen) {
* time to display frame 0 ?
*/
- /*
+#ifdef VIDEO_OUT_LOG
printf ("video_out: diff %d\n", diff);
- fflush(stdout);
- */
+#endif
if (diff<0) {
profiler_stop_count (prof_video_out);
@@ -271,10 +273,13 @@ static void *video_out_loop (void *this_gen) {
* remove frame from display queue and show it
*/
- xprintf (VERBOSE|VIDEO, "video_out : displaying image with pts = %d (diff=%d)\n", pts, diff);
+#ifdef VIDEO_OUT_LOG
+ printf ("video_out : displaying image with pts = %d (diff=%d)\n", pts, diff);
+#endif
img = vo_remove_from_img_buf_queue (this->display_img_buf_queue);
+
if (!img) {
profiler_stop_count (prof_video_out);
continue;
@@ -287,7 +292,9 @@ static void *video_out_loop (void *this_gen) {
img->display_locked = 0;
pthread_mutex_unlock (&img->mutex);
- xprintf (VERBOSE|VIDEO, "video_out : passing to video driver, image with pts = %d\n", pts);
+#ifdef VIDEO_OUT_LOG
+ printf ("video_out : passing to video driver, image with pts = %d\n", pts);
+#endif
if (this->overlay_source) {
/* This is the only way for the spu decoder to get pts values
@@ -471,10 +478,10 @@ static int vo_frame_draw (vo_frame_t *img) {
pic_vpts = this->metronom->got_video_frame (this->metronom, img->PTS, img->SCR);
- /*
+#ifdef VIDEO_OUT_LOG
printf ("video_out: got image %d. vpts for picture is %d (pts was %d)\n",
img, pic_vpts, img->PTS);
- */
+#endif
img->PTS = pic_vpts;
this->num_frames_delivered++;
diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h
index 26ed87b8a..a57e2bba1 100644
--- a/src/xine-engine/video_out.h
+++ b/src/xine-engine/video_out.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: video_out.h,v 1.27 2001/11/10 13:48:03 guenter Exp $
+ * $Id: video_out.h,v 1.28 2001/11/13 21:47:59 heikos Exp $
*
*
* xine version of video_out.h
@@ -62,6 +62,7 @@ struct vo_frame_s {
uint32_t PTS;
uint32_t SCR;
int bad_frame; /* e.g. frame skipped or based on skipped frame */
+ int drawn;
uint8_t *base[3];
diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h
index 9c4783617..99628c7e5 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.53 2001/10/25 00:47:03 miguelfreitas Exp $
+ * $Id: xine_internal.h,v 1.54 2001/11/13 21:47:59 heikos Exp $
*
*/
@@ -52,7 +52,7 @@ extern "C" {
#define INPUT_PLUGIN_MAX 50
#define DEMUXER_PLUGIN_MAX 50
#define DECODER_PLUGIN_MAX 256
-#define DECODER_PLUGIN_IFACE_VERSION 2
+#define DECODER_PLUGIN_IFACE_VERSION 3
#define AUDIO_OUT_PLUGIN_MAX 50
#define VIDEO_OUT_PLUGIN_MAX 50
#define XINE_MAX_EVENT_LISTENERS 50
@@ -77,6 +77,8 @@ struct video_decoder_s {
void (*decode_data) (video_decoder_t *this, buf_element_t *buf);
+ void (*flush) (video_decoder_t *this);
+
void (*close) (video_decoder_t *this);
char* (*get_identifier) (void);