Index: libs/libmythtv/NuppelVideoPlayer.cpp
===================================================================
--- libs/libmythtv/NuppelVideoPlayer.cpp	(revision 11605)
+++ libs/libmythtv/NuppelVideoPlayer.cpp	(working copy)
@@ -848,14 +848,15 @@
 
 void NuppelVideoPlayer::SetVideoParams(int width, int height, double fps,
                                        int keyframedistance, float aspect,
-                                       FrameScanType scan)
+                                       FrameScanType scan, bool video_codec_changed)
 {
     if (width == 0 || height == 0 || isnan(aspect) || isnan(fps))
         return;
 
     if ((video_width  == width ) && (video_height     == height) && 
         (video_aspect == aspect) && (video_frame_rate == fps   ) &&
-        ((keyframedistance <= 0) || (keyframedistance == keyframedist)))
+        ((keyframedistance <= 0) || (keyframedistance == keyframedist)) &&
+        !video_codec_changed)
     {
         return;
     }
Index: libs/libmythtv/avformatdecoder.cpp
===================================================================
--- libs/libmythtv/avformatdecoder.cpp	(revision 11605)
+++ libs/libmythtv/avformatdecoder.cpp	(working copy)
@@ -292,7 +292,8 @@
       disable_passthru(false),
       // DVD
       lastdvdtitle(-1), lastcellstart(0),
-      dvdmenupktseen(false), dvdvideopause(false)
+      dvdmenupktseen(false), dvdvideopause(false),
+      dvd_xvmc_enabled(false), dvd_video_codec_changed(false)
 {
     bzero(&params, sizeof(AVFormatParameters));
     bzero(prvpkt, 3 * sizeof(char));
@@ -803,6 +804,9 @@
         av_free_packet(&pkt1);
         ringBuffer->Seek(0,SEEK_SET);
         ringBuffer->DVD()->IgnoreStillOrWait(false);
+        QString dec = gContext->GetSetting("PreferredMPEG2Decoder", "ffmpeg");
+        if (dec.contains("xvmc"))
+            dvd_xvmc_enabled = true;
     }
     else
     {
@@ -944,6 +948,8 @@
 {
     float aspect_ratio;
 
+    directrendering = false;
+
     if (selectedStream)
     {
         fps = normalized_fps(stream, enc);
@@ -1027,7 +1033,9 @@
         }
 
         GetNVP()->SetVideoParams(align_width, align_height, fps,
-                                 keyframedist, aspect_ratio, kScan_Detect);
+                                 keyframedist, aspect_ratio, kScan_Detect, 
+                                 dvd_video_codec_changed);
+        dvd_video_codec_changed = false;
     }
 }
 
@@ -1365,17 +1373,28 @@
                         enc->codec_id = CODEC_ID_MPEG2VIDEO;
                     // HACK -- end
 
+                    bool force_xv = false;
+                    if (ringBuffer->InDVDMenuOrStillFrame() &&
+                        dvd_xvmc_enabled)
+                    {
+                        force_xv = true;
+                        enc->pix_fmt = PIX_FMT_YUV420P;
+                    }
+                    
                     MythCodecID mcid;
                     mcid = VideoOutputXv::GetBestSupportedCodec(
                         /* disp dim     */ enc->width, enc->height,
                         /* osd dim      */ /*enc->width*/ 0, /*enc->height*/ 0,
                         /* mpeg type    */ xvmc_stream_type(enc->codec_id),
                         /* xvmc pix fmt */ xvmc_pixel_format(enc->pix_fmt),
-                        /* test surface */ kCodec_NORMAL_END > video_codec_id);
+                        /* test surface */ kCodec_NORMAL_END > video_codec_id,
+                        /* force_xv     */ force_xv);
                     bool vcd, idct, mc;
                     enc->codec_id = myth2av_codecid(mcid, vcd, idct, mc);
+                    if (mcid != video_codec_id)
+                        dvd_video_codec_changed = true;
                     video_codec_id = mcid;
