Index: libs/libmythtv/NuppelVideoPlayer.cpp
===================================================================
--- libs/libmythtv/NuppelVideoPlayer.cpp	(revision 19990)
+++ libs/libmythtv/NuppelVideoPlayer.cpp	(working copy)
@@ -635,7 +635,8 @@
             GetDecoder()->GetVideoCodecID(),
             GetDecoder()->GetVideoCodecPrivate(),
             video_disp_dim, video_aspect,
-            widget->winId(), display_rect, 0 /*embedid*/);
+            widget->winId(), display_rect, (video_frame_rate * play_speed), 
+	    0 /*embedid*/);
 
         if (!videoOutput)
         {
@@ -650,7 +651,7 @@
         videoOutput->SetVideoScalingAllowed(db_scale);
 
         // We need to tell it this for automatic deinterlacer settings
-        videoOutput->SetVideoFrameRate(video_frame_rate * play_speed);
+	videoOutput->SetVideoFrameRate(video_frame_rate * play_speed);
 
         if (videoOutput->hasMCAcceleration() && !decode_extra_audio)
         {
Index: libs/libmythtv/videoout_d3d.cpp
===================================================================
--- libs/libmythtv/videoout_d3d.cpp	(revision 19990)
+++ libs/libmythtv/videoout_d3d.cpp	(working copy)
@@ -451,7 +451,7 @@
 
 bool VideoOutputD3D::Init(int width, int height, float aspect,
                           WId winid, int winx, int winy, int winw,
-                          int winh, WId embedid)
+                          int winh, float video_prate, WId embedid)
 {
     VERBOSE(VB_PLAYBACK, LOC +
             "Init w=" << width << " h=" << height);
@@ -462,8 +462,8 @@
                   kPrebufferFramesNormal, kPrebufferFramesSmall,
                   kKeepPrebuffer);
 
-    VideoOutput::Init(width, height, aspect, winid,
-                      winx, winy, winw, winh, embedid);
+    VideoOutput::Init(width, height, aspect, winid, winx, 
+		      winy, winw, winh, video_prate, embedid);
 
     m_hWnd = winid;
 
Index: libs/libmythtv/videoout_quartz.cpp
===================================================================
--- libs/libmythtv/videoout_quartz.cpp	(revision 19990)
+++ libs/libmythtv/videoout_quartz.cpp	(working copy)
@@ -1192,8 +1192,8 @@
 }
 
 bool VideoOutputQuartz::Init(int width, int height, float aspect,
-                             WId winid, int winx, int winy,
-                             int winw, int winh, WId embedid)
+                             WId winid, int winx, int winy, int winw,
+			     int winh, float video_prate, WId embedid)
 {
     VERBOSE(VB_PLAYBACK, LOC +
             QString("Init(WxH %1x%2, aspect=%3, winid=%4\n\t\t\t"
@@ -1215,8 +1215,8 @@
     vbuffers.Init(kNumBuffers, true, kNeedFreeFrames,
                   kPrebufferFramesNormal, kPrebufferFramesSmall,
                   kKeepPrebuffer);
-    VideoOutput::Init(width, height, aspect, winid,
-                      winx, winy, winw, winh, embedid);
+    VideoOutput::Init(width, height, aspect, winid, winx, 
+		      winy, winw, winh, video_prate, embedid);
 
     data->srcWidth  = video_dim.width();
     data->srcHeight = video_dim.height();
@@ -1381,6 +1381,7 @@
 
 void VideoOutputQuartz::SetVideoFrameRate(float playback_fps)
 {
+    video_prate = playback_fps;
     VERBOSE(VB_PLAYBACK, "SetVideoFrameRate("<<playback_fps<<")");
 }
 
Index: libs/libmythtv/videoout_dx.h
===================================================================
--- libs/libmythtv/videoout_dx.h	(revision 19990)
+++ libs/libmythtv/videoout_dx.h	(working copy)
@@ -21,7 +21,8 @@
    ~VideoOutputDX();
 
     bool Init(int width, int height, float aspect, WId winid,
-              int winx, int winy, int winw, int winh, WId embedid = 0);
+              int winx, int winy, int winw, int winh, 
+	      float video_prate, WId embedid = 0);
     void PrepareFrame(VideoFrame *buffer, FrameScanType);
     void Show(FrameScanType );
 
Index: libs/libmythtv/videoout_directfb.cpp
===================================================================
--- libs/libmythtv/videoout_directfb.cpp	(revision 19990)
+++ libs/libmythtv/videoout_directfb.cpp	(working copy)
@@ -353,7 +353,7 @@
 
 bool VideoOutputDirectfb::Init(int width, int height, float aspect, WId winid,
                                int winx, int winy, int winw, int winh,
-                               WId embedid)
+                               float video_prate, WId embedid)
 {
     // Hack to avoid embedded video output...
     if ((winw < 320) || (winh < 240))
@@ -646,7 +646,7 @@
                            display_visible_rect.y(),
                            display_visible_rect.width(),
                            display_visible_rect.height(),
-                           embedid))
+                           video_prate, embedid))
     {
         return false;
     }
