[MPlayer-dev-eng] [PATCH] -autosync corrected A/V sync

Sidik Isani lksi at cfht.hawaii.edu
Tue Oct 1 21:15:01 CEST 2002


Hello -

  Here's the A/V sync patch.  Please see the description in the part
  of the patch for the man page.  (I put it where -dapsync was, but
  you may want to move it down to the stream options? ... rename the
  option itself? ... whatever you like.)  The important thing is it
  should be evident from the patch that the default, -autosync 0,
  does NOT change the normal sync model of mplayer at all this time!

  Does anyone else use "-ao nas"?  I'd be interested to see if it
  works as well for them.  And if anyone manages to use it to work
  around problems with a buggy sound driver, I'd like to know if
  "-autosync 30" is enough (the parameter takes a value to indicate
  how much smoothing you want, until we figure out an optimal value.)
  Enjoy.

Be seeing you,

- Sidik

P.S.:  Creating only a wrapper around get_delay() was causing things to
       oscillate because of the way PTS correction is done, so this is
       a bit different, but hopefully I commented what it is doing
       well enough.  5 lines of code which hack on "delay" were added.
-------------- next part --------------
diff -ru MPlayer-cvs/DOCS/mplayer.1 MPlayer-isani/DOCS/mplayer.1
--- MPlayer-cvs/DOCS/mplayer.1	Tue Sep 24 03:19:19 2002
+++ MPlayer-isani/DOCS/mplayer.1	Tue Oct  1 08:29:26 2002
@@ -159,13 +159,25 @@
 can use some big number. You may not use it together with \-pp but it is OK
 with \-npp!
 .TP
+.B \-autosync <factor>
+Gradually adjusts the A/V sync based on audio delay measurements.
+Specifying \-autosync 0, the default, will cause frame timing to be based
+entirely on audio delay measurements.  Specifying \-autosync 1 will do the
+same, but will subtly change the A/V correction algorithm used.  An uneven
+video frame rate in a movie which plays fine with -nosound can often be
+helped by setting this to an integer value greater than 1.  The higher
+the value, the closer the timing will be to -nosound.
+
+Try \-autosync 30 to smooth out problems with sound drivers which do
+not implement a perfect audio delay measurement.  With this value, if
+large A/V sync offsets occur, they will only take about 1 or 2 seconds
+to settle out.  This delay in reaction time to sudden A/V offsets should
+be the only side-effect of turning this option on, for all sound drivers.
+.TP
 .B \-benchmark
 Prints some statistics on CPU usage and dropped frames at the end.
 Used in combination with \-nosound and \-vo null for benchmarking only video
 codec.
-.TP
-.B \-dapsync (OBSOLETE)
-Use alternative A/V sync method.
 .TP
 .B \-framedrop (see \-hardframedrop option too!)
 Frame dropping: decode all (except B) frames, video may skip.
diff -ru MPlayer-cvs/cfg-mplayer.h MPlayer-isani/cfg-mplayer.h
--- MPlayer-cvs/cfg-mplayer.h	Mon Sep 30 21:49:58 2002
+++ MPlayer-isani/cfg-mplayer.h	Mon Sep 30 23:14:40 2002
@@ -349,6 +349,8 @@
 	{"playlist", NULL, CONF_TYPE_STRING, 0, 0, 0, NULL},
 
 	// a-v sync stuff:
+	{"noautosync", &autosync, CONF_TYPE_FLAG, 0, 0, -1, NULL},
+	{"autosync", &autosync, CONF_TYPE_INT, CONF_RANGE, 0, 10000, NULL},
 //	{"dapsync", &dapsync, CONF_TYPE_FLAG, 0, 0, 1, NULL},
 //	{"nodapsync", &dapsync, CONF_TYPE_FLAG, 0, 1, 0, NULL},
 
diff -ru MPlayer-cvs/mplayer.c MPlayer-isani/mplayer.c
--- MPlayer-cvs/mplayer.c	Mon Sep 30 21:49:59 2002
+++ MPlayer-isani/mplayer.c	Tue Oct  1 08:50:58 2002
@@ -164,6 +164,9 @@
 static off_t step_sec=0;
 static int loop_times=-1;
 
+// A/V sync:
+static int autosync=0; // 30 might be a good default value.
+
 // may be changed by GUI:  (FIXME!)
 float rel_seek_secs=0;
 int abs_seek_pos=0;
@@ -1446,7 +1449,16 @@
 }
 #endif
 
-    if(drop_frame && !frame_time_remaining){
+    if(drop_frame && !frame_time_remaining && !autosync){
+      /*
+       * Note: time_frame should not be forced to 0 in autosync mode.
+       * It is used as a cumulative counter to predict and correct the
+       * delay measurements from the audio driver.  time_frame is already
+       * < 0, so the "time to sleep" code does not actually sleep.  Also,
+       * blit_frame is already 0 because drop_frame was true when
+       * decode_video was called (which causes it to set blit_frame to 0.)
+       * When autosync==0, the default behavior is still completely unchanged.
+       */
 
       time_frame=0;	// don't sleep!
       blit_frame=0;	// don't display!
@@ -1462,6 +1474,21 @@
 	  float delay=audio_out->get_delay();
 	  mp_dbg(MSGT_AVSYNC,MSGL_DBG2,"delay=%f\n",delay);
 
+	  if (autosync){
+	    /*
+	     * Adjust this raw delay value by calculating the expected
+	     * delay for this frame and generating a new value which is
+	     * weighted between the two.  The higher autosync is, the
+	     * closer to the delay value gets to that which "-nosound"
+	     * would have used, and the longer it will take for A/V
+	     * sync to settle at the right value (but it eventually will.)
+	     * This settling time is very short for values below 100.
+	     */
+	    float predicted = sh_audio->timer-sh_video->timer+time_frame;
+	    float difference = delay - predicted;
+	    delay = predicted + difference / (float)autosync;
+	  }
+
           time_frame=sh_video->timer;
           time_frame-=sh_audio->timer-delay;
 
@@ -1564,6 +1591,22 @@
 
     // unplayed bytes in our and soundcard/dma buffer:
     float delay=audio_out->get_delay()+(float)sh_audio->a_buffer_len/(float)sh_audio->o_bps;
+
+    if (autosync){
+      /*
+       * If autosync is enabled, the value for delay must be calculated
+       * a bit differently.  It is set only to the difference between
+       * the audio and video timers.  Any attempt to include the real
+       * or corrected delay causes the pts_correction code below to
+       * try to correct for the changes in delay which autosync is
+       * trying to measure.  This keeps the two from competing, but still
+       * allows the code to correct for PTS drift *only*.  (Using a delay
+       * value here, even a "corrected" one, would be incompatible with
+       * autosync mode.)
+       */
+      delay=sh_audio->timer-sh_video->timer;
+      delay+=(float)sh_audio->a_buffer_len/(float)sh_audio->o_bps;
+    }
 
     if(pts_from_bps){
 	// PTS = sample_no / samplerate


More information about the MPlayer-dev-eng mailing list