-                    if (kCodec_NORMAL_END < mcid && kCodec_STD_XVMC_END > mcid)
+                    if (!force_xv && kCodec_NORMAL_END < mcid && kCodec_STD_XVMC_END > mcid)
                     {
                         enc->pix_fmt = (idct) ?
                             PIX_FMT_XVMC_MPEG2_IDCT : PIX_FMT_XVMC_MPEG2_MC;
@@ -2830,17 +2849,28 @@
             {
                 int current_width = curstream->codec->width;
                 int video_width = GetNVP()->GetVideoWidth();
-                if (video_width > 0 && video_width != current_width)
+                bool switch_to_xv = false;
+                bool switch_to_xvmc = false;
+                if (dvd_xvmc_enabled && GetNVP() && GetNVP()->getVideoOutput())
                 {
+                    bool dvd_xvmc_active = GetNVP()->getVideoOutput()->hasMCAcceleration();
+                    bool indvdmenu   = ringBuffer->InDVDMenuOrStillFrame();
+                    if (indvdmenu && dvd_xvmc_active)
+                        switch_to_xv = true;
+                    else if (!indvdmenu && !dvd_xvmc_active)
+                        switch_to_xvmc = true;
+                }
+                
+                if ((video_width > 0 && video_width != current_width) ||
+                    switch_to_xv || switch_to_xvmc)
+                {
                     av_free_packet(pkt);
                     CloseCodecs();
                     ScanStreams(false);
+                    QMutexLocker locker(&avcodeclock);
                     allowedquit = true;
                     if (ringBuffer->DVD()->InStillFrame())
-                    {
-                        long long cellstartpos = ringBuffer->DVD()->GetCellStartPos();
-                        ringBuffer->DVD()->Seek(cellstartpos, SEEK_SET);
-                    }
+                        ringBuffer->DVD()->SeekCellStart();
                     continue;
                 }
             }
Index: libs/libmythtv/DVDRingBuffer.cpp
===================================================================
--- libs/libmythtv/DVDRingBuffer.cpp	(revision 11605)
+++ libs/libmythtv/DVDRingBuffer.cpp	(working copy)
@@ -69,6 +69,12 @@
             (NumMenuButtons() > 0));
 }
 
+long long DVDRingBufferPriv::NormalSeek(long long pos, int whence)
+{
+    QMutexLocker lock(&seekLock);
+    return Seek(pos, whence);
+}
+
 long long DVDRingBufferPriv::Seek(long long pos, int whence)
 {
     dvdnav_status_t dvdRet = dvdnav_sector_search(this->dvdnav, pos / DVD_BLOCK_SIZE , whence);
@@ -900,12 +906,6 @@
     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);
@@ -1020,6 +1020,13 @@
     return false;
 }
 
+void DVDRingBufferPriv::SeekCellStart(void)
+{
+    QMutexLocker lock(&seekLock);
+    gotoCellStart = true;
+    Seek(cellstartPos, SEEK_SET);
+}
+
 /**
  * \brief converts palette values from YUV to RGB
  */
Index: libs/libmythtv/NuppelVideoPlayer.h
===================================================================
--- libs/libmythtv/NuppelVideoPlayer.h	(revision 11605)
+++ libs/libmythtv/NuppelVideoPlayer.h	(working copy)
@@ -151,7 +151,8 @@
     void SetBookmark(void);
     void SetKeyframeDistance(int keyframedistance);
     void SetVideoParams(int w, int h, double fps, int keydist,
-                        float a = 1.33333, FrameScanType scan = kScan_Ignore);
+                        float a = 1.33333, FrameScanType scan = kScan_Ignore, 
+                        bool video_codec_changed = false);
     void SetFileLength(int total, int frames);
     void Zoom(int direction);
     void ClearBookmark(void);
Index: libs/libmythtv/RingBuffer.cpp
===================================================================
--- libs/libmythtv/RingBuffer.cpp	(revision 11605)
+++ libs/libmythtv/RingBuffer.cpp	(working copy)
@@ -1160,7 +1160,7 @@
 #ifdef USING_FRONTEND
     else if (dvdPriv)
     {
-        dvdPriv->Seek(pos, whence);
+        dvdPriv->NormalSeek(pos, whence);
     }
 #endif // USING_FRONTEND
     else
Index: libs/libmythtv/DVDRingBuffer.h
===================================================================
--- libs/libmythtv/DVDRingBuffer.h	(revision 11605)
+++ libs/libmythtv/DVDRingBuffer.h	(working copy)
@@ -50,7 +50,6 @@
     void ReleaseMenuButton(void);
 
     bool IgnoringStillorWait(void) { return skipstillorwait; }
-    long long GetCellStartPos(void);
     uint ButtonPosX(void) { return hl_startx; }
     uint ButtonPosY(void) { return hl_starty; }
     uint GetAudioLanguage(int id);
@@ -80,7 +79,7 @@
     bool nextTrack(void);
     void prevTrack(void);
     int  safe_read(void *data, unsigned sz);
-    long long Seek(long long pos, int whence);
+    long long NormalSeek(long long pos, int whence);
     void SkipStillFrame(void);
     void WaitSkip(void);
     void GoToMenu(const QString str);
