Index: libs/libmythtv/NuppelVideoPlayer.h
===================================================================
--- libs/libmythtv/NuppelVideoPlayer.h	(revision 9165)
+++ libs/libmythtv/NuppelVideoPlayer.h	(working copy)
@@ -319,6 +319,7 @@
     void ActivateDVDButton(void);
     void GoToDVDMenu(QString str);
     void GoToDVDProgram(bool direction);
+    void HideDVDButton(bool hide) { hidedvdbutton = hide; }
 
   protected:
     void DisplayPauseFrame(void);
@@ -666,6 +667,7 @@
 
     // DVD
     bool indvdstillframe;
+    bool hidedvdbutton;
 
     // Debugging variables
     Jitterometer *output_jmeter;
Index: libs/libmythtv/NuppelVideoPlayer.cpp
===================================================================
--- libs/libmythtv/NuppelVideoPlayer.cpp	(revision 9165)
+++ libs/libmythtv/NuppelVideoPlayer.cpp	(working copy)
@@ -175,7 +175,7 @@
       // LiveTVChain stuff
       livetvchain(NULL), m_tv(NULL),
       // DVD stuff
-      indvdstillframe(false),
+      indvdstillframe(false), hidedvdbutton(true),
       // Debugging variables
       output_jmeter(NULL)
 {
@@ -509,7 +509,7 @@
 
     ClearAfterSeek();
 
-    if (ringBuffer->InDVDMenuOrStillFrame())
+    if (ringBuffer->isDVD())
         ringBuffer->Seek(ringBuffer->DVD()->GetCellStartPos(), SEEK_SET);
 }
 
@@ -1954,7 +1954,7 @@
     video_actually_paused = false;
     resetvideo = false;
 
-    if (!ringBuffer->isDVD())
+    if (!ringBuffer->InDVDMenuOrStillFrame())
     {
         if (!PrebufferEnoughFrames())
             return;
@@ -2104,33 +2104,30 @@
                 if (ringBuffer->DVD()->IsWaiting())
                 {
                     ringBuffer->DVD()->WaitSkip();
-                    usleep(100000);
                     continue;
                 }
+                
                 if (ringBuffer->InDVDMenuOrStillFrame())
                 {
                     if (nbframes == 0)
                     {
-                        // wait to confirm there is no other frames been decoded.
-                        usleep(100000);
-                        nbframes = videoOutput->ValidVideoFrames();
-                        if (nbframes == 0)
-                        {
-                            ringBuffer->Seek(ringBuffer->DVD()->GetCellStartPos(),SEEK_SET);
-                            continue;
-                        }
+                        if (pausevideo)
+                            UnpauseVideo();
+                        continue;
                     }
-                    indvdstillframe = true;
                     if (!pausevideo && nbframes == 1)
+                    {
+                        indvdstillframe = true;
                         PauseVideo(false);
+                    }
                 }
             }
 
-            // restart playing after skipping still frame
             if (indvdstillframe && nbframes > 1)
             {
                 UnpauseVideo();
                 indvdstillframe = false;
+                continue;
             } 
         }
 
@@ -2925,11 +2922,11 @@
 
     int samples = len / samplesize;
 
-    if (ringBuffer->isDVD())
+    if (ringBuffer->InDVDMenuOrStillFrame())
     {
         audioOutput->Pause(false);
         audioOutput->Drain();
-    }
+    } 
 
     // If there is no warping, just send it to the audioOutput.
     if (!usevideotimebase)
@@ -5321,19 +5318,20 @@
     if (!ringBuffer->InDVDMenuOrStillFrame())
         return;
 
-    long long spupts = ringBuffer->DVD()->MenuSpuPts();
-    long long ptslow = spupts - 1000;
-    long long ptshigh = spupts + 1000;
     VideoFrame *buffer = videoOutput->GetLastShownFrame();
