diff options
Diffstat (limited to 'src/xine-engine')
-rw-r--r-- | src/xine-engine/audio_decoder.c | 14 | ||||
-rw-r--r-- | src/xine-engine/metronom.c | 123 | ||||
-rw-r--r-- | src/xine-engine/metronom.h | 5 | ||||
-rw-r--r-- | src/xine-engine/video_decoder.c | 43 | ||||
-rw-r--r-- | src/xine-engine/video_out.c | 35 | ||||
-rw-r--r-- | src/xine-engine/video_out.h | 3 | ||||
-rw-r--r-- | src/xine-engine/xine_internal.h | 6 |
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); |