From fa083c7a3ce910f487ff3c40a6b0faf47832048e Mon Sep 17 00:00:00 2001
From: Richard <peper03@yahoo.com>
Date: Thu, 7 Mar 2013 12:06:28 +0100
Subject: [PATCH] Fix displaying of menu highlights when a menu appears in a
 VTS title and clean up menu looping detection.

Querying the number of buttons as soon as a subpicture stream change notification appears is generally not possible as the button information is carried in NAV packets, which probably haven't been read yet.
---
 mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp |   62 ++++++++++++++++-----------
 mythtv/libs/libmythtv/DVD/dvdringbuffer.h   |    2 +
 2 files changed, 38 insertions(+), 26 deletions(-)

diff --git a/mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp b/mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp
index 2698142..2932cd8 100644
--- a/mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp
+++ b/mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp
@@ -99,9 +99,11 @@ DVDRingBuffer::DVDRingBuffer(const QString &lfilename) :
 
     m_skipstillorwait(true),
     m_cellstartPos(0), m_buttonSelected(false),
-    m_buttonExists(false), m_cellid(0),
-    m_lastcellid(0), m_vobid(0),
-    m_lastvobid(0), m_cellRepeated(false),
+    m_buttonExists(false),
+    m_buttonSeenInCell(false), m_lastButtonSeenInCell(false),
+    m_cellid(0), m_lastcellid(0),
+    m_vobid(0), m_lastvobid(0),
+    m_cellRepeated(false),
 
     m_curAudioTrack(0),
     m_curSubtitleTrack(0),
@@ -641,9 +643,11 @@ int DVDRingBuffer::safe_read(void *data, uint sz)
                 // clear menus/still frame selections
                 m_lastvobid = m_vobid;
                 m_lastcellid = m_cellid;
+                m_lastButtonSeenInCell = m_buttonSeenInCell;
                 m_buttonSelected = false;
                 m_vobid = m_cellid = 0;
                 m_cellRepeated = false;
+                m_buttonSeenInCell = false;
 
                 IncrementButtonVersion;
                 if (m_inMenu)
@@ -684,21 +688,6 @@ int DVDRingBuffer::safe_read(void *data, uint sz)
                 // clear any existing subs/buttons
                 IncrementButtonVersion;
 
-                // update the stream number
-                if (m_inMenu || NumMenuButtons() > 0)
-                {
-                    m_buttonStreamID = 32;
-                    int aspect = dvdnav_get_video_aspect(m_dvdnav);
-
-                    // workaround where dvd menu is
-                    // present in VTS_DOMAIN. dvdnav adds 0x80 to stream id
-                    // proper fix should be put in dvdnav sometime
-                    int physical_wide = (spu->physical_wide & 0xF);
-
-                    if (aspect != 0 && physical_wide > 0)
-                        m_buttonStreamID += physical_wide;
-                }
-
                 // not sure
                 if (m_autoselectsubtitle)
                     m_curSubtitleTrack = dvdnav_get_active_spu_stream(m_dvdnav);
@@ -778,15 +767,12 @@ int DVDRingBuffer::safe_read(void *data, uint sz)
 
                 // if we are in a looping menu, we don't want to reset the
                 // selected button when we restart
-                if (m_vobid == 0 && m_cellid == 0)
+                m_vobid  = dsi->dsi_gi.vobu_vob_idn;
+                m_cellid = dsi->dsi_gi.vobu_c_idn;
+                if ((m_lastvobid == m_vobid) && (m_lastcellid == m_cellid)
+                     && m_lastButtonSeenInCell)
                 {
-                    m_vobid  = dsi->dsi_gi.vobu_vob_idn;
-                    m_cellid = dsi->dsi_gi.vobu_c_idn;
-                    if ((m_lastvobid == m_vobid) && (m_lastcellid == m_cellid)
-                         && m_inMenu)
-                    {
-                        m_cellRepeated = true;
-                    }
+                    m_cellRepeated = true;
                 }
 
                 // update our status
@@ -809,6 +795,24 @@ int DVDRingBuffer::safe_read(void *data, uint sz)
                     }
                 }
 
+                // update the button stream number if this is the
+                // first NAV pack containing button information
+                if ( (pci->hli.hl_gi.hli_ss & 0x03) == 0x01 )
+                {
+                    m_buttonStreamID = 32;
+                    int aspect = dvdnav_get_video_aspect(m_dvdnav);
+
+                    // workaround where dvd menu is
+                    // present in VTS_DOMAIN. dvdnav adds 0x80 to stream id
+                    // proper fix should be put in dvdnav sometime
+                    int8_t spustream = dvdnav_get_active_spu_stream(m_dvdnav) & 0x7f;
+
+                    if (aspect != 0 && spustream > 0)
+                        m_buttonStreamID += spustream;
+
+                    m_buttonSeenInCell = true;
+                }
+
                 // debug
                 LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("DVDNAV_NAV_PACKET - time:%1, pos:%2, vob:%3, cell:%4, seeking:%5, seektime:%6")
                     .arg(m_currentTime)
@@ -867,6 +871,12 @@ int DVDRingBuffer::safe_read(void *data, uint sz)
                     m_audioStreamsChanged = true;
                 }
 
+                // Make sure we know we're not staying in the
+                // same cell (same vobid/cellid values can
+                // occur in every VTS)
+                m_lastvobid  = m_vobid  = 0;
+                m_lastcellid = m_cellid = 0;
+
                 // release buffer
                 if (blockBuf != m_dvdBlockWriteBuf)
                     dvdnav_free_cache_block(m_dvdnav, blockBuf);
diff --git a/mythtv/libs/libmythtv/DVD/dvdringbuffer.h b/mythtv/libs/libmythtv/DVD/dvdringbuffer.h
index 5468db7..1c089fe 100644
--- a/mythtv/libs/libmythtv/DVD/dvdringbuffer.h
+++ b/mythtv/libs/libmythtv/DVD/dvdringbuffer.h
@@ -183,6 +183,8 @@ class MTV_PUBLIC DVDRingBuffer : public RingBuffer
     long long      m_cellstartPos;
     bool           m_buttonSelected;
     bool           m_buttonExists;
+    bool           m_buttonSeenInCell;
+    bool           m_lastButtonSeenInCell;
     int            m_cellid;
     int            m_lastcellid;
     int            m_vobid;
-- 
1.7.9.5