Index: libs/libmythtv/videoout_d3d.h
===================================================================
--- libs/libmythtv/videoout_d3d.h	(revision 19990)
+++ libs/libmythtv/videoout_d3d.h	(working copy)
@@ -20,7 +20,8 @@
    ~VideoOutputD3D();
 
     bool Init(int width, int height, float aspect, WId winid,
-              int winx, int winy, int winw, int winh, WId embedid = 0);
+              int winx, int winy, int winw, int winh, 
+	      float video_prate, WId embedid = 0);
 
     bool InitD3D();
     void UnInitD3D();
Index: libs/libmythtv/videoout_ivtv.h
===================================================================
--- libs/libmythtv/videoout_ivtv.h	(revision 19990)
+++ libs/libmythtv/videoout_ivtv.h	(working copy)
@@ -16,7 +16,8 @@
    ~VideoOutputIvtv();
 
     bool Init(int width, int height, float aspect, WId winid,
-              int winx, int winy, int winw, int winh, WId embedid = 0);
+              int winx, int winy, int winw, int winh,
+	      float video_prate, WId embedid = 0);
     void PrepareFrame(VideoFrame *buffer, FrameScanType);
     void Show(FrameScanType );
 
Index: libs/libmythtv/videoout_null.cpp
===================================================================
--- libs/libmythtv/videoout_null.cpp	(revision 19990)
+++ libs/libmythtv/videoout_null.cpp	(working copy)
@@ -115,15 +115,15 @@
 
 bool VideoOutputNull::Init(int width, int height, float aspect,
                            WId winid, int winx, int winy, int winw, 
-                           int winh, WId embedid)
+                           int winh, float video_prate, WId embedid)
 {
     if ((width <= 0) || (height <= 0))
         return false;
 
     QMutexLocker locker(&global_lock);
 
-    VideoOutput::Init(width, height, aspect, winid,
-                      winx, winy, winw, winh, embedid);
+    VideoOutput::Init(width, height, aspect, winid, winx, 
+		      winy, winw, winh, video_prate, embedid);
 
     vbuffers.Init(kNumBuffers, true, kNeedFreeFrames, 
                   kPrebufferFramesNormal, kPrebufferFramesSmall, 
Index: libs/libmythtv/videooutbase.cpp
===================================================================
--- libs/libmythtv/videooutbase.cpp	(revision 19990)
+++ libs/libmythtv/videooutbase.cpp	(working copy)
@@ -67,7 +67,7 @@
         void          *codec_priv,
         const QSize   &video_dim, float        video_aspect,
         WId            win_id,    const QRect &display_rect,
-        WId            embed_id)
+	float video_prate,        WId            embed_id)
 {
     (void) codec_priv;
 
@@ -166,10 +166,12 @@
 
         if (vo)
         {
+	    vo->video_prate = video_prate;
             if (vo->Init(
                     video_dim.width(), video_dim.height(), video_aspect,
                     win_id, display_rect.x(), display_rect.y(),
-                    display_rect.width(), display_rect.height(), embed_id))
+                    display_rect.width(), display_rect.height(),
+		    video_prate, embed_id))
             {
                 return vo;
             }
@@ -181,6 +183,8 @@
         renderer = VideoDisplayProfile::GetBestVideoRenderer(renderers);
     }
 
+
+
     VERBOSE(VB_IMPORTANT, LOC_ERR +
             "Not compiled with any useable video output method.");
 
@@ -363,7 +367,8 @@
  * \return true if successful, false otherwise.
  */
 bool VideoOutput::Init(int width, int height, float aspect, WId winid,
-                       int winx, int winy, int winw, int winh, WId embedid)
+                       int winx, int winy, int winw, int winh,
+		       float video_prate, WId embedid)
 {
     (void)winid;
     (void)embedid;
@@ -405,6 +410,7 @@
 
 void VideoOutput::SetVideoFrameRate(float playback_fps)
 {
+    video_prate = playback_fps;
     db_vdisp_profile->SetOutput(playback_fps);
 }
 
Index: libs/libmythtv/videoout_directfb.h
===================================================================
--- libs/libmythtv/videoout_directfb.h	(revision 19990)
+++ libs/libmythtv/videoout_directfb.h	(working copy)
@@ -14,7 +14,8 @@
     ~VideoOutputDirectfb();
 
     bool Init(int width, int height, float aspect, WId winid,
-              int winx, int winy, int winw, int winh, WId embedid = 0);
+              int winx, int winy, int winw, int winh, 
+	      float video_prate, WId embedid = 0);
 
     void ProcessFrame(VideoFrame *frame, OSD *osd,
                       FilterChain *filterList,
Index: libs/libmythtv/videoout_xv.h
===================================================================
--- libs/libmythtv/videoout_xv.h	(revision 19990)
+++ libs/libmythtv/videoout_xv.h	(working copy)
@@ -60,7 +60,8 @@
    ~VideoOutputXv();
 
     bool Init(int width, int height, float aspect, WId winid,
-              int winx, int winy, int winw, int winh, WId embedid = 0);
+              int winx, int winy, int winw, int winh, 
+	      float video_prate, WId embedid = 0);
 
     bool SetDeinterlacingEnabled(bool);
     bool SetupDeinterlace(bool interlaced, const QString& ovrf="");
