From 576da56ad211834887b23ff2c917675fbe5b03d1 Mon Sep 17 00:00:00 2001
From: Richard <peper03@yahoo.com>
Date: Wed, 13 Mar 2013 18:16:53 +0100
Subject: [PATCH] Respect the start and end times of menu highlights to avoid
 showing the menu highlight too soon/for too long.

---
 mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp |   13 ++++++++-----
 mythtv/libs/libmythtv/DVD/dvdringbuffer.h   |    4 ++--
 mythtv/libs/libmythtv/DVD/mythdvdplayer.cpp |   26 ++++++++++++++++++++++++--
 mythtv/libs/libmythtv/avformatdecoder.cpp   |    9 +++++----
 4 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp b/mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp
index 2932cd8..a7ef500 100644
--- a/mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp
+++ b/mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp
@@ -1240,7 +1240,8 @@ void DVDRingBuffer::ActivateButton(void)
 
 /** \brief get SPU pkt from dvd menu subtitle stream
  */
-void DVDRingBuffer::GetMenuSPUPkt(uint8_t *buf, int buf_size, int stream_id)
+void DVDRingBuffer::GetMenuSPUPkt(uint8_t *buf, int buf_size,
+                                  int stream_id, uint32_t startTime)
 {
     if (buf_size < 4)
         return;
@@ -1266,7 +1267,7 @@ void DVDRingBuffer::GetMenuSPUPkt(uint8_t *buf, int buf_size, int stream_id)
     {
         int32_t gotbutton;
         m_buttonExists = DecodeSubtitles(&m_dvdMenuButton, &gotbutton,
-                                        m_menuSpuPkt, m_menuBuflength);
+                                        m_menuSpuPkt, m_menuBuflength, startTime);
     }
 }
 
