Ticket #5643: adjust_rate4-fixes.patch

File adjust_rate4-fixes.patch, 28.6 KB (added by jyavenard@…, 3 years ago)

Patch for 0.21-fixes

  • mythtv/libs/libmyth/DisplayRes.cpp

    old new  
    99#include "DisplayResOSX.h" 
    1010#endif 
    1111 
     12#include <cmath> 
     13 
    1214DisplayRes * DisplayRes::instance = NULL; 
    1315 
    1416DisplayRes * DisplayRes::GetDisplayRes(void) 
     
    3739    // Initialize GUI mode 
    3840    mode[GUI].Init(); 
    3941    tW = tH = 0; 
    40     gContext->GetResolutionSetting("GuiVidMode", tW, tH); 
     42    gContext->GetResolutionSetting("GuiVidMode", tW, tH, tAspect, tRate); 
    4143    GetDisplaySize(tW_mm, tH_mm); 
    4244    gContext->GetResolutionSetting("DisplaySize", tW_mm, tH_mm); 
    43     mode[GUI] = DisplayResScreen(tW, tH, tW_mm, tH_mm, -1.0, 0); 
     45    mode[GUI] = DisplayResScreen(tW, tH, tW_mm, tH_mm, -1.0, (float)tRate); 
    4446 
    4547 
    4648    // Initialize default VIDEO mode 
    4749    tW = tH = 0; 
    4850    gContext->GetResolutionSetting("TVVidMode", tW, tH, tAspect, tRate); 
    49     mode[VIDEO] = DisplayResScreen(tW, tH, tW_mm, tH_mm, tAspect, tRate); 
     51    mode[VIDEO] = DisplayResScreen(tW, tH, tW_mm, tH_mm, tAspect, (float)tRate); 
    5052 
    5153 
    5254    // Initialize video override mode 
     
    6466            break; 
    6567 
    6668        uint key = DisplayResScreen::CalcKey(iw, ih, irate); 
    67         DisplayResScreen scr(ow, oh, tW_mm, tH_mm, oaspect, orate); 
     69        DisplayResScreen scr(ow, oh, tW_mm, tH_mm, oaspect, (float)orate); 
    6870        in_size_to_output_mode[key] = scr;             
    6971    } 
    7072 
     
    8284    return true; 
    8385} 
    8486 
    85 bool DisplayRes::SwitchToVideo(int iwidth, int iheight, short irate) 
     87bool DisplayRes::SwitchToVideo(int iwidth, int iheight, float frate) 
    8688{ 
    8789    tmode next_mode = VIDEO; // default VIDEO mode 
    8890    DisplayResScreen next = mode[next_mode]; 
    8991 
     92    // If requested refresh rate is 0, attempt to match video fps 
     93    if (next.RefreshRate() == 0) 
     94    { 
     95        VERBOSE(VB_PLAYBACK, QString("*** Trying to match best resolution %1Hz") .arg(frate)); 
     96        next.AddRefreshRate(frate); 
     97    } 
     98 
    9099    // try to find video override mode 
    91     uint key = DisplayResScreen::CalcKey(iwidth, iheight, irate); 
     100    uint key = DisplayResScreen::CalcKey(iwidth, iheight, (short) roundf(frate)); 
    92101    DisplayResMapCIt it = in_size_to_output_mode.find(key); 
    93102    if (it != in_size_to_output_mode.end()) 
    94103        mode[next_mode = CUSTOM_VIDEO] = next = it->second; 
    95104 
    96105    // need to change video mode? 
    97     short target_rate = 0; 
     106    float target_rate = 0.0; 
    98107    DisplayResScreen::FindBestMatch(GetVideoModes(), next, target_rate); 
    99     bool chg = !(next == last) || !(last.RefreshRate() == target_rate); 
     108    bool chg = !(next == last) || !(DisplayResScreen::compare_rates(last.RefreshRate(),target_rate)); 
    100109 
    101110    VERBOSE(VB_PLAYBACK, QString("Trying %1x%2 %3 Hz") 
    102111            .arg(next.Width()).arg(next.Height()).arg(target_rate)); 
     
    128137    DisplayResScreen next = mode[next_mode]; 
    129138 
    130139    // need to change video mode? 
    131     short target_rate = 0; 
     140    float target_rate = 0.0; 
    132141    DisplayResScreen::FindBestMatch(GetVideoModes(), next, target_rate); 
    133     bool chg = !(next == last) || !(last.RefreshRate() == target_rate); 
     142    // If GuiVidModeRefreshRate is 0, assume any refresh rate is good enough. 
     143    bool chg = (!(next == last) || (next.RefreshRate() !=0 
     144                && !(DisplayResScreen::compare_rates(last.RefreshRate(), target_rate))));  
    134145 
    135146    VERBOSE(VB_PLAYBACK, QString("Trying %1x%2 %3 Hz") 
    136147            .arg(next.Width()).arg(next.Height()).arg(target_rate)); 
     
    154165bool DisplayRes::SwitchToCustomGUI(int width, int height, short rate) 
    155166{ 
    156167    mode[CUSTOM_GUI] = DisplayResScreen(width, height, mode[GUI].Width_mm(), 
    157                                         mode[GUI].Height_mm(), -1.0, rate); 
     168                                        mode[GUI].Height_mm(), -1.0, (float)rate); 
    158169    return SwitchToGUI(CUSTOM_GUI); 
    159170} 
    160171 
    161172const vector<short> DisplayRes::GetRefreshRates(int width, int height) const { 
    162     short tr; 
    163     vector<short> empty; 
     173    vector<short> srates; 
     174    vector<float> rates = GetRefreshRatesFloat(width, height); 
     175 
     176    for (int i=0; i<rates.size(); i++) 
     177        srates.push_back((short) rates[i]); 
     178    return srates; 
     179} 
     180const vector<float> DisplayRes::GetRefreshRatesFloat(int width, int height) const { 
     181    float tr; 
     182    vector<float> empty; 
    164183 
    165     const DisplayResScreen drs(width, height, 0, 0, -1.0, 0); 
     184    const DisplayResScreen drs(width, height, 0, 0, -1.0, 0.0); 
    166185    const DisplayResVector& drv = GetVideoModes(); 
    167186    int t = DisplayResScreen::FindBestMatch(drv, drs, tr); 
    168187    if (t < 0) 
  • 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, 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; 
  • 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 vector<float>& rr, const map<float, short>& rr2) 
     24: width(w), height(h), width_mm(mw), height_mm(mh), refreshRates(rr), realRates(rr2), custom(true) 
     25{ 
     26    SetAspectRatio(-1.0); 
     27} 
     28 
     29DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh, 
     30                                   const float* rr, uint rr_length) 
     31    : width(w), height(h), width_mm(mw), height_mm(mh), custom(false) 
    2332{ 
    2433    SetAspectRatio(-1.0); 
    2534    for (uint i = 0; i < rr_length; ++i) 
     
    2837    sort(refreshRates.begin(), refreshRates.end()); 
    2938} 
    3039 
     40DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh, 
     41                                   const short* rr, uint rr_length) 
     42    : width(w), height(h), width_mm(mw), height_mm(mh), custom(false) 
     43{ 
     44    SetAspectRatio(-1.0); 
     45    for (uint i = 0; i < rr_length; ++i) 
     46    { 
     47        refreshRates.push_back((float)rr[i]); 
     48    } 
     49    sort(refreshRates.begin(), refreshRates.end()); 
     50} 
     51 
    3152DisplayResScreen::DisplayResScreen(const QString &str) 
    32     : width(0), height(0), width_mm(0), height_mm(0), aspect(-1.0) 
     53    : width(0), height(0), width_mm(0), height_mm(0), aspect(-1.0), custom(false) 
    3354{ 
    3455    refreshRates.clear(); 
    3556    QStringList slist = QStringList::split(":", str); 
     
    4364        height_mm = slist[3].toInt(); 
    4465        aspect = slist[4].toDouble(); 
    4566        for (uint i = 5; i<slist.size(); ++i) 
    46             refreshRates.push_back(slist[i].toShort()); 
     67            refreshRates.push_back(slist[i].toFloat()); 
    4768    } 
    4869} 
    4970 
     
    80101    return dsr; 
    81102} 
    82103 
     104//compares if the float f1 is equal with f2 and returns 1 if true and 0 if false 
     105bool DisplayResScreen::compare_rates(float f1, float f2) 
     106{ 
     107    float precision = 0.01; 
     108    if (((f1 - precision) < f2) &&  
     109        ((f1 + precision) > f2)) 
     110    { 
     111        return true; 
     112    } 
     113    else 
     114    { 
     115        return false; 
     116    } 
     117} 
     118 
    83119int DisplayResScreen::FindBestMatch(const vector<DisplayResScreen>& dsr, 
    84120                                    const DisplayResScreen& d, 
    85121                                    short& target_rate) 
    86122{ 
     123    float target; 
     124    int i = FindBestMatch(dsr, d, target); 
     125    target_rate = target; 
     126    return i; 
     127} 
     128 
     129int DisplayResScreen::FindBestMatch(const vector<DisplayResScreen>& dsr, 
     130                                    const DisplayResScreen& d, 
     131                                    float& target_rate) 
     132{ 
     133  // Amend vector with custom list 
    87134    for (uint i=0; i<dsr.size(); ++i) 
    88135    { 
    89136        if (dsr[i].Width()==d.Width() && dsr[i].Height()==d.Height()) 
    90137        { 
    91             const vector<short>& rates = dsr[i].RefreshRates(); 
    92             if (rates.size()) 
     138            const vector<float>& rates = dsr[i].RefreshRates(); 
     139            if (rates.size() && d.RefreshRate() != 0) 
    93140            { 
    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; 
     141                for (uint j=0; j < rates.size(); ++j) 
     142                { 
     143                    // Multiple of target_rate will do 
     144                    if (compare_rates(d.RefreshRate(),rates[j]) || (fmod(rates[j],d.RefreshRate()) <= 0.01)) 
     145                    { 
     146                      target_rate = rates[j]; 
     147                      return i; 
     148                    } 
     149                } 
     150                // Can't find exact frame rate, so try rounding to the nearest integer, so 23.97Hz will work with 24Hz etc 
     151                for (uint j=0; j < rates.size(); ++j) 
     152                { 
     153                    float rounded = (float) ((int) (rates[j] + 0.5)); 
     154                    // Multiple of target_rate will do 
     155                    if (compare_rates(d.RefreshRate(),rounded) || (fmod(rounded,d.RefreshRate()) <= 0.01)) 
     156                    { 
     157                      target_rate = rounded; 
     158                              return i; 
     159                    } 
     160                } 
     161                target_rate = rates[rates.size() - 1]; 
    98162            } 
     163            return i; 
    99164        } 
    100165    } 
    101166    return -1; 
  • 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        { 
  • mythtv/libs/libmythtv/videoout_xv.cpp

    old new  
    405405    if ((width == 1920 || width == 1440) && height == 1088) 
    406406        height = 1080; // ATSC 1920x1080 
    407407 
    408     if (display_res && display_res->SwitchToVideo(width, height)) 
     408    if (display_res && display_res->SwitchToVideo(width, height, video_prate)) 
    409409    { 
    410410        // Switching to custom display resolution succeeded 
    411411        // Make a note of the new size 
  • mythtv/libs/libmythtv/videooutbase.cpp

    old new  
    6868        void          *codec_priv, 
    6969        const QSize   &video_dim, float        video_aspect, 
    7070        WId            win_id,    const QRect &display_rect, 
    71         WId            embed_id) 
     71        float          video_prate,     WId     embed_id) 
    7272{ 
    7373    (void) codec_priv; 
    7474 
     
    167167 
    168168        if (vo) 
    169169        { 
     170            vo->video_prate = video_prate; 
    170171            if (vo->Init( 
    171172                    video_dim.width(), video_dim.height(), video_aspect, 
    172173                    win_id, display_rect.x(), display_rect.y(), 
     
    406407 
    407408void VideoOutput::SetVideoFrameRate(float playback_fps) 
    408409{ 
     410    video_prate = playback_fps; 
    409411    db_vdisp_profile->SetOutput(playback_fps); 
    410412} 
    411413 
  • 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(); 
     
    276276    QSize   video_dim;        ///< Pixel dimensions of video buffer 
    277277    QSize   video_disp_dim;   ///< Pixel dimensions of video display area 
    278278    float   video_aspect;     ///< Physical aspect ratio of video 
     279    float   video_prate;      ///< Playback frame rate of video 
    279280 
    280281    /// Normally this is the same as videoAspect, but may not be 
    281282    /// if the user has toggled the aspect override mode. 
  • 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); 
    25862600        settings->addChild(defaultsettings); 
    25872601        settings->addChild(overrides); 
     2602        settings->addChild(customscreensettings); 
    25882603 
    25892604        addTarget("1", settings); 
    25902605        addTarget("0", new VerticalConfigurationGroup(true)); 
  • 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    } 
  • 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; 
  • 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 vector<float>& refreshRates, const map<float, short>& realrates); 
     24    DisplayResScreen(int w, int h, int mw, int mh, 
     25                     const float* refreshRates, uint rr_length); 
    2226    DisplayResScreen(int w, int h, int mw, int mh, 
    2327                     const short* refreshRates, uint rr_length); 
    2428    DisplayResScreen(const QString &str); 
     
    2933    int Height() const { return height; } 
    3034    int Width_mm() const { return width_mm; } 
    3135    int Height_mm() const { return height_mm; } 
     36    bool Custom() const { return custom; } 
     37 
    3238    inline double AspectRatio() const; 
    33     inline short RefreshRate() const; 
    34     const vector<short>& RefreshRates() const { return refreshRates; } 
     39    inline float RefreshRate() const; 
     40    const vector<float>& RefreshRates() const { return refreshRates; } 
    3541 
    3642    // Sets, adds 
    3743    void SetAspectRatio(double a); 
    38     void AddRefreshRate(short rr) { 
     44    void AddRefreshRate(float rr) { 
    3945        refreshRates.push_back(rr); 
    4046        sort(refreshRates.begin(), refreshRates.end()); 
    4147    } 
    42  
     48    void ClearRefreshRates(void) { 
     49        refreshRates.clear(); 
     50    }    
     51    void SetCustom(bool b) { 
     52        custom = b; 
     53    } 
     54         
     55    // Map for matching real rates and xrandr rate; 
     56    map<float, short> realRates; 
     57    map<short, float> xrandrRates; 
     58         
    4359    // Converters & comparitors 
    4460    QString toString() const; 
    4561    inline bool operator < (const DisplayResScreen& b) const; 
     
    5066    static vector<DisplayResScreen> Convert(const QStringList& slist); 
    5167    static int FindBestMatch(const vector<DisplayResScreen>& dsr, 
    5268                             const DisplayResScreen& d, 
     69                             float& target_rate); 
     70    static int FindBestMatch(const vector<DisplayResScreen>& dsr, 
     71                             const DisplayResScreen& d, 
    5372                             short& target_rate); 
    5473    static inline int CalcKey(int w, int h, int rate); 
     74    static bool compare_rates(float f1, float f2); 
    5575 
    5676  private: 
    5777    int width, height; // size in pixels 
    5878    int width_mm, height_mm; // physical size in millimeters 
    5979    double aspect; // aspect ratio, calculated or set 
    60     vector<short> refreshRates; 
     80    vector<float> refreshRates; 
     81    bool custom;        // Set if resolution was defined manually 
    6182}; 
    6283 
     84 
    6385typedef vector<DisplayResScreen>          DisplayResVector; 
    6486typedef DisplayResVector::iterator        DisplayResVectorIt; 
    6587typedef DisplayResVector::const_iterator  DisplayResVectorCIt; 
     
    85107    return aspect; 
    86108} 
    87109 
    88 inline short DisplayResScreen::RefreshRate() const 
     110inline float DisplayResScreen::RefreshRate() const 
    89111{ 
    90112    if (refreshRates.size() >= 1) 
    91113        return refreshRates[0]; 
    92     else return 0; 
     114    else return 0.0; 
    93115} 
    94116 
    95117inline bool DisplayResScreen::operator < (const DisplayResScreen& b) const 
  • 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        map<uint, DisplayResScreen> customscr; 
     116         
     117        QFileInfo fi(customscreen); 
     118        QFile file(customscreen); 
     119         
     120        if (!fi.exists() || !fi.isFile()) 
     121        { 
     122            VERBOSE(VB_PLAYBACK, QString("CustomScreenRate: \"%1\" failed: does not exist or isn't a file") 
     123                    .arg(customscreen)); 
     124        } 
     125        else if ( file.open(IO_ReadOnly) ) 
     126        { 
     127            QRegExp regexp = QRegExp("^\\s*(\\d+),(\\d+),(\\d+\\.?\\d*),(\\d+)\\s*$"); 
     128            QTextStream stream( &file ); 
     129            QString line; 
     130            int pos; 
     131            while ( !stream.atEnd() ) 
     132            { 
     133                pos = regexp.search(stream.readLine()); 
     134                if (pos > -1) 
     135                { 
     136                    int w = regexp.cap(1).toInt(); 
     137                    int h = regexp.cap(2).toInt(); 
     138                    float hz = regexp.cap(3).toFloat(); 
     139                    int xrandrhz = regexp.cap(4).toShort(); 
     140                    uint key = DisplayResScreen::CalcKey(w, h, 0); 
     141                    // Check if that resolution has already been defined, and if not create a new screen 
     142                    if (customscr.find(key) == customscr.end()) 
     143                    { 
     144                        customscr[key] = DisplayResScreen(w, h, 0, 0, 0, hz); 
     145                    } 
     146                    else 
     147                    { 
     148                        customscr[key].AddRefreshRate(hz); 
     149                    } 
     150                    customscr[key].realRates[hz] = xrandrhz; 
     151                    customscr[key].xrandrRates[xrandrhz] = hz; 
     152                } 
     153            } 
     154            file.close(); 
     155 
     156            // Update existing DisplayResScreen vector, and update it with new frequencies 
     157            for (uint i=0; i < m_video_modes.size(); i++) 
     158            { 
     159                DisplayResScreen scr = m_video_modes[i]; 
     160                int w = scr.Width(); 
     161                int h = scr.Height(); 
     162                int mw = scr.Width_mm(); 
     163                int mh = scr.Height_mm(); 
     164                uint key = DisplayResScreen::CalcKey(w, h, 0); 
     165                if (customscr.find(key) != customscr.end()) 
     166                { 
     167                    // Found custom information for that resolution 
     168                    // Replace xrandr refresh rate, with real one 
     169                    vector<float> newrates; 
     170                    map<float, short> realRates; 
     171                    const vector<float>& rates = scr.RefreshRates(); 
     172                    bool found = false; 
     173                    for (vector<float>::const_iterator it = rates.begin() ; it !=  rates.end();  it++) 
     174                    { 
     175                        if (customscr[key].xrandrRates.find(*it) != customscr[key].xrandrRates.end()) 
     176                        { 
     177                            // Defined in custom rate, use it 
     178                            newrates.push_back(customscr[key].xrandrRates[*it]); 
     179                            realRates[customscr[key].xrandrRates[*it]] = *it; 
     180                            found = true; 
     181                            VERBOSE(VB_PLAYBACK, QString("CustomRate Found, set %1 as %2Hz") .arg(*it) .arg(customscr[key].xrandrRates[*it])); 
     182                        } 
     183                    } 
     184                    if (found) 
     185                    { 
     186                        m_video_modes.erase(m_video_modes.begin() + i); 
     187                        sort(newrates.begin(), newrates.end()); 
     188                        m_video_modes.insert(m_video_modes.begin() + i, DisplayResScreen(w, h, mw, mh, newrates, realRates)); 
     189                    } 
     190                } 
     191            } 
     192        } 
     193    } 
     194 
    90195    m_video_modes_unsorted = m_video_modes; 
    91196    sort(m_video_modes.begin(), m_video_modes.end()); 
    92197 
  • 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;