Index: libs/libmythtv/videoout_xv.cpp
===================================================================
--- libs/libmythtv/videoout_xv.cpp	(revision 19990)
+++ libs/libmythtv/videoout_xv.cpp	(working copy)
@@ -405,8 +405,9 @@
     if ((width == 1920 || width == 1440) && height == 1088)
         height = 1080; // ATSC 1920x1080
 
-    if (display_res && display_res->SwitchToVideo(width, height))
-    {
+    if (display_res && display_res->SwitchToVideo(width, height, 
+						  (short) roundf(video_prate), video_prate))
+	{
         // Switching to custom display resolution succeeded
         // Make a note of the new size
         display_dim = QSize(display_res->GetPhysicalWidth(),
@@ -1568,14 +1569,14 @@
 }
 
 /**
- * \fn VideoOutputXv::Init(int,int,float,WId,int,int,int,int,WId)
+ * \fn VideoOutputXv::Init(int,int,float,WId,int,int,int,int,float,WId)
  * Initializes class for video output.
  *
  * \return success or failure.
  */
 bool VideoOutputXv::Init(
-    int width, int height, float aspect,
-    WId winid, int winx, int winy, int winw, int winh, WId embedid)
+    int width, int height, float aspect, WId winid, int winx, 
+    int winy, int winw, int winh, float video_prate, WId embedid)
 {
     needrepaint = true;
 
@@ -1609,7 +1610,7 @@
     // Basic setup
     VideoOutput::Init(width, height, aspect,
                       winid, winx, winy, winw, winh,
-                      embedid);
+                      video_prate, embedid);
 
     // Set resolution/measurements (check XRandR, Xinerama, config settings)
     InitDisplayMeasurements(width, height);
Index: libs/libmythtv/videooutbase.h
===================================================================
--- libs/libmythtv/videooutbase.h	(revision 19990)
+++ libs/libmythtv/videooutbase.h	(working copy)
@@ -36,14 +36,14 @@
         void          *codec_priv,
         const QSize   &video_dim, float        video_aspect,
         WId            win_id,    const QRect &display_rect,
-        WId            embed_id);
+        float video_prate,        WId            embed_id);
 
     VideoOutput();
     virtual ~VideoOutput();
 
     virtual bool Init(int width, int height, float aspect,
                       WId winid, int winx, int winy, int winw, 
-                      int winh, WId embedid = 0);
+                      int winh, float video_prate, WId embedid = 0);
     virtual void InitOSD(OSD *osd);
     virtual void SetVideoFrameRate(float);
 
@@ -276,6 +276,7 @@
     QSize   video_dim;        ///< Pixel dimensions of video buffer
     QSize   video_disp_dim;   ///< Pixel dimensions of video display area
     float   video_aspect;     ///< Physical aspect ratio of video
+    float   video_prate;  ///< Playback frame rate of video
 
     /// Normally this is the same as videoAspect, but may not be
     /// if the user has toggled the aspect override mode.
Index: libs/libmythtv/videoout_ivtv.cpp
===================================================================
--- libs/libmythtv/videoout_ivtv.cpp	(revision 19990)
+++ libs/libmythtv/videoout_ivtv.cpp	(working copy)
@@ -405,7 +405,7 @@
 
 bool VideoOutputIvtv::Init(int width, int height, float aspect, 
                            WId winid, int winx, int winy, int winw, 
-                           int winh, WId embedid)
+                           int winh, float video_prate, WId embedid)
 {
     VERBOSE(VB_PLAYBACK, LOC + "Init() -- begin");
 
@@ -416,7 +416,7 @@
     videoDevice = gContext->GetSetting("PVR350VideoDev");
 
     VideoOutput::Init(width, height, aspect, winid, winx, winy, winw, winh, 
-                      embedid);
+                      video_prate, embedid);
 
     osdbufsize = video_dim.width() * video_dim.height() * 4;
 
Index: libs/libmythtv/videoout_quartz.h
===================================================================
--- libs/libmythtv/videoout_quartz.h	(revision 19990)
+++ libs/libmythtv/videoout_quartz.h	(working copy)
@@ -13,7 +13,8 @@
    ~VideoOutputQuartz();
 
     bool Init(int width, int height, float aspect, WId winid,
-              int winx, int winy, int winw, int winh, WId embedid = 0);
+              int winx, int winy, int winw, int winh, 
+	      float video_prate, WId embedid = 0);
     void SetVideoFrameRate(float playback_fps);
     void PrepareFrame(VideoFrame *buffer, FrameScanType t);
     void Show(FrameScanType);
