Index: libs/libmythtv/vsync.cpp
===================================================================
--- libs/libmythtv/vsync.cpp	(revision 23520)
+++ libs/libmythtv/vsync.cpp	(working copy)
@@ -126,12 +126,6 @@
     m_delay(-1)
 {
     bzero(&m_nexttrigger, sizeof(m_nexttrigger));
-
-    int tolerance = m_refresh_interval / 200;
-    if (m_interlaced && m_refresh_interval > ((m_frame_interval/2) + tolerance))
-        m_interlaced = false; // can't display both fields at 2x rate
-
-    //cout << "Frame interval: " << m_frame_interval << endl;
 }
 
 void VideoSync::Start(void)
@@ -139,21 +133,6 @@
     gettimeofday(&m_nexttrigger, NULL); // now
 }
 
-/** \fn VideoSync::SetFrameInterval(int fr, bool intr)
- *  \brief Change frame interval and interlacing attributes
- */
-void VideoSync::SetFrameInterval(int fr, bool intr)
-{
-    m_frame_interval = fr;
-    m_interlaced = intr;
-    int tolerance = m_refresh_interval / 200;
-    if (m_interlaced && m_refresh_interval > ((m_frame_interval/2) + tolerance))
-        m_interlaced = false; // can't display both fields at 2x rate
-
-    VERBOSE(VB_PLAYBACK, QString("Set video sync frame interval to %1")
-                                 .arg(m_frame_interval));
-}
-
 void VideoSync::OffsetTimeval(struct timeval& tv, int offset)
 {
     tv.tv_usec += offset;
@@ -169,21 +148,6 @@
     }
 }
 
-/** \fn VideoSync::UpdateNexttrigger()
- *  \brief Internal method to tells video synchronization method to use
- *         the next frame (or field, if interlaced) for CalcDelay() 
- *         and WaitForFrame().
- */
-void VideoSync::UpdateNexttrigger()
-{
-    // Offset by frame interval -- if interlaced, only delay by half
-    // frame interval
-    if (m_interlaced)
-        OffsetTimeval(m_nexttrigger, m_frame_interval/2);
-    else
-        OffsetTimeval(m_nexttrigger, m_frame_interval);
-}
-
 /** \fn VideoSync::CalcDelay()
  *  \brief Calculates the delay to the next frame.
  *
@@ -370,12 +334,8 @@
         //cerr << "Wait " << n << " intervals. Count " << blank.request.sequence;
         //cerr  << " Delay " << m_delay << endl;
     }
-}
 
-void DRMVideoSync::AdvanceTrigger(void)
-{
     KeepPhase();
-    UpdateNexttrigger();
 }
 #endif /* !_WIN32 */
 
@@ -539,15 +499,7 @@
         m_delay = CalcDelay();
     }
     
-#endif /* USING_OPENGL_VSYNC */
-}
-
-void OpenGLVideoSync::AdvanceTrigger(void)
-{
-#ifdef USING_OPENGL_VSYNC
-
     KeepPhase();
-    UpdateNexttrigger();
 #endif /* USING_OPENGL_VSYNC */
 }
 #endif /* !_WIN32 */
@@ -610,11 +562,6 @@
             usleep(m_delay);
     }
 }
-
-void RTCVideoSync::AdvanceTrigger(void)
-{
-    UpdateNexttrigger();
-}
 #endif /* __linux__ */
 
 #ifdef USING_VDPAU
@@ -650,11 +597,6 @@
     vo->SetNextFrameDisplayTimeOffset(m_delay);
 }
 
-void VDPAUVideoSync::AdvanceTrigger(void)
-{
-    UpdateNexttrigger();
-}
-
 #endif
 
 BusyWaitVideoSync::BusyWaitVideoSync(VideoOutput *vo,
@@ -705,11 +647,6 @@
     }
 }
 
-void BusyWaitVideoSync::AdvanceTrigger(void)
-{
-    UpdateNexttrigger();
-}
-
 USleepVideoSync::USleepVideoSync(VideoOutput *vo,
                                  int fr, int ri, bool intl) : 
     VideoSync(vo, fr, ri, intl)
