Index: libs/libmythtv/NuppelVideoPlayer.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/NuppelVideoPlayer.h,v
retrieving revision 1.175
diff -u -r1.175 NuppelVideoPlayer.h
--- libs/libmythtv/NuppelVideoPlayer.h	1 Apr 2005 04:18:28 -0000	1.175
+++ libs/libmythtv/NuppelVideoPlayer.h	10 Apr 2005 10:40:34 -0000
@@ -419,13 +432,14 @@
     DecoderBase *decoder;
 
     /* avsync stuff */
-    int lastaudiotime;
+    long long lastaudiotime;
     int delay;
     int avsync_delay;
     int avsync_adjustment;
     int avsync_avg;
     int avsync_oldavg;
     int refreshrate;
+    long long audiotimecodefudge;
 
     QMutex decoder_lock;
     int frame_interval; // always adjusted for play_speed
@@ -470,6 +484,9 @@
     bool errored;
 
     int m_DeintSetting;
+
+    int playSkipCount;
+    int playIncCount;
 };
 
 #endif
Index: libs/libmythtv/NuppelVideoPlayer.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp,v
retrieving revision 1.453
diff -u -r1.453 NuppelVideoPlayer.cpp
--- libs/libmythtv/NuppelVideoPlayer.cpp	9 Apr 2005 19:48:08 -0000	1.453
+++ libs/libmythtv/NuppelVideoPlayer.cpp	10 Apr 2005 10:40:43 -0000
@@ -214,6 +215,9 @@
     videosync = NULL;
 
     errored = false;
+    audiotimecodefudge = 0;
+    playSkipCount = 0;
+    playIncCount = 100; // factor of 100
 }
 
 NuppelVideoPlayer::~NuppelVideoPlayer(void)
@@ -312,8 +316,6 @@
     decoder_lock.lock();
     next_play_speed = speed;
     next_normal_speed = normal;
-    if (normal)
-        audio_stretchfactor = speed;
     decoder_lock.unlock();
 
     return true;
@@ -871,7 +873,7 @@
             stop = framesPlayed <= keyframedist;
         }
         if (stop)
-            Play(audio_stretchfactor, true, true);
+            Play((ffrew_skip > 0)?1.0:audio_stretchfactor, true, true);
     }
 
     return true;
@@ -1268,9 +1274,17 @@
     warpfactor_avg = (warpfactor + (warpfactor_avg * (WARPAVLEN - 1))) /
                       WARPAVLEN;
 
-    //cerr << "Divergence: " << divergence << "  Rate: " << rate
-    //<< "  Warpfactor: " << warpfactor << "  warpfactor_avg: "
-    //<< warpfactor_avg << endl;
+#if 0
+    VERBOSE(VB_PLAYBACK, QString("A/V "
+        "Divergence: %1 "
+        "  Rate: %2" 
+        "  Warpfactor: %3" 
+        "  warpfactor_avg: %4")
+        .arg(divergence)
+        .arg(rate)
+        .arg(warpfactor)
+        .arg(warpfactor_avg);
+#endif
     return divergence;
 }
 
@@ -1335,10 +1349,24 @@
     else
         diverge = 0;
 