Index: libs/libmythtv/videoout_dx.cpp
===================================================================
--- libs/libmythtv/videoout_dx.cpp	(revision 19990)
+++ libs/libmythtv/videoout_dx.cpp	(working copy)
@@ -158,16 +158,16 @@
 }
 
 bool VideoOutputDX::Init(int width, int height, float aspect,
-                           WId winid, int winx, int winy, int winw, 
-                           int winh, WId embedid)
+                         WId winid, int winx, int winy, int winw, 
+			 int winh, float video_prate, WId embedid)
 {
     db_vdisp_profile->SetVideoRenderer("directx");
 
     vbuffers.Init(kNumBuffers, true, kNeedFreeFrames, 
                   kPrebufferFramesNormal, kPrebufferFramesSmall, 
                   kKeepPrebuffer);
-    VideoOutput::Init(width, height, aspect, winid,
-                      winx, winy, winw, winh, embedid);
+    VideoOutput::Init(width, height, aspect, winid, winx, 
+		      winy, winw, winh, video_prate, embedid);
 
     wnd = winid;
 
Index: libs/libmythtv/videoout_null.h
===================================================================
--- libs/libmythtv/videoout_null.h	(revision 19990)
+++ libs/libmythtv/videoout_null.h	(working copy)
@@ -12,7 +12,8 @@
    ~VideoOutputNull();
 
     bool Init(int width, int height, float aspect, WId winid,
-              int winx, int winy, int winw, int winh, WId embedid = 0);
+              int winx, int winy, int winw, int winh,
+	      float video_prate, WId embedid = 0);
 
     bool SetupDeinterlace(bool, const QString &ovrf = "")
         { (void)ovrf; return false; } // we don't deinterlace in null output..
Index: libs/libmyth/DisplayRes.cpp
===================================================================
--- libs/libmyth/DisplayRes.cpp	(revision 19990)
+++ libs/libmyth/DisplayRes.cpp	(working copy)
@@ -37,16 +37,16 @@
     // Initialize GUI mode
     mode[GUI].Init();
     tW = tH = 0;
-    gContext->GetResolutionSetting("GuiVidMode", tW, tH);
+    gContext->GetResolutionSetting("GuiVidMode", tW, tH, tAspect, tRate);
     GetDisplaySize(tW_mm, tH_mm);
     gContext->GetResolutionSetting("DisplaySize", tW_mm, tH_mm);
-    mode[GUI] = DisplayResScreen(tW, tH, tW_mm, tH_mm, -1.0, 0);
+    mode[GUI] = DisplayResScreen(tW, tH, tW_mm, tH_mm, -1.0, (float)tRate);
 
 
     // Initialize default VIDEO mode
     tW = tH = 0;
     gContext->GetResolutionSetting("TVVidMode", tW, tH, tAspect, tRate);
-    mode[VIDEO] = DisplayResScreen(tW, tH, tW_mm, tH_mm, tAspect, tRate);
+    mode[VIDEO] = DisplayResScreen(tW, tH, tW_mm, tH_mm, tAspect, (float)tRate);
 
 
     // Initialize video override mode
@@ -64,7 +64,7 @@
             break;
 
         uint key = DisplayResScreen::CalcKey(iw, ih, irate);
-        DisplayResScreen scr(ow, oh, tW_mm, tH_mm, oaspect, orate);
+        DisplayResScreen scr(ow, oh, tW_mm, tH_mm, oaspect, (float) orate);
         in_size_to_output_mode[key] = scr;            
     }
 
@@ -82,11 +82,18 @@
     return true;
 }
 
-bool DisplayRes::SwitchToVideo(int iwidth, int iheight, short irate)
+bool DisplayRes::SwitchToVideo(int iwidth, int iheight, short irate, float frate)
 {
     tmode next_mode = VIDEO; // default VIDEO mode
     DisplayResScreen next = mode[next_mode];
 
+    // If requested refresh rate is 0, attempt to match video fps
+    if (next.RefreshRate() == 0)
+    {
+        VERBOSE(VB_PLAYBACK, QString("*** Trying to match best resolution %1Hz") .arg(frate));
+		next.AddRefreshRate(frate);
+    }
+ 
     // try to find video override mode
     uint key = DisplayResScreen::CalcKey(iwidth, iheight, irate);
     DisplayResMapCIt it = in_size_to_output_mode.find(key);
@@ -94,9 +101,9 @@
         mode[next_mode = CUSTOM_VIDEO] = next = it->second;
 
     // need to change video mode?
-    short target_rate = 0;
+    float target_rate = 0.0;
     DisplayResScreen::FindBestMatch(GetVideoModes(), next, target_rate);
-    bool chg = !(next == last) || !(last.RefreshRate() == target_rate);
+    bool chg = !(next == last) || !(DisplayResScreen::compare_rates(last.RefreshRate(),target_rate));
 
     VERBOSE(VB_PLAYBACK, QString("Trying %1x%2 %3 Hz")
             .arg(next.Width()).arg(next.Height()).arg(target_rate));
@@ -128,9 +135,11 @@
     DisplayResScreen next = mode[next_mode];
 
     // need to change video mode?
-    short target_rate = 0;
+    float target_rate = 0.0;
     DisplayResScreen::FindBestMatch(GetVideoModes(), next, target_rate);
-    bool chg = !(next == last) || !(last.RefreshRate() == target_rate);
+    // If GuiVidModeRefreshRate is 0, assume any refresh rate is good enough.
+    bool chg = (!(next == last) || (next.RefreshRate() !=0
+    			&& !(DisplayResScreen::compare_rates(last.RefreshRate(),target_rate)))); 
 
     VERBOSE(VB_PLAYBACK, QString("Trying %1x%2 %3 Hz")
             .arg(next.Width()).arg(next.Height()).arg(target_rate));
@@ -154,15 +163,23 @@
 bool DisplayRes::SwitchToCustomGUI(int width, int height, short rate)
 {
     mode[CUSTOM_GUI] = DisplayResScreen(width, height, mode[GUI].Width_mm(),
-                                        mode[GUI].Height_mm(), -1.0, rate);
+                                        mode[GUI].Height_mm(), -1.0, (float) rate);
     return SwitchToGUI(CUSTOM_GUI);
 }
 
 const vector<short> DisplayRes::GetRefreshRates(int width, int height) const {
-    short tr;
-    vector<short> empty;
+    vector<short> srates;
+    vector<float> rates = GetRefreshRatesFloat(width, height);
 
-    const DisplayResScreen drs(width, height, 0, 0, -1.0, 0);
+    for (int i=0; i<rates.size(); i++)
+    	srates.push_back((short) rates[i]);
+    return srates;
+}
+const vector<float> DisplayRes::GetRefreshRatesFloat(int width, int height) const {
+    float tr;
+    vector<float> empty;
+
+    const DisplayResScreen drs(width, height, 0, 0, -1.0, 0.0);
     const DisplayResVector& drv = GetVideoModes();
     int t = DisplayResScreen::FindBestMatch(drv, drs, tr);
     if (t < 0)
Index: libs/libmyth/DisplayResOSX.cpp
===================================================================
--- libs/libmyth/DisplayResOSX.cpp	(revision 19990)
+++ libs/libmyth/DisplayResOSX.cpp	(working copy)
@@ -66,7 +66,7 @@
     return d;
 }
 