@@ -734,8 +671,3 @@
     if (m_delay > 0)
         usleep(m_delay);
 }
-
-void USleepVideoSync::AdvanceTrigger(void)
-{
-    UpdateNexttrigger();
-}
Index: libs/libmythtv/NuppelVideoPlayer.cpp
===================================================================
--- libs/libmythtv/NuppelVideoPlayer.cpp	(revision 23520)
+++ libs/libmythtv/NuppelVideoPlayer.cpp	(working copy)
@@ -26,8 +26,6 @@
 #include <QKeyEvent>
 #include <QDir>
 
-#define NEW_AVSYNC
-
 // MythTV headers
 #include "mythconfig.h"
 #include "mythdbcon.h"
@@ -960,9 +958,6 @@
      m_double_framerate = false;
      m_double_process   = false;
 
-     if (videosync)
-         videosync->SetFrameInterval(frame_interval, false);
-
      if (osd)
          osd->SetFrameInterval(frame_interval);
 
@@ -1039,7 +1034,6 @@
     if (interlaced && !m_deint_possible)
     {
         m_scan = scan;
-        videosync->SetFrameInterval(frame_interval, false);
         return;
     }
 
@@ -1055,9 +1049,7 @@
         if (videoOutput->NeedsDoubleFramerate())
         {
             m_double_framerate = true;
-            videosync->SetFrameInterval(frame_interval, true);
-            // Make sure video sync can double frame rate
-            m_can_double = videosync->UsesFieldInterval();
+            m_can_double = (frame_interval / 2 > videosync->getRefreshInterval() * 0.995);
             if (!m_can_double)
             {
                 VERBOSE(VB_IMPORTANT, "Video sync method can't support double "
@@ -1074,7 +1066,6 @@
         {
             m_double_process = false;
             m_double_framerate = false;
-            videosync->SetFrameInterval(frame_interval, false);
             videoOutput->SetDeinterlacingEnabled(false);
             VERBOSE(VB_PLAYBACK, "Disabled deinterlacing");
         }
@@ -2364,11 +2355,11 @@
 void NuppelVideoPlayer::AVSync(void)
 {
     float diverge = 0.0f;
+    int frameDelay = m_double_framerate ? frame_interval / 2 : frame_interval;
     // attempt to reduce fps for standalone PIP
     if (player_ctx->IsPIP() && framesPlayed % 2)
     {
-        videosync->WaitForFrame(avsync_adjustment);
-        videosync->AdvanceTrigger();
+        videosync->WaitForFrame(frameDelay + avsync_adjustment);
         if (!using_null_videoout)
             videoOutput->SetFramesPlayed(framesPlayed + 1);
         return;
@@ -2380,6 +2371,7 @@
         VERBOSE(VB_IMPORTANT, LOC_ERR + "AVSync: No video buffer");
         return;
     }
+
     if (videoOutput->IsErrored())
     {
         VERBOSE(VB_IMPORTANT, LOC_ERR + "AVSync: "
@@ -2402,10 +2394,8 @@
     if (kScan_Detect == m_scan || kScan_Ignore == m_scan)
         ps = kScan_Progressive;
 
-    bool dropframe = false;
     if (diverge < -MAXDIVERGE)
     {
-        dropframe = true;
         // If video is way behind of audio, adjust for it...
         QString dbg = QString("Video is %1 frames behind audio (too slow), ")
             .arg(-diverge);
@@ -2439,7 +2429,7 @@
 
         VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("AVSync waitforframe %1 %2")
                 .arg(avsync_adjustment).arg(m_double_framerate));
-        videosync->WaitForFrame(avsync_adjustment + repeat_delay);
+        videosync->WaitForFrame(frameDelay + avsync_adjustment + repeat_delay);
         VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, "AVSync show");
         if (!resetvideo)
             videoOutput->Show(ps);
@@ -2480,12 +2470,7 @@
                 videoOutput->PrepareFrame(buffer, ps);
 
             // Display the second field
-            videosync->AdvanceTrigger();
-#ifdef NEW_AVSYNC
-            videosync->WaitForFrame(avsync_adjustment);
-#else
-            videosync->WaitForFrame(0);
-#endif
+            videosync->WaitForFrame(frameDelay + avsync_adjustment);
             if (!resetvideo)
             {
                 videoOutput->Show(ps);
@@ -2500,7 +2485,7 @@
     }
     else
     {
-        videosync->WaitForFrame(0);
+        videosync->WaitForFrame(frameDelay);
     }
 
     if (output_jmeter && output_jmeter->RecordCycleTime())
@@ -2511,8 +2496,6 @@
                 .arg(warpfactor).arg(warpfactor_avg));
     }
 
-    if (!dropframe)
-        videosync->AdvanceTrigger();
     avsync_adjustment = 0;
 
     if (diverge > MAXDIVERGE)
@@ -2520,11 +2503,7 @@
         // If audio is way behind of video, adjust for it...
         // by cutting the frame rate in half for the length of this frame
 
-#ifdef NEW_AVSYNC
         avsync_adjustment = refreshrate;
-#else
-        avsync_adjustment = frame_interval;
-#endif
         lastsync = true;
         VERBOSE(VB_PLAYBACK, LOC +
                 QString("Video is %1 frames ahead of audio,\n"
@@ -2556,27 +2535,24 @@
             prevtc = buffer->timecode;
             //cerr << delta << " ";
 
+            avsync_delay = (buffer->timecode - currentaudiotime) * 1000;//usec
+            // prevents major jitter when pts resets during dvd title
+            if (avsync_delay > 2000000 && player_ctx->buffer->isDVD())
+                avsync_delay = 90000;
+            avsync_avg = (avsync_delay + (avsync_avg * 3)) / 4;
+
             // If the timecode is off by a frame (dropped frame) wait to sync
             if (delta > (int) frame_interval / 1200 &&
                 delta < (int) frame_interval / 1000 * 3 &&
                 prevrp == 0)
             {
-                //cerr << "+ ";
-                videosync->AdvanceTrigger();
-                if (m_double_framerate)
-                    videosync->AdvanceTrigger();
+                // wait an extra frame interval
+                avsync_adjustment = frame_interval;
             }
-            prevrp = buffer->repeat_pict;
-
-            avsync_delay = (buffer->timecode - currentaudiotime) * 1000;//usec
-            // prevents major jitter when pts resets during dvd title
-            if (avsync_delay > 2000000 && player_ctx->buffer->isDVD())
-                avsync_delay = 90000;
-            avsync_avg = (avsync_delay + (avsync_avg * 3)) / 4;
             if (!usevideotimebase)
             {
-                /* If the audio time codes and video diverge, shift
-                   the video by one interlaced field (1/2 frame) */
+                /* Adjust by the smoothed divergence amount;
+                 * divide by two to soften the effect. */
 
                 if (!lastsync)
                 {
@@ -2594,6 +2570,7 @@
                 else
                     lastsync = false;
             }
+            prevrp = buffer->repeat_pict;
         }
         else
         {
@@ -2964,10 +2941,8 @@
         // Make sure video sync can do it
         if (videosync != NULL && m_double_framerate)
         {
-            videosync->SetFrameInterval(frame_interval, m_double_framerate);
-            m_can_double = videosync->UsesFieldInterval();
-            if (!m_can_double)
-            {
+            m_can_double = (frame_interval / 2 > videosync->getRefreshInterval() * 1.005);
+            if (! m_can_double) {
                 VERBOSE(VB_IMPORTANT, "Video sync method can't support double "
                         "framerate (refresh rate too low for bob deint)");
                 FallbackDeint();
@@ -4343,9 +4318,6 @@
             (frame_interval>>1) : frame_interval);
     }
 
-    if (videosync != NULL)
-        videosync->SetFrameInterval(frame_interval, m_double_framerate);
-
     VERBOSE(VB_PLAYBACK, LOC + "DoPause() -- setting paused");
     paused = actuallypaused = true;
     decoderThreadPaused.wakeAll();
@@ -4422,7 +4394,6 @@
 
         m_double_framerate = videoOutput->NeedsDoubleFramerate();
         m_double_process = videoOutput->IsExtraProcessingRequired();
-        videosync->SetFrameInterval(frame_interval, m_double_framerate);
     }
 
     if (osd)
Index: libs/libmythtv/vsync.h
===================================================================
--- libs/libmythtv/vsync.h	(revision 23520)
+++ libs/libmythtv/vsync.h	(working copy)
@@ -39,15 +39,9 @@
  *   The factory method BestMethod tries subclasses in roughly quality
  *   order until one succeeds.
  *
- *   A/V sync methods may supply an additonal delay per frame. Other
+ *   A/V sync methods may supply the nominal delay per frame. Other
  *   than that, video timing is entirely up to these classes. When
  *   WaitForFrame returns, it is time to show the frame.
- *
- *   There is some basic support for interlaced video timing where the
- *   fields need to be displayed sequentially. Passing true for the
- *   interlaced flags for the constructors, BestMethod, and
- *   SetFrameInterval will cause us to wait for half the specified frame
- *   interval, if the refresh rate is sufficient to do so.
  */
 class VideoSync
 // virtual base class
@@ -80,16 +74,8 @@
      */
     virtual void WaitForFrame(int sync_delay) = 0;
 
-    /// \brief Use the next frame or field for CalcDelay(void)
-    ///        and WaitForFrame(int).
-    virtual void AdvanceTrigger(void) = 0;
-
-    void SetFrameInterval(int fi, bool interlaced);
-
-    /// \brief Returns true AdvanceTrigger(void) advances a field at a time.
-    bool UsesFieldInterval(void) const { return m_interlaced; }
-    /// \brief Returns true AdvanceTrigger(void) advances a frame at a time.
-    bool UsesFrameInterval(void) const { return !m_interlaced; }
+    /// \brief Returns the (minimum) refresh interval of the output device.
+    int getRefreshInterval(void) const { return m_refresh_interval; }
 
     /** \brief Stops VSync; must be called from main thread.
      *
@@ -105,7 +91,6 @@
                                  bool interlaced);
   protected:
     static void OffsetTimeval(struct timeval& tv, int offset);
-    void UpdateNexttrigger(void);
     int CalcDelay(void);
     void KeepPhase(void);
 
@@ -137,7 +122,6 @@
     bool TryInit(void);
     void Start(void);
     void WaitForFrame(int sync_delay);
-    void AdvanceTrigger(void);
 
   private:
     int m_dri_fd;
@@ -179,7 +163,6 @@
     bool TryInit(void);
     void Start(void);
     void WaitForFrame(int sync_delay);
-    void AdvanceTrigger(void);
 
   private:
     OpenGLContext  *m_context;
@@ -208,7 +191,6 @@
     QString getName(void) const { return QString("RTC"); }
     bool TryInit(void);
     void WaitForFrame(int sync_delay);
-    void AdvanceTrigger(void);
 
   private:
     int m_rtcfd;
@@ -229,7 +211,6 @@
     QString getName(void) const { return QString("VDPAU"); }
     bool TryInit(void);
     void WaitForFrame(int sync_delay);
-    void AdvanceTrigger(void);
 
   private:
 };
@@ -257,7 +238,6 @@
     QString getName(void) const { return QString("USleep with busy wait"); }
     bool TryInit(void);
     void WaitForFrame(int sync_delay);
-    void AdvanceTrigger(void);
 
   private:
     int m_cheat;
@@ -285,6 +265,5 @@
     QString getName(void) const { return QString("USleep"); }
     bool TryInit(void);
     void WaitForFrame(int sync_delay);
-    void AdvanceTrigger(void);
 };
 #endif /* VSYNC_H_INCLUDED */
