summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/xine-engine/metronom.c46
-rw-r--r--src/xine-engine/metronom.h5
2 files changed, 44 insertions, 7 deletions
diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c
index 8b194c5ac..a3652b02b 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.72 2002/03/22 18:20:03 miguelfreitas Exp $
+ * $Id: metronom.c,v 1.73 2002/03/23 13:28:35 miguelfreitas Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -46,6 +46,7 @@
#define MAX_SCR_PROVIDERS 10
#define PREBUFFER_PTS_OFFSET 30000
#define VIDEO_DRIFT_TOLERANCE 45000
+#define AUDIO_DRIFT_TOLERANCE 45000
/*
#define LOG
@@ -434,6 +435,9 @@ static void metronom_handle_audio_discontinuity (metronom_t *this, int type,
}
/* next_vpts_offset, in_discontinuity is handled in expect_video_discontinuity */
+
+ this->audio_samples = 0;
+ this->audio_drift_step = 0;
pthread_mutex_unlock (&this->lock);
}
@@ -442,6 +446,7 @@ static int64_t metronom_got_audio_samples (metronom_t *this, int64_t pts,
int nsamples) {
int64_t vpts;
+ int64_t diff;
#ifdef LOG
printf ("metronom: got %d audio samples, pts is %lld\n", nsamples, pts);
@@ -454,12 +459,41 @@ static int64_t metronom_got_audio_samples (metronom_t *this, int64_t pts,
if (pts) {
vpts = pts + this->vpts_offset;
- this->audio_vpts = vpts;
- } else
- vpts = this->audio_vpts;
-
- this->audio_vpts += nsamples * this->pts_per_smpls / AUDIO_SAMPLE_NUM;
+ diff = this->audio_vpts - vpts;
+
+ /* compare predicted and given vpts */
+ if( abs(diff) > AUDIO_DRIFT_TOLERANCE ) {
+ this->audio_vpts = vpts;
+ this->audio_drift_step = 0;
+ printf("metronom: audio jump\n");
+ }
+ else {
+ if( this->audio_samples ) {
+ /* calculate drift_step to recover vpts errors */
+ printf("audio diff = %lld ", diff );
+ diff *= AUDIO_SAMPLE_NUM;
+ diff /= this->audio_samples * 4;
+
+ /* drift_step is not allowed to change rate by more than 25% */
+ if( diff > this->pts_per_smpls/4 )
+ diff = this->pts_per_smpls/4;
+ if( diff < -this->pts_per_smpls/4 )
+ diff = -this->pts_per_smpls/4;
+
+ this->audio_drift_step = diff;
+
+ printf("audio_drift = %lld, pts_per_smpls = %lld\n", diff,
+ this->pts_per_smpls );
+ }
+ }
+ this->audio_samples = 0;
+ }
+ vpts = this->audio_vpts;
+ this->audio_vpts += nsamples * (this->pts_per_smpls-this->audio_drift_step)
+ / AUDIO_SAMPLE_NUM;
+ this->audio_samples += nsamples;
+
#ifdef LOG
printf ("metronom: audio vpts for %10lld : %10lld\n", pts, vpts);
#endif
diff --git a/src/xine-engine/metronom.h b/src/xine-engine/metronom.h
index 08b64eb57..edddd2061 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.23 2002/03/20 23:12:58 guenter Exp $
+ * $Id: metronom.h,v 1.24 2002/03/23 13:28:36 miguelfreitas Exp $
*
* metronom: general pts => virtual calculation/assoc
*
@@ -218,6 +218,9 @@ struct metronom_s {
int64_t video_drift;
int64_t video_drift_step;
+
+ int audio_samples;
+ int64_t audio_drift_step;
int64_t av_offset;