-bool DisplayResOSX::SwitchToVideoMode(int width, int height, short refreshrate)
+bool DisplayResOSX::SwitchToVideoMode(int width, int height, float refreshrate)
 {
     CGDirectDisplayID d = mythtv_display();
     CFDictionaryRef dispMode = NULL;
@@ -75,7 +75,7 @@
     // find mode that matches the desired size
     if (refreshrate)
         dispMode = CGDisplayBestModeForParametersAndRefreshRate(
-            d, 32, width, height, (CGRefreshRate)(refreshrate), &match);
+            d, 32, width, height, (CGRefreshRate)((short)refreshrate), &match);
 
     if (!match)
         dispMode = 
@@ -122,7 +122,7 @@
 
 	if (screen_map.find(key)==screen_map.end())
             screen_map[key] = DisplayResScreen(width, height,
-                                               0, 0, -1.0, refresh);
+                                               0, 0, -1.0, (float) refresh);
         else
             screen_map[key].AddRefreshRate(refresh);
     }
Index: libs/libmyth/DisplayResX.h
===================================================================
--- libs/libmyth/DisplayResX.h	(revision 19990)
+++ libs/libmyth/DisplayResX.h	(working copy)
@@ -12,7 +12,7 @@
 
   protected:
     bool GetDisplaySize(int &width_mm, int &height_mm) const;
-    bool SwitchToVideoMode(int width, int height, short framerate);
+    bool SwitchToVideoMode(int width, int height, float framerate);
 
   private:
     mutable vector<DisplayResScreen> m_video_modes;
Index: libs/libmyth/DisplayResScreen.h
===================================================================
--- libs/libmyth/DisplayResScreen.h	(revision 19990)
+++ libs/libmyth/DisplayResScreen.h	(working copy)
@@ -14,12 +14,14 @@
   public:
     // Constructors, initializers
     DisplayResScreen()
-        : width(0), height(0), width_mm(0), height_mm(0), aspect(-1.0) {;}
+        : width(0), height(0), width_mm(0), height_mm(0), aspect(-1.0), custom(false) {;}
     DisplayResScreen(int w, int h, int mw, int mh,
-                     double aspectRatio/* = -1.0*/, short refreshRate/* = 0*/);
+                     double aspectRatio/* = -1.0*/, float refreshRate/* = 0*/);
     DisplayResScreen(int w, int h, int mw, int mh,
-                     const vector<short>& refreshRates);
+                     const vector<float>& refreshRates);
     DisplayResScreen(int w, int h, int mw, int mh,
+                     const float* refreshRates, uint rr_length);
+    DisplayResScreen(int w, int h, int mw, int mh,
                      const short* refreshRates, uint rr_length);
     DisplayResScreen(const QString &str);
     inline void Init();
@@ -29,17 +31,28 @@
     int Height() const { return height; }
     int Width_mm() const { return width_mm; }
     int Height_mm() const { return height_mm; }
+    bool Custom() const { return custom; }
+
     inline double AspectRatio() const;
-    inline short RefreshRate() const;
-    const vector<short>& RefreshRates() const { return refreshRates; }
+    inline float RefreshRate() const;
+    const vector<float>& RefreshRates() const { return refreshRates; }
 
     // Sets, adds
     void SetAspectRatio(double a);