+    playSkipCount -= 100;   // consume frame reward
+    if (playSkipCount > 0)
+    {
+        // discard frame as we are running behind
+        //prevtc = buffer->timecode;
+        //return;
+        lastsync = true;
+        //videosync->AdjustTrigger(avsync_adjustment);
+    }
+    else
+    {
     // If video is way ahead of audio, drop some frames until we're
     // close again.
     if (diverge < -MAXDIVERGE)
     {
+        //playSkipCount = 0;  // cost of displaying the frame
+        playSkipCount += 100;   // consume frame reward
+
         if (diverge < -DIVERGELIMIT)
             diverge = -DIVERGELIMIT;
 
@@ -1348,6 +1376,8 @@
     }
     else if (!disablevideo)
     {
+        playSkipCount += playIncCount;  // cost of displaying the frame
+
         if (videoOutput->IsErrored())
         {   // this check prevents calling prepareframe
             VERBOSE(VB_IMPORTANT, "NVP: Error condition detected "
@@ -1392,11 +1422,21 @@
     }
     else
     {
+        playSkipCount += playIncCount;  // cost of pseudo displaying the frame
         videosync->WaitForFrame(0);
     }
 
     if (output_jmeter && output_jmeter->RecordCycleTime())
     {
+        VERBOSE(VB_PLAYBACK, QString("A/V "
+            "avsync_delay: %1" 
+            ", avsync_avg: %2" 
+            ", warpfactor: %3" 
+            ", warpfactor_avg: %4")
+                .arg(avsync_delay / 1000)
+                .arg(avsync_avg / 1000)
+                .arg(warpfactor)
+                .arg(warpfactor_avg));
         //cerr << "avsync_delay: " << avsync_delay / 1000
         //     << ", avsync_avg: " << avsync_avg / 1000
         //     << ", warpfactor: " << warpfactor
@@ -1405,6 +1445,7 @@
 
     videosync->AdvanceTrigger();
     avsync_adjustment = 0;
+    }
 
     if (diverge > MAXDIVERGE)
     {
@@ -1419,15 +1460,39 @@
         lastsync = true;
     }
 
+    //if (playSkipCount <= 0)
     if (audioOutput && normal_speed)
     {
         // ms, same scale as timecodes
-        lastaudiotime = audioOutput->GetAudiotime();
+        lastaudiotime = audioOutput->GetAudiotime() + audiotimecodefudge;
+        VERBOSE(VB_PLAYBACK, QString("A/V timecodes audio %1 video %2 frameinterval %3 avdel %4 avg %5 sc %6 fudge %7")
+                .arg(lastaudiotime)
+                .arg(buffer->timecode)
+                .arg(frame_interval)
+                .arg(buffer->timecode - lastaudiotime)
+                .arg(avsync_avg)
+                .arg(playSkipCount)
+                .arg(audiotimecodefudge)
+                );
         if (lastaudiotime != 0 && buffer->timecode != 0)
-        { // lastaudiotime = 0 after a seek
+        { // lastaudiotime == 0 after a seek
+            if (labs(buffer->timecode - lastaudiotime)>1000000)
+            {
+                VERBOSE(VB_IMPORTANT, QString("A/V timecodes audio %1 video %2 frameinterval %3 avdel %4 avg %5")
+                        .arg(lastaudiotime)
+                        .arg(buffer->timecode)
+                        .arg(frame_interval)
+                        .arg(buffer->timecode - lastaudiotime)
+                        .arg(avsync_avg)
+                        );
+                lastaudiotime = audioOutput->GetAudiotime();
+                audiotimecodefudge = buffer->timecode - lastaudiotime;
+                VERBOSE(VB_IMPORTANT, QString("A/V audio timecode instantaneously diverged by %1")
+                        .arg(audiotimecodefudge));
+            }
             // The time at the start of this frame (ie, now) is given by
             // last->timecode
-            int delta = buffer->timecode - prevtc - (frame_interval / 1000);
+            int delta = (int)((buffer->timecode - prevtc)/play_speed) - (frame_interval / 1000);
             prevtc = buffer->timecode;
             //cerr << delta << " ";
 
@@ -1624,12 +1689,15 @@
 
         VideoFrame *frame = videoOutput->GetLastShownFrame();
 
+        if (playSkipCount <= 100)
+        {
         if (cc)
             ShowText();
 
         videofiltersLock.lock();
         videoOutput->ProcessFrame(frame, osd, videoFilters, pipplayer);
         videofiltersLock.unlock();
+        }
 
         AVSync();
 
@@ -2391,13 +2471,17 @@
     }
 #endif
 
     if (normal_speed && audioOutput)
     {
-        audioOutput->SetStretchFactor(play_speed);
+        audio_stretchfactor = play_speed;
+        audioOutput->SetStretchFactor(audio_stretchfactor);
 #ifdef USING_DIRECTX
         audioOutput->Reset();
 #endif
     }
+    playIncCount = (int)(play_speed*100);
+    if (playIncCount < 100)
+        playIncCount = 100;
 
     //cout << "setting unpaused" << endl << endl;
     paused = actuallypaused = false;
