[MPlayer-dev-eng] a-v sync fixes/cleanup backported from g2

Arpi arpi at thot.banki.hu
Wed Aug 6 00:32:48 CEST 2003


Hi,

I've started to backport the new a-v sync code from g2.

Although it won't be so good, without codecs (especially audio) allowed
to fixup timestamps, and fixing video pts reordering for IPB files.
I won't port that mess, it means API and demuxer design changes...

So this patch is mainly cleanup, doesn't really changes a-v behaviour,
except that it uses stream timer delay for PTS correction, like it
did before for -autosync only, but now it is used all time.

Please tets it, before commit. I think it's ok, but should be tested
on very slow system (with and without -framedrop, i wanna know if A-V
starts drifting away from 0 then).

patch:

Index: mplayer.c
===================================================================
RCS file: /cvsroot/mplayer/main/mplayer.c,v
retrieving revision 1.709
diff -u -r1.709 mplayer.c
--- mplayer.c	4 Aug 2003 09:12:40 -0000	1.709
+++ mplayer.c	5 Aug 2003 22:28:07 -0000
@@ -717,7 +717,7 @@
 
 int file_format=DEMUXER_TYPE_UNKNOWN;
 
-int delay_corrected=1;
+int a_pts_available=1;
 
 // movie info:
 int eof=0;
@@ -2199,63 +2199,39 @@
     float a_pts=0;
     float v_pts=0;
 
-    // unplayed bytes in our and soundcard/dma buffer:
-    float delay=playback_speed*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->delay;
-      delay+=(float)sh_audio->a_buffer_len/(float)sh_audio->o_bps;
-    }
-
-#if 0
-    if(pts_from_bps){
-	// PTS = sample_no / samplerate
-        unsigned int samples=
-//	  (sh_audio->audio.dwSampleSize)?
-//          ((ds_tell(d_audio)-sh_audio->a_in_buffer_len)/sh_audio->audio.dwSampleSize) :
-          ds_tell_block(d_audio); // <- used for VBR audio
-	samples+=sh_audio->audio.dwStart; // offset
-        a_pts=samples*(float)sh_audio->audio.dwScale/(float)sh_audio->audio.dwRate;
-	delay_corrected=1;
-	a_pts-=(sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
-    } else 
-#endif
-    {
-      // PTS = (last timestamp) + (bytes after last timestamp)/(bytes per sec)
-      a_pts=d_audio->pts;
-      if(!delay_corrected) if(a_pts) delay_corrected=1;
+// calculate effective audio stream PTS:
+    // PTS = (last timestamp) + (bytes after last timestamp)/(bytes per sec)
+    a_pts=d_audio->pts;
+    if(!a_pts_available) if(a_pts) a_pts_available=1;
 #if 0
       printf("\n#X# pts=%5.3f ds_pts=%5.3f buff=%5.3f total=%5.3f\n",
           a_pts,
 	  ds_tell_pts(d_audio)/(float)sh_audio->i_bps,
 	  -sh_audio->a_in_buffer_len/(float)sh_audio->i_bps,
 	  a_pts+(ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps);
-#endif	  
-      a_pts+=(ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
-    }
+#endif
+    // adjust by delay of the undecoded (buffered in codec or demuxer) data:
+    a_pts+=(ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
+    // adjust by delay of unplayed samples in our output buffer:
+    a_pts-=(float)sh_audio->a_buffer_len/(float)sh_audio->o_bps;
+    // remove stream timers' difference: (audio preload time)
+    a_pts-=sh_audio->delay;
+    // adjust by forced A-V delay (option -delay):
+    a_pts-=audio_delay;
+    
     v_pts=sh_video ? sh_video->pts : d_video->pts;
 
-      mp_dbg(MSGT_AVSYNC,MSGL_DBG2,"### A:%8.3f (%8.3f)  V:%8.3f  A-V:%7.4f  \n",a_pts,a_pts-audio_delay-delay,v_pts,(a_pts-delay-audio_delay)-v_pts);
+      mp_dbg(MSGT_AVSYNC,MSGL_DBG2,"### A:%8.3f  V:%8.3f  A-V:%7.4f  \n",a_pts,v_pts,a_pts-v_pts);
 
-      if(delay_corrected){
+      if(a_pts_available){
 	static int drop_message=0;
         float x;
-	AV_delay=(a_pts-delay-audio_delay)-v_pts;
+	AV_delay=a_pts-v_pts;
 	if(AV_delay>0.5 && drop_frame_cnt>50+drop_message*250){
 	  ++drop_message;
 	  mp_msg(MSGT_AVSYNC,MSGL_WARN,MSGTR_SystemTooSlow);
 	}
+	// limit per-frame A-V timer correction:
         x=AV_delay*0.1f;
         if(x<-max_pts_correction) x=-max_pts_correction; else
         if(x> max_pts_correction) x= max_pts_correction;
@@ -2265,7 +2241,7 @@
           max_pts_correction=sh_video->frametime*0.10; // +-10% of time
 	if(!frame_time_remaining){ sh_audio->delay+=x; c_total+=x;} // correction
         if(!quiet) mp_msg(MSGT_AVSYNC,MSGL_STATUS,"A:%6.1f V:%6.1f A-V:%7.3f ct:%7.3f  %3d/%3d  %2d%% %2d%% %4.1f%% %d %d %d%%\r",
-	  a_pts-audio_delay-delay,v_pts,AV_delay,c_total,
+	  a_pts,v_pts,AV_delay,c_total,
           (int)sh_video->num_frames,(int)sh_video->num_frames_decoded,
           (sh_video->timer>0.5)?(int)(100.0*video_time_usage*playback_speed/(double)sh_video->timer):0,
           (sh_video->timer>0.5)?(int)(100.0*vout_time_usage*playback_speed/(double)sh_video->timer):0,
@@ -2274,7 +2250,7 @@
 	  ,output_quality
 	  ,cache_fill_status
         );
-        fflush(stdout);
+//        fflush(stdout);  // done by mp_msg.c
       }
     
   } else {



A'rpi / Astral & ESP-team

--
Developer of MPlayer G2, the Movie Framework for all - http://www.MPlayerHQ.hu



More information about the MPlayer-dev-eng mailing list