Ticket #5643: adjust_rate4-trunk20764.patch

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

Patch for trunk #20764

  • mythtv/libs/libmythtv/NuppelVideoPlayer.cpp

    old new  
    737737            GetDecoder()->GetVideoCodecPrivate(), 
    738738            pipState, 
    739739            video_disp_dim, video_aspect, 
    740             widget->winId(), display_rect, 0 /*embedid*/); 
     740            widget->winId(), display_rect, (video_frame_rate * play_speed), 
     741            0 /*embedid*/); 
    741742 
    742743        if (!videoOutput) 
    743744        { 
  • mythtv/libs/libmythtv/videooutbase.cpp

    old new  
    7373        PIPState pipState, 
    7474        const QSize   &video_dim, float        video_aspect, 
    7575        WId            win_id,    const QRect &display_rect, 
    76         WId            embed_id) 
     76        float          video_prate,     WId     embed_id) 
    7777{ 
    7878    (void) codec_priv; 
    7979 
     
    194194        if (vo) 
    195195        { 
    196196            vo->SetPIPState(pipState); 
     197            vo->video_prate = video_prate; 
    197198            if (vo->Init( 
    198199                    video_dim.width(), video_dim.height(), video_aspect, 
    199200                    win_id, display_rect.x(), display_rect.y(), 
     
    419420 
    420421void VideoOutput::SetVideoFrameRate(float playback_fps) 
    421422{ 
     423    video_prate = playback_fps; 
    422424    if (db_vdisp_profile) 
    423425        db_vdisp_profile->SetOutput(playback_fps); 
    424426} 
     
    15131515    if ((width == 1920 || width == 1440) && height == 1088) 
    15141516        height = 1080; // ATSC 1920x1080 
    15151517 
    1516     if (display_res && display_res->SwitchToVideo(width, height)) 
     1518    if (display_res && display_res->SwitchToVideo(width, height, video_prate)) 
    15171519    { 
    15181520        // Switching to custom display resolution succeeded 
    15191521        // Make a note of the new size 
  • mythtv/libs/libmythtv/videooutbase.h

    old new  
    4949        PIPState       pipState, 
    5050        const QSize   &video_dim, float        video_aspect, 
    5151        WId            win_id,    const QRect &display_rect, 
    52         WId            embed_id); 
     52        float video_prate,        WId          embed_id); 
    5353 
    5454    VideoOutput(); 
    5555    virtual ~VideoOutput(); 
     
    297297    bool    db_use_picture_controls; 
    298298 
    299299    VideoDisplayProfile *db_vdisp_profile; 
     300    float   video_prate;  ///< Playback frame rate of video 
    300301 
    301302    // Picture-in-Picture 
    302303    QSize   pip_desired_display_size; 
  • mythtv/libs/libmythui/DisplayRes.cpp

    old new  
    1010#include "DisplayResOSX.h" 
    1111#endif 
    1212 
     13#include <cmath> 
     14 
    1315DisplayRes * DisplayRes::instance = NULL; 
    1416bool         DisplayRes::locked   = false; 
    1517 
     
    5658    // Initialise DESKTOP mode 
    5759    GetDisplayInfo(tW, tH, tW_mm, tH_mm, tRate); 
    5860    mode[DESKTOP].Init(); 
    59     mode[DESKTOP] = DisplayResScreen(tW, tH, tW_mm, tH_mm, -1.0, tRate); 
     61    mode[DESKTOP] = DisplayResScreen(tW, tH, tW_mm, tH_mm, -1.0, (float) tRate); 
    6062    VERBOSE(VB_GENERAL, QString("Desktop video mode: %1x%2 %3 Hz") 
    6163            .arg(tW).arg(tH).arg(tRate)); 
    6264 
    6365    // Initialize GUI mode 
    6466    mode[GUI].Init(); 
    6567    tW = tH = 0; 
    66     GetMythDB()->GetResolutionSetting("GuiVidMode", tW, tH); 
     68    GetMythDB()->GetResolutionSetting("GuiVidMode", tW, tH, tAspect, tRate); 
    6769    GetMythDB()->GetResolutionSetting("DisplaySize", tW_mm, tH_mm); 
    68     mode[GUI] = DisplayResScreen(tW, tH, tW_mm, tH_mm, -1.0, tRate); 
     70    mode[GUI] = DisplayResScreen(tW, tH, tW_mm, tH_mm, -1.0, (float) tRate); 
    6971 
    7072 
    7173    // Initialize default VIDEO mode 
    7274    tW = tH = 0; 
    7375    GetMythDB()->GetResolutionSetting("TVVidMode", tW, tH, tAspect, tRate); 
    74     mode[VIDEO] = DisplayResScreen(tW, tH, tW_mm, tH_mm, tAspect, tRate); 
     76    mode[VIDEO] = DisplayResScreen(tW, tH, tW_mm, tH_mm, tAspect, (float) tRate); 
    7577 
    7678 
    7779    // Initialize video override mode 
     
    8991            break; 
    9092 
    9193        uint key = DisplayResScreen::CalcKey(iw, ih, irate); 
    92         DisplayResScreen scr(ow, oh, tW_mm, tH_mm, oaspect, orate); 
     94        DisplayResScreen scr(ow, oh, tW_mm, tH_mm, oaspect, (float)orate); 
    9395        in_size_to_output_mode[key] = scr;             
    9496    } 
    9597 
     
    107109    return true; 
    108110} 
    109111 
    110 bool DisplayRes::SwitchToVideo(int iwidth, int iheight, short irate) 
     112bool DisplayRes::SwitchToVideo(int iwidth, int iheight, float frate) 
    111113{ 
    112114    tmode next_mode = VIDEO; // default VIDEO mode 
    113115    DisplayResScreen next = mode[next_mode]; 
    114116 
     117    // If requested refresh rate is 0, attempt to match video fps 
     118    if (next.RefreshRate() == 0) 
     119    { 
     120        VERBOSE(VB_PLAYBACK, QString("*** Trying to match best resolution %1Hz") .arg(frate)); 
     121        next.AddRefreshRate(frate); 
     122    } 
     123 
    115124    // try to find video override mode 
    116     uint key = DisplayResScreen::CalcKey(iwidth, iheight, irate); 
     125    uint key = DisplayResScreen::CalcKey(iwidth, iheight, (short) roundf(frate)); 
    117126    DisplayResMapCIt it = in_size_to_output_mode.find(key); 
    118127    if (it != in_size_to_output_mode.end()) 
    119128        mode[next_mode = CUSTOM_VIDEO] = next = it->second; 
    120129 
    121130    // need to change video mode? 
    122     short target_rate = 0; 
     131    float target_rate = 0.0; 
    123132    DisplayResScreen::FindBestMatch(GetVideoModes(), next, target_rate); 
    124     bool chg = !(next == last) || !(last.RefreshRate() == target_rate); 
     133    bool chg = !(next == last) || !(DisplayResScreen::compare_rates(last.RefreshRate(),target_rate)); 
    125134 
    126135    VERBOSE(VB_PLAYBACK, QString("Trying %1x%2 %3 Hz") 
    127136            .arg(next.Width()).arg(next.Height()).arg(target_rate)); 
     
    153162    DisplayResScreen next = mode[next_mode]; 
    154163 
    155164    // need to change video mode? 
    156     short target_rate = next.RefreshRate(); 
     165    float target_rate = next.RefreshRate(); 
    157166    DisplayResScreen::FindBestMatch(GetVideoModes(), next, target_rate); 
    158     bool chg = !(next == last) || !(last.RefreshRate() == target_rate); 
     167    // If GuiVidModeRefreshRate is 0, assume any refresh rate is good enough. 
     168    bool chg = (!(next == last) || (next.RefreshRate() !=0 
     169                && !(DisplayResScreen::compare_rates(last.RefreshRate(), target_rate))));  
    159170 
    160171    VERBOSE(VB_GENERAL, QString("Trying %1x%2 %3 Hz") 
    161172            .arg(next.Width()).arg(next.Height()).arg(target_rate)); 
     
    180191bool DisplayRes::SwitchToCustomGUI(int width, int height, short rate) 
    181192{ 
    182193    mode[CUSTOM_GUI] = DisplayResScreen(width, height, mode[GUI].Width_mm(), 
    183                                         mode[GUI].Height_mm(), -1.0, rate); 
     194                                        mode[GUI].Height_mm(), -1.0, (float)rate); 
    184195    return SwitchToGUI(CUSTOM_GUI); 
    185196} 
    186197 
    187 const std::vector<short> DisplayRes::GetRefreshRates(int width, 
    188                                                      int height) const { 
    189     short tr; 
    190     std::vector<short> empty; 
     198const std::vector<short> DisplayRes::GetRefreshRates(int width, int height) const { 
     199    std::vector<short> srates; 
     200    std::vector<float> rates = GetRefreshRatesFloat(width, height); 
     201 
     202    for (int i=0; i<rates.size(); i++) 
     203        srates.push_back((short) rates[i]); 
     204    return srates; 
     205} 
     206const std::vector<float> DisplayRes::GetRefreshRatesFloat(int width, int height) const { 
     207    float tr; 
     208    std::vector<float> empty; 
    191209 
    192     const DisplayResScreen drs(width, height, 0, 0, -1.0, 0); 
     210    const DisplayResScreen drs(width, height, 0, 0, -1.0, 0.0); 
    193211    const DisplayResVector& drv = GetVideoModes(); 
    194212    int t = DisplayResScreen::FindBestMatch(drv, drs, tr); 
    195213    if (t < 0) 
  • mythtv/libs/libmythui/DisplayRes.h

    old new  
    5959     * @{ 
    6060     */ 
    6161 
    62     /** \fn SwitchToVideo(int iwidth, int iheight, short irate = 0) 
     62    /** \fn SwitchToVideo(int iwidth, int iheight, float frate = 0) 
    6363     *  \brief Switches to the resolution and refresh rate defined in the 
    6464     *         database for the specified video resolution and frame rate. 
    6565     */ 
    66     bool SwitchToVideo(int iwidth, int iheight, short irate = 0); 
     66    bool SwitchToVideo(int iwidth, int iheight, float frate = 0.0); 
    6767    /** \brief Switches to the GUI resolution specified. 
    6868     * 
    6969     *   If which_gui is GUI then this switches to the resolution 
     
    127127    /// \brief Returns all video modes supported by the display. 
    128128    virtual const std::vector<DisplayResScreen>& GetVideoModes() const = 0; 
    129129    /// \brief Returns refresh rates available at a specific screen resolution. 
     130    const std::vector<float> GetRefreshRatesFloat(int width, int height) const; 
    130131    const std::vector<short> GetRefreshRates(int width, int height) const; 
    131132    /** @} */ 
    132133 
     
    138139    // These methods are implemented by the subclasses 
    139140    virtual bool GetDisplayInfo(int &w_pix, int &h_pix, int &w_mm, 
    140141                                int &h_mm, short &rate) const = 0; 
    141     virtual bool SwitchToVideoMode(int width, int height, short framerate) = 0; 
     142    virtual bool SwitchToVideoMode(int width, int height, float framerate) = 0; 
    142143 
    143144  private: 
    144145    DisplayRes(const DisplayRes & rhs); // disable copy constructor; 
  • mythtv/libs/libmythui/DisplayResOSX.cpp

    old new  
    7070    return d; 
    7171} 
    7272 
    73 bool DisplayResOSX::SwitchToVideoMode(int width, int height, short refreshrate) 
     73bool DisplayResOSX::SwitchToVideoMode(int width, int height, float refreshrate) 
    7474{ 
    7575    CGDirectDisplayID d = mythtv_display(); 
    7676    CFDictionaryRef dispMode = NULL; 
     
    7979    // find mode that matches the desired size 
    8080    if (refreshrate) 
    8181        dispMode = CGDisplayBestModeForParametersAndRefreshRate( 
    82             d, 32, width, height, (CGRefreshRate)(refreshrate), &match); 
     82            d, 32, width, height, (CGRefreshRate)((short)refreshrate), &match); 
    8383 
    8484    if (!match) 
    8585        dispMode =  
     
    126126 
    127127        if (screen_map.find(key)==screen_map.end()) 
    128128            screen_map[key] = DisplayResScreen(width, height, 
    129                                                0, 0, -1.0, refresh); 
     129                                               0, 0, -1.0, (float) refresh); 
    130130        else 
    131131            screen_map[key].AddRefreshRate(refresh); 
    132132    } 
  • mythtv/libs/libmythui/DisplayResOSX.h

    old new  
    1313  protected: 
    1414    bool GetDisplayInfo(int &w_pix, int &h_pix, int &w_mm, 
    1515                        int &h_mm, short &rate) const; 
    16     bool SwitchToVideoMode(int width, int height, short framerate); 
     16    bool SwitchToVideoMode(int width, int height, float framerate); 
    1717     
    1818  private: 
    1919    mutable std::vector<DisplayResScreen> m_video_modes; 
  • mythtv/libs/libmythui/DisplayResScreen.cpp

    old new  
    11#include <QStringList> 
    22 
    33#include "DisplayResScreen.h" 
     4#include <cmath> 
    45 
    56DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh, 
    6                                    double aspectRatio, short refreshRate) 
    7     : 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) 
    89{ 
    910    SetAspectRatio(aspectRatio); 
    1011    if (refreshRate > 0) 
     
    1213} 
    1314 
    1415DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh, 
    15                                    const std::vector<short>& rr) 
    16     : width(w), height(h), width_mm(mw), height_mm(mh), refreshRates(rr) 
     16                                   const std::vector<float>& rr) 
     17    : width(w), height(h), width_mm(mw), height_mm(mh), refreshRates(rr), custom(false) 
    1718{ 
    1819    SetAspectRatio(-1.0); 
    1920} 
    2021 
    2122DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh, 
    22                                    const short* rr, uint rr_length) 
    23     : width(w), height(h), width_mm(mw), height_mm(mh) 
     23                                   const std::vector<float>& rr, const std::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) 
    2432{ 
    2533    SetAspectRatio(-1.0); 
    2634    for (uint i = 0; i < rr_length; ++i) 
     
    2937    std::sort(refreshRates.begin(), refreshRates.end()); 
    3038} 
    3139 
     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    std::sort(refreshRates.begin(), refreshRates.end()); 
     50} 
     51 
    3252DisplayResScreen::DisplayResScreen(const QString &str) 
    33     : 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) 
    3454{ 
    3555    refreshRates.clear(); 
    3656    QStringList slist = str.split(":"); 
     
    4464        height_mm = slist[3].toInt(); 
    4565        aspect = slist[4].toDouble(); 
    4666        for (int i = 5; i<slist.size(); ++i) 
    47             refreshRates.push_back(slist[i].toShort()); 
     67            refreshRates.push_back(slist[i].toFloat()); 
    4868    } 
    4969} 
    5070 
     
    81101    return dsr; 
    82102} 
    83103 
     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 
    84119int DisplayResScreen::FindBestMatch(const std::vector<DisplayResScreen>& dsr, 
    85120                                    const DisplayResScreen& d, 
    86121                                    short& target_rate) 
    87122{ 
     123    float target; 
     124    int i = FindBestMatch(dsr, d, target); 
     125    target_rate = target; 
     126    return i; 
     127} 
     128 
     129int DisplayResScreen::FindBestMatch(const std::vector<DisplayResScreen>& dsr, 
     130                                    const DisplayResScreen& d, 
     131                                    float& target_rate) 
     132{ 
     133  // Amend vector with custom list 
    88134    for (uint i=0; i<dsr.size(); ++i) 
    89135    { 
    90136        if (dsr[i].Width()==d.Width() && dsr[i].Height()==d.Height()) 
    91137        { 
    92             const std::vector<short>& rates = dsr[i].RefreshRates(); 
    93             if (rates.size()) 
     138            const std::vector<float>& rates = dsr[i].RefreshRates(); 
     139            if (rates.size() && d.RefreshRate() != 0) 
    94140            { 
    95                 std::vector<short>::const_iterator it = 
    96                     find(rates.begin(), rates.end(), d.RefreshRate()); 
    97                 target_rate = (it == rates.end()) ? *(--rates.end()) : *it; 
    98                 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]; 
    99162            } 
     163            return i; 
    100164        } 
    101165    } 
    102166    return -1; 
  • mythtv/libs/libmythui/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 std::vector<short>& refreshRates); 
     21                     const std::vector<float>& refreshRates); 
     22    DisplayResScreen(int w, int h, int mw, int mh, 
     23                     const std::vector<float>& refreshRates, const std::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 std::vector<short>& RefreshRates() const { return refreshRates; } 
     39    inline float RefreshRate() const; 
     40    const std::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        std::sort(refreshRates.begin(), refreshRates.end()); 
    4147    } 
     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    std::map<float, short> realRates; 
     57    std::map<short, float> xrandrRates; 
    4258 
    4359    // Converters & comparitors 
    4460    QString toString() const; 
     
    5066    static std::vector<DisplayResScreen> Convert(const QStringList& slist); 
    5167    static int FindBestMatch(const std::vector<DisplayResScreen>& dsr, 
    5268                             const DisplayResScreen& d, 
     69                             float& target_rate); 
     70    static int FindBestMatch(const std::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     std::vector<short> refreshRates; 
     80    std::vector<float> refreshRates; 
     81    bool custom;        // Set if resolution was defined manually 
    6182}; 
    6283 
    6384typedef std::vector<DisplayResScreen>          DisplayResVector; 
     
    85106    return aspect; 
    86107} 
    87108 
    88 inline short DisplayResScreen::RefreshRate() const 
     109inline float DisplayResScreen::RefreshRate() const 
    89110{ 
    90111    if (refreshRates.size() >= 1) 
    91112        return refreshRates[0]; 
    92     else return 0; 
     113    else return 0.0; 
    93114} 
    94115 
    95116inline bool DisplayResScreen::operator < (const DisplayResScreen& b) const 
  • mythtv/libs/libmythui/DisplayResX.cpp

    old new  
    11#include <iostream> 
    22 
     3#include "config.h" 
     4#include "DisplayResX.h" 
     5#include "mythverbose.h" 
     6#include "mythdb.h" 
     7 
    38#include "mythxdisplay.h" 
    49 
    5 #include <X11/extensions/Xrandr.h> // this has to be after util-x11.h (Qt bug) 
     10#include <QRegExp> 
     11#include <QIODevice> 
     12#include <QFileInfo> 
    613 
    7 #include "DisplayResX.h" 
     14#include <X11/extensions/Xrandr.h> // this has to be after util-x11.h (Qt bug) 
    815 
    916using std::cerr; 
    1017using std::endl; 
     
    4754    return success; 
    4855} 
    4956 
    50 bool DisplayResX::SwitchToVideoMode(int width, int height, short desired_rate) 
     57bool DisplayResX::SwitchToVideoMode(int width, int height, float desired_rate) 
    5158{ 
    52     short rate; 
     59    float rate; 
     60    short finalrate; 
    5361    DisplayResScreen desired_screen(width, height, 0, 0, -1.0, desired_rate); 
    5462    int idx = DisplayResScreen::FindBestMatch(m_video_modes_unsorted, 
    5563                                              desired_screen, rate); 
     
    6371        Rotation rot; 
    6472        XRRConfigCurrentConfiguration(cfg, &rot); 
    6573         
     74        // Search real xrandr rate for desired_rate 
     75        finalrate = (short) rate; 
     76        for (uint i=0; i < m_video_modes.size(); i++) { 
     77            if ((m_video_modes[i].Width() == width) && (m_video_modes[i].Height() == height)) 
     78            { 
     79                if (m_video_modes[i].Custom()) 
     80                { 
     81                    finalrate = m_video_modes[i].realRates[rate]; 
     82                    VERBOSE(VB_PLAYBACK, QString("CustomRate Found, set %1Hz as %2") .arg(rate) .arg(finalrate)); 
     83                } 
     84                break; 
     85            } 
     86        } 
     87 
    6688        Window root = display->GetRoot(); 
    6789        Status status = XRRSetScreenConfigAndRate(display->GetDisplay(), cfg, 
    68                                                   root, idx, rot, rate, 
     90                                                  root, idx, rot, finalrate, 
    6991                                                  CurrentTime); 
    7092         
    7193        XRRFreeScreenConfigInfo(cfg); 
     
    102124                             rates, num_rates); 
    103125        m_video_modes.push_back(scr); 
    104126    } 
     127 
     128    QString customscreen = GetMythDB()->GetSetting("CustomScreenRate"); 
     129    if (GetMythDB()->GetNumSetting("UseVideoModes", 0) && customscreen.size()); 
     130    { 
     131        std::map<uint, DisplayResScreen> customscr; 
     132         
     133        QFileInfo fi(customscreen); 
     134        QFile file(customscreen); 
     135 
     136        if (!fi.exists() || !fi.isFile()) 
     137        { 
     138            VERBOSE(VB_PLAYBACK, QString("CustomScreenRate: \"%1\" failed: does not exist or isn't a file") 
     139                    .arg(customscreen)); 
     140        } 
     141        else if ( file.open(QIODevice::ReadOnly) ) { 
     142            QRegExp regexp = QRegExp("^\\s*(\\d+),(\\d+),(\\d+\\.?\\d*),(\\d+)\\s*$"); 
     143            QTextStream stream( &file ); 
     144            QString line; 
     145            int pos; 
     146            while ( !stream.atEnd() ) 
     147            { 
     148                pos = regexp.indexIn(stream.readLine()); 
     149                if (pos > -1) 
     150                { 
     151                    int w = regexp.cap(1).toInt(); 
     152                    int h = regexp.cap(2).toInt(); 
     153                    float hz = regexp.cap(3).toFloat(); 
     154                    int xrandrhz = regexp.cap(4).toShort(); 
     155                    uint key = DisplayResScreen::CalcKey(w, h, 0); 
     156                    // Check if that resolution has already been defined, and if not create a new screen 
     157                    if (customscr.find(key) == customscr.end()) 
     158                    { 
     159                        customscr[key] = DisplayResScreen(w, h, 0, 0, 0, hz); 
     160                    } 
     161                    else 
     162                    { 
     163                        customscr[key].AddRefreshRate(hz); 
     164                    } 
     165                    customscr[key].realRates[hz] = xrandrhz; 
     166                    customscr[key].xrandrRates[xrandrhz] = hz; 
     167                } 
     168            } 
     169            file.close(); 
     170 
     171            // Update existing DisplayResScreen vector, and update it with new frequencies 
     172            for (uint i=0; i < m_video_modes.size(); i++) 
     173            { 
     174                DisplayResScreen scr = m_video_modes[i]; 
     175                int w = scr.Width(); 
     176                int h = scr.Height(); 
     177                int mw = scr.Width_mm(); 
     178                int mh = scr.Height_mm(); 
     179                uint key = DisplayResScreen::CalcKey(w, h, 0); 
     180                if (customscr.find(key) != customscr.end()) 
     181                { 
     182                    // Found custom information for that resolution 
     183                    // Replace xrandr refresh rate, with real one 
     184                    std::vector<float> newrates; 
     185                    std::map<float, short> realRates; 
     186                    const std::vector<float>& rates = scr.RefreshRates(); 
     187                    bool found = false; 
     188                    for (std::vector<float>::const_iterator it = rates.begin() ; it !=  rates.end();  it++) 
     189                    { 
     190                        if (customscr[key].xrandrRates.find(*it) != customscr[key].xrandrRates.end()) 
     191                        { 
     192                            // Defined in custom rate, use it 
     193                            newrates.push_back(customscr[key].xrandrRates[*it]); 
     194                            realRates[customscr[key].xrandrRates[*it]] = *it; 
     195                            found = true; 
     196                            VERBOSE(VB_PLAYBACK, QString("CustomRate Found, set %1 as %2Hz") .arg(*it) .arg(customscr[key].xrandrRates[*it])); 
     197                        } 
     198                    } 
     199                    if (found) 
     200                    { 
     201                        m_video_modes.erase(m_video_modes.begin() + i); 
     202                        std::sort(newrates.begin(), newrates.end()); 
     203                        m_video_modes.insert(m_video_modes.begin() + i, DisplayResScreen(w, h, mw, mh, newrates, realRates)); 
     204                    } 
     205                } 
     206            } 
     207        } 
     208    } 
     209 
    105210    m_video_modes_unsorted = m_video_modes; 
    106211    std::sort(m_video_modes.begin(), m_video_modes.end()); 
    107212    XRRFreeScreenConfigInfo(cfg); 
  • mythtv/programs/mythfrontend/globalsettings.cpp

    old new  
    25252525    return gc; 
    25262526} 
    25272527 
     2528static HostLineEdit *CustomScreenConfig() 
     2529{ 
     2530    HostLineEdit *gedit = new HostLineEdit("CustomScreenRate"); 
     2531    gedit->setLabel(QObject::tr("Custom screen rate definition file")); 
     2532    gedit->setHelpText(QObject::tr("Custom screen resolution configuration " 
     2533                                        "for matching xrandr value.")); 
     2534    return gedit; 
     2535} 
     2536 
    25282537static HostSpinBox *VidModeWidth(int idx) 
    25292538{ 
    25302539    HostSpinBox *gs = new HostSpinBox(QString("VidModeWidth%1").arg(idx), 
     
    26932702                    rate, SLOT(ChangeResolution(const QString&))); 
    26942703        } 
    26952704 
     2705        ConfigurationGroup* customscreensettings = 
     2706            new HorizontalConfigurationGroup(false, false); 
     2707 
     2708        customscreensettings->addChild(CustomScreenConfig()); 
     2709 
    26962710        ConfigurationGroup* settings = new VerticalConfigurationGroup(false); 
    26972711        settings->addChild(defaultsettings); 
    26982712        settings->addChild(overrides); 
     2713        settings->addChild(customscreensettings); 
    26992714 
    27002715        addTarget("1", settings); 
    27012716        addTarget("0", new VerticalConfigurationGroup(true)); 
  • mythtv/libs/libmythui/DisplayResX.h

    old new  
    1313  protected: 
    1414    bool GetDisplayInfo(int &w_pix, int &h_pix, int &w_mm, 
    1515                        int &h_mm, short &rate) const; 
    16     bool SwitchToVideoMode(int width, int height, short framerate); 
     16    bool SwitchToVideoMode(int width, int height, float framerate); 
    1717 
    1818  private: 
    1919    mutable std::vector<DisplayResScreen> m_video_modes;