From b6260f55a0703edca761c212f2eda936e4cb961d Mon Sep 17 00:00:00 2001
From: Richard <peper03@yahoo.com>
Date: Mon, 3 Jun 2013 00:51:28 +0200
Subject: [PATCH] Fixed seeking issues on some DVDs where, for example, trying
 to jump backwards could actually cause playback to jump
 forwards.

dvdnav_absolute_time_search in libdvdnav (renamed from the original dvdnav_time_search but functionally the same) uses a time offset with a start sector, which will only work if all NAV packets are equally spaced.  On at least one DVD that had issues, the distance between consecutive NAV packets ranged from 96 to 457.

The existing mechanism to check whether a seek was successful and, if not, narrow in on the required time was broken when jumping backwards.
---
 mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp |    8 ++++----
 mythtv/libs/libmythtv/DVD/dvdringbuffer.h   |    6 +++---
 mythtv/libs/libmythtv/tv_play.cpp           |    2 +-
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp b/mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp
index 3f99f3b..5b64e28 100644
--- a/mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp
+++ b/mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp
@@ -275,8 +275,8 @@ long long DVDRingBuffer::Seek(long long time)
     }
     else
     {
-        m_seektime = (uint64_t)time;
-        dvdRet = dvdnav_absolute_time_search(m_dvdnav, m_seektime, 0);
+        m_seektime = time;
+        dvdRet = dvdnav_absolute_time_search(m_dvdnav, (uint64_t)m_seektime, 0);
     }
 
     LOG(VB_PLAYBACK, LOG_DEBUG,
@@ -781,7 +781,7 @@ int DVDRingBuffer::safe_read(void *data, uint sz)
                 }
 
                 // update our status
-                m_currentTime = (uint)dvdnav_get_current_time(m_dvdnav);
+                m_currentTime = dvdnav_get_current_time(m_dvdnav);
                 m_currentpos = GetReadPosition();
 
                 if (m_seeking)
@@ -789,7 +789,7 @@ int DVDRingBuffer::safe_read(void *data, uint sz)
 
                     int relativetime =
                         (int)((m_seektime - m_currentTime)/ 90000);
-                    if (relativetime <= 1)
+                    if (abs(relativetime) <= 1)
                     {
                         m_seeking = false;
                         m_seektime = 0;
diff --git a/mythtv/libs/libmythtv/DVD/dvdringbuffer.h b/mythtv/libs/libmythtv/DVD/dvdringbuffer.h
index 9c4b6cf..56a42b3 100644
--- a/mythtv/libs/libmythtv/DVD/dvdringbuffer.h
+++ b/mythtv/libs/libmythtv/DVD/dvdringbuffer.h
@@ -129,7 +129,7 @@ class MTV_PUBLIC DVDRingBuffer : public RingBuffer
 
     virtual void IgnoreWaitStates(bool ignore) { m_skipstillorwait = ignore; }
     void AudioStreamsChanged(bool change) { m_audioStreamsChanged = change; }
-    uint GetCurrentTime(void)             { return (m_currentTime / 90000); }
+    int64_t GetCurrentTime(void)          { return (m_currentTime / 90000); }
     uint TitleTimeLeft(void);
     void  SetTrack(uint type, int trackNo);
     int   GetTrack(uint type);
@@ -198,8 +198,8 @@ class MTV_PUBLIC DVDRingBuffer : public RingBuffer
     const char    *m_dvdname;
     const char    *m_serialnumber;
     bool           m_seeking;
-    uint64_t       m_seektime;
-    uint           m_currentTime;
+    int64_t        m_seektime;
+    int64_t        m_currentTime;
     QMap<uint, uint> m_seekSpeedMap;
     QMap<uint, QList<uint64_t> > m_chapterMap;
 
diff --git a/mythtv/libs/libmythtv/tv_play.cpp b/mythtv/libs/libmythtv/tv_play.cpp
index eebb902..004021f 100644
--- a/mythtv/libs/libmythtv/tv_play.cpp
+++ b/mythtv/libs/libmythtv/tv_play.cpp
@@ -12945,7 +12945,7 @@ void TV::DVDJumpForward(PlayerContext *ctx)
     {
         uint titleLength = dvdrb->GetTotalTimeOfTitle();
         uint chapterLength = dvdrb->GetChapterLength();
-        uint currentTime = dvdrb->GetCurrentTime();
+        uint currentTime = (uint)dvdrb->GetCurrentTime();
         if ((titleLength == chapterLength) &&
              (currentTime < (chapterLength - (ctx->jumptime * 60))) &&
              chapterLength > 300)
-- 
1.7.9.5

