[MPlayer-dev-eng] [PATCH] DXR3

David Holm david at realityrift.com
Mon Feb 4 10:04:35 CET 2002


Hi,
I've been playing with DXR3 prebuffering for a long while and have never
succeeded in getting it to sync with audio after seeking/pausing.
I finally managed to figure out what the problem was. After a seek you
have to flush the video buffer so that the buffered frames won't be
played out (because if they are, you will get a video/audio differance
as big as the number of frames in the buffer). MPlayer seems to pass
audio data to the audio device and then send video data to the video
device now this would be logical in a movie player. The problem is that
when you use prebuffering on the dxr3 and a seek or pause happens, the
video buffer is flushed, but this takes a small amount of time, since
audio has already been written to the audio device audio playback has
already started while the dxr3 is still flushing it's buffers. When the
dxr3 starts pushing video frames back into the buffer audio will already
be out of sync by a fraction. The more you seek the more out of sync you
will be...
The attached patch moves the audio section to after the video section in
mplayer.c, it's a minor modification (as you can see). But with this I
can use prebuffering on the dxr3, without it I cannot. Please allow this
patch (I've tested it with xv playback and it does not seem to affect
sync in any way).

//David Holm


-------------- next part --------------
Index: mplayer.c
===================================================================
RCS file: /cvsroot/mplayer/main/mplayer.c,v
retrieving revision 1.385
diff -u -r1.385 mplayer.c
--- mplayer.c	3 Feb 2002 15:16:46 -0000	1.385
+++ mplayer.c	4 Feb 2002 09:07:23 -0000
@@ -1488,43 +1488,6 @@
   vo_pts=sh_video->timer*90000.0;
   vo_fps=sh_video->fps;
 
-/*========================== PLAY AUDIO ============================*/
-while(sh_audio){
-  unsigned int t;
-  int playsize;
-  
-  ao_data.pts=sh_audio->timer*90000.0;
-  playsize=audio_out->get_space();
-  
-  if(!playsize) break; // buffer is full, do not block here!!!
-  
-  if(playsize>MAX_OUTBURST) playsize=MAX_OUTBURST; // we shouldn't exceed it!
-  //if(playsize>outburst) playsize=outburst;
-
-  // Update buffer if needed
-  current_module="decode_audio";   // Enter AUDIO decoder module
-  t=GetTimer();
-  while(sh_audio->a_buffer_len<playsize && !d_audio->eof){
-    int ret=decode_audio(sh_audio,&sh_audio->a_buffer[sh_audio->a_buffer_len],
-        playsize-sh_audio->a_buffer_len,sh_audio->a_buffer_size-sh_audio->a_buffer_len);
-    if(ret>0) sh_audio->a_buffer_len+=ret; else break;
-  }
-  current_module=NULL;   // Leave AUDIO decoder module
-  t=GetTimer()-t;audio_time_usage+=t*0.000001;
-  
-  if(playsize>sh_audio->a_buffer_len) playsize=sh_audio->a_buffer_len;
-  
-  playsize=audio_out->play(sh_audio->a_buffer,playsize,0);
-
-  if(playsize>0){
-      sh_audio->a_buffer_len-=playsize;
-      memcpy(sh_audio->a_buffer,&sh_audio->a_buffer[playsize],sh_audio->a_buffer_len);
-      sh_audio->timer+=playsize/(float)(sh_audio->o_bps);
-  }
-
-  break;
-} // if(sh_audio)
-
 /*========================== UPDATE TIMERS ============================*/
 #if 0
   if(alsa){
@@ -1696,6 +1659,43 @@
 	EventHandling();
       }
 #endif
+
+/*========================== PLAY AUDIO ============================*/
+while(sh_audio){
+  unsigned int t;
+  int playsize;
+  
+  ao_data.pts=sh_audio->timer*90000.0;
+  playsize=audio_out->get_space();
+  
+  if(!playsize) break; // buffer is full, do not block here!!!
+  
+  if(playsize>MAX_OUTBURST) playsize=MAX_OUTBURST; // we shouldn't exceed it!
+  //if(playsize>outburst) playsize=outburst;
+
+  // Update buffer if needed
+  current_module="decode_audio";   // Enter AUDIO decoder module
+  t=GetTimer();
+  while(sh_audio->a_buffer_len<playsize && !d_audio->eof){
+    int ret=decode_audio(sh_audio,&sh_audio->a_buffer[sh_audio->a_buffer_len],
+        playsize-sh_audio->a_buffer_len,sh_audio->a_buffer_size-sh_audio->a_buffer_len);
+    if(ret>0) sh_audio->a_buffer_len+=ret; else break;
+  }
+  current_module=NULL;   // Leave AUDIO decoder module
+  t=GetTimer()-t;audio_time_usage+=t*0.000001;
+  
+  if(playsize>sh_audio->a_buffer_len) playsize=sh_audio->a_buffer_len;
+  
+  playsize=audio_out->play(sh_audio->a_buffer,playsize,0);
+
+  if(playsize>0){
+      sh_audio->a_buffer_len-=playsize;
+      memcpy(sh_audio->a_buffer,&sh_audio->a_buffer[playsize],sh_audio->a_buffer_len);
+      sh_audio->timer+=playsize/(float)(sh_audio->o_bps);
+  }
+
+  break;
+} // if(sh_audio)
 
 if(!(vo_flags&256)){ // flag 256 means: libvo driver does its timing (dvb card)
 


More information about the MPlayer-dev-eng mailing list