-
-    if (!osd->IsSetDisplaying("subtitles") &&
-        (buffer->timecode > 0) &&
-        ((buffer->timecode < ptslow) || 
-         (buffer->timecode > ptshigh)))
+    int numbuttons = ringBuffer->DVD()->NumMenuButtons();
+    bool osdshown = osd->IsSetDisplaying("subtitles");
+    long long menupktpts = ringBuffer->DVD()->GetMenuPktPts();
+    
+    if ((numbuttons == 0) ||
+            (osdshown) ||
+            ((!osdshown) && (hidedvdbutton) &&
+             (buffer->timecode > 0) && (menupktpts != buffer->timecode)))
     {
-        return; 
+        return;
     }
 
+    hidedvdbutton = false;
     AVSubtitleRect *highlightButton;
     OSDSet *subtitleOSD = NULL;
     highlightButton = ringBuffer->DVD()->GetMenuButton();
@@ -5383,10 +5381,7 @@
     if (!ringBuffer->isDVD())
         return;
 
-    if (videoOutput->ValidVideoFrames() > 20)
-        DiscardVideoFrames(true);
     ringBuffer->DVD()->ActivateButton();
-    ringBuffer->DVD()->HideMenuButton(true);
 }
 
 void NuppelVideoPlayer::GoToDVDMenu(QString str)
@@ -5394,8 +5389,7 @@
     if (!ringBuffer->isDVD())
         return;
 
-    if (videoOutput->ValidVideoFrames() > 20)
-        DiscardVideoFrames(true);
+    subtitlesOn = false;
     ringBuffer->DVD()->GoToMenu(str);
 }
 