@@ -98,8 +97,11 @@
     int   GetTrack(uint type);
     uint8_t GetNumAudioChannels(int id);
     void JumpToTitle(bool change) { jumptotitle = change; }
-    
+    void SeekCellStart(void);
+
     void SetParent(NuppelVideoPlayer *p) { parent = p; }
+
+
     
   protected:
     dvdnav_t      *dvdnav;
@@ -160,7 +162,9 @@
     NuppelVideoPlayer *parent;
 
     QMutex menuBtnLock;
+    QMutex seekLock;
 
+    long long Seek(long long pos, int whence);
     bool DrawMenuButton(uint8_t *spu_pkt, int buf_size);
     bool DVDButtonUpdate(bool b_mode);
     void ClearMenuSPUParameters(void);
Index: libs/libmythtv/videoout_xv.h
===================================================================
--- libs/libmythtv/videoout_xv.h	(revision 11605)
+++ libs/libmythtv/videoout_xv.h	(working copy)
@@ -94,7 +94,7 @@
     static MythCodecID GetBestSupportedCodec(uint width, uint height,
                                              uint osd_width, uint osd_height,
                                              uint stream_type, int xvmc_chroma,
-                                             bool test_surface);
+                                             bool test_surface, bool force_xv);
 
     static int GrabSuitableXvPort(Display* disp, Window root,
                                   MythCodecID type,
@@ -144,7 +144,7 @@
     bool CreateBuffers(VOSType subtype);
     vector<void*> CreateXvMCSurfaces(uint num, bool create_xvmc_blocks);
     vector<unsigned char*> CreateShmImages(uint num, bool use_xv);
-    void CreatePauseFrame(void);
+    void CreatePauseFrame(VOSType subtype);
     void CopyFrame(VideoFrame *to, const VideoFrame *from);
 
     void DeleteBuffers(VOSType subtype, bool delete_pause_frame);
Index: libs/libmythtv/videoout_xv.cpp
===================================================================
--- libs/libmythtv/videoout_xv.cpp	(revision 11605)
+++ libs/libmythtv/videoout_xv.cpp	(working copy)
@@ -649,10 +649,10 @@
  *
  * \sideeffect sets av_pause_frame.
  */
-void VideoOutputXv::CreatePauseFrame(void)
+void VideoOutputXv::CreatePauseFrame(VOSType subtype)
 {
     // All methods but XvMC use a pause frame, create it if needed
-    if (VideoOutputSubType() <= XVideo)
+    if (subtype <= XVideo)
     {
         vbuffers.LockFrame(&av_pause_frame, "CreatePauseFrame");
 
@@ -992,11 +992,14 @@
 MythCodecID VideoOutputXv::GetBestSupportedCodec(
     uint width,       uint height,
     uint osd_width,   uint osd_height,
-    uint stream_type, int xvmc_chroma,    bool test_surface)
+    uint stream_type, int xvmc_chroma,    
+    bool test_surface, bool force_xv)
 {
     (void)width, (void)height, (void)osd_width, (void)osd_height;
     (void)stream_type, (void)xvmc_chroma, (void)test_surface;
 
+    if (force_xv)
+        return (MythCodecID)(kCodec_MPEG1 + (stream_type-1));
 #ifdef USING_XVMC
     Display *disp = MythXOpenDisplay();
 
@@ -1719,7 +1722,7 @@
     }
 
     if (ok)
-        CreatePauseFrame();
+        CreatePauseFrame(subtype);
 
     return ok;
 }
Index: libs/libmythtv/avformatdecoder.h
===================================================================
--- libs/libmythtv/avformatdecoder.h	(revision 11605)
+++ libs/libmythtv/avformatdecoder.h	(working copy)
@@ -255,6 +255,8 @@
     uint lastcellstart;
     bool dvdmenupktseen;
     bool dvdvideopause;
+    bool dvd_xvmc_enabled;
+    bool dvd_video_codec_changed;
 
 };
 
Index: libs/libavcodec/mpeg12.c
===================================================================
--- libs/libavcodec/mpeg12.c	(revision 11605)
+++ libs/libavcodec/mpeg12.c	(working copy)
@@ -2078,6 +2078,8 @@
     s->mpeg_enc_ctx.picture_number = 0;
     s->repeat_field = 0;
     s->mpeg_enc_ctx.codec_id= avctx->codec->id;
+    avctx->xvmc_acceleration = 0;
+    avctx->xvmc_vld_hwslice  = 0;
     return 0;
 }
 