-    void AddRefreshRate(short rr) {
+    void AddRefreshRate(float rr) {
         refreshRates.push_back(rr);
         sort(refreshRates.begin(), refreshRates.end());
     }
-
+    void ClearRefreshRates(void) {
+    	refreshRates.clear();
+    }	
+    void SetCustom(bool b) {
+    	custom = b;
+    }
+	
+	// Map for matching real rates and xrandr rate;
+	map<float, short> realRates;
+	
     // Converters & comparitors
     QString toString() const;
     inline bool operator < (const DisplayResScreen& b) const;
@@ -50,16 +63,22 @@
     static vector<DisplayResScreen> Convert(const QStringList& slist);
     static int FindBestMatch(const vector<DisplayResScreen>& dsr,
                              const DisplayResScreen& d,
+                             float& target_rate);
+    static int FindBestMatch(const vector<DisplayResScreen>& dsr,
+                             const DisplayResScreen& d,
                              short& target_rate);
     static inline int CalcKey(int w, int h, int rate);
+	static bool compare_rates(float f1, float f2);
 
   private:
     int width, height; // size in pixels
     int width_mm, height_mm; // physical size in millimeters
     double aspect; // aspect ratio, calculated or set
-    vector<short> refreshRates;
+    vector<float> refreshRates;
+	bool custom;	// Set if resolution was defined manually
 };
 
+
 typedef vector<DisplayResScreen>          DisplayResVector;
 typedef DisplayResVector::iterator        DisplayResVectorIt;
 typedef DisplayResVector::const_iterator  DisplayResVectorCIt;
@@ -85,11 +104,11 @@
     return aspect;
 }
 
-inline short DisplayResScreen::RefreshRate() const
+inline float DisplayResScreen::RefreshRate() const
 {
     if (refreshRates.size() >= 1)
         return refreshRates[0];
-    else return 0;
+    else return 0.0;
 }
 
 inline bool DisplayResScreen::operator < (const DisplayResScreen& b) const
Index: libs/libmyth/DisplayResX.cpp
===================================================================
--- libs/libmyth/DisplayResX.cpp	(revision 19990)
+++ libs/libmyth/DisplayResX.cpp	(working copy)
@@ -4,6 +4,11 @@
 #include <cstring>
 #include <cstdlib>
 
+#include "mythcontext.h"
+#include <qregexp.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+
 #include "util-x11.h"
 
 #include <X11/extensions/Xrandr.h> // this has to be after util-x11.h (Qt bug)
@@ -32,9 +37,11 @@
     return false;
 }
 
-bool DisplayResX::SwitchToVideoMode(int width, int height, short desired_rate)
+bool DisplayResX::SwitchToVideoMode(int width, int height, float desired_rate)
 {
-    short rate;
+    float rate;
+    short finalrate;
+
     DisplayResScreen desired_screen(width, height, 0, 0, -1.0, desired_rate);
     int idx = DisplayResScreen::FindBestMatch(m_video_modes_unsorted,
                                               desired_screen, rate);
@@ -49,9 +56,23 @@
         Rotation rot;
         XRRConfigCurrentConfiguration(cfg, &rot);
         
+        // Search real xrandr rate for desired_rate
+   		finalrate = (short) rate;
+ 		for (int i=0; i < m_video_modes.size(); i++) {
+    		if ((m_video_modes[i].Width() == width) && (m_video_modes[i].Height() == height))
+    		{
+        		if (m_video_modes[i].Custom())
+        		{
+		    		finalrate = m_video_modes[i].realRates[rate];
+			        VERBOSE(VB_PLAYBACK, QString("CustomRate Found, set %1Hz as %2") .arg(rate) .arg(finalrate));
+        		}
+    			break;
+    		}
+    	}
+    	       
         Window root = DefaultRootWindow(display);
         Status status = XRRSetScreenConfigAndRate(display, cfg, root, idx,
-                                                  rot, rate, CurrentTime);
+                                                  rot, finalrate, CurrentTime);
         
         XRRFreeScreenConfigInfo(cfg);
         XCloseDisplay(display);
@@ -67,8 +88,8 @@
 
 const DisplayResVector& DisplayResX::GetVideoModes(void) const
 {
-    if (m_video_modes.size())
-        return m_video_modes;
+	if (m_video_modes.size())
+		return m_video_modes;
 
     Display *display = NULL;
     XRRScreenConfiguration *cfg = GetScreenConfig(display);
@@ -78,15 +99,70 @@
     int num_sizes, num_rates;
     XRRScreenSize *sizes = NULL;
     X11S(sizes = XRRConfigSizes(cfg, &num_sizes));
+
     for (int i = 0; i < num_sizes; ++i)
     {
         short *rates = NULL;
         X11S(rates = XRRRates(display, DefaultScreen(display), i, &num_rates));
         DisplayResScreen scr(sizes[i].width, sizes[i].height,
-                             sizes[i].mwidth, sizes[i].mheight,
-                             rates, num_rates);
-        m_video_modes.push_back(scr);
+							sizes[i].mwidth, sizes[i].mheight,
+							rates, num_rates);
+		m_video_modes.push_back(scr);
     }