@@ -5406,9 +5400,7 @@
 {
     if (!ringBuffer->isDVD())
         return;
- 
-    if (videoOutput->ValidVideoFrames() > 20)
-        DiscardVideoFrames(true);
+
     if (direction == 0)
         ringBuffer->DVD()->GoToPreviousProgram();
     else
Index: libs/libmythtv/DVDRingBuffer.h
===================================================================
--- libs/libmythtv/DVDRingBuffer.h	(revision 9165)
+++ libs/libmythtv/DVDRingBuffer.h	(working copy)
@@ -45,17 +45,17 @@
     bool InStillFrame(void) { return cellHasStillFrame; }
     bool IsWaiting(void) { return dvdWaiting; }
     int    NumPartsInTitle(void) { return titleParts; }
-    void GetMenuSPUPkt(uint8_t *buf, int buf_size,long long pts);
+    void GetMenuSPUPkt(uint8_t *buf, int len, int stream_id);
     AVSubtitleRect *GetMenuButton(void);
     bool IgnoringStillorWait(void) { return skipstillorwait; }
-    long long GetCellStartPos(void) { return cellstartPos; }
-    void HideMenuButton(bool hide);
+    long long GetCellStartPos(void);
     uint ButtonPosX(void) { return hl_startx; }
     uint ButtonPosY(void) { return hl_starty; }
     uint GetAudioLanguage(int id);
     uint GetSubtitleLanguage(int id);
-    long long MenuSpuPts(void) { return menuspupts; }
-
+    void SetMenuPktPts(long long pts) { menupktpts = pts; }
+    long long GetMenuPktPts(void) { return menupktpts; }
+    
     // commands
     bool OpenFile(const QString &filename);
     void close(void);
@@ -76,6 +76,8 @@
     int NumMenuButtons(void);
     void IgnoreStillOrWait(bool skip) { skipstillorwait = skip; }
     uint GetCurrentTime(void);
+    int  SelectedAudioTrack(void);
+    uint8_t GetNumAudioChannels(int id);
     
     void SetParent(NuppelVideoPlayer *p) { parent = p; }
     
@@ -111,14 +113,20 @@
     int            menuBuflength;
     uint8_t       *buttonBitmap;
     AVSubtitleRect *dvdMenuButton;
-    int            buttonCoords;
     bool           skipstillorwait;
     bool           spuStreamLetterbox;
     long long      cellstartPos;
     bool           buttonSelected;
     bool           buttonExists;
-    long long      menuspupts;
-
+    int            cellid;
+    int            lastcellid;
+    int            vobid;
+    int            lastvobid;
+    bool           cellRepeated;
+    int            buttonstreamid;
+    bool           gotoCellStart;
+    long long      menupktpts;
+    
     NuppelVideoPlayer *parent;
 
     bool DrawMenuButton(uint8_t *spu_pkt, int buf_size);
@@ -126,6 +134,8 @@
     void ClearMenuSPUParameters(void);
     bool MenuButtonChanged(void);
     uint ConvertLangCode(uint16_t code); // converts 2char key to 3char key
+    void SelectDefaultButton(void);
+    void ClearSubtitlesOSD(void);
     
     /* copied from dvdsub.c from ffmpeg */
     int get_nibble(const uint8_t *buf, int nibble_offset);
Index: libs/libmythtv/avformatdecoder.cpp
===================================================================
--- libs/libmythtv/avformatdecoder.cpp	(revision 9165)
+++ libs/libmythtv/avformatdecoder.cpp	(working copy)
@@ -278,7 +278,7 @@
       // language preference
       languagePreference(iso639_get_language_key_list()),
       // DVD
-      lastdvdtitle(0)
+      lastdvdtitle(0), dvdmenupktseen(false)
 {
     bzero(&params, sizeof(AVFormatParameters));
     bzero(prvpkt, 3 * sizeof(char));
@@ -431,13 +431,9 @@
 void AvFormatDecoder::SeekReset(long long newKey, uint skipFrames,
                                 bool doflush, bool discardFrames)
 {
-    if (ringBuffer->isDVD())
-    {
-        int totaltime = ringBuffer->DVD()->GetTotalTimeOfTitle();
-        if (totaltime < 30 || ringBuffer->InDVDMenuOrStillFrame())
-            return;
-    }
-
+    if (ringBuffer->InDVDMenuOrStillFrame())
+        return;
+    
     VERBOSE(VB_PLAYBACK, LOC +
             QString("SeekReset(%1, %2, %3 flush, %4 discard)")
             .arg(newKey).arg(skipFrames)
@@ -1194,7 +1190,7 @@
                 lang_indx = lang_sub_cnt[lang];
                 lang_sub_cnt[lang]++;
             }
-            subtitleStreams.push_back(StreamInfo(i, lang, lang_indx));
+            subtitleStreams.push_back(StreamInfo(i, lang, lang_indx,ic->streams[i]->id));
 
             VERBOSE(VB_PLAYBACK, LOC + QString(
                         "Subtitle track #%1 is A/V stream #%2 "
@@ -1213,8 +1209,7 @@
                 lang_indx = lang_aud_cnt[lang];
                 lang_aud_cnt[lang]++;
             }
-            audioStreams.push_back(StreamInfo(i, lang, lang_indx));
-
+            audioStreams.push_back(StreamInfo(i, lang, lang_indx,ic->streams[i]->id));
             VERBOSE(VB_AUDIO, LOC + QString(
                         "Audio Track #%1 is A/V stream #%2 "
                         "and has %3 channels in the %4 language(%5).")
@@ -1235,6 +1230,17 @@
     currentAudioTrack = -1;
     currentSubtitleTrack = -1;
 
+    if (ringBuffer->isDVD())
+    {
+        if (audioStreams.size() > 1)
+        {
+            qBubbleSort(audioStreams);
+            setCurrentAudioTrack(ringBuffer->DVD()->SelectedAudioTrack());
+        }
+        if (subtitleStreams.size() > 1)
+            qBubbleSort(subtitleStreams);
+    }
+
     // We have to do this here to avoid the NVP getting stuck
     // waiting on audio.
     if (GetNVP()->HasAudioIn() && audioStreams.empty())
@@ -1914,13 +1920,19 @@
             else
                 msg += QString(" %1").arg(s->codec->codec->name).upper();
 
-            if (!s->codec->channels)
-                msg += QString(" ?ch");
-            else if ((s->codec->channels > 4) && !(s->codec->channels & 1))
-                msg += QString(" %1.1ch").arg(s->codec->channels - 1);
+            int channels = 0;
+            if (ringBuffer->isDVD())
+                channels = ringBuffer->DVD()->GetNumAudioChannels(i);
+            else if (s->codec->channels)
+                channels = s->codec->channels;
+
+            if (channels == 0)
+                msg+= QString(" ?ch");
+            else if((channels > 4) && !(channels & 1))
+                msg += QString(" %1.1ch").arg(channels - 1);
             else
-                msg += QString(" %1ch").arg(s->codec->channels);
-        }
+                msg += QString(" %1ch").arg(channels);
+        }   
         list += QString("%1: %2").arg(i+1).arg(msg);
     }
 
@@ -2301,6 +2313,7 @@
                 VERBOSE(VB_PLAYBACK,
                     QString(LOC + "DVD Title Changed. Update framesPlayed: %1 ")
                             .arg(framesPlayed));
+                setCurrentAudioTrack(ringBuffer->DVD()->SelectedAudioTrack());
             }
             lastdvdtitle = dvdtitle;
             
@@ -2313,7 +2326,7 @@
         if (gotvideo)
         {
             if (lowbuffers && onlyvideo == 0 && lastapts < lastvpts + 100 &&
-                lastapts > lastvpts - 10000 && !ringBuffer->isDVD())
+                lastapts > lastvpts - 10000 && !ringBuffer->InDVDMenuOrStillFrame())
             {
                 //cout << "behind: " << lastapts << " " << lastvpts << endl;
                 storevideoframes = true;
@@ -2325,8 +2338,8 @@
             }
         }
 