@@ -1311,7 +1312,7 @@ QRect DVDRingBuffer::GetButtonCoords(void)
  * code obtained from ffmpeg project
  */
 bool DVDRingBuffer::DecodeSubtitles(AVSubtitle *sub, int *gotSubtitles,
-                                    const uint8_t *spu_pkt, int buf_size)
+                                    const uint8_t *spu_pkt, int buf_size, uint32_t startTime)
 {
     #define GETBE16(p) (((p)[0] << 8) | (p)[1])
 
@@ -1349,12 +1350,14 @@ bool DVDRingBuffer::DecodeSubtitles(AVSubtitle *sub, int *gotSubtitles,
             {
                 case 0x00:
                     force_subtitle_display = true;
+                    sub->start_display_time = startTime;
+                    sub->end_display_time   = 0xFFFFFFFF;
                 break;
                 case 0x01:
-                    sub->start_display_time = (date << 10) / 90;
+                    sub->start_display_time = ((date << 10) / 90) + startTime;
                 break;
                 case 0x02:
-                    sub->end_display_time = (date << 10) / 90;
+                    sub->end_display_time = ((date << 10) / 90) + startTime;
                 break;
                 case 0x03:
                 {
diff --git a/mythtv/libs/libmythtv/DVD/dvdringbuffer.h b/mythtv/libs/libmythtv/DVD/dvdringbuffer.h
index 1c089fe..0e3247f 100644
--- a/mythtv/libs/libmythtv/DVD/dvdringbuffer.h
+++ b/mythtv/libs/libmythtv/DVD/dvdringbuffer.h
@@ -77,7 +77,7 @@ class MTV_PUBLIC DVDRingBuffer : public RingBuffer
     bool AudioStreamsChanged(void) const { return m_audioStreamsChanged; }
     bool IsWaiting(void) const           { return m_dvdWaiting;          }
     int  NumPartsInTitle(void)     const { return m_titleParts;          }
-    void GetMenuSPUPkt(uint8_t *buf, int len, int stream_id);
+    void GetMenuSPUPkt(uint8_t *buf, int len, int stream_id, uint32_t startTime);
     int64_t GetTimeDiff(void)      const { return m_timeDiff; }
 
     // Public menu/button stuff
@@ -91,7 +91,7 @@ class MTV_PUBLIC DVDRingBuffer : public RingBuffer
     // Subtitles
     uint GetSubtitleLanguage(int key);
     bool DecodeSubtitles(AVSubtitle * sub, int * gotSubtitles,
-                         const uint8_t * buf, int buf_size);
+                         const uint8_t * buf, int buf_size, uint32_t startTime);
 
     uint GetAudioLanguage(int id);
     int  GetAudioTrackNum(uint key);
diff --git a/mythtv/libs/libmythtv/DVD/mythdvdplayer.cpp b/mythtv/libs/libmythtv/DVD/mythdvdplayer.cpp
index 3f79e4b..2faf2dd 100644
--- a/mythtv/libs/libmythtv/DVD/mythdvdplayer.cpp
+++ b/mythtv/libs/libmythtv/DVD/mythdvdplayer.cpp
@@ -518,15 +518,31 @@ void MythDVDPlayer::DisplayDVDButton(void)
     AVSubtitle *dvdSubtitle = player_ctx->buffer->DVD()->GetMenuSubtitle(buttonversion);
     bool numbuttons    = player_ctx->buffer->DVD()->NumMenuButtons();
 
+    bool expired = false;
+
+    VideoFrame *currentFrame = videoOutput ? videoOutput->GetLastShownFrame() : NULL;
+
+    if (!currentFrame)
+    {
+        player_ctx->buffer->DVD()->ReleaseMenuButton();
+        return;
+    }
+
+    if (dvdSubtitle &&
+        (dvdSubtitle->end_display_time < currentFrame->timecode))
+    {
+        expired = true;
+    }
+
     // nothing to do
-    if (buttonversion == ((uint)m_buttonVersion))
+    if (!expired && (buttonversion == ((uint)m_buttonVersion)))
     {
         player_ctx->buffer->DVD()->ReleaseMenuButton();
         return;
     }
 
     // clear any buttons
-    if (!numbuttons || !dvdSubtitle || (buttonversion == 0))
+    if (!numbuttons || !dvdSubtitle || (buttonversion == 0) || expired)
     {
         SetCaptionsEnabled(false, false);
         osdLock.lock();
@@ -538,6 +554,12 @@ void MythDVDPlayer::DisplayDVDButton(void)
         return;
     }
 
+    if (currentFrame->timecode && (dvdSubtitle->start_display_time > currentFrame->timecode))
+    {
+        player_ctx->buffer->DVD()->ReleaseMenuButton();
+        return;
+    }
+
     m_buttonVersion = buttonversion;
     QRect buttonPos = player_ctx->buffer->DVD()->GetButtonCoords();
     osdLock.lock();
diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
index 7a1716b..cb55ac9 100644
--- a/mythtv/libs/libmythtv/avformatdecoder.cpp
+++ b/mythtv/libs/libmythtv/avformatdecoder.cpp
@@ -3696,7 +3696,7 @@ bool AvFormatDecoder::ProcessSubtitlePacket(AVStream *curstream, AVPacket *pkt)
         if (ringBuffer->DVD()->NumMenuButtons() > 0)
         {
             ringBuffer->DVD()->GetMenuSPUPkt(pkt->data, pkt->size,
-                                             curstream->id);
+                                             curstream->id, pts);
         }
         else
         {
@@ -3704,7 +3704,7 @@ bool AvFormatDecoder::ProcessSubtitlePacket(AVStream *curstream, AVPacket *pkt)
             {
                 QMutexLocker locker(avcodeclock);
                 ringBuffer->DVD()->DecodeSubtitles(&subtitle, &gotSubtitles,
-                                                   pkt->data, pkt->size);
+                                                   pkt->data, pkt->size, pts);
             }
         }
     }
@@ -3713,14 +3713,15 @@ bool AvFormatDecoder::ProcessSubtitlePacket(AVStream *curstream, AVPacket *pkt)
         QMutexLocker locker(avcodeclock);
         avcodec_decode_subtitle2(curstream->codec, &subtitle, &gotSubtitles,
                                  pkt);
+
+        subtitle.start_display_time += pts;
+        subtitle.end_display_time += pts;
     }
 
     if (gotSubtitles)
     {
         if (isForcedTrack)
             subtitle.forced = true;
-        subtitle.start_display_time += pts;
-        subtitle.end_display_time += pts;
         LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, LOC +
             QString("subtl timecode %1 %2 %3 %4")
                 .arg(pkt->pts).arg(pkt->dts)
-- 
1.7.9.5