+
+    QString customscreen = gContext->GetSetting("CustomScreenRate");
+    if (gContext->GetNumSetting("UseVideoModes", 0) && (customscreen != ""));
+	{
+		QFileInfo fi(customscreen);
+		QFile file(customscreen);
+	
+	    if (!fi.exists() || !fi.isFile())
+	    {
+	        VERBOSE(VB_PLAYBACK, QString("CustomScreenRate: \"%1\" failed: does not exist or isn't a file")
+	                .arg(customscreen));
+	    }
+	    else if ( file.open( IO_ReadOnly ) ) {
+	        QRegExp regexp = QRegExp("^\\s*(\\d+),(\\d+),(\\d+\\.?\\d*),(\\d+)\\s*$");
+	        QTextStream stream( &file );
+	        QString line;
+	        int pos;
+	        while ( !stream.atEnd() ) {
+	            pos = regexp.search(stream.readLine());
+	            if (pos > -1) {
+			        int w = regexp.cap(1).toInt();
+			        int h = regexp.cap(2).toInt();
+			        float hz = regexp.cap(3).toFloat();
+			        int xrandrhz = regexp.cap(4).toShort();
+			        int found = -1;
+			        VERBOSE(VB_PLAYBACK, QString("Found definition for %1x%2 @ %3Hz (xrandr: %4)")
+			        .arg(w) .arg(h) .arg(hz) .arg(xrandrhz));
+	            	// find if video mode already exist, and remove refresh rates for custom one
+	            	for (int i=0; i < m_video_modes.size(); i++) {
+	            		if ((m_video_modes[i].Width() == w) && (m_video_modes[i].Height() == h))
+	            		{
+	            			found = i;
+		            		if (!m_video_modes[i].Custom())
+		            		{
+		            			m_video_modes[i].ClearRefreshRates();
+								m_video_modes[i].SetCustom(true);
+		            		}
+		            		m_video_modes[i].AddRefreshRate(hz);
+		            		m_video_modes[i].realRates[hz] = xrandrhz;
+	            			break;
+	            		}
+	            	}
+	            	if (found < 0)
+	            	{
+						DisplayResScreen scr(w, h, 0, 0, -1.0, hz);
+						scr.SetCustom(true);
+				        m_video_modes.push_back(scr);
+	            	}
+	            }
+	        }
+	        file.close();
+	    }
+    }
+
     m_video_modes_unsorted = m_video_modes;
     sort(m_video_modes.begin(), m_video_modes.end());
 
Index: libs/libmyth/DisplayResScreen.cpp
===================================================================
--- libs/libmyth/DisplayResScreen.cpp	(revision 19990)
+++ libs/libmyth/DisplayResScreen.cpp	(working copy)
@@ -1,9 +1,11 @@
 #include "DisplayResScreen.h"
 #include "mythcontext.h"
 
+#include <cmath>
+
 DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh,
-                                   double aspectRatio, short refreshRate)
-    : width(w), height(h), width_mm(mw), height_mm(mh)
+                                   double aspectRatio, float refreshRate)
+    : width(w), height(h), width_mm(mw), height_mm(mh), custom(false)
 {
     SetAspectRatio(aspectRatio);
     if (refreshRate > 0)
@@ -11,15 +13,15 @@
 }
 
 DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh,
-                                   const vector<short>& rr)
-    : width(w), height(h), width_mm(mw), height_mm(mh), refreshRates(rr)
+                                   const vector<float>& rr)
+    : width(w), height(h), width_mm(mw), height_mm(mh), refreshRates(rr), custom(false)
 {
     SetAspectRatio(-1.0);
 }
 
 DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh,
-                                   const short* rr, uint rr_length)
-    : width(w), height(h), width_mm(mw), height_mm(mh)
+                                   const float* rr, uint rr_length)
+    : width(w), height(h), width_mm(mw), height_mm(mh), custom(false)
 {
     SetAspectRatio(-1.0);
     for (uint i = 0; i < rr_length; ++i)
@@ -28,8 +30,19 @@
     sort(refreshRates.begin(), refreshRates.end());
 }
 
+DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh,
+                                   const short* rr, uint rr_length)
+    : width(w), height(h), width_mm(mw), height_mm(mh), custom(false)
+{
+    SetAspectRatio(-1.0);
+    for (uint i = 0; i < rr_length; ++i)
+        refreshRates.push_back((float)rr[i]);
+
+    sort(refreshRates.begin(), refreshRates.end());
+}
+
 DisplayResScreen::DisplayResScreen(const QString &str)
-    : width(0), height(0), width_mm(0), height_mm(0), aspect(-1.0)
+    : width(0), height(0), width_mm(0), height_mm(0), aspect(-1.0), custom(false)
 {
     refreshRates.clear();
     QStringList slist = QStringList::split(":", str);
@@ -43,7 +56,7 @@
         height_mm = slist[3].toInt();
         aspect = slist[4].toDouble();
         for (uint i = 5; i<slist.size(); ++i)
-            refreshRates.push_back(slist[i].toShort());
+            refreshRates.push_back(slist[i].toFloat());
     }
 }
 
@@ -80,22 +93,55 @@
     return dsr;
 }
 
