diff options
author | Michael Roitzsch <mroi@users.sourceforge.net> | 2004-04-09 15:06:02 +0000 |
---|---|---|
committer | Michael Roitzsch <mroi@users.sourceforge.net> | 2004-04-09 15:06:02 +0000 |
commit | 5b4795e9f35230e97a8a4ec61de6681eed4aa3f9 (patch) | |
tree | 1224a9db9ce374ba292548ee6c78643ba00d5b92 /src | |
parent | 039fe9adb8fdc6e361d0b193ae1d7bcfec5287d9 (diff) | |
download | xine-lib-5b4795e9f35230e97a8a4ec61de6681eed4aa3f9.tar.gz xine-lib-5b4795e9f35230e97a8a4ec61de6681eed4aa3f9.tar.bz2 |
improving precision of audio vpts calculation, the comment in metronom.c explains
CVS patchset: 6363
CVS date: 2004/04/09 15:06:02
Diffstat (limited to 'src')
-rw-r--r-- | src/xine-engine/metronom.c | 27 | ||||
-rw-r--r-- | src/xine-engine/metronom.h | 3 |
2 files changed, 26 insertions, 4 deletions
diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c index 708efc222..f1803e431 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.136 2004/02/19 02:50:26 rockyb Exp $ + * $Id: metronom.c,v 1.137 2004/04/09 15:06:02 mroi Exp $ */ #ifdef HAVE_CONFIG_H @@ -310,6 +310,7 @@ static void metronom_handle_discontinuity (metronom_t *this, int type, case DISC_STREAMSEEK: this->video_vpts = this->prebuffer + cur_time; this->audio_vpts = this->video_vpts; + this->audio_vpts_rmndr = 0; this->force_audio_jump = 1; this->force_video_jump = 1; this->video_drift = 0; @@ -329,6 +330,7 @@ static void metronom_handle_discontinuity (metronom_t *this, int type, /* still frame, no audio */ this->video_vpts = this->prebuffer + cur_time; this->audio_vpts = this->video_vpts; + this->audio_vpts_rmndr = 0; this->force_video_jump = 1; this->force_audio_jump = 1; this->video_drift = 0; @@ -340,6 +342,7 @@ static void metronom_handle_discontinuity (metronom_t *this, int type, if (this->audio_vpts < cur_time) { /* video, no sound */ this->audio_vpts = this->video_vpts; + this->audio_vpts_rmndr = 0; xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio vpts adjusted to audio vpts\n"); } else { /* video + audio */ @@ -588,6 +591,7 @@ static int64_t metronom_got_audio_samples (metronom_t *this, int64_t pts, this->video_vpts = this->audio_vpts = this->master->video_vpts; else this->video_vpts = this->audio_vpts = this->master->audio_vpts; + this->audio_vpts_rmndr = 0; /* when being attached to the first master, do not drift into * his vpts values but adopt at once */ this->force_audio_jump = 1; @@ -615,6 +619,7 @@ static int64_t metronom_got_audio_samples (metronom_t *this, int64_t pts, if((abs(diff) > AUDIO_DRIFT_TOLERANCE) || (this->force_audio_jump)) { this->force_audio_jump = 0; this->audio_vpts = vpts; + this->audio_vpts_rmndr = 0; this->audio_drift_step = 0; xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio jump, diff=%" PRId64 "\n", diff); } else { @@ -645,8 +650,22 @@ static int64_t metronom_got_audio_samples (metronom_t *this, int64_t pts, * good because sound card won't play it faster or slower just because * we want. however, adding the error to the vpts_offset will force video * to change it's frame rate to keep in sync with us. + * + * Since we are using integer division below, it can happen that we lose + * precision for the calculated duration in vpts for each audio buffer + * (< 1 PTS, e.g. 0.25 PTS during playback of most DVDs with LPCM audio). + * This would lead to a situation where the sound card actually needs + * more time to play back the buffers, than the audio buffer's vpts field + * indicates. This makes audio_out loop think we are in sync with the + * soundcard, while we actually are not. So that's why there is the extra + * modulo calculation, to keep track of the truncated, fractional part. */ - this->audio_vpts += nsamples * this->pts_per_smpls / AUDIO_SAMPLE_NUM; + this->audio_vpts_rmndr += nsamples * this->pts_per_smpls % AUDIO_SAMPLE_NUM; + this->audio_vpts += nsamples * this->pts_per_smpls / AUDIO_SAMPLE_NUM; + if (this->audio_vpts_rmndr >= AUDIO_SAMPLE_NUM) { + this->audio_vpts += 1; + this->audio_vpts_rmndr -= AUDIO_SAMPLE_NUM; + } this->audio_samples += nsamples; this->vpts_offset += nsamples * this->audio_drift_step / AUDIO_SAMPLE_NUM; @@ -678,7 +697,8 @@ static void metronom_set_option (metronom_t *this, int option, int64_t value) { xprintf(this->xine, XINE_VERBOSITY_LOG, "spu_offset=%" PRId64 " pts\n", this->spu_offset); break; case METRONOM_ADJ_VPTS_OFFSET: - this->audio_vpts += value; + this->audio_vpts += value; + this->audio_vpts_rmndr = 0; /* that message should be rare, please report otherwise. * when xine is in some sort of "steady state" hearing it @@ -915,6 +935,7 @@ metronom_t * _x_metronom_init (int have_video, int have_audio, xine_t *xine) { this->have_video = have_video; this->have_audio = have_audio; this->audio_vpts = this->prebuffer; + this->audio_vpts_rmndr = 0; this->audio_discontinuity_count = 0; pthread_cond_init (&this->audio_discontinuity_reached, NULL); diff --git a/src/xine-engine/metronom.h b/src/xine-engine/metronom.h index 9a0019692..7c422a250 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.57 2004/02/16 20:19:10 uid86226 Exp $ + * $Id: metronom.h,v 1.58 2004/04/09 15:06:03 mroi Exp $ * * metronom: general pts => virtual calculation/assoc * @@ -189,6 +189,7 @@ struct metronom_s { int64_t video_vpts; int64_t spu_vpts; int64_t audio_vpts; + int64_t audio_vpts_rmndr; /* the remainder for integer division */ int64_t vpts_offset; |