diff options
Diffstat (limited to 'src/xine-engine')
-rw-r--r-- | src/xine-engine/audio_decoder.c | 12 | ||||
-rw-r--r-- | src/xine-engine/audio_out.c | 4 | ||||
-rw-r--r-- | src/xine-engine/audio_out.h | 3 | ||||
-rw-r--r-- | src/xine-engine/buffer.h | 28 | ||||
-rw-r--r-- | src/xine-engine/buffer_types.c | 11 | ||||
-rw-r--r-- | src/xine-engine/metronom.c | 346 | ||||
-rw-r--r-- | src/xine-engine/metronom.h | 37 | ||||
-rw-r--r-- | src/xine-engine/video_decoder.c | 8 | ||||
-rw-r--r-- | src/xine-engine/xine.c | 4 |
9 files changed, 145 insertions, 308 deletions
diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c index f329db056..2e4c9f5c8 100644 --- a/src/xine-engine/audio_decoder.c +++ b/src/xine-engine/audio_decoder.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: audio_decoder.c,v 1.63 2002/03/10 21:43:30 miguelfreitas Exp $ + * $Id: audio_decoder.c,v 1.64 2002/03/11 12:31:26 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->expect_audio_discontinuity (this->metronom); + this->metronom->audio_stream_start (this->metronom); break; @@ -98,7 +98,7 @@ void *audio_decoder_loop (void *this_gen) { pthread_mutex_lock (&this->finished_lock); - if (!this->audio_finished && (buf->decoder_info[0]==0)) { + if (!this->audio_finished && (buf->decoder_flags==BUF_FLAG_END_USER)) { this->audio_finished = 1; if (this->video_finished) { @@ -131,7 +131,7 @@ void *audio_decoder_loop (void *this_gen) { case BUF_CONTROL_DISCONTINUITY: printf ("audio_decoder: discontinuity ahead\n"); - this->metronom->expect_audio_discontinuity (this->metronom); + this->metronom->expect_audio_discontinuity (this->metronom, buf->disc_off); break; case BUF_CONTROL_AUDIO_CHANNEL: diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c index 2c0bd80d4..56f777469 100644 --- a/src/xine-engine/audio_out.c +++ b/src/xine-engine/audio_out.c @@ -17,7 +17,7 @@ * along with self program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_out.c,v 1.43 2002/03/01 09:29:50 guenter Exp $ + * $Id: audio_out.c,v 1.44 2002/03/11 12:31:26 guenter Exp $ * * 22-8-2001 James imported some useful AC3 sections from the previous alsa driver. * (c) 2001 Andy Lo A Foe <andy@alsaplayer.org> @@ -474,7 +474,7 @@ static void ao_put_buffer (ao_instance_t *this, audio_buffer_t *buf) { pts = buf->vpts; buf->vpts = this->metronom->got_audio_samples (this->metronom, pts, - buf->num_frames, buf->scr); + buf->num_frames); #ifdef LOG printf ("audio_out: got buffer, pts=%lld, vpts=%lld\n", diff --git a/src/xine-engine/audio_out.h b/src/xine-engine/audio_out.h index d864be464..dd820a6f4 100644 --- a/src/xine-engine/audio_out.h +++ b/src/xine-engine/audio_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: audio_out.h,v 1.24 2002/02/17 17:32:50 guenter Exp $ + * $Id: audio_out.h,v 1.25 2002/03/11 12:31:26 guenter Exp $ */ #ifndef HAVE_AUDIO_OUT_H #define HAVE_AUDIO_OUT_H @@ -137,7 +137,6 @@ struct audio_buffer_s { int num_frames; int64_t vpts; - int64_t scr; uint32_t frame_header_count; uint32_t first_access_unit; }; diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h index 995249a43..5444d78d5 100644 --- a/src/xine-engine/buffer.h +++ b/src/xine-engine/buffer.h @@ -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: buffer.h,v 1.34 2002/03/01 09:29:50 guenter Exp $ + * $Id: buffer.h,v 1.35 2002/03/11 12:31:26 guenter Exp $ * * * contents: @@ -98,6 +98,7 @@ extern "C" { #define BUF_VIDEO_REAL 0x02170000 #define BUF_VIDEO_VP31 0x02180000 #define BUF_VIDEO_H263 0x02190000 +#define BUF_VIDEO_3IVX 0x021A0000 /* audio buffer types: (please keep in sync with buffer_types.c) */ @@ -139,15 +140,18 @@ struct buf_element_s { buf_element_t *next; unsigned char *mem; - unsigned char *content; /* start of raw content in pMem (without header etc) */ + unsigned char *content; /* start of raw content in mem (without header etc) */ - int32_t size ; /* size of _content_ */ - int32_t max_size; + int32_t size ; /* size of _content_ */ + int32_t max_size; /* size of pre-allocated memory pointed to by "mem" */ uint32_t type; - int64_t pts; /* presentation time stamp, used for a/v sync */ - int64_t scr; /* system clock reference, used for discont. detection */ + int64_t pts; /* presentation time stamp, used for a/v sync */ + int64_t disc_off; /* discontinuity offset */ off_t input_pos; /* remember where this buf came from in the input source */ int input_time;/* time offset in seconds from beginning of stream */ + + uint32_t decoder_flags; /* stuff like keyframe, is_header ... see below */ + uint32_t decoder_info[4]; /* additional decoder flags and other dec-spec. stuff */ void (*free_buffer) (buf_element_t *buf); @@ -157,6 +161,14 @@ struct buf_element_s { } ; +#define BUF_FLAG_KEYFRAME 0x0001 +#define BUF_FLAG_FRAME_START 0x0002 +#define BUF_FLAG_FRAME_END 0x0004 +#define BUF_FLAG_HEADER 0x0008 +#define BUF_FLAG_PREVIEW 0x0010 +#define BUF_FLAG_END_USER 0x0020 +#define BUF_FLAG_END_STREAM 0x0040 + typedef struct fifo_buffer_s fifo_buffer_t; struct fifo_buffer_s { diff --git a/src/xine-engine/buffer_types.c b/src/xine-engine/buffer_types.c index f9b66892f..fab61fa2f 100644 --- a/src/xine-engine/buffer_types.c +++ b/src/xine-engine/buffer_types.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: buffer_types.c,v 1.10 2002/02/09 07:13:24 guenter Exp $ + * $Id: buffer_types.c,v 1.11 2002/03/11 12:31:26 guenter Exp $ * * * contents: @@ -123,7 +123,6 @@ static video_db_t video_db[] = { mmioFOURCC('d', 'i', 'v', '5'), mmioFOURCC('D', 'I', 'V', '6'), mmioFOURCC('d', 'i', 'v', '6'), - mmioFOURCC('3', 'I', 'V', '1'), mmioFOURCC('A', 'P', '4', '1'), mmioFOURCC('M', 'P', 'G', '3'), 0 @@ -133,6 +132,14 @@ static video_db_t video_db[] = { }, { { + mmioFOURCC('3', 'I', 'V', '1'), + 0 + }, + BUF_VIDEO_3IVX, + "3ivx MPEG-4" +}, +{ + { mmioFOURCC('d', 'm', 'b', '1'), mmioFOURCC('M', 'J', 'P', 'G'), mmioFOURCC('m', 'j', 'p', 'a'), diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c index b578ea5cf..e54bbca1c 100644 --- a/src/xine-engine/metronom.c +++ b/src/xine-engine/metronom.c @@ -1,7 +1,7 @@ /* * 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: metronom.c,v 1.64 2002/03/10 21:16:15 miguelfreitas Exp $ + * $Id: metronom.c,v 1.65 2002/03/11 12:31:26 guenter Exp $ */ #ifdef HAVE_CONFIG_H @@ -253,7 +253,7 @@ static void metronom_set_audio_rate (metronom_t *this, int64_t pts_per_smpls) { } static int64_t metronom_got_spu_packet (metronom_t *this, int64_t pts, - int64_t duration, int64_t scr ) { + int64_t duration) { int64_t vpts; pthread_mutex_lock (&this->lock); @@ -265,47 +265,30 @@ static int64_t metronom_got_spu_packet (metronom_t *this, int64_t pts, this->spu_vpts=this->spu_vpts; } - /* - It happens with the dxr3 that got_spu_packet is called before - got_video_frame. Since video_wrap_offset is zero until then, - the return value would be wrong. In this case zero is returned. - - Also this->video_discontinuity means that scr discontinuity was - detected but this->video_wrap_offset not updated (would give - wrong values too). - */ - if ( this->video_discontinuity ) { - /* we can safely use audio_wrap_offset if already updated */ - if( !this->audio_discontinuity ) { - vpts = pts + this->audio_wrap_offset; - } else { - vpts = 0; - } - } else { - vpts = pts + this->video_wrap_offset; + if ( !this->in_discontinuity ) { + vpts = pts + this->vpts_offset; + } else { + vpts = 0; } pthread_mutex_unlock (&this->lock); return vpts; } -static void metronom_expect_video_discontinuity (metronom_t *this, int starting) { +static void metronom_handle_video_discontinuity (metronom_t *this, int is_stream_start, + int64_t disc_off) { pthread_mutex_lock (&this->lock); - this->video_starting = starting; - - this->video_discontinuity = 10; - this->video_discontinuity_count++; pthread_cond_signal (&this->video_discontinuity_reached); printf ("metronom: video discontinuity #%d\n", this->video_discontinuity_count); - if( this->have_audio ) { - while ( this->audio_discontinuity_count < - this->video_discontinuity_count ) { + if (this->have_audio) { + while (this->audio_discontinuity_count < + this->video_discontinuity_count) { printf ("metronom: waiting for audio discontinuity #%d\n", this->video_discontinuity_count); @@ -313,145 +296,89 @@ static void metronom_expect_video_discontinuity (metronom_t *this, int starting) pthread_cond_wait (&this->audio_discontinuity_reached, &this->lock); } - if ( this->video_vpts < this->audio_vpts ) { + if (this->video_vpts < this->audio_vpts) { this->video_vpts = this->audio_vpts; printf ("metronom: video vpts adjusted to %lld\n", this->video_vpts); } } - + + if (this->in_discontinuity) + this->vpts_offset = this->next_vpts_offset; + + if (is_stream_start) { + this->vpts_offset = this->video_vpts; + } else { + this->next_vpts_offset = this->vpts_offset - disc_off; + this->in_discontinuity = 30; + } 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; int64_t pts = img->pts; int64_t duration = img->duration; - int pts_discontinuity = 0; pthread_mutex_lock (&this->lock); - - /* check for pts discontinuities against the predicted pts value */ - if (pts && this->last_video_pts) { - - int64_t diff, predicted_pts; - - predicted_pts = this->last_video_pts + duration; - - diff = pts - predicted_pts; - -#ifdef LOG - printf ("metronom: got video pts %lld, predicted %lld (= %lld + %lld) => diff %lld\n", - pts, predicted_pts, this->last_video_pts, duration, diff); -#endif - - if ( abs (diff) > WRAP_THRESHOLD ) { - pts_discontinuity = 1; - -#ifdef LOG - printf ("metronom: this is a video discontinuity\n"); -#endif + if (this->in_discontinuity) { + this->in_discontinuity--; - /* - * ignore discontinuities created by frame reordering around - * the REAL discontinuity. :) - */ - if( !this->video_discontinuity ) { - pts = 0; -#ifdef LOG - printf ("metronom: not expecting a video discontinuity => ignored\n"); -#endif - } - } + if (!this->in_discontinuity) + this->vpts_offset = this->next_vpts_offset; + else + pts = 0; /* ignore pts during discontinuities */ } if (pts) { + int64_t diff; + /* - * check if there was any pending SCR discontinuity (video_discontinuity - * is set from the decoder loop) together with pts discont. + * compare predicted (this->video_vpts) and given (pts+vpts_offset) + * pts values - hopefully they will be the same + * if not, for small diffs try to interpolate + * for big diffs: jump */ - if ( this->video_discontinuity && - (pts_discontinuity || this->video_starting) ) { - this->video_starting = 0; - this->video_discontinuity = 0; - this->wrap_diff_counter = 0; - - this->video_wrap_offset = this->video_vpts - pts; - - vpts = pts + this->video_wrap_offset; - - printf ("metronom: video pts discontinuity/start, pts is %lld, wrap_offset is %lld, vpts is %lld\n", - pts, this->video_wrap_offset, vpts); - - } else { - - int64_t diff; - - /* - * audio and video wrap are not allowed to differ for too long - */ - - if ( this->have_audio - && (this->video_wrap_offset != this->audio_wrap_offset) ){ + + vpts = pts + this->vpts_offset; - this->wrap_diff_counter++; - - if (this->wrap_diff_counter > MAX_NUM_WRAP_DIFF) { - - printf ("metronom: forcing video_wrap (%lld) and audio wrap (%lld)", - this->video_wrap_offset, this->audio_wrap_offset); - - if (this->video_wrap_offset > this->audio_wrap_offset) - this->audio_wrap_offset = this->video_wrap_offset; - else - this->video_wrap_offset = this->audio_wrap_offset; - - printf (" to %lld\n", this->video_wrap_offset); - - this->wrap_diff_counter = 0; - } - } - - /* - * compare predicted (this->video_vpts) and given (pts+wrap_offset) - * pts values - hopefully they will be the same - * if not, for small diffs try to interpolate - * for big diffs: jump - */ - - vpts = pts + this->video_wrap_offset; - - diff = this->video_vpts - vpts; + diff = this->video_vpts - vpts; #ifdef LOG - printf ("metronom: video diff is %lld (predicted %lld, given %lld)\n", - diff, this->video_vpts, vpts); + printf ("metronom: video diff is %lld (predicted %lld, given %lld)\n", + diff, this->video_vpts, vpts); #endif - if (abs (diff) > VIDEO_DRIFT_TOLERANCE) { + if (abs (diff) > VIDEO_DRIFT_TOLERANCE) { - this->video_vpts = vpts; - this->video_drift = 0; + this->video_vpts = vpts; + this->video_drift = 0; #ifdef LOG - printf ("metronom: video jump, ignoring predicted vpts\n"); + printf ("metronom: video jump\n"); #endif - } else if (diff) { + } else if (diff) { - this->video_drift = diff / 30; + this->video_drift = diff; #ifdef LOG - printf ("metronom: video drift, compensation will be %lld pts/frame\n", - this->video_drift); + printf ("metronom: video drift, drift is %lld\n", this->video_drift); #endif - } } - - this->last_video_pts = pts; - } else - this->last_video_pts = this->video_vpts - this->video_wrap_offset; + } + + this->video_vpts -= this->video_drift / 30; + this->video_drift -= this->video_drift / 30; img->vpts = this->video_vpts + this->av_offset; @@ -459,18 +386,16 @@ static void metronom_got_video_frame (metronom_t *this, vo_frame_t *img) { printf ("metronom: video vpts for %10lld : %10lld (duration:%lld)\n", pts, this->video_vpts, duration); #endif - - this->video_vpts += duration - this->video_drift; - img->duration -= this->video_drift; + + this->video_vpts += duration; pthread_mutex_unlock (&this->lock); } -static void metronom_expect_audio_discontinuity (metronom_t *this) { +static void metronom_expect_audio_discontinuity (metronom_t *this, int64_t disc_off) { pthread_mutex_lock (&this->lock); - this->audio_discontinuity = 10; this->audio_discontinuity_count++; pthread_cond_signal (&this->audio_discontinuity_reached); @@ -487,120 +412,40 @@ static void metronom_expect_audio_discontinuity (metronom_t *this) { } if ( this->audio_vpts < this->video_vpts ) { - this->audio_vpts = this->video_vpts; + this->audio_vpts = this->video_vpts; printf ("metronom: audio vpts adjusted to %lld\n", this->audio_vpts); } - - /* this->num_audio_samples_guessed = 1; */ - /* this->last_audio_pts = this->audio_vpts - this->audio_wrap_offset; */ + + /* next_vpts_offset, in_discontinuity is handled in expect_video_discontinuity */ 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, int64_t scr) { + int nsamples) { int64_t vpts; #ifdef LOG - printf ("metronom: got %d audio samples, pts is %lld, last_pts is %lld, diff = %lld\n", - nsamples, pts, this->last_audio_pts, pts - this->last_audio_pts); - printf ("metronom: audio wrap offset is %lld\n", this->audio_wrap_offset); + printf ("metronom: got %d audio samples, pts is %lld\n", nsamples, pts); #endif pthread_mutex_lock (&this->lock); -#if 0 - if (this->audio_discontinuity && this->video_discontinuity) { - - /* this is needed to take care of still frame with no audio - were vpts are not updated. - we can only do it here because audio and video decoder threads - have just been synced */ - if ( this->audio_vpts < metronom_get_current_time(this) ) { - this->audio_vpts = metronom_get_current_time(this) + PREBUFFER_PTS_OFFSET; - this->video_vpts = this->audio_vpts; - printf ("metronom: audio/video vpts too old, adjusted to %lld\n", - this->audio_vpts); - } - } -#endif - + if (this->in_discontinuity) + pts = 0; /* ignore pts during discontinuities */ + if (pts) { - - /* - * discontinuity ? - */ - if ( this->audio_discontinuity ) { - this->audio_discontinuity = 0; - this->wrap_diff_counter = 0; - - this->audio_wrap_offset = this->audio_vpts - pts ; - - /* - * this->num_audio_samples_guessed - * (this->audio_pts_delta + this->pts_per_smpls) / AUDIO_SAMPLE_NUM ; - */ - - vpts = pts + this->audio_wrap_offset; - - printf ("metronom: audio pts discontinuity/start, pts is %lld, wrap_offset is %lld, vpts is %lld\n", - pts, this->audio_wrap_offset, vpts); - - - } else { - - /* - * audio and video wrap are not allowed to differ - * for too long - */ - - if ( this->video_wrap_offset != this->audio_wrap_offset ) { - this->wrap_diff_counter++; - - if (this->wrap_diff_counter > MAX_NUM_WRAP_DIFF) { - - printf ("metronom: forcing video_wrap (%lld) and audio wrap (%lld)", - this->video_wrap_offset, this->audio_wrap_offset); - - if (this->video_wrap_offset > this->audio_wrap_offset) - this->audio_wrap_offset = this->video_wrap_offset; - else - this->video_wrap_offset = this->audio_wrap_offset; - - printf ("to %lld\n", this->video_wrap_offset); - - this->wrap_diff_counter = 0; - } - } - - vpts = pts + this->audio_wrap_offset; - - /* - * calc delta to compensate wrong samplerates - */ - - if (this->last_audio_pts && (pts>this->last_audio_pts)) { - int32_t vpts_diff; - - vpts_diff = vpts - this->audio_vpts; - - this->audio_pts_delta += vpts_diff*AUDIO_SAMPLE_NUM / (this->num_audio_samples_guessed); - - if (abs(this->audio_pts_delta) >= MAX_AUDIO_DELTA) - this->audio_pts_delta = 0; - } - } - - this->num_audio_samples_guessed = 0; - this->last_audio_pts = pts; - this->audio_vpts = vpts; + vpts = pts + this->vpts_offset; + this->audio_vpts = vpts; } else vpts = this->audio_vpts; - this->audio_vpts += nsamples * (this->audio_pts_delta + this->pts_per_smpls) / AUDIO_SAMPLE_NUM; - this->num_audio_samples_guessed += nsamples; + this->audio_vpts += nsamples * this->pts_per_smpls / AUDIO_SAMPLE_NUM; #ifdef LOG printf ("metronom: audio vpts for %10lld : %10lld\n", pts, vpts); @@ -734,6 +579,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->set_av_offset = metronom_set_av_offset; @@ -759,47 +606,26 @@ metronom_t * metronom_init (int have_audio, void *xine) { printf ("metronom: cannot create sync thread (%s)\n", strerror(err)); - pthread_cond_init (&this->video_discontinuity_reached, NULL); - pthread_cond_init (&this->audio_discontinuity_reached, NULL); - - this->av_offset = 0; - + this->av_offset = 0; + this->in_discontinuity = 0; + this->vpts_offset = 0; + this->next_vpts_offset = 0; /* initialize video stuff */ - this->have_audio = have_audio; this->video_vpts = PREBUFFER_PTS_OFFSET; - - this->last_video_pts = 0; this->video_drift = 0; - - this->video_wrap_offset = PREBUFFER_PTS_OFFSET; - this->wrap_diff_counter = 0; - - this->video_discontinuity = 0; this->video_discontinuity_count = 0; + pthread_cond_init (&this->video_discontinuity_reached, NULL); /* initialize audio stuff */ + this->have_audio = have_audio; this->audio_vpts = PREBUFFER_PTS_OFFSET; - - this->audio_pts_delta = 0; - - this->num_audio_samples_guessed = 1; - this->last_audio_pts = 0; - - this->audio_wrap_offset = PREBUFFER_PTS_OFFSET; - this->wrap_diff_counter = 0; - - this->audio_discontinuity = 0; this->audio_discontinuity_count = 0; + pthread_cond_init (&this->audio_discontinuity_reached, NULL); + return this; } - - - - - - diff --git a/src/xine-engine/metronom.h b/src/xine-engine/metronom.h index dd0cd703d..5ad28dcb2 100644 --- a/src/xine-engine/metronom.h +++ b/src/xine-engine/metronom.h @@ -1,7 +1,7 @@ /* * 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: metronom.h,v 1.20 2002/03/10 21:16:15 miguelfreitas Exp $ + * $Id: metronom.h,v 1.21 2002/03/11 12:31:26 guenter Exp $ * * metronom: general pts => virtual calculation/assoc * @@ -58,8 +58,7 @@ typedef struct scr_plugin_s scr_plugin_t; struct metronom_s { /* - * Pointer to current xine object. We use a void pointer to avoid type declaration clash. - * Ugly but working. + * pointer to current xine object. a void pointer is used to avoid type declaration clash. */ void *xine; @@ -90,7 +89,6 @@ struct metronom_s { * * parameter pts : pts for audio data if known, 0 otherwise * nsamples : number of samples delivered - * scr : system clock reference, may be 0 or == pts if unknown * * return value: virtual pts for audio data * @@ -100,21 +98,19 @@ struct metronom_s { */ int64_t (*got_audio_samples) (metronom_t *this, int64_t pts, - int nsamples, int64_t scr); + int nsamples); /* * called by SPU decoder whenever a packet is delivered to it * * parameter pts : pts for SPU packet if known, 0 otherwise - * scr : system clock reference, may be 0 or == pts if unknown * * return value: virtual pts for SPU packet * (this is the only pts to vpts function that cannot update the wrap_offset * due to the lack of regularity on spu packets) */ - int64_t (*got_spu_packet) (metronom_t *this, int64_t pts, int64_t duration, - int64_t scr); + int64_t (*got_spu_packet) (metronom_t *this, int64_t pts, int64_t duration); /* * tell metronom about discontinuities. @@ -136,8 +132,11 @@ struct metronom_s { * whenever we get a new pts we can calculate the new xxx_wrap_offset) * */ - void (*expect_audio_discontinuity) (metronom_t *this); - void (*expect_video_discontinuity) (metronom_t *this, int starting); + 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); /* * manually correct audio <-> video sync @@ -203,21 +202,16 @@ struct metronom_s { int64_t pts_per_smpls; - int64_t audio_pts_delta; - int64_t video_vpts; int64_t spu_vpts; int64_t audio_vpts; - int64_t video_wrap_offset; - int64_t audio_wrap_offset; - int wrap_diff_counter; + int64_t vpts_offset; + int64_t next_vpts_offset; - int64_t last_video_pts; - int64_t video_drift; + int in_discontinuity; - int64_t last_audio_pts; - int num_audio_samples_guessed; + int64_t video_drift; int64_t av_offset; @@ -228,10 +222,7 @@ struct metronom_s { pthread_mutex_t lock; int have_audio; - int video_starting; - int video_discontinuity; int video_discontinuity_count; - int audio_discontinuity; int audio_discontinuity_count; pthread_cond_t video_discontinuity_reached; pthread_cond_t audio_discontinuity_reached; diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c index d5b1f9d4c..cd8e14142 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.75 2002/03/10 21:16:14 miguelfreitas Exp $ + * $Id: video_decoder.c,v 1.76 2002/03/11 12:31:26 guenter Exp $ * */ @@ -106,7 +106,7 @@ void *video_decoder_loop (void *this_gen) { pthread_mutex_unlock (&this->finished_lock); - this->metronom->expect_video_discontinuity (this->metronom, 1); + this->metronom->video_stream_start (this->metronom); break; @@ -155,7 +155,7 @@ void *video_decoder_loop (void *this_gen) { pthread_mutex_lock (&this->finished_lock); this->spu_finished = 1; - if (!this->video_finished && (buf->decoder_info[0]==0)) { + if (!this->video_finished && (buf->decoder_flags==BUF_FLAG_END_STREAM)) { this->video_finished = 1; @@ -186,7 +186,7 @@ void *video_decoder_loop (void *this_gen) { this->video_in_discontinuity = 1; - this->metronom->expect_video_discontinuity (this->metronom, 0); + this->metronom->expect_video_discontinuity (this->metronom, buf->disc_off); this->video_in_discontinuity = 0; break; diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index 1e8216a5f..691700e91 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.105 2002/03/01 09:29:50 guenter Exp $ + * $Id: xine.c,v 1.106 2002/03/11 12:31:26 guenter Exp $ * * top-level xine functions * @@ -892,6 +892,8 @@ void xine_log (xine_t *this, int buf, const char *format, ...) { this->log_buffers[buf]->scratch_printf (this->log_buffers[buf], format, argp); + vprintf (format, argp); + va_end (argp); } |