Ticket #5643: adjust_rate3-fixes.patch

File adjust_rate3-fixes.patch, 80.1 KB (added by jyavenard@…, 11 years ago)

For 0.21-fixes

  • adjust_rate3.patch

    diff -Naur --exclude=.svn mythtv.opengl/adjust_rate3.patch mythtv/adjust_rate3.patch
    old new  
     1diff -Naur --exclude=.svn mythtv.opengl/libs/libmyth/DisplayRes.h mythtv/libs/libmyth/DisplayRes.h
     2--- mythtv.opengl/libs/libmyth/DisplayRes.h     2009-05-02 07:32:09.000000000 +1000
     3+++ mythtv/libs/libmyth/DisplayRes.h    2009-05-15 16:57:30.000000000 +1000
     4@@ -46,7 +46,7 @@
     5      *  \brief Switches to the resolution and refresh rate defined in the
     6      *         database for the specified video resolution and frame rate.
     7      */
     8-    bool SwitchToVideo(int iwidth, int iheight, short irate = 0);
     9+    bool SwitchToVideo(int iwidth, int iheight, short irate = 0, float frate = 0.0);
     10     /** \brief Switches to the GUI resolution specified.
     11      *
     12      *   If which_gui is GUI then this switches to the resolution
     13@@ -110,7 +110,8 @@
     14     /// \brief Returns all video modes supported by the display.
     15     virtual const vector<DisplayResScreen>& GetVideoModes() const = 0;
     16     /// \brief Returns refresh rates available at a specific screen resolution.
     17-    const vector<short> GetRefreshRates(int width, int height) const;
     18+    const vector<float> GetRefreshRatesFloat(int width, int height) const;
     19+    const vector<short> GetRefreshRates(int width, int height) const;
     20     /** @} */
     21 
     22   protected:
     23@@ -120,7 +121,7 @@
     24     
     25     // These methods are implemented by the subclasses
     26     virtual bool GetDisplaySize(int &width_mm, int &height_mm) const = 0;
     27-    virtual bool SwitchToVideoMode(int width, int height, short framerate) = 0;
     28+    virtual bool SwitchToVideoMode(int width, int height, float framerate) = 0;
     29 
     30   private:
     31     DisplayRes(const DisplayRes & rhs); // disable copy constructor;
  • adjust_rate3.patch~

    diff -Naur --exclude=.svn mythtv.opengl/adjust_rate3.patch~ mythtv/adjust_rate3.patch~
    old new  
     1diff -Naur --exclude=.svn mythtv.opengl/libs/libmyth/DisplayRes.cpp mythtv/libs/libmyth/DisplayRes.cpp
     2--- mythtv.opengl/libs/libmyth/DisplayRes.cpp   2009-05-02 07:32:08.000000000 +1000
     3+++ mythtv/libs/libmyth/DisplayRes.cpp  2009-05-16 21:10:25.000000000 +1000
     4@@ -37,16 +37,16 @@
     5     // Initialize GUI mode
     6     mode[GUI].Init();
     7     tW = tH = 0;
     8-    gContext->GetResolutionSetting("GuiVidMode", tW, tH);
     9+    gContext->GetResolutionSetting("GuiVidMode", tW, tH, tAspect, tRate);
     10     GetDisplaySize(tW_mm, tH_mm);
     11     gContext->GetResolutionSetting("DisplaySize", tW_mm, tH_mm);
     12-    mode[GUI] = DisplayResScreen(tW, tH, tW_mm, tH_mm, -1.0, 0);
     13+    mode[GUI] = DisplayResScreen(tW, tH, tW_mm, tH_mm, -1.0, (float)tRate);
     14 
     15 
     16     // Initialize default VIDEO mode
     17     tW = tH = 0;
     18     gContext->GetResolutionSetting("TVVidMode", tW, tH, tAspect, tRate);
     19-    mode[VIDEO] = DisplayResScreen(tW, tH, tW_mm, tH_mm, tAspect, tRate);
     20+    mode[VIDEO] = DisplayResScreen(tW, tH, tW_mm, tH_mm, tAspect, (float)tRate);
     21 
     22 
     23     // Initialize video override mode
     24@@ -64,7 +64,7 @@
     25             break;
     26 
     27         uint key = DisplayResScreen::CalcKey(iw, ih, irate);
     28-        DisplayResScreen scr(ow, oh, tW_mm, tH_mm, oaspect, orate);
     29+        DisplayResScreen scr(ow, oh, tW_mm, tH_mm, oaspect, (float)orate);
     30         in_size_to_output_mode[key] = scr;           
     31     }
     32 
     33@@ -82,11 +82,18 @@
     34     return true;
     35 }
     36 
     37-bool DisplayRes::SwitchToVideo(int iwidth, int iheight, short irate)
     38+bool DisplayRes::SwitchToVideo(int iwidth, int iheight, short irate, float frate)
     39 {
     40     tmode next_mode = VIDEO; // default VIDEO mode
     41     DisplayResScreen next = mode[next_mode];
     42 
     43+    // If requested refresh rate is 0, attempt to match video fps
     44+    if (next.RefreshRate() == 0)
     45+    {
     46+        VERBOSE(VB_PLAYBACK, QString("*** Trying to match best resolution %1Hz") .arg(frate));
     47+        next.AddRefreshRate(frate);
     48+    }
     49+
     50     // try to find video override mode
     51     uint key = DisplayResScreen::CalcKey(iwidth, iheight, irate);
     52     DisplayResMapCIt it = in_size_to_output_mode.find(key);
     53@@ -94,9 +101,9 @@
     54         mode[next_mode = CUSTOM_VIDEO] = next = it->second;
     55 
     56     // need to change video mode?
     57-    short target_rate = 0;
     58+    float target_rate = 0.0;
     59     DisplayResScreen::FindBestMatch(GetVideoModes(), next, target_rate);
     60-    bool chg = !(next == last) || !(last.RefreshRate() == target_rate);
     61+    bool chg = !(next == last) || !(DisplayResScreen::compare_rates(last.RefreshRate(),target_rate));
     62 
     63     VERBOSE(VB_PLAYBACK, QString("Trying %1x%2 %3 Hz")
     64             .arg(next.Width()).arg(next.Height()).arg(target_rate));
     65@@ -128,9 +135,11 @@
     66     DisplayResScreen next = mode[next_mode];
     67 
     68     // need to change video mode?
     69-    short target_rate = 0;
     70+    float target_rate = 0.0;
     71     DisplayResScreen::FindBestMatch(GetVideoModes(), next, target_rate);
     72-    bool chg = !(next == last) || !(last.RefreshRate() == target_rate);
     73+    // If GuiVidModeRefreshRate is 0, assume any refresh rate is good enough.
     74+    bool chg = (!(next == last) || (next.RefreshRate() !=0
     75+                && !(DisplayResScreen::compare_rates(last.RefreshRate(), target_rate))));
     76 
     77     VERBOSE(VB_PLAYBACK, QString("Trying %1x%2 %3 Hz")
     78             .arg(next.Width()).arg(next.Height()).arg(target_rate));
     79@@ -154,15 +163,23 @@
     80 bool DisplayRes::SwitchToCustomGUI(int width, int height, short rate)
     81 {
     82     mode[CUSTOM_GUI] = DisplayResScreen(width, height, mode[GUI].Width_mm(),
     83-                                        mode[GUI].Height_mm(), -1.0, rate);
     84+                                        mode[GUI].Height_mm(), -1.0, (float)rate);
     85     return SwitchToGUI(CUSTOM_GUI);
     86 }
     87 
     88 const vector<short> DisplayRes::GetRefreshRates(int width, int height) const {
     89-    short tr;
     90-    vector<short> empty;
     91+    vector<short> srates;
     92+    vector<float> rates = GetRefreshRatesFloat(width, height);
     93+
     94+    for (int i=0; i<rates.size(); i++)
     95+        srates.push_back((short) rates[i]);
     96+    return srates;
     97+}
     98+const vector<float> DisplayRes::GetRefreshRatesFloat(int width, int height) const {
     99+    float tr;
     100+    vector<float> empty;
     101 
     102-    const DisplayResScreen drs(width, height, 0, 0, -1.0, 0);
     103+    const DisplayResScreen drs(width, height, 0, 0, -1.0, 0.0);
     104     const DisplayResVector& drv = GetVideoModes();
     105     int t = DisplayResScreen::FindBestMatch(drv, drs, tr);
     106     if (t < 0)
     107diff -Naur --exclude=.svn mythtv.opengl/libs/libmyth/DisplayRes.h mythtv/libs/libmyth/DisplayRes.h
     108--- mythtv.opengl/libs/libmyth/DisplayRes.h     2009-05-02 07:32:09.000000000 +1000
     109+++ mythtv/libs/libmyth/DisplayRes.h    2009-05-15 16:57:30.000000000 +1000
     110@@ -46,7 +46,7 @@
     111      *  \brief Switches to the resolution and refresh rate defined in the
     112      *         database for the specified video resolution and frame rate.
     113      */
     114-    bool SwitchToVideo(int iwidth, int iheight, short irate = 0);
     115+    bool SwitchToVideo(int iwidth, int iheight, short irate = 0, float frate = 0.0);
     116     /** \brief Switches to the GUI resolution specified.
     117      *
     118      *   If which_gui is GUI then this switches to the resolution
     119@@ -110,7 +110,8 @@
     120     /// \brief Returns all video modes supported by the display.
     121     virtual const vector<DisplayResScreen>& GetVideoModes() const = 0;
     122     /// \brief Returns refresh rates available at a specific screen resolution.
     123-    const vector<short> GetRefreshRates(int width, int height) const;
     124+    const vector<float> GetRefreshRatesFloat(int width, int height) const;
     125+    const vector<short> GetRefreshRates(int width, int height) const;
     126     /** @} */
     127 
     128   protected:
     129@@ -120,7 +121,7 @@
     130     
     131     // These methods are implemented by the subclasses
     132     virtual bool GetDisplaySize(int &width_mm, int &height_mm) const = 0;
     133-    virtual bool SwitchToVideoMode(int width, int height, short framerate) = 0;
     134+    virtual bool SwitchToVideoMode(int width, int height, float framerate) = 0;
     135 
     136   private:
     137     DisplayRes(const DisplayRes & rhs); // disable copy constructor;
     138diff -Naur --exclude=.svn mythtv.opengl/libs/libmyth/DisplayResOSX.cpp mythtv/libs/libmyth/DisplayResOSX.cpp
     139--- mythtv.opengl/libs/libmyth/DisplayResOSX.cpp        2009-05-02 07:32:08.000000000 +1000
     140+++ mythtv/libs/libmyth/DisplayResOSX.cpp       2009-05-15 16:57:30.000000000 +1000
     141@@ -66,7 +66,7 @@
     142     return d;
     143 }
     144 
     145-bool DisplayResOSX::SwitchToVideoMode(int width, int height, short refreshrate)
     146+bool DisplayResOSX::SwitchToVideoMode(int width, int height, float refreshrate)
     147 {
     148     CGDirectDisplayID d = mythtv_display();
     149     CFDictionaryRef dispMode = NULL;
     150@@ -75,7 +75,7 @@
     151     // find mode that matches the desired size
     152     if (refreshrate)
     153         dispMode = CGDisplayBestModeForParametersAndRefreshRate(
     154-            d, 32, width, height, (CGRefreshRate)(refreshrate), &match);
     155+            d, 32, width, height, (CGRefreshRate)((short)refreshrate), &match);
     156 
     157     if (!match)
     158         dispMode =
     159@@ -122,7 +122,7 @@
     160 
     161        if (screen_map.find(key)==screen_map.end())
     162             screen_map[key] = DisplayResScreen(width, height,
     163-                                               0, 0, -1.0, refresh);
     164+                                               0, 0, -1.0, (float) refresh);
     165         else
     166             screen_map[key].AddRefreshRate(refresh);
     167     }
     168diff -Naur --exclude=.svn mythtv.opengl/libs/libmyth/DisplayResOSX.h mythtv/libs/libmyth/DisplayResOSX.h
     169--- mythtv.opengl/libs/libmyth/DisplayResOSX.h  2009-05-02 07:32:08.000000000 +1000
     170+++ mythtv/libs/libmyth/DisplayResOSX.h 2009-05-15 16:57:30.000000000 +1000
     171@@ -12,7 +12,7 @@
     172 
     173   protected:
     174     bool GetDisplaySize(int &width_mm, int &height_mm) const;
     175-    bool SwitchToVideoMode(int width, int height, short framerate);
     176+    bool SwitchToVideoMode(int width, int height, float framerate);
     177     
     178   private:
     179     mutable vector<DisplayResScreen> m_video_modes;
     180diff -Naur --exclude=.svn mythtv.opengl/libs/libmyth/DisplayResScreen.cpp mythtv/libs/libmyth/DisplayResScreen.cpp
     181--- mythtv.opengl/libs/libmyth/DisplayResScreen.cpp     2009-05-02 07:32:08.000000000 +1000
     182+++ mythtv/libs/libmyth/DisplayResScreen.cpp    2009-05-15 16:57:30.000000000 +1000
     183@@ -1,9 +1,11 @@
     184 #include "DisplayResScreen.h"
     185 #include "mythcontext.h"
     186 
     187+#include <cmath>
     188+
     189 DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh,
     190-                                   double aspectRatio, short refreshRate)
     191-    : width(w), height(h), width_mm(mw), height_mm(mh)
     192+                                   double aspectRatio, float refreshRate)
     193+    : width(w), height(h), width_mm(mw), height_mm(mh), custom(false)
     194 {
     195     SetAspectRatio(aspectRatio);
     196     if (refreshRate > 0)
     197@@ -11,15 +13,15 @@
     198 }
     199 
     200 DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh,
     201-                                   const vector<short>& rr)
     202-    : width(w), height(h), width_mm(mw), height_mm(mh), refreshRates(rr)
     203+                                   const vector<float>& rr)
     204+    : width(w), height(h), width_mm(mw), height_mm(mh), refreshRates(rr), custom(false)
     205 {
     206     SetAspectRatio(-1.0);
     207 }
     208 
     209 DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh,
     210-                                   const short* rr, uint rr_length)
     211-    : width(w), height(h), width_mm(mw), height_mm(mh)
     212+                                   const float* rr, uint rr_length)
     213+    : width(w), height(h), width_mm(mw), height_mm(mh), custom(false)
     214 {
     215     SetAspectRatio(-1.0);
     216     for (uint i = 0; i < rr_length; ++i)
     217@@ -28,8 +30,19 @@
     218     sort(refreshRates.begin(), refreshRates.end());
     219 }
     220 
     221+DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh,
     222+                                   const short* rr, uint rr_length)
     223+    : width(w), height(h), width_mm(mw), height_mm(mh), custom(false)
     224+{
     225+    SetAspectRatio(-1.0);
     226+    for (uint i = 0; i < rr_length; ++i)
     227+        refreshRates.push_back((float)rr[i]);
     228+
     229+    sort(refreshRates.begin(), refreshRates.end());
     230+}
     231+
     232 DisplayResScreen::DisplayResScreen(const QString &str)
     233-    : width(0), height(0), width_mm(0), height_mm(0), aspect(-1.0)
     234+    : width(0), height(0), width_mm(0), height_mm(0), aspect(-1.0), custom(false)
     235 {
     236     refreshRates.clear();
     237     QStringList slist = QStringList::split(":", str);
     238@@ -43,7 +56,7 @@
     239         height_mm = slist[3].toInt();
     240         aspect = slist[4].toDouble();
     241         for (uint i = 5; i<slist.size(); ++i)
     242-            refreshRates.push_back(slist[i].toShort());
     243+            refreshRates.push_back(slist[i].toFloat());
     244     }
     245 }
     246 
     247@@ -80,22 +93,66 @@
     248     return dsr;
     249 }
     250 
     251+//compares if the float f1 is equal with f2 and returns 1 if true and 0 if false
     252+bool DisplayResScreen::compare_rates(float f1, float f2)
     253+{
     254+       float precision = 0.01;
     255+       if (((f1 - precision) < f2) &&
     256+           ((f1 + precision) > f2))
     257+       {
     258+               return true;
     259+       }
     260+       else
     261+       {
     262+               return false;
     263+       }
     264+}
     265+
     266 int DisplayResScreen::FindBestMatch(const vector<DisplayResScreen>& dsr,
     267                                     const DisplayResScreen& d,
     268                                     short& target_rate)
     269 {
     270+       float target;
     271+       int i = FindBestMatch(dsr, d, target);
     272+       target_rate = target;
     273+       return i;
     274+}
     275+
     276+int DisplayResScreen::FindBestMatch(const vector<DisplayResScreen>& dsr,
     277+                                    const DisplayResScreen& d,
     278+                                    float& target_rate)
     279+{
     280+  // Amend vector with custom list
     281     for (uint i=0; i<dsr.size(); ++i)
     282     {
     283         if (dsr[i].Width()==d.Width() && dsr[i].Height()==d.Height())
     284         {
     285-            const vector<short>& rates = dsr[i].RefreshRates();
     286-            if (rates.size())
     287+            const vector<float>& rates = dsr[i].RefreshRates();
     288+            if (rates.size() && d.RefreshRate() != 0)
     289             {
     290-                vector<short>::const_iterator it =
     291-                    find(rates.begin(), rates.end(), d.RefreshRate());
     292-                target_rate = (it == rates.end()) ? *(--rates.end()) : *it;
     293-                return i;
     294-            }
     295+             for (uint j=0; j < rates.size(); ++j)
     296+               {
     297+                 // Multiple of target_rate will do
     298+                 if (compare_rates(d.RefreshRate(),rates[j]) || (fmod(rates[j],d.RefreshRate()) <= 0.01))
     299+                   {
     300+                     target_rate = rates[j];
     301+                     return i;
     302+                   }
     303+               }
     304+             // Can't find exact frame rate, so try rounding to the nearest integer, so 23.97Hz will work with 24Hz etc
     305+             for (uint j=0; j < rates.size(); ++j)
     306+               {
     307+                 float rounded = (float) ((int) (rates[j] + 0.5));
     308+                 // Multiple of target_rate will do
     309+                 if (compare_rates(d.RefreshRate(),rounded) || (fmod(rounded,d.RefreshRate()) <= 0.01))
     310+                   {
     311+                     target_rate = rounded;
     312+                     return i;
     313+                   }
     314+               }
     315+             target_rate = rates[rates.size() - 1];
     316+           }
     317+           return i;
     318         }
     319     }
     320     return -1;
     321diff -Naur --exclude=.svn mythtv.opengl/libs/libmyth/DisplayResScreen.h mythtv/libs/libmyth/DisplayResScreen.h
     322--- mythtv.opengl/libs/libmyth/DisplayResScreen.h       2009-05-02 07:32:08.000000000 +1000
     323+++ mythtv/libs/libmyth/DisplayResScreen.h      2009-05-16 18:29:21.000000000 +1000
     324@@ -14,11 +14,13 @@
     325   public:
     326     // Constructors, initializers
     327     DisplayResScreen()
     328-        : width(0), height(0), width_mm(0), height_mm(0), aspect(-1.0) {;}
     329+        : width(0), height(0), width_mm(0), height_mm(0), aspect(-1.0), custom(false) {;}
     330     DisplayResScreen(int w, int h, int mw, int mh,
     331-                     double aspectRatio/* = -1.0*/, short refreshRate/* = 0*/);
     332+                     double aspectRatio/* = -1.0*/, float refreshRate/* = 0*/);
     333     DisplayResScreen(int w, int h, int mw, int mh,
     334-                     const vector<short>& refreshRates);
     335+                     const vector<float>& refreshRates);
     336+    DisplayResScreen(int w, int h, int mw, int mh,
     337+                     const float* refreshRates, uint rr_length);
     338     DisplayResScreen(int w, int h, int mw, int mh,
     339                      const short* refreshRates, uint rr_length);
     340     DisplayResScreen(const QString &str);
     341@@ -29,17 +31,28 @@
     342     int Height() const { return height; }
     343     int Width_mm() const { return width_mm; }
     344     int Height_mm() const { return height_mm; }
     345+    bool Custom() const { return custom; }
     346+
     347     inline double AspectRatio() const;
     348-    inline short RefreshRate() const;
     349-    const vector<short>& RefreshRates() const { return refreshRates; }
     350+    inline float RefreshRate() const;
     351+    const vector<float>& RefreshRates() const { return refreshRates; }
     352 
     353     // Sets, adds
     354     void SetAspectRatio(double a);
     355-    void AddRefreshRate(short rr) {
     356+    void AddRefreshRate(float rr) {
     357         refreshRates.push_back(rr);
     358         sort(refreshRates.begin(), refreshRates.end());
     359     }
     360-
     361+    void ClearRefreshRates(void) {
     362+       refreshRates.clear();
     363+    } 
     364+    void SetCustom(bool b) {
     365+       custom = b;
     366+    }
     367+       
     368+       // Map for matching real rates and xrandr rate;
     369+       map<float, short> realRates;
     370+       
     371     // Converters & comparitors
     372     QString toString() const;
     373     inline bool operator < (const DisplayResScreen& b) const;
     374@@ -50,16 +63,22 @@
     375     static vector<DisplayResScreen> Convert(const QStringList& slist);
     376     static int FindBestMatch(const vector<DisplayResScreen>& dsr,
     377                              const DisplayResScreen& d,
     378+                             float& target_rate);
     379+    static int FindBestMatch(const vector<DisplayResScreen>& dsr,
     380+                             const DisplayResScreen& d,
     381                              short& target_rate);
     382     static inline int CalcKey(int w, int h, int rate);
     383+    static bool compare_rates(float f1, float f2);
     384 
     385   private:
     386     int width, height; // size in pixels
     387     int width_mm, height_mm; // physical size in millimeters
     388     double aspect; // aspect ratio, calculated or set
     389-    vector<short> refreshRates;
     390+    vector<float> refreshRates;
     391+    bool custom;       // Set if resolution was defined manually
     392 };
     393 
     394+
     395 typedef vector<DisplayResScreen>          DisplayResVector;
     396 typedef DisplayResVector::iterator        DisplayResVectorIt;
     397 typedef DisplayResVector::const_iterator  DisplayResVectorCIt;
     398@@ -85,11 +104,11 @@
     399     return aspect;
     400 }
     401 
     402-inline short DisplayResScreen::RefreshRate() const
     403+inline float DisplayResScreen::RefreshRate() const
     404 {
     405     if (refreshRates.size() >= 1)
     406         return refreshRates[0];
     407-    else return 0;
     408+    else return 0.0;
     409 }
     410 
     411 inline bool DisplayResScreen::operator < (const DisplayResScreen& b) const
     412diff -Naur --exclude=.svn mythtv.opengl/libs/libmyth/DisplayResX.cpp mythtv/libs/libmyth/DisplayResX.cpp
     413--- mythtv.opengl/libs/libmyth/DisplayResX.cpp  2009-05-02 07:32:08.000000000 +1000
     414+++ mythtv/libs/libmyth/DisplayResX.cpp 2009-05-16 18:44:28.000000000 +1000
     415@@ -4,6 +4,11 @@
     416 #include <cstring>
     417 #include <cstdlib>
     418 
     419+#include "mythcontext.h"
     420+#include <qregexp.h>
     421+#include <qfile.h>
     422+#include <qfileinfo.h>
     423+
     424 #include "util-x11.h"
     425 
     426 #include <X11/extensions/Xrandr.h> // this has to be after util-x11.h (Qt bug)
     427@@ -32,9 +37,11 @@
     428     return false;
     429 }
     430 
     431-bool DisplayResX::SwitchToVideoMode(int width, int height, short desired_rate)
     432+bool DisplayResX::SwitchToVideoMode(int width, int height, float desired_rate)
     433 {
     434-    short rate;
     435+    float rate;
     436+    short finalrate;
     437+
     438     DisplayResScreen desired_screen(width, height, 0, 0, -1.0, desired_rate);
     439     int idx = DisplayResScreen::FindBestMatch(m_video_modes_unsorted,
     440                                               desired_screen, rate);
     441@@ -49,9 +56,23 @@
     442         Rotation rot;
     443         XRRConfigCurrentConfiguration(cfg, &rot);
     444         
     445+        // Search real xrandr rate for desired_rate
     446+        finalrate = (short) rate;
     447+        for (int i=0; i < m_video_modes.size(); i++) {
     448+            if ((m_video_modes[i].Width() == width) && (m_video_modes[i].Height() == height))
     449+            {
     450+                if (m_video_modes[i].Custom())
     451+                {
     452+                    finalrate = m_video_modes[i].realRates[rate];
     453+                    VERBOSE(VB_PLAYBACK, QString("CustomRate Found, set %1Hz as %2") .arg(rate) .arg(finalrate));
     454+                }
     455+                break;
     456+            }
     457+        }
     458+             
     459         Window root = DefaultRootWindow(display);
     460         Status status = XRRSetScreenConfigAndRate(display, cfg, root, idx,
     461-                                                  rot, rate, CurrentTime);
     462+                                                  rot, finalrate, CurrentTime);
     463         
     464         XRRFreeScreenConfigInfo(cfg);
     465         XCloseDisplay(display);
     466@@ -87,6 +108,60 @@
     467                              rates, num_rates);
     468         m_video_modes.push_back(scr);
     469     }
     470+
     471+    QString customscreen = gContext->GetSetting("CustomScreenRate");
     472+    if (gContext->GetNumSetting("UseVideoModes", 0) && !customscreen.size());
     473+    {
     474+        QFileInfo fi(customscreen);
     475+        QFile file(customscreen);
     476+       
     477+        if (!fi.exists() || !fi.isFile())
     478+        {
     479+            VERBOSE(VB_PLAYBACK, QString("CustomScreenRate: \"%1\" failed: does not exist or isn't a file")
     480+                    .arg(customscreen));
     481+        }
     482+        else if ( file.open( IO_ReadOnly ) ) {
     483+            QRegExp regexp = QRegExp("^\\s*(\\d+),(\\d+),(\\d+\\.?\\d*),(\\d+)\\s*$");
     484+            QTextStream stream( &file );
     485+            QString line;
     486+            int pos;
     487+            while ( !stream.atEnd() ) {
     488+                pos = regexp.search(stream.readLine());
     489+                if (pos > -1) {
     490+                    int w = regexp.cap(1).toInt();
     491+                    int h = regexp.cap(2).toInt();
     492+                    float hz = regexp.cap(3).toFloat();
     493+                    int xrandrhz = regexp.cap(4).toShort();
     494+                    int found = -1;
     495+                    VERBOSE(VB_PLAYBACK, QString("Found definition for %1x%2 @ %3Hz (xrandr: %4)")
     496+                            .arg(w) .arg(h) .arg(hz) .arg(xrandrhz));
     497+                    // find if video mode already exist, and remove refresh rates for custom one
     498+                    for (int i=0; i < m_video_modes.size(); i++) {
     499+                        if ((m_video_modes[i].Width() == w) && (m_video_modes[i].Height() == h))
     500+                        {
     501+                            found = i;
     502+                            if (!m_video_modes[i].Custom())
     503+                            {
     504+                                m_video_modes[i].ClearRefreshRates();
     505+                                m_video_modes[i].SetCustom(true);
     506+                            }
     507+                            m_video_modes[i].AddRefreshRate(hz);
     508+                            m_video_modes[i].realRates[hz] = xrandrhz;
     509+                            break;
     510+                        }
     511+                    }
     512+                    if (found < 0)
     513+                    {
     514+                        DisplayResScreen scr(w, h, 0, 0, -1.0, hz);
     515+                        scr.SetCustom(true);
     516+                        m_video_modes.push_back(scr);
     517+                    }
     518+                }
     519+            }
     520+            file.close();
     521+        }
     522+    }
     523+
     524     m_video_modes_unsorted = m_video_modes;
     525     sort(m_video_modes.begin(), m_video_modes.end());
     526 
     527diff -Naur --exclude=.svn mythtv.opengl/libs/libmyth/DisplayResX.h mythtv/libs/libmyth/DisplayResX.h
     528--- mythtv.opengl/libs/libmyth/DisplayResX.h    2009-05-02 07:32:08.000000000 +1000
     529+++ mythtv/libs/libmyth/DisplayResX.h   2009-05-15 16:57:30.000000000 +1000
     530@@ -12,7 +12,7 @@
     531 
     532   protected:
     533     bool GetDisplaySize(int &width_mm, int &height_mm) const;
     534-    bool SwitchToVideoMode(int width, int height, short framerate);
     535+    bool SwitchToVideoMode(int width, int height, float framerate);
     536 
     537   private:
     538     mutable vector<DisplayResScreen> m_video_modes;
     539diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/NuppelVideoPlayer.cpp mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
     540--- mythtv.opengl/libs/libmythtv/NuppelVideoPlayer.cpp  2009-05-15 16:58:34.000000000 +1000
     541+++ mythtv/libs/libmythtv/NuppelVideoPlayer.cpp 2009-05-16 19:13:30.000000000 +1000
     542@@ -635,7 +635,8 @@
     543             GetDecoder()->GetVideoCodecID(),
     544             GetDecoder()->GetVideoCodecPrivate(),
     545             video_disp_dim, video_aspect,
     546-            widget->winId(), display_rect, 0 /*embedid*/);
     547+            widget->winId(), display_rect, (video_frame_rate * play_speed),
     548+            0 /*embedid*/);
     549 
     550         if (!videoOutput)
     551         {
     552diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_d3d.cpp mythtv/libs/libmythtv/videoout_d3d.cpp
     553--- mythtv.opengl/libs/libmythtv/videoout_d3d.cpp       2009-05-02 07:30:34.000000000 +1000
     554+++ mythtv/libs/libmythtv/videoout_d3d.cpp      2009-05-16 19:16:43.000000000 +1000
     555@@ -451,7 +451,7 @@
     556 
     557 bool VideoOutputD3D::Init(int width, int height, float aspect,
     558                           WId winid, int winx, int winy, int winw,
     559-                          int winh, WId embedid)
     560+                          int winh, float video_prate, WId embedid)
     561 {
     562     VERBOSE(VB_PLAYBACK, LOC +
     563             "Init w=" << width << " h=" << height);
     564@@ -462,8 +462,8 @@
     565                   kPrebufferFramesNormal, kPrebufferFramesSmall,
     566                   kKeepPrebuffer);
     567 
     568-    VideoOutput::Init(width, height, aspect, winid,
     569-                      winx, winy, winw, winh, embedid);
     570+    VideoOutput::Init(width, height, aspect, winid, winx,
     571+                      winy, winw, winh, video_prate, embedid);
     572 
     573     m_hWnd = winid;
     574 
     575diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_d3d.h mythtv/libs/libmythtv/videoout_d3d.h
     576--- mythtv.opengl/libs/libmythtv/videoout_d3d.h 2009-05-02 07:30:34.000000000 +1000
     577+++ mythtv/libs/libmythtv/videoout_d3d.h        2009-05-16 19:17:02.000000000 +1000
     578@@ -20,7 +20,8 @@
     579    ~VideoOutputD3D();
     580 
     581     bool Init(int width, int height, float aspect, WId winid,
     582-              int winx, int winy, int winw, int winh, WId embedid = 0);
     583+              int winx, int winy, int winw, int winh,
     584+              float video_prate, WId embedid = 0);
     585 
     586     bool InitD3D();
     587     void UnInitD3D();
     588diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_directfb.cpp mythtv/libs/libmythtv/videoout_directfb.cpp
     589--- mythtv.opengl/libs/libmythtv/videoout_directfb.cpp  2009-05-02 07:30:34.000000000 +1000
     590+++ mythtv/libs/libmythtv/videoout_directfb.cpp 2009-05-15 16:57:30.000000000 +1000
     591@@ -353,7 +353,7 @@
     592 
     593 bool VideoOutputDirectfb::Init(int width, int height, float aspect, WId winid,
     594                                int winx, int winy, int winw, int winh,
     595-                               WId embedid)
     596+                               float video_prate, WId embedid)
     597 {
     598     // Hack to avoid embedded video output...
     599     if ((winw < 320) || (winh < 240))
     600@@ -646,7 +646,7 @@
     601                            display_visible_rect.y(),
     602                            display_visible_rect.width(),
     603                            display_visible_rect.height(),
     604-                           embedid))
     605+                           video_prate, embedid))
     606     {
     607         return false;
     608     }
     609diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_directfb.h mythtv/libs/libmythtv/videoout_directfb.h
     610--- mythtv.opengl/libs/libmythtv/videoout_directfb.h    2009-05-02 07:30:35.000000000 +1000
     611+++ mythtv/libs/libmythtv/videoout_directfb.h   2009-05-16 20:21:24.000000000 +1000
     612@@ -14,7 +14,8 @@
     613     ~VideoOutputDirectfb();
     614 
     615     bool Init(int width, int height, float aspect, WId winid,
     616-              int winx, int winy, int winw, int winh, WId embedid = 0);
     617+              int winx, int winy, int winw, int winh,
     618+              float video_prate, WId embedid = 0);
     619 
     620     void ProcessFrame(VideoFrame *frame, OSD *osd,
     621                       FilterChain *filterList,
     622diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_dx.cpp mythtv/libs/libmythtv/videoout_dx.cpp
     623--- mythtv.opengl/libs/libmythtv/videoout_dx.cpp        2009-05-02 07:30:36.000000000 +1000
     624+++ mythtv/libs/libmythtv/videoout_dx.cpp       2009-05-16 20:56:37.000000000 +1000
     625@@ -158,16 +158,16 @@
     626 }
     627 
     628 bool VideoOutputDX::Init(int width, int height, float aspect,
     629-                           WId winid, int winx, int winy, int winw,
     630-                           int winh, WId embedid)
     631+                         WId winid, int winx, int winy, int winw,
     632+                         int winh, float video_prate, WId embedid)
     633 {
     634     db_vdisp_profile->SetVideoRenderer("directx");
     635 
     636     vbuffers.Init(kNumBuffers, true, kNeedFreeFrames,
     637                   kPrebufferFramesNormal, kPrebufferFramesSmall,
     638                   kKeepPrebuffer);
     639-    VideoOutput::Init(width, height, aspect, winid,
     640-                      winx, winy, winw, winh, embedid);
     641+    VideoOutput::Init(width, height, aspect, winid, winx,
     642+                      winy, winw, winh, video_prate, embedid);
     643 
     644     wnd = winid;
     645 
     646diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_dx.h mythtv/libs/libmythtv/videoout_dx.h
     647--- mythtv.opengl/libs/libmythtv/videoout_dx.h  2009-05-02 07:30:34.000000000 +1000
     648+++ mythtv/libs/libmythtv/videoout_dx.h 2009-05-16 20:38:14.000000000 +1000
     649@@ -21,7 +21,8 @@
     650    ~VideoOutputDX();
     651 
     652     bool Init(int width, int height, float aspect, WId winid,
     653-              int winx, int winy, int winw, int winh, WId embedid = 0);
     654+              int winx, int winy, int winw, int winh,
     655+              float video_prate, WId embedid = 0);
     656     void PrepareFrame(VideoFrame *buffer, FrameScanType);
     657     void Show(FrameScanType );
     658 
     659diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_ivtv.cpp mythtv/libs/libmythtv/videoout_ivtv.cpp
     660--- mythtv.opengl/libs/libmythtv/videoout_ivtv.cpp      2009-05-02 07:30:35.000000000 +1000
     661+++ mythtv/libs/libmythtv/videoout_ivtv.cpp     2009-05-15 16:57:30.000000000 +1000
     662@@ -405,7 +405,7 @@
     663 
     664 bool VideoOutputIvtv::Init(int width, int height, float aspect,
     665                            WId winid, int winx, int winy, int winw,
     666-                           int winh, WId embedid)
     667+                           int winh, float video_prate, WId embedid)
     668 {
     669     VERBOSE(VB_PLAYBACK, LOC + "Init() -- begin");
     670 
     671@@ -416,7 +416,7 @@
     672     videoDevice = gContext->GetSetting("PVR350VideoDev");
     673 
     674     VideoOutput::Init(width, height, aspect, winid, winx, winy, winw, winh,
     675-                      embedid);
     676+                      video_prate, embedid);
     677 
     678     osdbufsize = video_dim.width() * video_dim.height() * 4;
     679 
     680diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_ivtv.h mythtv/libs/libmythtv/videoout_ivtv.h
     681--- mythtv.opengl/libs/libmythtv/videoout_ivtv.h        2009-05-02 07:30:34.000000000 +1000
     682+++ mythtv/libs/libmythtv/videoout_ivtv.h       2009-05-16 20:24:09.000000000 +1000
     683@@ -16,7 +16,8 @@
     684    ~VideoOutputIvtv();
     685 
     686     bool Init(int width, int height, float aspect, WId winid,
     687-              int winx, int winy, int winw, int winh, WId embedid = 0);
     688+              int winx, int winy, int winw, int winh,
     689+              float video_prate, WId embedid = 0);
     690     void PrepareFrame(VideoFrame *buffer, FrameScanType);
     691     void Show(FrameScanType );
     692 
     693diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_null.cpp mythtv/libs/libmythtv/videoout_null.cpp
     694--- mythtv.opengl/libs/libmythtv/videoout_null.cpp      2009-05-02 07:30:35.000000000 +1000
     695+++ mythtv/libs/libmythtv/videoout_null.cpp     2009-05-16 20:25:07.000000000 +1000
     696@@ -115,15 +115,15 @@
     697 
     698 bool VideoOutputNull::Init(int width, int height, float aspect,
     699                            WId winid, int winx, int winy, int winw,
     700-                           int winh, WId embedid)
     701+                           int winh, float video_prate, WId embedid)
     702 {
     703     if ((width <= 0) || (height <= 0))
     704         return false;
     705 
     706     QMutexLocker locker(&global_lock);
     707 
     708-    VideoOutput::Init(width, height, aspect, winid,
     709-                      winx, winy, winw, winh, embedid);
     710+    VideoOutput::Init(width, height, aspect, winid, winx,
     711+                      winy, winw, winh, video_prate, embedid);
     712 
     713     vbuffers.Init(kNumBuffers, true, kNeedFreeFrames,
     714                   kPrebufferFramesNormal, kPrebufferFramesSmall,
     715diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_null.h mythtv/libs/libmythtv/videoout_null.h
     716--- mythtv.opengl/libs/libmythtv/videoout_null.h        2009-05-02 07:30:36.000000000 +1000
     717+++ mythtv/libs/libmythtv/videoout_null.h       2009-05-16 20:25:34.000000000 +1000
     718@@ -12,7 +12,8 @@
     719    ~VideoOutputNull();
     720 
     721     bool Init(int width, int height, float aspect, WId winid,
     722-              int winx, int winy, int winw, int winh, WId embedid = 0);
     723+              int winx, int winy, int winw, int winh,
     724+              float video_prate, WId embedid = 0);
     725 
     726     bool SetupDeinterlace(bool, const QString &ovrf = "")
     727         { (void)ovrf; return false; } // we don't deinterlace in null output..
     728diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_quartz.cpp mythtv/libs/libmythtv/videoout_quartz.cpp
     729--- mythtv.opengl/libs/libmythtv/videoout_quartz.cpp    2009-05-02 07:30:34.000000000 +1000
     730+++ mythtv/libs/libmythtv/videoout_quartz.cpp   2009-05-16 20:27:22.000000000 +1000
     731@@ -1192,8 +1192,8 @@
     732 }
     733 
     734 bool VideoOutputQuartz::Init(int width, int height, float aspect,
     735-                             WId winid, int winx, int winy,
     736-                             int winw, int winh, WId embedid)
     737+                             WId winid, int winx, int winy, int winw,
     738+                             int winh, float video_prate, WId embedid)
     739 {
     740     VERBOSE(VB_PLAYBACK, LOC +
     741             QString("Init(WxH %1x%2, aspect=%3, winid=%4\n\t\t\t"
     742@@ -1215,8 +1215,8 @@
     743     vbuffers.Init(kNumBuffers, true, kNeedFreeFrames,
     744                   kPrebufferFramesNormal, kPrebufferFramesSmall,
     745                   kKeepPrebuffer);
     746-    VideoOutput::Init(width, height, aspect, winid,
     747-                      winx, winy, winw, winh, embedid);
     748+    VideoOutput::Init(width, height, aspect, winid, winx,
     749+                      winy, winw, winh, video_prate, embedid);
     750 
     751     data->srcWidth  = video_dim.width();
     752     data->srcHeight = video_dim.height();
     753@@ -1381,6 +1381,7 @@
     754 
     755 void VideoOutputQuartz::SetVideoFrameRate(float playback_fps)
     756 {
     757+    video_prate = playback_fps;
     758     VERBOSE(VB_PLAYBACK, "SetVideoFrameRate("<<playback_fps<<")");
     759 }
     760 
     761diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_quartz.h mythtv/libs/libmythtv/videoout_quartz.h
     762--- mythtv.opengl/libs/libmythtv/videoout_quartz.h      2009-05-02 07:30:36.000000000 +1000
     763+++ mythtv/libs/libmythtv/videoout_quartz.h     2009-05-16 20:27:58.000000000 +1000
     764@@ -13,7 +13,8 @@
     765    ~VideoOutputQuartz();
     766 
     767     bool Init(int width, int height, float aspect, WId winid,
     768-              int winx, int winy, int winw, int winh, WId embedid = 0);
     769+              int winx, int winy, int winw, int winh,
     770+              float video_prate, WId embedid = 0);
     771     void SetVideoFrameRate(float playback_fps);
     772     void PrepareFrame(VideoFrame *buffer, FrameScanType t);
     773     void Show(FrameScanType);
     774diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_xv.cpp mythtv/libs/libmythtv/videoout_xv.cpp
     775--- mythtv.opengl/libs/libmythtv/videoout_xv.cpp        2009-05-15 16:58:35.000000000 +1000
     776+++ mythtv/libs/libmythtv/videoout_xv.cpp       2009-05-16 20:48:13.000000000 +1000
     777@@ -450,7 +450,9 @@
     778     if ((width == 1920 || width == 1440) && height == 1088)
     779         height = 1080; // ATSC 1920x1080
     780 
     781-    if (display_res && display_res->SwitchToVideo(width, height))
     782+    if (display_res && display_res->SwitchToVideo(width, height,
     783+                                                  (short) roundf(video_prate),
     784+                                                  video_prate))
     785     {
     786         // Switching to custom display resolution succeeded
     787         // Make a note of the new size
     788@@ -1698,14 +1700,14 @@
     789 }
     790 
     791 /**
     792- * \fn VideoOutputXv::Init(int,int,float,WId,int,int,int,int,WId)
     793+ * \fn VideoOutputXv::Init(int,int,float,WId,int,int,int,int,float,WId)
     794  * Initializes class for video output.
     795  *
     796  * \return success or failure.
     797  */
     798 bool VideoOutputXv::Init(
     799-    int width, int height, float aspect,
     800-    WId winid, int winx, int winy, int winw, int winh, WId embedid)
     801+    int width, int height, float aspect, WId winid, int winx,
     802+    int winy, int winw, int winh, float video_prate, WId embedid)
     803 {
     804     needrepaint = true;
     805 
     806@@ -1739,7 +1741,7 @@
     807     // Basic setup
     808     VideoOutput::Init(width, height, aspect,
     809                       winid, winx, winy, winw, winh,
     810-                      embedid);
     811+                      video_prate, embedid);
     812 
     813     // Set resolution/measurements (check XRandR, Xinerama, config settings)
     814     InitDisplayMeasurements(width, height);
     815diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_xv.h mythtv/libs/libmythtv/videoout_xv.h
     816--- mythtv.opengl/libs/libmythtv/videoout_xv.h  2009-05-15 16:58:35.000000000 +1000
     817+++ mythtv/libs/libmythtv/videoout_xv.h 2009-05-16 20:29:46.000000000 +1000
     818@@ -62,7 +62,8 @@
     819    ~VideoOutputXv();
     820 
     821     bool Init(int width, int height, float aspect, WId winid,
     822-              int winx, int winy, int winw, int winh, WId embedid = 0);
     823+              int winx, int winy, int winw, int winh,
     824+              float video_prate, WId embedid = 0);
     825 
     826     bool SetDeinterlacingEnabled(bool);
     827     bool SetupDeinterlace(bool interlaced, const QString& ovrf="");
     828diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videooutbase.cpp mythtv/libs/libmythtv/videooutbase.cpp
     829--- mythtv.opengl/libs/libmythtv/videooutbase.cpp       2009-05-15 16:58:35.000000000 +1000
     830+++ mythtv/libs/libmythtv/videooutbase.cpp      2009-05-16 20:53:44.000000000 +1000
     831@@ -71,7 +71,7 @@
     832         void          *codec_priv,
     833         const QSize   &video_dim, float        video_aspect,
     834         WId            win_id,    const QRect &display_rect,
     835-        WId            embed_id)
     836+        float          video_prate,     WId     embed_id)
     837 {
     838     (void) codec_priv;
     839 
     840@@ -170,10 +170,12 @@
     841 
     842         if (vo)
     843         {
     844+            vo->video_prate = video_prate;
     845             if (vo->Init(
     846                     video_dim.width(), video_dim.height(), video_aspect,
     847                     win_id, display_rect.x(), display_rect.y(),
     848-                    display_rect.width(), display_rect.height(), embed_id))
     849+                    display_rect.width(), display_rect.height(),
     850+                    video_prate, embed_id))
     851             {
     852                 return vo;
     853             }
     854@@ -367,7 +369,8 @@
     855  * \return true if successful, false otherwise.
     856  */
     857 bool VideoOutput::Init(int width, int height, float aspect, WId winid,
     858-                       int winx, int winy, int winw, int winh, WId embedid)
     859+                       int winx, int winy, int winw, int winh,
     860+                       float video_prate, WId embedid)
     861 {
     862     (void)winid;
     863     (void)embedid;
     864@@ -409,6 +412,7 @@
     865 
     866 void VideoOutput::SetVideoFrameRate(float playback_fps)
     867 {
     868+    video_prate = playback_fps;
     869     db_vdisp_profile->SetOutput(playback_fps);
     870 }
     871 
     872diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videooutbase.h mythtv/libs/libmythtv/videooutbase.h
     873--- mythtv.opengl/libs/libmythtv/videooutbase.h 2009-05-15 16:58:35.000000000 +1000
     874+++ mythtv/libs/libmythtv/videooutbase.h        2009-05-16 20:49:57.000000000 +1000
     875@@ -36,14 +36,14 @@
     876         void          *codec_priv,
     877         const QSize   &video_dim, float        video_aspect,
     878         WId            win_id,    const QRect &display_rect,
     879-        WId            embed_id);
     880+        float video_prate,        WId          embed_id);
     881 
     882     VideoOutput();
     883     virtual ~VideoOutput();
     884 
     885     virtual bool Init(int width, int height, float aspect,
     886                       WId winid, int winx, int winy, int winw,
     887-                      int winh, WId embedid = 0);
     888+                      int winh, float video_prate, WId embedid = 0);
     889     virtual void InitOSD(OSD *osd);
     890     virtual void SetVideoFrameRate(float);
     891 
     892@@ -279,6 +279,7 @@
     893     QSize   video_dim;        ///< Pixel dimensions of video buffer
     894     QSize   video_disp_dim;   ///< Pixel dimensions of video display area
     895     float   video_aspect;     ///< Physical aspect ratio of video
     896+    float   video_prate;  ///< Playback frame rate of video
     897 
     898     /// Normally this is the same as videoAspect, but may not be
     899     /// if the user has toggled the aspect override mode.
     900diff -Naur --exclude=.svn mythtv.opengl/programs/mythfrontend/globalsettings.cpp mythtv/programs/mythfrontend/globalsettings.cpp
     901--- mythtv.opengl/programs/mythfrontend/globalsettings.cpp      2009-05-02 07:32:18.000000000 +1000
     902+++ mythtv/programs/mythfrontend/globalsettings.cpp     2009-05-15 16:57:30.000000000 +1000
     903@@ -2414,6 +2414,15 @@
     904     return gc;
     905 }
     906 
     907+static HostLineEdit *CustomScreenConfig()
     908+{
     909+    HostLineEdit *gedit = new HostLineEdit("CustomScreenRate");
     910+    gedit->setLabel(QObject::tr("Custom screen rate definition file"));
     911+    gedit->setHelpText(QObject::tr("Custom screen resolution configuration "
     912+                                        "for matching xrandr value."));
     913+    return gedit;
     914+}
     915+
     916 static HostSpinBox *VidModeWidth(int idx)
     917 {
     918     HostSpinBox *gs = new HostSpinBox(QString("VidModeWidth%1").arg(idx),
     919@@ -2582,9 +2591,16 @@
     920                     rate, SLOT(ChangeResolution(const QString&)));
     921         }
     922 
     923+        ConfigurationGroup* customscreensettings =
     924+            new HorizontalConfigurationGroup(false, false);
     925+
     926+        customscreensettings->addChild(CustomScreenConfig());
     927+
     928         ConfigurationGroup* settings = new VerticalConfigurationGroup(false);
     929+
     930         settings->addChild(defaultsettings);
     931         settings->addChild(overrides);
     932+        settings->addChild(customscreensettings);
     933 
     934         addTarget("1", settings);
     935         addTarget("0", new VerticalConfigurationGroup(true));
  • libs/libmyth/DisplayRes.cpp

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmyth/DisplayRes.cpp mythtv/libs/libmyth/DisplayRes.cpp
    old new  
    3737    // Initialize GUI mode
    3838    mode[GUI].Init();
    3939    tW = tH = 0;
    40     gContext->GetResolutionSetting("GuiVidMode", tW, tH);
     40    gContext->GetResolutionSetting("GuiVidMode", tW, tH, tAspect, tRate);
    4141    GetDisplaySize(tW_mm, tH_mm);
    4242    gContext->GetResolutionSetting("DisplaySize", tW_mm, tH_mm);
    43     mode[GUI] = DisplayResScreen(tW, tH, tW_mm, tH_mm, -1.0, 0);
     43    mode[GUI] = DisplayResScreen(tW, tH, tW_mm, tH_mm, -1.0, (float)tRate);
    4444
    4545
    4646    // Initialize default VIDEO mode
    4747    tW = tH = 0;
    4848    gContext->GetResolutionSetting("TVVidMode", tW, tH, tAspect, tRate);
    49     mode[VIDEO] = DisplayResScreen(tW, tH, tW_mm, tH_mm, tAspect, tRate);
     49    mode[VIDEO] = DisplayResScreen(tW, tH, tW_mm, tH_mm, tAspect, (float)tRate);
    5050
    5151
    5252    // Initialize video override mode
     
    6464            break;
    6565
    6666        uint key = DisplayResScreen::CalcKey(iw, ih, irate);
    67         DisplayResScreen scr(ow, oh, tW_mm, tH_mm, oaspect, orate);
     67        DisplayResScreen scr(ow, oh, tW_mm, tH_mm, oaspect, (float)orate);
    6868        in_size_to_output_mode[key] = scr;           
    6969    }
    7070
     
    8282    return true;
    8383}
    8484
    85 bool DisplayRes::SwitchToVideo(int iwidth, int iheight, short irate)
     85bool DisplayRes::SwitchToVideo(int iwidth, int iheight, short irate, float frate)
    8686{
    8787    tmode next_mode = VIDEO; // default VIDEO mode
    8888    DisplayResScreen next = mode[next_mode];
    8989
     90    // If requested refresh rate is 0, attempt to match video fps
     91    if (next.RefreshRate() == 0)
     92    {
     93        VERBOSE(VB_PLAYBACK, QString("*** Trying to match best resolution %1Hz") .arg(frate));
     94        next.AddRefreshRate(frate);
     95    }
     96
    9097    // try to find video override mode
    9198    uint key = DisplayResScreen::CalcKey(iwidth, iheight, irate);
    9299    DisplayResMapCIt it = in_size_to_output_mode.find(key);
     
    94101        mode[next_mode = CUSTOM_VIDEO] = next = it->second;
    95102
    96103    // need to change video mode?
    97     short target_rate = 0;
     104    float target_rate = 0.0;
    98105    DisplayResScreen::FindBestMatch(GetVideoModes(), next, target_rate);
    99     bool chg = !(next == last) || !(last.RefreshRate() == target_rate);
     106    bool chg = !(next == last) || !(DisplayResScreen::compare_rates(last.RefreshRate(),target_rate));
    100107
    101108    VERBOSE(VB_PLAYBACK, QString("Trying %1x%2 %3 Hz")
    102109            .arg(next.Width()).arg(next.Height()).arg(target_rate));
     
    128135    DisplayResScreen next = mode[next_mode];
    129136
    130137    // need to change video mode?
    131     short target_rate = 0;
     138    float target_rate = 0.0;
    132139    DisplayResScreen::FindBestMatch(GetVideoModes(), next, target_rate);
    133     bool chg = !(next == last) || !(last.RefreshRate() == target_rate);
     140    // If GuiVidModeRefreshRate is 0, assume any refresh rate is good enough.
     141    bool chg = (!(next == last) || (next.RefreshRate() !=0
     142                && !(DisplayResScreen::compare_rates(last.RefreshRate(), target_rate))));
    134143
    135144    VERBOSE(VB_PLAYBACK, QString("Trying %1x%2 %3 Hz")
    136145            .arg(next.Width()).arg(next.Height()).arg(target_rate));
     
    154163bool DisplayRes::SwitchToCustomGUI(int width, int height, short rate)
    155164{
    156165    mode[CUSTOM_GUI] = DisplayResScreen(width, height, mode[GUI].Width_mm(),
    157                                         mode[GUI].Height_mm(), -1.0, rate);
     166                                        mode[GUI].Height_mm(), -1.0, (float)rate);
    158167    return SwitchToGUI(CUSTOM_GUI);
    159168}
    160169
    161170const vector<short> DisplayRes::GetRefreshRates(int width, int height) const {
    162     short tr;
    163     vector<short> empty;
     171    vector<short> srates;
     172    vector<float> rates = GetRefreshRatesFloat(width, height);
     173
     174    for (int i=0; i<rates.size(); i++)
     175        srates.push_back((short) rates[i]);
     176    return srates;
     177}
     178const vector<float> DisplayRes::GetRefreshRatesFloat(int width, int height) const {
     179    float tr;
     180    vector<float> empty;
    164181
    165     const DisplayResScreen drs(width, height, 0, 0, -1.0, 0);
     182    const DisplayResScreen drs(width, height, 0, 0, -1.0, 0.0);
    166183    const DisplayResVector& drv = GetVideoModes();
    167184    int t = DisplayResScreen::FindBestMatch(drv, drs, tr);
    168185    if (t < 0)
  • libs/libmyth/DisplayRes.h

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmyth/DisplayRes.h mythtv/libs/libmyth/DisplayRes.h
    old new  
    4646     *  \brief Switches to the resolution and refresh rate defined in the
    4747     *         database for the specified video resolution and frame rate.
    4848     */
    49     bool SwitchToVideo(int iwidth, int iheight, short irate = 0);
     49    bool SwitchToVideo(int iwidth, int iheight, short irate = 0, float frate = 0.0);
    5050    /** \brief Switches to the GUI resolution specified.
    5151     *
    5252     *   If which_gui is GUI then this switches to the resolution
     
    110110    /// \brief Returns all video modes supported by the display.
    111111    virtual const vector<DisplayResScreen>& GetVideoModes() const = 0;
    112112    /// \brief Returns refresh rates available at a specific screen resolution.
    113     const vector<short> GetRefreshRates(int width, int height) const;
     113    const vector<float> GetRefreshRatesFloat(int width, int height) const;
     114    const vector<short> GetRefreshRates(int width, int height) const;
    114115    /** @} */
    115116
    116117  protected:
     
    120121   
    121122    // These methods are implemented by the subclasses
    122123    virtual bool GetDisplaySize(int &width_mm, int &height_mm) const = 0;
    123     virtual bool SwitchToVideoMode(int width, int height, short framerate) = 0;
     124    virtual bool SwitchToVideoMode(int width, int height, float framerate) = 0;
    124125
    125126  private:
    126127    DisplayRes(const DisplayRes & rhs); // disable copy constructor;
  • libs/libmyth/DisplayResOSX.cpp

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmyth/DisplayResOSX.cpp mythtv/libs/libmyth/DisplayResOSX.cpp
    old new  
    6666    return d;
    6767}
    6868
    69 bool DisplayResOSX::SwitchToVideoMode(int width, int height, short refreshrate)
     69bool DisplayResOSX::SwitchToVideoMode(int width, int height, float refreshrate)
    7070{
    7171    CGDirectDisplayID d = mythtv_display();
    7272    CFDictionaryRef dispMode = NULL;
     
    7575    // find mode that matches the desired size
    7676    if (refreshrate)
    7777        dispMode = CGDisplayBestModeForParametersAndRefreshRate(
    78             d, 32, width, height, (CGRefreshRate)(refreshrate), &match);
     78            d, 32, width, height, (CGRefreshRate)((short)refreshrate), &match);
    7979
    8080    if (!match)
    8181        dispMode =
     
    122122
    123123        if (screen_map.find(key)==screen_map.end())
    124124            screen_map[key] = DisplayResScreen(width, height,
    125                                                0, 0, -1.0, refresh);
     125                                               0, 0, -1.0, (float) refresh);
    126126        else
    127127            screen_map[key].AddRefreshRate(refresh);
    128128    }
  • libs/libmyth/DisplayResOSX.h

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmyth/DisplayResOSX.h mythtv/libs/libmyth/DisplayResOSX.h
    old new  
    1212
    1313  protected:
    1414    bool GetDisplaySize(int &width_mm, int &height_mm) const;
    15     bool SwitchToVideoMode(int width, int height, short framerate);
     15    bool SwitchToVideoMode(int width, int height, float framerate);
    1616   
    1717  private:
    1818    mutable vector<DisplayResScreen> m_video_modes;
  • libs/libmyth/DisplayResScreen.cpp

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmyth/DisplayResScreen.cpp mythtv/libs/libmyth/DisplayResScreen.cpp
    old new  
    11#include "DisplayResScreen.h"
    22#include "mythcontext.h"
    33
     4#include <cmath>
     5
    46DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh,
    5                                    double aspectRatio, short refreshRate)
    6     : width(w), height(h), width_mm(mw), height_mm(mh)
     7                                   double aspectRatio, float refreshRate)
     8    : width(w), height(h), width_mm(mw), height_mm(mh), custom(false)
    79{
    810    SetAspectRatio(aspectRatio);
    911    if (refreshRate > 0)
     
    1113}
    1214
    1315DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh,
    14                                    const vector<short>& rr)
    15     : width(w), height(h), width_mm(mw), height_mm(mh), refreshRates(rr)
     16                                   const vector<float>& rr)
     17    : width(w), height(h), width_mm(mw), height_mm(mh), refreshRates(rr), custom(false)
    1618{
    1719    SetAspectRatio(-1.0);
    1820}
    1921
    2022DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh,
    21                                    const short* rr, uint rr_length)
    22     : width(w), height(h), width_mm(mw), height_mm(mh)
     23                                   const float* rr, uint rr_length)
     24    : width(w), height(h), width_mm(mw), height_mm(mh), custom(false)
    2325{
    2426    SetAspectRatio(-1.0);
    2527    for (uint i = 0; i < rr_length; ++i)
     
    2830    sort(refreshRates.begin(), refreshRates.end());
    2931}
    3032
     33DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh,
     34                                   const short* rr, uint rr_length)
     35    : width(w), height(h), width_mm(mw), height_mm(mh), custom(false)
     36{
     37    SetAspectRatio(-1.0);
     38    for (uint i = 0; i < rr_length; ++i)
     39        refreshRates.push_back((float)rr[i]);
     40
     41    sort(refreshRates.begin(), refreshRates.end());
     42}
     43
    3144DisplayResScreen::DisplayResScreen(const QString &str)
    32     : width(0), height(0), width_mm(0), height_mm(0), aspect(-1.0)
     45    : width(0), height(0), width_mm(0), height_mm(0), aspect(-1.0), custom(false)
    3346{
    3447    refreshRates.clear();
    3548    QStringList slist = QStringList::split(":", str);
     
    4356        height_mm = slist[3].toInt();
    4457        aspect = slist[4].toDouble();
    4558        for (uint i = 5; i<slist.size(); ++i)
    46             refreshRates.push_back(slist[i].toShort());
     59            refreshRates.push_back(slist[i].toFloat());
    4760    }
    4861}
    4962
     
    8093    return dsr;
    8194}
    8295
     96//compares if the float f1 is equal with f2 and returns 1 if true and 0 if false
     97bool DisplayResScreen::compare_rates(float f1, float f2)
     98{
     99        float precision = 0.01;
     100        if (((f1 - precision) < f2) &&
     101            ((f1 + precision) > f2))
     102        {
     103                return true;
     104        }
     105        else
     106        {
     107                return false;
     108        }
     109}
     110
    83111int DisplayResScreen::FindBestMatch(const vector<DisplayResScreen>& dsr,
    84112                                    const DisplayResScreen& d,
    85113                                    short& target_rate)
    86114{
     115        float target;
     116        int i = FindBestMatch(dsr, d, target);
     117        target_rate = target;
     118        return i;
     119}
     120
     121int DisplayResScreen::FindBestMatch(const vector<DisplayResScreen>& dsr,
     122                                    const DisplayResScreen& d,
     123                                    float& target_rate)
     124{
     125  // Amend vector with custom list
    87126    for (uint i=0; i<dsr.size(); ++i)
    88127    {
    89128        if (dsr[i].Width()==d.Width() && dsr[i].Height()==d.Height())
    90129        {
    91             const vector<short>& rates = dsr[i].RefreshRates();
    92             if (rates.size())
     130            const vector<float>& rates = dsr[i].RefreshRates();
     131            if (rates.size() && d.RefreshRate() != 0)
    93132            {
    94                 vector<short>::const_iterator it =
    95                     find(rates.begin(), rates.end(), d.RefreshRate());
    96                 target_rate = (it == rates.end()) ? *(--rates.end()) : *it;
    97                 return i;
    98             }
     133              for (uint j=0; j < rates.size(); ++j)
     134                {
     135                  // Multiple of target_rate will do
     136                  if (compare_rates(d.RefreshRate(),rates[j]) || (fmod(rates[j],d.RefreshRate()) <= 0.01))
     137                    {
     138                      target_rate = rates[j];
     139                      return i;
     140                    }
     141                }
     142              // Can't find exact frame rate, so try rounding to the nearest integer, so 23.97Hz will work with 24Hz etc
     143              for (uint j=0; j < rates.size(); ++j)
     144                {
     145                  float rounded = (float) ((int) (rates[j] + 0.5));
     146                  // Multiple of target_rate will do
     147                  if (compare_rates(d.RefreshRate(),rounded) || (fmod(rounded,d.RefreshRate()) <= 0.01))
     148                    {
     149                      target_rate = rounded;
     150                      return i;
     151                    }
     152                }
     153              target_rate = rates[rates.size() - 1];
     154            }
     155            return i;
    99156        }
    100157    }
    101158    return -1;
  • libs/libmyth/DisplayResScreen.h

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmyth/DisplayResScreen.h mythtv/libs/libmyth/DisplayResScreen.h
    old new  
    1414  public:
    1515    // Constructors, initializers
    1616    DisplayResScreen()
    17         : width(0), height(0), width_mm(0), height_mm(0), aspect(-1.0) {;}
     17        : width(0), height(0), width_mm(0), height_mm(0), aspect(-1.0), custom(false) {;}
    1818    DisplayResScreen(int w, int h, int mw, int mh,
    19                      double aspectRatio/* = -1.0*/, short refreshRate/* = 0*/);
     19                     double aspectRatio/* = -1.0*/, float refreshRate/* = 0*/);
    2020    DisplayResScreen(int w, int h, int mw, int mh,
    21                      const vector<short>& refreshRates);
     21                     const vector<float>& refreshRates);
     22    DisplayResScreen(int w, int h, int mw, int mh,
     23                     const float* refreshRates, uint rr_length);
    2224    DisplayResScreen(int w, int h, int mw, int mh,
    2325                     const short* refreshRates, uint rr_length);
    2426    DisplayResScreen(const QString &str);
     
    2931    int Height() const { return height; }
    3032    int Width_mm() const { return width_mm; }
    3133    int Height_mm() const { return height_mm; }
     34    bool Custom() const { return custom; }
     35
    3236    inline double AspectRatio() const;
    33     inline short RefreshRate() const;
    34     const vector<short>& RefreshRates() const { return refreshRates; }
     37    inline float RefreshRate() const;
     38    const vector<float>& RefreshRates() const { return refreshRates; }
    3539
    3640    // Sets, adds
    3741    void SetAspectRatio(double a);
    38     void AddRefreshRate(short rr) {
     42    void AddRefreshRate(float rr) {
    3943        refreshRates.push_back(rr);
    4044        sort(refreshRates.begin(), refreshRates.end());
    4145    }
    42 
     46    void ClearRefreshRates(void) {
     47        refreshRates.clear();
     48    }   
     49    void SetCustom(bool b) {
     50        custom = b;
     51    }
     52       
     53    // Map for matching real rates and xrandr rate;
     54    map<float, short> realRates;
     55       
    4356    // Converters & comparitors
    4457    QString toString() const;
    4558    inline bool operator < (const DisplayResScreen& b) const;
     
    5063    static vector<DisplayResScreen> Convert(const QStringList& slist);
    5164    static int FindBestMatch(const vector<DisplayResScreen>& dsr,
    5265                             const DisplayResScreen& d,
     66                             float& target_rate);
     67    static int FindBestMatch(const vector<DisplayResScreen>& dsr,
     68                             const DisplayResScreen& d,
    5369                             short& target_rate);
    5470    static inline int CalcKey(int w, int h, int rate);
     71    static bool compare_rates(float f1, float f2);
    5572
    5673  private:
    5774    int width, height; // size in pixels
    5875    int width_mm, height_mm; // physical size in millimeters
    5976    double aspect; // aspect ratio, calculated or set
    60     vector<short> refreshRates;
     77    vector<float> refreshRates;
     78    bool custom;        // Set if resolution was defined manually
    6179};
    6280
     81
    6382typedef vector<DisplayResScreen>          DisplayResVector;
    6483typedef DisplayResVector::iterator        DisplayResVectorIt;
    6584typedef DisplayResVector::const_iterator  DisplayResVectorCIt;
     
    85104    return aspect;
    86105}
    87106
    88 inline short DisplayResScreen::RefreshRate() const
     107inline float DisplayResScreen::RefreshRate() const
    89108{
    90109    if (refreshRates.size() >= 1)
    91110        return refreshRates[0];
    92     else return 0;
     111    else return 0.0;
    93112}
    94113
    95114inline bool DisplayResScreen::operator < (const DisplayResScreen& b) const
  • libs/libmyth/DisplayResX.cpp

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmyth/DisplayResX.cpp mythtv/libs/libmyth/DisplayResX.cpp
    old new  
    44#include <cstring>
    55#include <cstdlib>
    66
     7#include "mythcontext.h"
     8#include <qregexp.h>
     9#include <qfile.h>
     10#include <qfileinfo.h>
     11
    712#include "util-x11.h"
    813
    914#include <X11/extensions/Xrandr.h> // this has to be after util-x11.h (Qt bug)
     
    3237    return false;
    3338}
    3439
    35 bool DisplayResX::SwitchToVideoMode(int width, int height, short desired_rate)
     40bool DisplayResX::SwitchToVideoMode(int width, int height, float desired_rate)
    3641{
    37     short rate;
     42    float rate;
     43    short finalrate;
     44
    3845    DisplayResScreen desired_screen(width, height, 0, 0, -1.0, desired_rate);
    3946    int idx = DisplayResScreen::FindBestMatch(m_video_modes_unsorted,
    4047                                              desired_screen, rate);
     
    4956        Rotation rot;
    5057        XRRConfigCurrentConfiguration(cfg, &rot);
    5158       
     59        // Search real xrandr rate for desired_rate
     60        finalrate = (short) rate;
     61        for (uint i=0; i < m_video_modes.size(); i++) {
     62            if ((m_video_modes[i].Width() == width) && (m_video_modes[i].Height() == height))
     63            {
     64                if (m_video_modes[i].Custom())
     65                {
     66                    finalrate = m_video_modes[i].realRates[rate];
     67                    VERBOSE(VB_PLAYBACK, QString("CustomRate Found, set %1Hz as %2") .arg(rate) .arg(finalrate));
     68                }
     69                break;
     70            }
     71        }
     72               
    5273        Window root = DefaultRootWindow(display);
    5374        Status status = XRRSetScreenConfigAndRate(display, cfg, root, idx,
    54                                                   rot, rate, CurrentTime);
     75                                                  rot, finalrate, CurrentTime);
    5576       
    5677        XRRFreeScreenConfigInfo(cfg);
    5778        XCloseDisplay(display);
     
    87108                             rates, num_rates);
    88109        m_video_modes.push_back(scr);
    89110    }
     111
     112    QString customscreen = gContext->GetSetting("CustomScreenRate");
     113    if (gContext->GetNumSetting("UseVideoModes", 0) && !customscreen.length());
     114    {
     115        QFileInfo fi(customscreen);
     116        QFile file(customscreen);
     117       
     118        if (!fi.exists() || !fi.isFile())
     119        {
     120            VERBOSE(VB_PLAYBACK, QString("CustomScreenRate: \"%1\" failed: does not exist or isn't a file")
     121                    .arg(customscreen));
     122        }
     123        else if ( file.open(IO_ReadOnly) ) {
     124            QRegExp regexp = QRegExp("^\\s*(\\d+),(\\d+),(\\d+\\.?\\d*),(\\d+)\\s*$");
     125            QTextStream stream( &file );
     126            QString line;
     127            int pos;
     128            while ( !stream.atEnd() ) {
     129                pos = regexp.search(stream.readLine());
     130                if (pos > -1) {
     131                    int w = regexp.cap(1).toInt();
     132                    int h = regexp.cap(2).toInt();
     133                    float hz = regexp.cap(3).toFloat();
     134                    int xrandrhz = regexp.cap(4).toShort();
     135                    int found = -1;
     136                    VERBOSE(VB_PLAYBACK, QString("Found definition for %1x%2 @ %3Hz (xrandr: %4)")
     137                            .arg(w) .arg(h) .arg(hz) .arg(xrandrhz));
     138                    // find if video mode already exist, and remove refresh rates for custom one
     139                    for (uint i=0; i < m_video_modes.size(); i++) {
     140                        if ((m_video_modes[i].Width() == w) && (m_video_modes[i].Height() == h))
     141                        {
     142                            found = i;
     143                            if (!m_video_modes[i].Custom())
     144                            {
     145                                m_video_modes[i].ClearRefreshRates();
     146                                m_video_modes[i].SetCustom(true);
     147                            }
     148                            m_video_modes[i].AddRefreshRate(hz);
     149                            m_video_modes[i].realRates[hz] = xrandrhz;
     150                            break;
     151                        }
     152                    }
     153                    if (found < 0)
     154                    {
     155                        DisplayResScreen scr(w, h, 0, 0, -1.0, hz);
     156                        scr.SetCustom(true);
     157                        m_video_modes.push_back(scr);
     158                    }
     159                }
     160            }
     161            file.close();
     162        }
     163    }
     164
    90165    m_video_modes_unsorted = m_video_modes;
    91166    sort(m_video_modes.begin(), m_video_modes.end());
    92167
  • libs/libmyth/DisplayResX.h

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmyth/DisplayResX.h mythtv/libs/libmyth/DisplayResX.h
    old new  
    1212
    1313  protected:
    1414    bool GetDisplaySize(int &width_mm, int &height_mm) const;
    15     bool SwitchToVideoMode(int width, int height, short framerate);
     15    bool SwitchToVideoMode(int width, int height, float framerate);
    1616
    1717  private:
    1818    mutable vector<DisplayResScreen> m_video_modes;
  • libs/libmythtv/NuppelVideoPlayer.cpp

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/NuppelVideoPlayer.cpp mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
    old new  
    635635            GetDecoder()->GetVideoCodecID(),
    636636            GetDecoder()->GetVideoCodecPrivate(),
    637637            video_disp_dim, video_aspect,
    638             widget->winId(), display_rect, 0 /*embedid*/);
     638            widget->winId(), display_rect, (video_frame_rate * play_speed),
     639            0 /*embedid*/);
    639640
    640641        if (!videoOutput)
    641642        {
  • libs/libmythtv/videoout_d3d.cpp

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_d3d.cpp mythtv/libs/libmythtv/videoout_d3d.cpp
    old new  
    451451
    452452bool VideoOutputD3D::Init(int width, int height, float aspect,
    453453                          WId winid, int winx, int winy, int winw,
    454                           int winh, WId embedid)
     454                          int winh, float video_prate, WId embedid)
    455455{
    456456    VERBOSE(VB_PLAYBACK, LOC +
    457457            "Init w=" << width << " h=" << height);
     
    462462                  kPrebufferFramesNormal, kPrebufferFramesSmall,
    463463                  kKeepPrebuffer);
    464464
    465     VideoOutput::Init(width, height, aspect, winid,
    466                       winx, winy, winw, winh, embedid);
     465    VideoOutput::Init(width, height, aspect, winid, winx,
     466                      winy, winw, winh, video_prate, embedid);
    467467
    468468    m_hWnd = winid;
    469469
  • libs/libmythtv/videoout_d3d.h

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_d3d.h mythtv/libs/libmythtv/videoout_d3d.h
    old new  
    2020   ~VideoOutputD3D();
    2121
    2222    bool Init(int width, int height, float aspect, WId winid,
    23               int winx, int winy, int winw, int winh, WId embedid = 0);
     23              int winx, int winy, int winw, int winh,
     24              float video_prate, WId embedid = 0);
    2425
    2526    bool InitD3D();
    2627    void UnInitD3D();
  • libs/libmythtv/videoout_directfb.cpp

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_directfb.cpp mythtv/libs/libmythtv/videoout_directfb.cpp
    old new  
    353353
    354354bool VideoOutputDirectfb::Init(int width, int height, float aspect, WId winid,
    355355                               int winx, int winy, int winw, int winh,
    356                                WId embedid)
     356                               float video_prate, WId embedid)
    357357{
    358358    // Hack to avoid embedded video output...
    359359    if ((winw < 320) || (winh < 240))
     
    646646                           display_visible_rect.y(),
    647647                           display_visible_rect.width(),
    648648                           display_visible_rect.height(),
    649                            embedid))
     649                           video_prate, embedid))
    650650    {
    651651        return false;
    652652    }
  • libs/libmythtv/videoout_directfb.h

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_directfb.h mythtv/libs/libmythtv/videoout_directfb.h
    old new  
    1414    ~VideoOutputDirectfb();
    1515
    1616    bool Init(int width, int height, float aspect, WId winid,
    17               int winx, int winy, int winw, int winh, WId embedid = 0);
     17              int winx, int winy, int winw, int winh,
     18              float video_prate, WId embedid = 0);
    1819
    1920    void ProcessFrame(VideoFrame *frame, OSD *osd,
    2021                      FilterChain *filterList,
  • libs/libmythtv/videoout_dx.cpp

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_dx.cpp mythtv/libs/libmythtv/videoout_dx.cpp
    old new  
    158158}
    159159
    160160bool VideoOutputDX::Init(int width, int height, float aspect,
    161                            WId winid, int winx, int winy, int winw,
    162                            int winh, WId embedid)
     161                         WId winid, int winx, int winy, int winw,
     162                         int winh, float video_prate, WId embedid)
    163163{
    164164    db_vdisp_profile->SetVideoRenderer("directx");
    165165
    166166    vbuffers.Init(kNumBuffers, true, kNeedFreeFrames,
    167167                  kPrebufferFramesNormal, kPrebufferFramesSmall,
    168168                  kKeepPrebuffer);
    169     VideoOutput::Init(width, height, aspect, winid,
    170                       winx, winy, winw, winh, embedid);
     169    VideoOutput::Init(width, height, aspect, winid, winx,
     170                      winy, winw, winh, video_prate, embedid);
    171171
    172172    wnd = winid;
    173173
  • libs/libmythtv/videoout_dx.h

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_dx.h mythtv/libs/libmythtv/videoout_dx.h
    old new  
    2121   ~VideoOutputDX();
    2222
    2323    bool Init(int width, int height, float aspect, WId winid,
    24               int winx, int winy, int winw, int winh, WId embedid = 0);
     24              int winx, int winy, int winw, int winh,
     25              float video_prate, WId embedid = 0);
    2526    void PrepareFrame(VideoFrame *buffer, FrameScanType);
    2627    void Show(FrameScanType );
    2728
  • libs/libmythtv/videoout_ivtv.cpp

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_ivtv.cpp mythtv/libs/libmythtv/videoout_ivtv.cpp
    old new  
    405405
    406406bool VideoOutputIvtv::Init(int width, int height, float aspect,
    407407                           WId winid, int winx, int winy, int winw,
    408                            int winh, WId embedid)
     408                           int winh, float video_prate, WId embedid)
    409409{
    410410    VERBOSE(VB_PLAYBACK, LOC + "Init() -- begin");
    411411
     
    416416    videoDevice = gContext->GetSetting("PVR350VideoDev");
    417417
    418418    VideoOutput::Init(width, height, aspect, winid, winx, winy, winw, winh,
    419                       embedid);
     419                      video_prate, embedid);
    420420
    421421    osdbufsize = video_dim.width() * video_dim.height() * 4;
    422422
  • libs/libmythtv/videoout_ivtv.h

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_ivtv.h mythtv/libs/libmythtv/videoout_ivtv.h
    old new  
    1616   ~VideoOutputIvtv();
    1717
    1818    bool Init(int width, int height, float aspect, WId winid,
    19               int winx, int winy, int winw, int winh, WId embedid = 0);
     19              int winx, int winy, int winw, int winh,
     20              float video_prate, WId embedid = 0);
    2021    void PrepareFrame(VideoFrame *buffer, FrameScanType);
    2122    void Show(FrameScanType );
    2223
  • libs/libmythtv/videoout_null.cpp

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_null.cpp mythtv/libs/libmythtv/videoout_null.cpp
    old new  
    115115
    116116bool VideoOutputNull::Init(int width, int height, float aspect,
    117117                           WId winid, int winx, int winy, int winw,
    118                            int winh, WId embedid)
     118                           int winh, float video_prate, WId embedid)
    119119{
    120120    if ((width <= 0) || (height <= 0))
    121121        return false;
    122122
    123123    QMutexLocker locker(&global_lock);
    124124
    125     VideoOutput::Init(width, height, aspect, winid,
    126                       winx, winy, winw, winh, embedid);
     125    VideoOutput::Init(width, height, aspect, winid, winx,
     126                      winy, winw, winh, video_prate, embedid);
    127127
    128128    vbuffers.Init(kNumBuffers, true, kNeedFreeFrames,
    129129                  kPrebufferFramesNormal, kPrebufferFramesSmall,
  • libs/libmythtv/videoout_null.h

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_null.h mythtv/libs/libmythtv/videoout_null.h
    old new  
    1212   ~VideoOutputNull();
    1313
    1414    bool Init(int width, int height, float aspect, WId winid,
    15               int winx, int winy, int winw, int winh, WId embedid = 0);
     15              int winx, int winy, int winw, int winh,
     16              float video_prate, WId embedid = 0);
    1617
    1718    bool SetupDeinterlace(bool, const QString &ovrf = "")
    1819        { (void)ovrf; return false; } // we don't deinterlace in null output..
  • libs/libmythtv/videoout_quartz.cpp

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_quartz.cpp mythtv/libs/libmythtv/videoout_quartz.cpp
    old new  
    11921192}
    11931193
    11941194bool VideoOutputQuartz::Init(int width, int height, float aspect,
    1195                              WId winid, int winx, int winy,
    1196                              int winw, int winh, WId embedid)
     1195                             WId winid, int winx, int winy, int winw,
     1196                             int winh, float video_prate, WId embedid)
    11971197{
    11981198    VERBOSE(VB_PLAYBACK, LOC +
    11991199            QString("Init(WxH %1x%2, aspect=%3, winid=%4\n\t\t\t"
     
    12151215    vbuffers.Init(kNumBuffers, true, kNeedFreeFrames,
    12161216                  kPrebufferFramesNormal, kPrebufferFramesSmall,
    12171217                  kKeepPrebuffer);
    1218     VideoOutput::Init(width, height, aspect, winid,
    1219                       winx, winy, winw, winh, embedid);
     1218    VideoOutput::Init(width, height, aspect, winid, winx,
     1219                      winy, winw, winh, video_prate, embedid);
    12201220
    12211221    data->srcWidth  = video_dim.width();
    12221222    data->srcHeight = video_dim.height();
     
    13811381
    13821382void VideoOutputQuartz::SetVideoFrameRate(float playback_fps)
    13831383{
     1384    video_prate = playback_fps;
    13841385    VERBOSE(VB_PLAYBACK, "SetVideoFrameRate("<<playback_fps<<")");
    13851386}
    13861387
  • libs/libmythtv/videoout_quartz.h

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_quartz.h mythtv/libs/libmythtv/videoout_quartz.h
    old new  
    1313   ~VideoOutputQuartz();
    1414
    1515    bool Init(int width, int height, float aspect, WId winid,
    16               int winx, int winy, int winw, int winh, WId embedid = 0);
     16              int winx, int winy, int winw, int winh,
     17              float video_prate, WId embedid = 0);
    1718    void SetVideoFrameRate(float playback_fps);
    1819    void PrepareFrame(VideoFrame *buffer, FrameScanType t);
    1920    void Show(FrameScanType);
  • libs/libmythtv/videoout_xv.cpp

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_xv.cpp mythtv/libs/libmythtv/videoout_xv.cpp
    old new  
    450450    if ((width == 1920 || width == 1440) && height == 1088)
    451451        height = 1080; // ATSC 1920x1080
    452452
    453     if (display_res && display_res->SwitchToVideo(width, height))
     453    if (display_res && display_res->SwitchToVideo(width, height,
     454                                                  (short) roundf(video_prate),
     455                                                  video_prate))
    454456    {
    455457        // Switching to custom display resolution succeeded
    456458        // Make a note of the new size
     
    16981700}
    16991701
    17001702/**
    1701  * \fn VideoOutputXv::Init(int,int,float,WId,int,int,int,int,WId)
     1703 * \fn VideoOutputXv::Init(int,int,float,WId,int,int,int,int,float,WId)
    17021704 * Initializes class for video output.
    17031705 *
    17041706 * \return success or failure.
    17051707 */
    17061708bool VideoOutputXv::Init(
    1707     int width, int height, float aspect,
    1708     WId winid, int winx, int winy, int winw, int winh, WId embedid)
     1709    int width, int height, float aspect, WId winid, int winx,
     1710    int winy, int winw, int winh, float video_prate, WId embedid)
    17091711{
    17101712    needrepaint = true;
    17111713
     
    17391741    // Basic setup
    17401742    VideoOutput::Init(width, height, aspect,
    17411743                      winid, winx, winy, winw, winh,
    1742                       embedid);
     1744                      video_prate, embedid);
    17431745
    17441746    // Set resolution/measurements (check XRandR, Xinerama, config settings)
    17451747    InitDisplayMeasurements(width, height);
  • libs/libmythtv/videoout_xv.h

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videoout_xv.h mythtv/libs/libmythtv/videoout_xv.h
    old new  
    6262   ~VideoOutputXv();
    6363
    6464    bool Init(int width, int height, float aspect, WId winid,
    65               int winx, int winy, int winw, int winh, WId embedid = 0);
     65              int winx, int winy, int winw, int winh,
     66              float video_prate, WId embedid = 0);
    6667
    6768    bool SetDeinterlacingEnabled(bool);
    6869    bool SetupDeinterlace(bool interlaced, const QString& ovrf="");
  • libs/libmythtv/videooutbase.cpp

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videooutbase.cpp mythtv/libs/libmythtv/videooutbase.cpp
    old new  
    7171        void          *codec_priv,
    7272        const QSize   &video_dim, float        video_aspect,
    7373        WId            win_id,    const QRect &display_rect,
    74         WId            embed_id)
     74        float          video_prate,     WId     embed_id)
    7575{
    7676    (void) codec_priv;
    7777
     
    170170
    171171        if (vo)
    172172        {
     173            vo->video_prate = video_prate;
    173174            if (vo->Init(
    174175                    video_dim.width(), video_dim.height(), video_aspect,
    175176                    win_id, display_rect.x(), display_rect.y(),
    176                     display_rect.width(), display_rect.height(), embed_id))
     177                    display_rect.width(), display_rect.height(),
     178                    video_prate, embed_id))
    177179            {
    178180                return vo;
    179181            }
     
    367369 * \return true if successful, false otherwise.
    368370 */
    369371bool VideoOutput::Init(int width, int height, float aspect, WId winid,
    370                        int winx, int winy, int winw, int winh, WId embedid)
     372                       int winx, int winy, int winw, int winh,
     373                       float video_prate, WId embedid)
    371374{
    372375    (void)winid;
    373376    (void)embedid;
     
    409412
    410413void VideoOutput::SetVideoFrameRate(float playback_fps)
    411414{
     415    video_prate = playback_fps;
    412416    db_vdisp_profile->SetOutput(playback_fps);
    413417}
    414418
  • libs/libmythtv/videooutbase.h

    diff -Naur --exclude=.svn mythtv.opengl/libs/libmythtv/videooutbase.h mythtv/libs/libmythtv/videooutbase.h
    old new  
    3636        void          *codec_priv,
    3737        const QSize   &video_dim, float        video_aspect,
    3838        WId            win_id,    const QRect &display_rect,
    39         WId            embed_id);
     39        float video_prate,        WId          embed_id);
    4040
    4141    VideoOutput();
    4242    virtual ~VideoOutput();
    4343
    4444    virtual bool Init(int width, int height, float aspect,
    4545                      WId winid, int winx, int winy, int winw,
    46                       int winh, WId embedid = 0);
     46                      int winh, float video_prate, WId embedid = 0);
    4747    virtual void InitOSD(OSD *osd);
    4848    virtual void SetVideoFrameRate(float);
    4949
     
    279279    QSize   video_dim;        ///< Pixel dimensions of video buffer
    280280    QSize   video_disp_dim;   ///< Pixel dimensions of video display area
    281281    float   video_aspect;     ///< Physical aspect ratio of video
     282    float   video_prate;  ///< Playback frame rate of video
    282283
    283284    /// Normally this is the same as videoAspect, but may not be
    284285    /// if the user has toggled the aspect override mode.
  • programs/mythfrontend/globalsettings.cpp

    diff -Naur --exclude=.svn mythtv.opengl/programs/mythfrontend/globalsettings.cpp mythtv/programs/mythfrontend/globalsettings.cpp
    old new  
    24142414    return gc;
    24152415}
    24162416
     2417static HostLineEdit *CustomScreenConfig()
     2418{
     2419    HostLineEdit *gedit = new HostLineEdit("CustomScreenRate");
     2420    gedit->setLabel(QObject::tr("Custom screen rate definition file"));
     2421    gedit->setHelpText(QObject::tr("Custom screen resolution configuration "
     2422                                        "for matching xrandr value."));
     2423    return gedit;
     2424}
     2425 
    24172426static HostSpinBox *VidModeWidth(int idx)
    24182427{
    24192428    HostSpinBox *gs = new HostSpinBox(QString("VidModeWidth%1").arg(idx),
     
    25822591                    rate, SLOT(ChangeResolution(const QString&)));
    25832592        }
    25842593
     2594        ConfigurationGroup* customscreensettings =
     2595            new HorizontalConfigurationGroup(false, false);
     2596
     2597        customscreensettings->addChild(CustomScreenConfig());
     2598
    25852599        ConfigurationGroup* settings = new VerticalConfigurationGroup(false);
     2600
    25862601        settings->addChild(defaultsettings);
    25872602        settings->addChild(overrides);
     2603        settings->addChild(customscreensettings);
    25882604
    25892605        addTarget("1", settings);
    25902606        addTarget("0", new VerticalConfigurationGroup(true));