-        if (ringBuffer->isDVD() && ringBuffer->DVD()->InStillFrame() && 
-                storedPackets.count() > 0)
+        if (ringBuffer->isDVD() && 
+                ringBuffer->DVD()->InStillFrame())
         {
             storevideoframes = false;
             dvdvideopause = true;
@@ -2720,6 +2733,12 @@
                     gotvideo = 1;
                     framesPlayed++;
 
+                    if (dvdmenupktseen)
+                    {
+                        ringBuffer->DVD()->SetMenuPktPts(pts);
+                        dvdmenupktseen = false;
+                    }
+
                     lastvpts = temppts;
                     break;
                 }
@@ -2729,7 +2748,10 @@
                     AVSubtitle subtitle;
 
                     if (ringBuffer->isDVD() && ringBuffer->DVD()->IsInMenu())
-                        ringBuffer->DVD()->GetMenuSPUPkt(ptr,len,pts);
+                    {
+                        dvdmenupktseen = true;
+                        ringBuffer->DVD()->GetMenuSPUPkt(ptr,len,curstream->id);
+                    }
                     else if (pkt->stream_index == subIdx)
                     {
                         QMutexLocker locker(&avcodeclock);
Index: libs/libmythtv/tv_play.cpp
===================================================================
--- libs/libmythtv/tv_play.cpp	(revision 9165)
+++ libs/libmythtv/tv_play.cpp	(working copy)
@@ -2311,7 +2311,7 @@
             if (prbuffer->isDVD())
             {
                 if (prbuffer->InDVDMenuOrStillFrame())
-                    UpdateOSDSeekMessage(tr("Skipping Back Not Allowed"),
+                    UpdateOSDSeekMessage(tr("Skip Back Not Allowed"),
                                          osd_general_timeout);
                 else if (prbuffer->DVD()->NumPartsInTitle() < 2)
                 {
Index: libs/libmythtv/DVDRingBuffer.cpp
===================================================================
--- libs/libmythtv/DVDRingBuffer.cpp	(revision 9165)
+++ libs/libmythtv/DVDRingBuffer.cpp	(working copy)
@@ -30,11 +30,14 @@
       title(0),         gotStop(false),
       cellHasStillFrame(false), dvdWaiting(false),
       titleLength(0),  spuchanged(false),
-      menuBuflength(0),  buttonCoords(0),
-      skipstillorwait(true), spuStreamLetterbox(false),
+      menuBuflength(0), skipstillorwait(true), 
+      spuStreamLetterbox(false),
       cellstartPos(0), buttonSelected(false), 
-      buttonExists(false), menuspupts(0),
-      parent(0)
+      buttonExists(false), cellid(0), 
+      lastcellid(0), vobid(0), 
+      lastvobid(0), cellRepeated(false), 
+      buttonstreamid(0), gotoCellStart(false), 
+      menupktpts(0), parent(0)
 {
     dvdMenuButton = (AVSubtitleRect*)av_mallocz(sizeof(AVSubtitleRect));
 }
@@ -119,7 +122,7 @@
             {
                 dvdnav_get_number_of_parts(dvdnav, curTitle, &titleParts);
                 VERBOSE(VB_IMPORTANT,
-                        QString("There are title %1 has %2 parts.")
+                        QString("Title %1 has %2 parts.")
                         .arg(curTitle).arg(titleParts));
             }
         }
@@ -222,13 +225,24 @@
                 dvdnav_get_position(dvdnav, &pos, &length);
                 titleLength = length *DVD_BLOCK_SIZE;
                 cellstartPos = GetReadPosition();
-                buttonSelected = false; 
-
-                if (parent && parent->GetOSD())
+                buttonSelected = false;
+                if (gotoCellStart)
                 {
-                    parent->GetOSD()->HideSet("subtitles");
-                    parent->GetOSD()->ClearAll("subtitles");
+                    lastvobid = lastcellid = 0;
+                    gotoCellStart = false;
                 }
+                else
+                {
+                    lastvobid = vobid;
+                    lastcellid = cellid;
+                }
+                vobid = 0;
+                cellid = 0;
+                cellRepeated = false;
+                menupktpts = 0;
+               
+                if (parent)
+                   parent->HideDVDButton(true);
 
                 if (blockBuf != dvdBlockWriteBuf)
                 {
@@ -259,7 +273,8 @@
                     spuStreamLetterbox = false;
                 spuchanged = true;
                 ClearMenuSPUParameters();
-
+                ClearSubtitlesOSD();
+                
                 if (blockBuf != dvdBlockWriteBuf)
                 {
                     dvdnav_free_cache_block(dvdnav, blockBuf);
@@ -284,19 +299,16 @@
             case DVDNAV_NAV_PACKET:
             {
                 lastNav = (dvdnav_t *)blockBuf;
-                if (IsInMenu() && NumMenuButtons() > 0 && 
-                        !buttonSelected)
+                if (vobid == 0 && cellid == 0)
                 {
-                    pci_t *pci = dvdnav_get_current_nav_pci(dvdnav);
-
-                    uint8_t button = pci->hli.hl_gi.fosl_btnn;
-                    if (button > 0)
-                        dvdnav_button_select(dvdnav,pci,button);
-                    else
-                        dvdnav_button_select(dvdnav,pci,1);
-
-                    buttonSelected = true;
-                    spuchanged = false;
+                    dsi_t *dsi = dvdnav_get_current_nav_dsi(dvdnav);
+                    vobid  = dsi->dsi_gi.vobu_vob_idn;
+                    cellid = dsi->dsi_gi.vobu_c_idn;
+                    if ((lastvobid == vobid) && (lastcellid == cellid) 
+                            && IsInMenu())
+                    {
+                        cellRepeated = true;
+                    }
                 }
                 if (blockBuf != dvdBlockWriteBuf)
                 {
@@ -348,7 +360,7 @@
 
                 if (DVDButtonUpdate(false))
                     buttonExists = DrawMenuButton(menuSpuPkt,menuBuflength);
-
+                ClearSubtitlesOSD();
                 if (blockBuf != dvdBlockWriteBuf)
                 {
                     dvdnav_free_cache_block(dvdnav, blockBuf);
@@ -521,38 +533,37 @@
     }
 }
 
-void DVDRingBufferPriv::GetMenuSPUPkt(uint8_t *buf, int buf_size,long long pts)
-{    
+void DVDRingBufferPriv::GetMenuSPUPkt(uint8_t *buf, int buf_size, int stream_id)
+{
     if (buf_size < 4)
         return;
 
-    menuspupts = pts;    
-    if (buf_size == menuBuflength)
+
+    if ((buttonstreamid < stream_id) && 
+        (buttonstreamid > 0))
         return;
-    else if (spuStreamLetterbox)
-    {
-        if ((buf_size < menuBuflength) && menuBuflength > 0)
-            return;
-    }
-    else
-    {
-        if ((buf_size > menuBuflength) && (menuBuflength > 0))
-            return;
-    }
+    
+    buttonstreamid = stream_id;
     ClearMenuSPUParameters();
     uint8_t *spu_pkt;
     spu_pkt = (uint8_t*)av_malloc(buf_size);
     memcpy(spu_pkt, buf, buf_size);
     menuSpuPkt = spu_pkt;
     menuBuflength = buf_size;
-    buttonCoords = 0;
+    if (!buttonSelected)
+    {
+        SelectDefaultButton();
+        buttonSelected = true;
+        spuchanged = false;
+    }
     if (DVDButtonUpdate(false))
         buttonExists = DrawMenuButton(menuSpuPkt,menuBuflength);
+    
 }
 
 AVSubtitleRect *DVDRingBufferPriv::GetMenuButton(void)
 {
-    if (MenuButtonChanged() && buttonExists)
+    if ((menuBuflength > 4) && buttonExists)
         return dvdMenuButton;
 
     return NULL;
@@ -684,6 +695,10 @@
 
 bool DVDRingBufferPriv::DVDButtonUpdate(bool b_mode)
 {
+    if (!parent)
+        return false;
+    int videoheight = parent->GetVideoHeight();
+    int videowidth = parent->GetVideoWidth();
     int32_t button;
     pci_t *pci;
     dvdnav_highlight_area_t hl;
@@ -702,11 +717,11 @@
     hl_starty = hl.sy;
     hl_height  = hl.ey - hl.sy;
 
-    int total_start_pos = hl.sx + hl.sy;
-    if ( total_start_pos == 0 || total_start_pos > (720 + 576 ))
-        return false;
+    if (((hl.sx + hl.sy) > 0) && 
+            (hl.sx < videowidth && hl.sy < videoheight))
+        return true;
 
-    return true;
+    return false;
 }
 
 void DVDRingBufferPriv::ClearMenuSPUParameters(void)
@@ -727,24 +742,8 @@
     dvdMenuButton->y = 0;
     hl_startx = hl_starty = 0;
     hl_width = hl_height = 0;
-    buttonCoords = (720+480+100);
 }
 
-bool DVDRingBufferPriv::MenuButtonChanged(void)
-{
-    if (menuBuflength < 4 || buttonCoords > (720+576))
-        return false;
-
-    int x = hl_startx;
-    int y = hl_starty;
-    if (buttonCoords != (x+y))
-    {
-        buttonCoords = (x+y);
-        return true;
-    }
-    return false;
-}
-
 int DVDRingBufferPriv::NumMenuButtons(void)
 {
     pci_t *pci = dvdnav_get_current_nav_pci(dvdnav);
@@ -755,14 +754,6 @@
         return 0;
 }
 
-void DVDRingBufferPriv::HideMenuButton(bool hide)
-{
-    if (hide)
-        buttonCoords = (720+480+100);
-    else
-        buttonCoords = 0;
-}
-
 uint DVDRingBufferPriv::GetCurrentTime(void)
 {
     // Macro to convert Binary Coded Decimal to Decimal
@@ -778,6 +769,12 @@
     return currentTime;
 }
 
+long long DVDRingBufferPriv::GetCellStartPos(void)
+{
+    gotoCellStart = true;
+    return cellstartPos;
+}
+
 uint DVDRingBufferPriv::GetAudioLanguage(int id)
 {
     int8_t channel = dvdnav_get_audio_logical_stream(dvdnav,id);
@@ -810,6 +807,44 @@
     return 0;
 }
 
+void DVDRingBufferPriv::SelectDefaultButton(void)
+{
+    pci_t *pci = dvdnav_get_current_nav_pci(dvdnav);
+    int button = pci->hli.hl_gi.fosl_btnn;
+    if (button > 0 && !cellRepeated)
+    {
+        dvdnav_button_select(dvdnav,pci,button);
+        return;
+    }
+    dvdnav_get_current_highlight(dvdnav,&button);
+    if (button > 0 && button <= NumMenuButtons())
+        dvdnav_button_select(dvdnav,pci,button);
+    else
+        dvdnav_button_select(dvdnav,pci,1);    
+}
+
+int DVDRingBufferPriv::SelectedAudioTrack(void)
+{
+    return dvdnav_get_active_audio_stream(dvdnav);
+}
+
+uint8_t DVDRingBufferPriv::GetNumAudioChannels(int id)
+{
+    unsigned char channels = dvdnav_audio_get_channels(dvdnav,id);
+    if (channels == 0xff)
+        return 0;
+   return (uint8_t)channels + 1; 
+}
+
+void DVDRingBufferPriv::ClearSubtitlesOSD(void)
+{
+    if (parent && parent->GetOSD())
+    {
+        parent->GetOSD()->HideSet("subtitles");
+        parent->GetOSD()->ClearAll("subtitles");
+    }
+}
+
 void DVDRingBufferPriv::guess_palette(uint32_t *rgba_palette,uint8_t *palette,
                                         uint8_t *alpha)
 {
Index: libs/libmythtv/avformatdecoder.h
===================================================================
--- libs/libmythtv/avformatdecoder.h	(revision 9165)
+++ libs/libmythtv/avformatdecoder.h	(working copy)
@@ -27,12 +27,14 @@
 {
   public:
     StreamInfo() : av_stream_index(-1), language(-2), language_index(0) {}
-    StreamInfo(int a, int b, uint c)
-        : av_stream_index(a), language(b), language_index(c) {}
+    StreamInfo(int a, int b, uint c, int d)
+        : av_stream_index(a), language(b), language_index(c), stream_id(d) {}
   public:
     int  av_stream_index;
     int  language; ///< ISO639 canonical language key
     uint language_index;
+    int  stream_id;
+    bool operator<(const StreamInfo& b) { return (this->stream_id < b.stream_id) ; }
 };
 typedef vector<StreamInfo> sinfo_vec_t;
 
@@ -266,6 +268,7 @@
 
     // DVD
     int lastdvdtitle;
+    bool dvdmenupktseen;
 };
 
 #endif
Index: libs/libavcodec/mpeg12.c
===================================================================
--- libs/libavcodec/mpeg12.c	(revision 9165)
+++ libs/libavcodec/mpeg12.c	(working copy)
@@ -3033,6 +3033,17 @@
         }
     }
 
+    /* look for SEQ_END_CODE at the last data in this buffer*/
+    /* dvd's won't send the next frame start on still images*/
+    /* state should hold the last startcode if one was found above*/
+    /* i will point to the position after that startcode */
+    if(!pc->frame_start_found){
+        if(state == SEQ_END_CODE){
+            pc->state=-1;
+            return i;
+        }
+    }
+    
     if(pc->frame_start_found){
         /* EOF considered as end of frame */
         if (buf_size == 0)
Index: libs/libmythdvdnav/dvdnav.c
===================================================================
--- libs/libmythdvdnav/dvdnav.c	(revision 9165)
+++ libs/libmythdvdnav/dvdnav.c	(working copy)
@@ -877,6 +877,26 @@
   return attr.lang_code;
 }
 
+unsigned char dvdnav_audio_get_channels(dvdnav_t *this, uint8_t stream){
+  audio_attr_t  attr;
+
+  if(!this) {
+    printerr("Passed a NULL pointer.");
+    return 0xff;
+  }
+  if(!this->started) {
+    printerr("Virtual DVD machine not started.");
+    return 0xff;
+  }
+
+  pthread_mutex_lock(&this->vm_lock);
+  attr = vm_get_audio_attr(this->vm, stream);
+  pthread_mutex_unlock(&this->vm_lock);
+
+  return attr.channels;
+              
+}
+
 uint16_t dvdnav_spu_stream_to_lang(dvdnav_t *this, uint8_t stream) {
   subp_attr_t  attr;
   
Index: libs/libmythdvdnav/dvdnav.h
===================================================================
--- libs/libmythdvdnav/dvdnav.h	(revision 9165)
+++ libs/libmythdvdnav/dvdnav.h	(working copy)
@@ -550,6 +550,13 @@
 uint16_t dvdnav_audio_stream_to_lang(dvdnav_t *self, uint8_t stream);
 
 /*
+ * Get number of audio channels.
+ * (1 -> 2 channels , 5 -> 6 channels)
+ * (returns 0xff if no such stream).
+ */
+unsigned char dvdnav_audio_get_channels(dvdnav_t *self, uint8_t stream);
+
+/*
  * Converts a *logical* subpicture stream id into country code 
  * (returns 0xffff if no such stream).
  */
