Ticket #5643: adjust_rate3-fixes.2.patch

File adjust_rate3-fixes.2.patch, 78.3 KB (added by jyavenard@…, 3 years ago)

patch 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.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));