Ticket #5643: adjust_rate4-trunk20764.patch

File adjust_rate4-trunk20764.patch, 29.0 KB (added by jyavenard@…, 11 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;