Index: libs/libmythtv/NuppelVideoPlayer.cpp
===================================================================
--- libs/libmythtv/NuppelVideoPlayer.cpp	(revision 9369)
+++ libs/libmythtv/NuppelVideoPlayer.cpp	(working copy)
@@ -227,6 +227,7 @@
       livetvchain(NULL), m_tv(NULL),
       // DVD stuff
       indvdstillframe(false), hidedvdbutton(true),
+      delaydvdbutton(0),
       // Debugging variables
       output_jmeter(NULL)
 {
@@ -554,9 +555,6 @@
 
     ClearAfterSeek();
 
-    if (ringBuffer->isDVD())
-        ringBuffer->Seek(ringBuffer->DVD()->GetCellStartPos(), SEEK_SET);
-
     if (textDisplayMode)
     {
         DisableCaptions(textDisplayMode);
@@ -829,9 +827,6 @@
 int NuppelVideoPlayer::OpenFile(bool skipDsp, uint retries,
                                 bool allow_libmpeg2)
 {
-    if (ringBuffer && ringBuffer->isDVD())
-        allow_libmpeg2 = false;
-
     if (!skipDsp)
     {
         if (!ringBuffer)
@@ -2861,7 +2856,7 @@
     decoder_thread = pthread_self();
     pthread_create(&output_video, NULL, kickoffOutputVideoLoop, this);
 
-    if (!using_null_videoout)
+    if (!using_null_videoout && !ringBuffer->isDVD())
     {
         // Request that the video output thread run with realtime priority.
         // If mythyv/mythfrontend was installed SUID root, this will work.
@@ -5722,24 +5717,34 @@
     int numbuttons = ringBuffer->DVD()->NumMenuButtons();
     bool osdshown = osd->IsSetDisplaying("subtitles");
     long long menupktpts = ringBuffer->DVD()->GetMenuPktPts();
+    bool instillframe = ringBuffer->DVD()->InStillFrame();
 
-    if ((numbuttons == 0) || (osdshown) ||
-        ((!osdshown) && (hidedvdbutton) &&
-         (buffer->timecode > 0) && (menupktpts != buffer->timecode)))
+    if ((numbuttons == 0) || 
+        (osdshown) ||
+        (instillframe && buffer->timecode > 0) ||
+        ((!osdshown) &&
+            (!indvdstillframe) &&
+            (hidedvdbutton) &&
+            (buffer->timecode > 0)  &&
+            (menupktpts != buffer->timecode)))
     {
         return; 
     }
 
-    hidedvdbutton = false;
-    AVSubtitleRect *highlightButton;
     OSDSet *subtitleOSD = NULL;
-    highlightButton = ringBuffer->DVD()->GetMenuButton();
+    AVSubtitleRect *highlightButton = ringBuffer->DVD()->GetMenuButton();
 
-    subtitleLock.lock();
     if (highlightButton != NULL)
     {
         osd->HideSet("subtitles");
         osd->ClearAll("subtitles");
+        if (indvdstillframe)
+        {
+            delaydvdbutton++;
+            if (delaydvdbutton < 5)
+                return;
+        }
+        subtitleLock.lock();
         int h = highlightButton->h;
         int w = highlightButton->w;
         int linesize = highlightButton->linesize;
@@ -5770,9 +5775,9 @@
 
         subtitleOSD->AddType(image);
         osd->SetVisible(subtitleOSD, 0);
+        hidedvdbutton = false;
+        subtitleLock.unlock();
     }
-
-    subtitleLock.unlock();
 }
 
 void NuppelVideoPlayer::ActivateDVDButton(void)
Index: libs/libmythtv/avformatdecoder.cpp
===================================================================
--- libs/libmythtv/avformatdecoder.cpp	(revision 9369)
+++ libs/libmythtv/avformatdecoder.cpp	(working copy)
@@ -274,7 +274,8 @@
       allow_ac3_passthru(false),    allow_dts_passthru(false),
       disable_passthru(false),
       // DVD
-      lastdvdtitle(0), dvdmenupktseen(false)
+      lastdvdtitle(0), lastcellstart(0),
+      dvdmenupktseen(false), dvdvideopause(false)
 {
     bzero(&params, sizeof(AVFormatParameters));
     bzero(prvpkt, 3 * sizeof(char));
@@ -493,7 +494,7 @@
     // Skip all the desired number of skipFrames
     for (;skipFrames > 0 && !ateof; skipFrames--)
     {
-	GetFrame(0);
+        GetFrame(0);
         if (decoded_video_frame)
             GetNVP()->DiscardVideoFrame(decoded_video_frame);
     }
@@ -1321,7 +1322,7 @@
         }
     }
 
-    // Select a new tracks at the next opportunity.
+    // Select a new track at the next opportunity
     ResetTracks();
 
     // We have to do this here to avoid the NVP getting stuck
@@ -1665,6 +1666,7 @@
 #define PICTURE_START 0x00000100
 #define SLICE_MIN     0x00000101
 #define SLICE_MAX     0x000001af
+#define SEQ_END_CODE  0x000001b7
 
 void AvFormatDecoder::MpegPreProcessPkt(AVStream *stream, AVPacket *pkt)
 {
@@ -1684,6 +1686,14 @@
         unsigned int last_state = state;
         state = ((state << 8) | v) & 0xFFFFFF;
 
+        if (ringBuffer->isDVD() && pkt->size == 4 
+                && state == SEQ_END_CODE && !dvdvideopause)
+        {
+            dvdvideopause = true;
+            d->ResetMPEG2();
+            return;
+        }
+        
         if (last_state != 0x000001)
             continue;
         else if (state >= SLICE_MIN && state <= SLICE_MAX)
@@ -1713,6 +1723,13 @@
                                          keyframedist, aspect, 
                                          kScan_Detect);
 
+                if (ringBuffer->InDVDMenuOrStillFrame())
+                {
+                    ScanStreams(true);
+                    ringBuffer->Seek(ringBuffer->DVD()->GetCellStartPos(),
+                                        SEEK_SET);
+                }
+
                 current_width  = width;
                 current_height = height;
                 current_aspect = aspect;
@@ -2159,7 +2176,6 @@
 
     bool allowedquit = false;
     bool storevideoframes = false;
-    bool dvdvideopause = false;
 
     avcodeclock.lock();
     AutoSelectTracks();
@@ -2178,24 +2194,31 @@
         }
 
         if (ringBuffer->isDVD())
-        { 
+        {
             int dvdtitle  = 0;
             int dvdpart = 0;
             ringBuffer->DVD()->GetPartAndTitle(dvdtitle,dvdpart);
-            if (dvdtitle != lastdvdtitle)
+            uint cellstart = ringBuffer->DVD()->GetCellStart();
+            if (GetNVP()->AtNormalSpeed() &&
+                    ((lastcellstart != cellstart) ||
+                    (lastdvdtitle != dvdtitle)))
             {
-                posmapStarted = false;
-                m_positionMap.clear();
-                SyncPositionMap();
+                if (dvdtitle != lastdvdtitle)
+                {
+                    posmapStarted = false;
+                    m_positionMap.clear();
+                    SyncPositionMap();
+                    VERBOSE(VB_PLAYBACK, LOC + "DVD Title Changed");
+                    ScanStreams(true);
+                    lastdvdtitle = dvdtitle;
+                }
                 framesPlayed = DVDCurrentFrameNumber();
                 framesRead = framesPlayed;
-                VERBOSE(VB_PLAYBACK,
-                    QString(LOC + "DVD Title Changed. Update framesPlayed: %1 ")
-                            .arg(framesPlayed));
-                ScanStreams(false);
+                VERBOSE(VB_PLAYBACK, QString(LOC + "DVD Cell Changed. Update framesPlayed: %1 ")
+                        .arg(framesPlayed));
+                lastcellstart = cellstart;
             }
-            lastdvdtitle = dvdtitle;
-            
+
             if (storedPackets.count() < 2 && !dvdvideopause)
                 storevideoframes = true;
             else
@@ -2218,12 +2241,6 @@
             }
         }
 
-        if (ringBuffer->isDVD() && ringBuffer->DVD()->InStillFrame())
-        {
-            storevideoframes = false;
-            dvdvideopause = true;
-        }
-
         if (!storevideoframes && storedPackets.count() > 0)
         {
             if (pkt)
@@ -2273,11 +2290,25 @@
         if (pkt->dts != (int64_t)AV_NOPTS_VALUE)
             pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000);
 
-        if (ringBuffer->isDVD() && pkt->size == 4)
+        if (ringBuffer->isDVD() && 
+                curstream->codec->codec_type == CODEC_TYPE_VIDEO)
         {
-            dvdvideopause = true;
-            av_free_packet(pkt);
-            continue;
+            if (pkt->size == 4)
+                MpegPreProcessPkt(curstream,pkt);
+            else if (!d->HasMPEG2Dec())
+            {
+                int current_width = curstream->codec->width;
+                int video_width = GetNVP()->GetVideoWidth();
+                if (video_width > 0 &&
+                    (video_width != current_width))
+                {
+                    av_free_packet(pkt);
+                    av_find_stream_info(ic);
+                    ScanStreams(false);
+                    allowedquit = true;
+                    continue;
+                }
+            }
         }
 
         if (storevideoframes &&
@@ -2317,6 +2348,9 @@
                 }
             }
 
+            if (len == 4 && dvdvideopause)
+                dvdvideopause = false;
+
             if (framesRead == 0 && !justAfterChange &&
                 !(pkt->flags & PKT_FLAG_KEY))
             {
@@ -2521,7 +2555,7 @@
                         ret = avcodec_decode_video(context, &mpa_pic,
                                                    &gotpicture, ptr, len);
                         // Reparse it to not drop the DVD still frame
-                        if (dvdvideopause && storedPackets.count() == 0)
+                        if (dvdvideopause)
                             ret = avcodec_decode_video(context, &mpa_pic,
                                                         &gotpicture, ptr, len);
                     }
Index: libs/libmythtv/DVDRingBuffer.cpp
===================================================================
--- libs/libmythtv/DVDRingBuffer.cpp	(revision 9369)
+++ libs/libmythtv/DVDRingBuffer.cpp	(working copy)
@@ -811,16 +811,10 @@
 
 uint DVDRingBufferPriv::GetCurrentTime(void)
 {
-    // Macro to convert Binary Coded Decimal to Decimal
-    // Obtained from VLC Code.
-    #define BCD2D(__x__) (((__x__ & 0xf0) >> 4) * 10 + (__x__ & 0x0f))
-
     dsi_t *dvdnavDsi = dvdnav_get_current_nav_dsi(dvdnav);
     dvd_time_t timeFromCellStart = dvdnavDsi->dsi_gi.c_eltm;
-    uint8_t hours = BCD2D(timeFromCellStart.hour);
-    uint8_t minutes = BCD2D(timeFromCellStart.minute);
-    uint8_t seconds = BCD2D(timeFromCellStart.second);
-    uint currentTime = GetCellStart() + (hours * 3600) + (minutes * 60) + seconds;
+    uint currentTime = GetCellStart() + 
+        (uint)(dvdnav_convert_time(&timeFromCellStart) / 90000);
     return currentTime;
 }
 
Index: libs/libmythtv/NuppelVideoPlayer.h
===================================================================
--- libs/libmythtv/NuppelVideoPlayer.h	(revision 9369)
+++ libs/libmythtv/NuppelVideoPlayer.h	(working copy)
@@ -354,7 +354,12 @@
     void ActivateDVDButton(void);
     void GoToDVDMenu(QString str);
     void GoToDVDProgram(bool direction);
-    void HideDVDButton(bool hide) { hidedvdbutton = hide; }
+    void HideDVDButton(bool hide) 
+    { 
+        hidedvdbutton = hide;
+        if (hide)
+            delaydvdbutton = 0;
+    }
     void SetSubtitleMode(bool setting)
     {
         if (setting)
@@ -716,6 +721,7 @@
     // DVD
     bool indvdstillframe;
     bool hidedvdbutton;
+    int  delaydvdbutton;
 
     // Debugging variables
     Jitterometer *output_jmeter;
Index: libs/libmythtv/tv_play.cpp
===================================================================
--- libs/libmythtv/tv_play.cpp	(revision 9369)
+++ libs/libmythtv/tv_play.cpp	(working copy)
@@ -2675,7 +2675,7 @@
             QString action = actions[i];
             handled = true;
 
-            if (prbuffer->isDVD() && prbuffer->DVD()->IsInMenu())
+            if (prbuffer->InDVDMenuOrStillFrame())
             {
                 int nb_buttons = prbuffer->DVD()->NumMenuButtons();
                 if (nb_buttons > 0)
Index: libs/libmythtv/decoderbase.cpp
===================================================================
--- libs/libmythtv/decoderbase.cpp	(revision 9369)
+++ libs/libmythtv/decoderbase.cpp	(working copy)
@@ -713,7 +713,7 @@
             SeekReset(framesPlayed, 0, true, true);
 
         // update frames played
-        long long played = (int)(elapsed * fps);
+        long long played = DVDCurrentFrameNumber();
 
         framesPlayed = played;
         GetNVP()->getVideoOutput()->SetFramesPlayed(played + 1);
Index: libs/libmythtv/avformatdecoder.h
===================================================================
--- libs/libmythtv/avformatdecoder.h	(revision 9369)
+++ libs/libmythtv/avformatdecoder.h	(working copy)
@@ -232,7 +232,9 @@
 
     // DVD
     int lastdvdtitle;
+    uint lastcellstart;
     bool dvdmenupktseen;
+    bool dvdvideopause;
 };
 
 #endif
