Author: rolf
Date: 2008-02-06 18:39:19 -0500 (Wed, 06 Feb 2008)
New Revision: 95099

Modified:
   trunk/moon/src/ChangeLog
   trunk/moon/src/mplayer.cpp
Log:
* mplayer.cpp: AdvanceFrame: Create a target_pts range, if we're within
  the range, draw the current frame. If we're ahead of the range, do
  nothing (fixes some video/audio sync problems), and if we're behind
  drop frames. The range makes sure that we paint every frame even
  when the audio loop doesn't update the target pts as often as we're
  drawing video.

Modified: trunk/moon/src/ChangeLog
===================================================================
--- trunk/moon/src/ChangeLog    2008-02-06 23:31:39 UTC (rev 95098)
+++ trunk/moon/src/ChangeLog    2008-02-06 23:39:19 UTC (rev 95099)
@@ -1,5 +1,13 @@
 2008-02-07  Rolf Bjarne Kvinge <[EMAIL PROTECTED]> 
 
+       * mplayer.cpp: AdvanceFrame: Create a target_pts range, if we're within 
the
+         range, draw the current frame. If we're ahead of the range, do nothing
+         (fixes some video/audio sync problems), and if we're behind drop 
frames.
+         The range makes sure that we paint every frame even when the audio 
loop
+         doesn't update the target pts as often as we're drawing video.
+
+2008-02-07  Rolf Bjarne Kvinge <[EMAIL PROTECTED]> 
+
        * panel.cpp, runtime.cpp: Fix warnings.
 
 2008-02-06  Rolf Bjarne Kvinge <[EMAIL PROTECTED]> 

Modified: trunk/moon/src/mplayer.cpp
===================================================================
--- trunk/moon/src/mplayer.cpp  2008-02-06 23:31:39 UTC (rev 95098)
+++ trunk/moon/src/mplayer.cpp  2008-02-06 23:39:19 UTC (rev 95099)
@@ -468,6 +468,8 @@
        mplayer->rendered_frame = true;
 }
 
+#define DEBUG_AF 0
+
 bool
 MediaPlayer::AdvanceFrame ()
 {
@@ -475,20 +477,23 @@
        Packet *pkt = NULL;
        MediaFrame *frame = NULL;
        IMediaStream *stream;
+       uint64_t target_pts = 0;
+       uint64_t target_pts_start = 0;
+       uint64_t target_pts_end = 0;
+       uint64_t target_pts_delta = MilliSeconds_ToPts (100);
        bool update = false;
-       uint64_t target_pts;
        
+#if DEBUG_AF
+       int skipped = 0;
+#endif
+       
        load_frame = false;
        
-       if (paused) {
-               // shouldn't happen, but just in case
-               printf ("WARNING: MediaPlayer::AdvanceFrame() called when 
paused\n");
+       if (paused)
                return false;
-       }
        
-       if (seeking) {
+       if (seeking)
                return false;
-       }
        
        if (eof)
                return false;
@@ -509,6 +514,17 @@
                this->target_pts = target_pts;
        }
        
+       target_pts_start = target_pts_delta > target_pts ? 0 : target_pts - 
target_pts_delta;
+       target_pts_end = target_pts + target_pts_delta;
+       
+       if (current_pts >= target_pts_end && caught_up_with_seek) {
+#if DEBUG_AF
+               printf ("MediaPlayer::AdvanceFrame (): video is running too 
fast, wait a bit (current_pts: %llu, target_pts: %llu, delta: %llu, diff: 
%lld).\n",
+                       current_pts, target_pts, target_pts_delta, current_pts 
- target_pts);
+#endif
+               return false;
+       }
+               
        while ((pkt = (Packet *) video->queue->Pop ())) {
                if (pkt->frame->event == FrameEventEOF) {
                        delete pkt;
@@ -519,9 +535,8 @@
                // always decode the frame or we get glitches in the screen
                frame = pkt->frame;
                stream = frame->stream;
+               current_pts = frame->pts;
                update = true;
-
-               current_pts = frame->pts;
                
                media_player_enqueue_frames (this, 0, 1);       
                
@@ -530,12 +545,12 @@
                        MediaResult result = stream->decoder->DecodeFrame 
(frame);
                        
                        if (!MEDIA_SUCCEEDED (result)) {
-                               printf ("MediaPlayer::AdvanceFrame (): Couldn't 
decode frame.\n");
+                               printf ("MediaPlayer::AdvanceFrame (): Couldn't 
decode frame (%i)\n", result);
                                update = false;
                        }
                }
                
-               if (update && current_pts >= target_pts) {
+               if (update && current_pts >= target_pts_start) {
                        caught_up_with_seek = true;
                        // we are in sync (or ahead) of audio playback
                        break;
@@ -548,12 +563,18 @@
                }
                
                // we are lagging behind, drop this frame
+#if DEBUG_AF
+               printf ("MediaPlayer::AdvanceFrame (): skipped frame with pts 
%llu, target pts: %llu, diff: %lld, milliseconds: %lld\n", frame->pts, 
target_pts, target_pts - frame->pts, MilliSeconds_FromPts ((target_pts - 
frame->pts)));
+               skipped++;
+#endif
                frame = NULL;
                delete pkt;
        }
        
        if (update && frame && caught_up_with_seek) {
-               //printf ("MediaPlayer::AdvanceFrame (): rendering pts 
%llu.\n", frame->pts);
+#if DEBUG_AF
+               printf ("MediaPlayer::AdvanceFrame (): rendering pts %llu 
(target pts: %llu, current pts: %llu, caught_up_with_seek: %s, skipped frames: 
%i)\n", frame->pts, target_pts, current_pts, caught_up_with_seek ? "true" : 
"false", skipped);
+#endif
                render_frame (this, frame);
                delete pkt;
                

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to