+//compares if the float f1 is equal with f2 and returns 1 if true and 0 if false
+bool DisplayResScreen::compare_rates(float f1, float f2)
+{
+	float precision = 0.01;
+	if (((f1 - precision) < f2) && 
+	    ((f1 + precision) > f2))
+	{
+		return true;
+	}
+	else
+	{
+		return false;
+	}
+}
+
 int DisplayResScreen::FindBestMatch(const vector<DisplayResScreen>& dsr,
                                     const DisplayResScreen& d,
                                     short& target_rate)
 {
+	float target;
+	int i = FindBestMatch(dsr, d, target);
+	target_rate = target;
+	return i;
+}
+
+int DisplayResScreen::FindBestMatch(const vector<DisplayResScreen>& dsr,
+                                    const DisplayResScreen& d,
+                                    float& target_rate)
+{
+  // Amend vector with custom list
     for (uint i=0; i<dsr.size(); ++i)
     {
         if (dsr[i].Width()==d.Width() && dsr[i].Height()==d.Height())
         {
-            const vector<short>& rates = dsr[i].RefreshRates();
-            if (rates.size())
+            const vector<float>& rates = dsr[i].RefreshRates();
+            if (rates.size() && d.RefreshRate() != 0)
             {
-                vector<short>::const_iterator it =
-                    find(rates.begin(), rates.end(), d.RefreshRate());
-                target_rate = (it == rates.end()) ? *(--rates.end()) : *it;
-                return i;
-            }
+				for (uint j=0; j < rates.size(); ++j)
+				{
+				    // Multiple of target_rate will do
+				  if (compare_rates(d.RefreshRate(),rates[j]) || (fmod(rates[j],d.RefreshRate()) <= 0.01))
+				    {
+						target_rate = rates[j];
+						return i;
+				    }
+				}
+        		target_rate = rates[rates.size() - 1];
+			}
+	    	return i;
         }
     }
     return -1;
Index: libs/libmyth/DisplayResOSX.h
===================================================================
--- libs/libmyth/DisplayResOSX.h	(revision 19990)
+++ libs/libmyth/DisplayResOSX.h	(working copy)
@@ -12,7 +12,7 @@
 
   protected:
     bool GetDisplaySize(int &width_mm, int &height_mm) const;
-    bool SwitchToVideoMode(int width, int height, short framerate);
+    bool SwitchToVideoMode(int width, int height, float framerate);
     
   private:
     mutable vector<DisplayResScreen> m_video_modes;
Index: libs/libmyth/DisplayRes.h
===================================================================
--- libs/libmyth/DisplayRes.h	(revision 19990)
+++ libs/libmyth/DisplayRes.h	(working copy)
@@ -46,7 +46,7 @@
      *  \brief Switches to the resolution and refresh rate defined in the
      *         database for the specified video resolution and frame rate.
      */
-    bool SwitchToVideo(int iwidth, int iheight, short irate = 0);
+    bool SwitchToVideo(int iwidth, int iheight, short irate = 0, float frate = 0.0);
     /** \brief Switches to the GUI resolution specified.
      *
      *   If which_gui is GUI then this switches to the resolution
@@ -110,7 +110,8 @@
     /// \brief Returns all video modes supported by the display.
     virtual const vector<DisplayResScreen>& GetVideoModes() const = 0;
     /// \brief Returns refresh rates available at a specific screen resolution.
-    const vector<short> GetRefreshRates(int width, int height) const;
+    const vector<float> GetRefreshRatesFloat(int width, int height) const;
+    const vector<short> GetRefreshRates(int width, int height) const; 
     /** @} */
 
   protected:
@@ -120,7 +121,7 @@
     
     // These methods are implemented by the subclasses
     virtual bool GetDisplaySize(int &width_mm, int &height_mm) const = 0;
-    virtual bool SwitchToVideoMode(int width, int height, short framerate) = 0;
+    virtual bool SwitchToVideoMode(int width, int height, float framerate) = 0;
 
   private:
     DisplayRes(const DisplayRes & rhs); // disable copy constructor;
Index: programs/mythfrontend/globalsettings.cpp
===================================================================
--- programs/mythfrontend/globalsettings.cpp	(revision 19990)
+++ programs/mythfrontend/globalsettings.cpp	(working copy)
@@ -2414,6 +2414,15 @@
     return gc;
 }
 
+static HostLineEdit *CustomScreenConfig()
+{
+    HostLineEdit *gedit = new HostLineEdit("CustomScreenRate");
+    gedit->setLabel(QObject::tr("Custom screen rate definition file"));
+    gedit->setHelpText(QObject::tr("Custom screen resolution configuration "
+                                        "for matching xrandr value."));
+    return gedit;
+}
+ 
 static HostSpinBox *VidModeWidth(int idx)
 {
     HostSpinBox *gs = new HostSpinBox(QString("VidModeWidth%1").arg(idx),
@@ -2582,9 +2591,16 @@
                     rate, SLOT(ChangeResolution(const QString&)));
         }
 
+        ConfigurationGroup* customscreensettings =
+            new HorizontalConfigurationGroup(false, false);
+
+        customscreensettings->addChild(CustomScreenConfig());
+
         ConfigurationGroup* settings = new VerticalConfigurationGroup(false);
+
         settings->addChild(defaultsettings);
         settings->addChild(overrides);
+        settings->addChild(customscreensettings);
 
         addTarget("1", settings);
         addTarget("0", new VerticalConfigurationGroup(true));

