Ticket #5643: adjust_rate4-fixes.patch

File adjust_rate4-fixes.patch, 28.6 KB (added by jyavenard@…, 15 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;