Ticket #5643: adjust_rate.diff

File adjust_rate.diff, 37.6 KB (added by jyavenard@…, 11 years ago)

Handle nvidia refresh rates and non-integer frequencies...

  • version.pro

     
    1717version.target = version.cpp
    1818
    1919version.commands = sh -c "echo 'const char *myth_source_version =' \
    20 '\"'`(svnversion $${SVNTREEDIR} 2>/dev/null) || echo Unknown`'\";' \
     20'\"'19990-openglvdpau'\";' \
    2121> .vers.new"
    2222
    2323version.commands += ; sh -c "echo 'const char *myth_source_path =' \
  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    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        {
     
    650651        videoOutput->SetVideoScalingAllowed(db_scale);
    651652
    652653        // We need to tell it this for automatic deinterlacer settings
    653         videoOutput->SetVideoFrameRate(video_frame_rate * play_speed);
     654        videoOutput->SetVideoFrameRate(video_frame_rate * play_speed);
    654655
    655656        if (videoOutput->hasMCAcceleration() && !decode_extra_audio)
    656657        {
  • libs/libmythtv/videoout_d3d.cpp

     
    451451
    452452bool VideoOutputD3D::Init(int width, int height, float aspect,
    453453                          WId winid, int winx, int winy, int winw,
    454                           int winh, WId embedid)
     454                          int winh, float video_prate, WId embedid)
    455455{
    456456    VERBOSE(VB_PLAYBACK, LOC +
    457457            "Init w=" << width << " h=" << height);
     
    462462                  kPrebufferFramesNormal, kPrebufferFramesSmall,
    463463                  kKeepPrebuffer);
    464464
    465     VideoOutput::Init(width, height, aspect, winid,
    466                       winx, winy, winw, winh, embedid);
     465    VideoOutput::Init(width, height, aspect, winid, winx,
     466                      winy, winw, winh, video_prate, embedid);
    467467
    468468    m_hWnd = winid;
    469469
  • libs/libmythtv/videoout_quartz.cpp

     
    11921192}
    11931193
    11941194bool VideoOutputQuartz::Init(int width, int height, float aspect,
    1195                              WId winid, int winx, int winy,
    1196                              int winw, int winh, WId embedid)
     1195                             WId winid, int winx, int winy, int winw,
     1196                             int winh, float video_prate, WId embedid)
    11971197{
    11981198    VERBOSE(VB_PLAYBACK, LOC +
    11991199            QString("Init(WxH %1x%2, aspect=%3, winid=%4\n\t\t\t"
     
    12151215    vbuffers.Init(kNumBuffers, true, kNeedFreeFrames,
    12161216                  kPrebufferFramesNormal, kPrebufferFramesSmall,
    12171217                  kKeepPrebuffer);
    1218     VideoOutput::Init(width, height, aspect, winid,
    1219                       winx, winy, winw, winh, embedid);
     1218    VideoOutput::Init(width, height, aspect, winid, winx,
     1219                      winy, winw, winh, video_prate, embedid);
    12201220
    12211221    data->srcWidth  = video_dim.width();
    12221222    data->srcHeight = video_dim.height();
     
    13811381
    13821382void VideoOutputQuartz::SetVideoFrameRate(float playback_fps)
    13831383{
     1384    video_prate = playback_fps;
    13841385    VERBOSE(VB_PLAYBACK, "SetVideoFrameRate("<<playback_fps<<")");
    13851386}
    13861387
  • libs/libmythtv/videoout_dx.h

     
    2121   ~VideoOutputDX();
    2222
    2323    bool Init(int width, int height, float aspect, WId winid,
    24               int winx, int winy, int winw, int winh, WId embedid = 0);
     24              int winx, int winy, int winw, int winh,
     25              float video_prate, WId embedid = 0);
    2526    void PrepareFrame(VideoFrame *buffer, FrameScanType);
    2627    void Show(FrameScanType );
    2728
  • libs/libmythtv/videoout_directfb.cpp

     
    353353
    354354bool VideoOutputDirectfb::Init(int width, int height, float aspect, WId winid,
    355355                               int winx, int winy, int winw, int winh,
    356                                WId embedid)
     356                               float video_prate, WId embedid)
    357357{
    358358    // Hack to avoid embedded video output...
    359359    if ((winw < 320) || (winh < 240))
     
    646646                           display_visible_rect.y(),
    647647                           display_visible_rect.width(),
    648648                           display_visible_rect.height(),
    649                            embedid))
     649                           video_prate, embedid))
    650650    {
    651651        return false;
    652652    }
  • libs/libmythtv/videoout_d3d.h

     
    2020   ~VideoOutputD3D();
    2121
    2222    bool Init(int width, int height, float aspect, WId winid,
    23               int winx, int winy, int winw, int winh, WId embedid = 0);
     23              int winx, int winy, int winw, int winh,
     24              float video_prate, WId embedid = 0);
    2425
    2526    bool InitD3D();
    2627    void UnInitD3D();
  • libs/libmythtv/videoout_ivtv.h

     
    1616   ~VideoOutputIvtv();
    1717
    1818    bool Init(int width, int height, float aspect, WId winid,
    19               int winx, int winy, int winw, int winh, WId embedid = 0);
     19              int winx, int winy, int winw, int winh,
     20              float video_prate, WId embedid = 0);
    2021    void PrepareFrame(VideoFrame *buffer, FrameScanType);
    2122    void Show(FrameScanType );
    2223
  • libs/libmythtv/videoout_null.cpp

     
    115115
    116116bool VideoOutputNull::Init(int width, int height, float aspect,
    117117                           WId winid, int winx, int winy, int winw,
    118                            int winh, WId embedid)
     118                           int winh, float video_prate, WId embedid)
    119119{
    120120    if ((width <= 0) || (height <= 0))
    121121        return false;
    122122
    123123    QMutexLocker locker(&global_lock);
    124124
    125     VideoOutput::Init(width, height, aspect, winid,
    126                       winx, winy, winw, winh, embedid);
     125    VideoOutput::Init(width, height, aspect, winid, winx,
     126                      winy, winw, winh, video_prate, embedid);
    127127
    128128    vbuffers.Init(kNumBuffers, true, kNeedFreeFrames,
    129129                  kPrebufferFramesNormal, kPrebufferFramesSmall,
  • libs/libmythtv/videooutbase.cpp

     
    6767        void          *codec_priv,
    6868        const QSize   &video_dim, float        video_aspect,
    6969        WId            win_id,    const QRect &display_rect,
    70         WId            embed_id)
     70        float video_prate,        WId            embed_id)
    7171{
    7272    (void) codec_priv;
    7373
     
    166166
    167167        if (vo)
    168168        {
     169            vo->video_prate = video_prate;
    169170            if (vo->Init(
    170171                    video_dim.width(), video_dim.height(), video_aspect,
    171172                    win_id, display_rect.x(), display_rect.y(),
    172                     display_rect.width(), display_rect.height(), embed_id))
     173                    display_rect.width(), display_rect.height(),
     174                    video_prate, embed_id))
    173175            {
    174176                return vo;
    175177            }
     
    181183        renderer = VideoDisplayProfile::GetBestVideoRenderer(renderers);
    182184    }
    183185
     186
     187
    184188    VERBOSE(VB_IMPORTANT, LOC_ERR +
    185189            "Not compiled with any useable video output method.");
    186190
     
    363367 * \return true if successful, false otherwise.
    364368 */
    365369bool VideoOutput::Init(int width, int height, float aspect, WId winid,
    366                        int winx, int winy, int winw, int winh, WId embedid)
     370                       int winx, int winy, int winw, int winh,
     371                       float video_prate, WId embedid)
    367372{
    368373    (void)winid;
    369374    (void)embedid;
     
    405410
    406411void VideoOutput::SetVideoFrameRate(float playback_fps)
    407412{
     413    video_prate = playback_fps;
    408414    db_vdisp_profile->SetOutput(playback_fps);
    409415}
    410416
  • libs/libmythtv/videoout_directfb.h

     
    1414    ~VideoOutputDirectfb();
    1515
    1616    bool Init(int width, int height, float aspect, WId winid,
    17               int winx, int winy, int winw, int winh, WId embedid = 0);
     17              int winx, int winy, int winw, int winh,
     18              float video_prate, WId embedid = 0);
    1819
    1920    void ProcessFrame(VideoFrame *frame, OSD *osd,
    2021                      FilterChain *filterList,
  • libs/libmythtv/videoout_xv.h

     
    6060   ~VideoOutputXv();
    6161
    6262    bool Init(int width, int height, float aspect, WId winid,
    63               int winx, int winy, int winw, int winh, WId embedid = 0);
     63              int winx, int winy, int winw, int winh,
     64              float video_prate, WId embedid = 0);
    6465
    6566    bool SetDeinterlacingEnabled(bool);
    6667    bool SetupDeinterlace(bool interlaced, const QString& ovrf="");
  • libs/libmythtv/videoout_xv.cpp

     
    405405    if ((width == 1920 || width == 1440) && height == 1088)
    406406        height = 1080; // ATSC 1920x1080
    407407
    408     if (display_res && display_res->SwitchToVideo(width, height))
    409     {
     408    if (display_res && display_res->SwitchToVideo(width, height,
     409                                                  (short) roundf(video_prate), video_prate))
     410        {
    410411        // Switching to custom display resolution succeeded
    411412        // Make a note of the new size
    412413        display_dim = QSize(display_res->GetPhysicalWidth(),
     
    15681569}
    15691570
    15701571/**
    1571  * \fn VideoOutputXv::Init(int,int,float,WId,int,int,int,int,WId)
     1572 * \fn VideoOutputXv::Init(int,int,float,WId,int,int,int,int,float,WId)
    15721573 * Initializes class for video output.
    15731574 *
    15741575 * \return success or failure.
    15751576 */
    15761577bool VideoOutputXv::Init(
    1577     int width, int height, float aspect,
    1578     WId winid, int winx, int winy, int winw, int winh, WId embedid)
     1578    int width, int height, float aspect, WId winid, int winx,
     1579    int winy, int winw, int winh, float video_prate, WId embedid)
    15791580{
    15801581    needrepaint = true;
    15811582
     
    16091610    // Basic setup
    16101611    VideoOutput::Init(width, height, aspect,
    16111612                      winid, winx, winy, winw, winh,
    1612                       embedid);
     1613                      video_prate, embedid);
    16131614
    16141615    // Set resolution/measurements (check XRandR, Xinerama, config settings)
    16151616    InitDisplayMeasurements(width, height);
  • libs/libmythtv/videooutbase.h

     
    3636        void          *codec_priv,
    3737        const QSize   &video_dim, float        video_aspect,
    3838        WId            win_id,    const QRect &display_rect,
    39         WId            embed_id);
     39        float video_prate,        WId            embed_id);
    4040
    4141    VideoOutput();
    4242    virtual ~VideoOutput();
    4343
    4444    virtual bool Init(int width, int height, float aspect,
    4545                      WId winid, int winx, int winy, int winw,
    46                       int winh, WId embedid = 0);
     46                      int winh, float video_prate, WId embedid = 0);
    4747    virtual void InitOSD(OSD *osd);
    4848    virtual void SetVideoFrameRate(float);
    4949
     
    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.
  • libs/libmythtv/videoout_ivtv.cpp

     
    405405
    406406bool VideoOutputIvtv::Init(int width, int height, float aspect,
    407407                           WId winid, int winx, int winy, int winw,
    408                            int winh, WId embedid)
     408                           int winh, float video_prate, WId embedid)
    409409{
    410410    VERBOSE(VB_PLAYBACK, LOC + "Init() -- begin");
    411411
     
    416416    videoDevice = gContext->GetSetting("PVR350VideoDev");
    417417
    418418    VideoOutput::Init(width, height, aspect, winid, winx, winy, winw, winh,
    419                       embedid);
     419                      video_prate, embedid);
    420420
    421421    osdbufsize = video_dim.width() * video_dim.height() * 4;
    422422
  • libs/libmythtv/videoout_quartz.h

     
    1313   ~VideoOutputQuartz();
    1414
    1515    bool Init(int width, int height, float aspect, WId winid,
    16               int winx, int winy, int winw, int winh, WId embedid = 0);
     16              int winx, int winy, int winw, int winh,
     17              float video_prate, WId embedid = 0);
    1718    void SetVideoFrameRate(float playback_fps);
    1819    void PrepareFrame(VideoFrame *buffer, FrameScanType t);
    1920    void Show(FrameScanType);
  • libs/libmythtv/videoout_dx.cpp

     
    158158}
    159159
    160160bool VideoOutputDX::Init(int width, int height, float aspect,
    161                            WId winid, int winx, int winy, int winw,
    162                            int winh, WId embedid)
     161                         WId winid, int winx, int winy, int winw,
     162                         int winh, float video_prate, WId embedid)
    163163{
    164164    db_vdisp_profile->SetVideoRenderer("directx");
    165165
    166166    vbuffers.Init(kNumBuffers, true, kNeedFreeFrames,
    167167                  kPrebufferFramesNormal, kPrebufferFramesSmall,
    168168                  kKeepPrebuffer);
    169     VideoOutput::Init(width, height, aspect, winid,
    170                       winx, winy, winw, winh, embedid);
     169    VideoOutput::Init(width, height, aspect, winid, winx,
     170                      winy, winw, winh, video_prate, embedid);
    171171
    172172    wnd = winid;
    173173
  • libs/libmythtv/videoout_null.h

     
    1212   ~VideoOutputNull();
    1313
    1414    bool Init(int width, int height, float aspect, WId winid,
    15               int winx, int winy, int winw, int winh, WId embedid = 0);
     15              int winx, int winy, int winw, int winh,
     16              float video_prate, WId embedid = 0);
    1617
    1718    bool SetupDeinterlace(bool, const QString &ovrf = "")
    1819        { (void)ovrf; return false; } // we don't deinterlace in null output..
  • libs/libmyth/DisplayRes.cpp

     
    3737    // Initialize GUI mode
    3838    mode[GUI].Init();
    3939    tW = tH = 0;
    40     gContext->GetResolutionSetting("GuiVidMode", tW, tH);
     40    gContext->GetResolutionSetting("GuiVidMode", tW, tH, tAspect, tRate);
    4141    GetDisplaySize(tW_mm, tH_mm);
    4242    gContext->GetResolutionSetting("DisplaySize", tW_mm, tH_mm);
    43     mode[GUI] = DisplayResScreen(tW, tH, tW_mm, tH_mm, -1.0, 0);
     43    mode[GUI] = DisplayResScreen(tW, tH, tW_mm, tH_mm, -1.0, (float)tRate);
    4444
    4545
    4646    // Initialize default VIDEO mode
    4747    tW = tH = 0;
    4848    gContext->GetResolutionSetting("TVVidMode", tW, tH, tAspect, tRate);
    49     mode[VIDEO] = DisplayResScreen(tW, tH, tW_mm, tH_mm, tAspect, tRate);
     49    mode[VIDEO] = DisplayResScreen(tW, tH, tW_mm, tH_mm, tAspect, (float)tRate);
    5050
    5151
    5252    // Initialize video override mode
     
    6464            break;
    6565
    6666        uint key = DisplayResScreen::CalcKey(iw, ih, irate);
    67         DisplayResScreen scr(ow, oh, tW_mm, tH_mm, oaspect, orate);
     67        DisplayResScreen scr(ow, oh, tW_mm, tH_mm, oaspect, (float) orate);
    6868        in_size_to_output_mode[key] = scr;           
    6969    }
    7070
     
    8282    return true;
    8383}
    8484
    85 bool DisplayRes::SwitchToVideo(int iwidth, int iheight, short irate)
     85bool DisplayRes::SwitchToVideo(int iwidth, int iheight, short irate, float frate)
    8686{
    8787    tmode next_mode = VIDEO; // default VIDEO mode
    8888    DisplayResScreen next = mode[next_mode];
    8989
     90    // If requested refresh rate is 0, attempt to match video fps
     91    if (next.RefreshRate() == 0)
     92    {
     93        VERBOSE(VB_PLAYBACK, QString("*** Trying to match best resolution %1Hz") .arg(frate));
     94                next.AddRefreshRate(frate);
     95    }
     96 
    9097    // try to find video override mode
    9198    uint key = DisplayResScreen::CalcKey(iwidth, iheight, irate);
    9299    DisplayResMapCIt it = in_size_to_output_mode.find(key);
     
    94101        mode[next_mode = CUSTOM_VIDEO] = next = it->second;
    95102
    96103    // need to change video mode?
    97     short target_rate = 0;
     104    float target_rate = 0.0;
    98105    DisplayResScreen::FindBestMatch(GetVideoModes(), next, target_rate);
    99     bool chg = !(next == last) || !(last.RefreshRate() == target_rate);
     106    bool chg = !(next == last) || !(DisplayResScreen::compare_rates(last.RefreshRate(),target_rate));
    100107
    101108    VERBOSE(VB_PLAYBACK, QString("Trying %1x%2 %3 Hz")
    102109            .arg(next.Width()).arg(next.Height()).arg(target_rate));
     
    128135    DisplayResScreen next = mode[next_mode];
    129136
    130137    // need to change video mode?
    131     short target_rate = 0;
     138    float target_rate = 0.0;
    132139    DisplayResScreen::FindBestMatch(GetVideoModes(), next, target_rate);
    133     bool chg = !(next == last) || !(last.RefreshRate() == target_rate);
     140    // If GuiVidModeRefreshRate is 0, assume any refresh rate is good enough.
     141    bool chg = (!(next == last) || (next.RefreshRate() !=0
     142                        && !(DisplayResScreen::compare_rates(last.RefreshRate(),target_rate))));
    134143
    135144    VERBOSE(VB_PLAYBACK, QString("Trying %1x%2 %3 Hz")
    136145            .arg(next.Width()).arg(next.Height()).arg(target_rate));
     
    154163bool DisplayRes::SwitchToCustomGUI(int width, int height, short rate)
    155164{
    156165    mode[CUSTOM_GUI] = DisplayResScreen(width, height, mode[GUI].Width_mm(),
    157                                         mode[GUI].Height_mm(), -1.0, rate);
     166                                        mode[GUI].Height_mm(), -1.0, (float) rate);
    158167    return SwitchToGUI(CUSTOM_GUI);
    159168}
    160169
    161170const vector<short> DisplayRes::GetRefreshRates(int width, int height) const {
    162     short tr;
    163     vector<short> empty;
     171    vector<short> srates;
     172    vector<float> rates = GetRefreshRatesFloat(width, height);
    164173
    165     const DisplayResScreen drs(width, height, 0, 0, -1.0, 0);
     174    for (int i=0; i<rates.size(); i++)
     175        srates.push_back((short) rates[i]);
     176    return srates;
     177}
     178const vector<float> DisplayRes::GetRefreshRatesFloat(int width, int height) const {
     179    float tr;
     180    vector<float> empty;
     181
     182    const DisplayResScreen drs(width, height, 0, 0, -1.0, 0.0);
    166183    const DisplayResVector& drv = GetVideoModes();
    167184    int t = DisplayResScreen::FindBestMatch(drv, drs, tr);
    168185    if (t < 0)
  • libs/libmyth/DisplayResOSX.cpp

     
    6666    return d;
    6767}
    6868
    69 bool DisplayResOSX::SwitchToVideoMode(int width, int height, short refreshrate)
     69bool DisplayResOSX::SwitchToVideoMode(int width, int height, float refreshrate)
    7070{
    7171    CGDirectDisplayID d = mythtv_display();
    7272    CFDictionaryRef dispMode = NULL;
     
    7575    // find mode that matches the desired size
    7676    if (refreshrate)
    7777        dispMode = CGDisplayBestModeForParametersAndRefreshRate(
    78             d, 32, width, height, (CGRefreshRate)(refreshrate), &match);
     78            d, 32, width, height, (CGRefreshRate)((short)refreshrate), &match);
    7979
    8080    if (!match)
    8181        dispMode =
     
    122122
    123123        if (screen_map.find(key)==screen_map.end())
    124124            screen_map[key] = DisplayResScreen(width, height,
    125                                                0, 0, -1.0, refresh);
     125                                               0, 0, -1.0, (float) refresh);
    126126        else
    127127            screen_map[key].AddRefreshRate(refresh);
    128128    }
  • libs/libmyth/DisplayResX.h

     
    1212
    1313  protected:
    1414    bool GetDisplaySize(int &width_mm, int &height_mm) const;
    15     bool SwitchToVideoMode(int width, int height, short framerate);
     15    bool SwitchToVideoMode(int width, int height, float framerate);
    1616
    1717  private:
    1818    mutable vector<DisplayResScreen> m_video_modes;
  • libs/libmyth/DisplayResScreen.h

     
    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);
    2222    DisplayResScreen(int w, int h, int mw, int mh,
     23                     const float* refreshRates, uint rr_length);
     24    DisplayResScreen(int w, int h, int mw, int mh,
    2325                     const short* refreshRates, uint rr_length);
    2426    DisplayResScreen(const QString &str);
    2527    inline void Init();
     
    2931    int Height() const { return height; }
    3032    int Width_mm() const { return width_mm; }
    3133    int Height_mm() const { return height_mm; }
     34    bool Custom() const { return custom; }
     35
    3236    inline double AspectRatio() const;
    33     inline short RefreshRate() const;
    34     const vector<short>& RefreshRates() const { return refreshRates; }
     37    inline float RefreshRate() const;
     38    const vector<float>& RefreshRates() const { return refreshRates; }
    3539
    3640    // Sets, adds
    3741    void SetAspectRatio(double a);
    38     void AddRefreshRate(short rr) {
     42    void AddRefreshRate(float rr) {
    3943        refreshRates.push_back(rr);
    4044        sort(refreshRates.begin(), refreshRates.end());
    4145    }
    42 
     46    void ClearRefreshRates(void) {
     47        refreshRates.clear();
     48    }   
     49    void SetCustom(bool b) {
     50        custom = b;
     51    }
     52       
     53        // Map for matching real rates and xrandr rate;
     54        map<float, short> realRates;
     55       
    4356    // Converters & comparitors
    4457    QString toString() const;
    4558    inline bool operator < (const DisplayResScreen& b) const;
     
    5063    static vector<DisplayResScreen> Convert(const QStringList& slist);
    5164    static int FindBestMatch(const vector<DisplayResScreen>& dsr,
    5265                             const DisplayResScreen& d,
     66                             float& target_rate);
     67    static int FindBestMatch(const vector<DisplayResScreen>& dsr,
     68                             const DisplayResScreen& d,
    5369                             short& target_rate);
    5470    static inline int CalcKey(int w, int h, int rate);
     71        static bool compare_rates(float f1, float f2);
    5572
    5673  private:
    5774    int width, height; // size in pixels
    5875    int width_mm, height_mm; // physical size in millimeters
    5976    double aspect; // aspect ratio, calculated or set
    60     vector<short> refreshRates;
     77    vector<float> refreshRates;
     78        bool custom;    // Set if resolution was defined manually
    6179};
    6280
     81
    6382typedef vector<DisplayResScreen>          DisplayResVector;
    6483typedef DisplayResVector::iterator        DisplayResVectorIt;
    6584typedef DisplayResVector::const_iterator  DisplayResVectorCIt;
     
    85104    return aspect;
    86105}
    87106
    88 inline short DisplayResScreen::RefreshRate() const
     107inline float DisplayResScreen::RefreshRate() const
    89108{
    90109    if (refreshRates.size() >= 1)
    91110        return refreshRates[0];
    92     else return 0;
     111    else return 0.0;
    93112}
    94113
    95114inline bool DisplayResScreen::operator < (const DisplayResScreen& b) const
  • libs/libmyth/DisplayResX.cpp

     
    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 (int 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);
     
    6788
    6889const DisplayResVector& DisplayResX::GetVideoModes(void) const
    6990{
    70     if (m_video_modes.size())
    71         return m_video_modes;
     91        if (m_video_modes.size())
     92                return m_video_modes;
    7293
    7394    Display *display = NULL;
    7495    XRRScreenConfiguration *cfg = GetScreenConfig(display);
     
    7899    int num_sizes, num_rates;
    79100    XRRScreenSize *sizes = NULL;
    80101    X11S(sizes = XRRConfigSizes(cfg, &num_sizes));
     102
    81103    for (int i = 0; i < num_sizes; ++i)
    82104    {
    83105        short *rates = NULL;
    84106        X11S(rates = XRRRates(display, DefaultScreen(display), i, &num_rates));
    85107        DisplayResScreen scr(sizes[i].width, sizes[i].height,
    86                              sizes[i].mwidth, sizes[i].mheight,
    87                              rates, num_rates);
    88         m_video_modes.push_back(scr);
     108                                                        sizes[i].mwidth, sizes[i].mheight,
     109                                                        rates, num_rates);
     110                m_video_modes.push_back(scr);
    89111    }
     112
     113    QString customscreen = gContext->GetSetting("CustomScreenRate");
     114    if (gContext->GetNumSetting("UseVideoModes", 0) && (customscreen != ""));
     115        {
     116                QFileInfo fi(customscreen);
     117                QFile file(customscreen);
     118       
     119            if (!fi.exists() || !fi.isFile())
     120            {
     121                VERBOSE(VB_PLAYBACK, QString("CustomScreenRate: \"%1\" failed: does not exist or isn't a file")
     122                        .arg(customscreen));
     123            }
     124            else if ( file.open( IO_ReadOnly ) ) {
     125                QRegExp regexp = QRegExp("^\\s*(\\d+),(\\d+),(\\d+\\.?\\d*),(\\d+)\\s*$");
     126                QTextStream stream( &file );
     127                QString line;
     128                int pos;
     129                while ( !stream.atEnd() ) {
     130                    pos = regexp.search(stream.readLine());
     131                    if (pos > -1) {
     132                                int w = regexp.cap(1).toInt();
     133                                int h = regexp.cap(2).toInt();
     134                                float hz = regexp.cap(3).toFloat();
     135                                int xrandrhz = regexp.cap(4).toShort();
     136                                int found = -1;
     137                                VERBOSE(VB_PLAYBACK, QString("Found definition for %1x%2 @ %3Hz (xrandr: %4)")
     138                                .arg(w) .arg(h) .arg(hz) .arg(xrandrhz));
     139                        // find if video mode already exist, and remove refresh rates for custom one
     140                        for (int i=0; i < m_video_modes.size(); i++) {
     141                                if ((m_video_modes[i].Width() == w) && (m_video_modes[i].Height() == h))
     142                                {
     143                                        found = i;
     144                                        if (!m_video_modes[i].Custom())
     145                                        {
     146                                                m_video_modes[i].ClearRefreshRates();
     147                                                                m_video_modes[i].SetCustom(true);
     148                                        }
     149                                        m_video_modes[i].AddRefreshRate(hz);
     150                                        m_video_modes[i].realRates[hz] = xrandrhz;
     151                                        break;
     152                                }
     153                        }
     154                        if (found < 0)
     155                        {
     156                                                DisplayResScreen scr(w, h, 0, 0, -1.0, hz);
     157                                                scr.SetCustom(true);
     158                                        m_video_modes.push_back(scr);
     159                        }
     160                    }
     161                }
     162                file.close();
     163            }
     164    }
     165
    90166    m_video_modes_unsorted = m_video_modes;
    91167    sort(m_video_modes.begin(), m_video_modes.end());
    92168
  • libs/libmyth/DisplayResScreen.cpp

     
    11#include "DisplayResScreen.h"
    22#include "mythcontext.h"
    33
     4#include <cmath>
     5
    46DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh,
    5                                    double aspectRatio, short refreshRate)
    6     : width(w), height(h), width_mm(mw), height_mm(mh)
     7                                   double aspectRatio, float refreshRate)
     8    : width(w), height(h), width_mm(mw), height_mm(mh), custom(false)
    79{
    810    SetAspectRatio(aspectRatio);
    911    if (refreshRate > 0)
     
    1113}
    1214
    1315DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh,
    14                                    const vector<short>& rr)
    15     : width(w), height(h), width_mm(mw), height_mm(mh), refreshRates(rr)
     16                                   const vector<float>& rr)
     17    : width(w), height(h), width_mm(mw), height_mm(mh), refreshRates(rr), custom(false)
    1618{
    1719    SetAspectRatio(-1.0);
    1820}
    1921
    2022DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh,
    21                                    const short* rr, uint rr_length)
    22     : width(w), height(h), width_mm(mw), height_mm(mh)
     23                                   const float* rr, uint rr_length)
     24    : width(w), height(h), width_mm(mw), height_mm(mh), custom(false)
    2325{
    2426    SetAspectRatio(-1.0);
    2527    for (uint i = 0; i < rr_length; ++i)
     
    2830    sort(refreshRates.begin(), refreshRates.end());
    2931}
    3032
     33DisplayResScreen::DisplayResScreen(int w, int h, int mw, int mh,
     34                                   const short* rr, uint rr_length)
     35    : width(w), height(h), width_mm(mw), height_mm(mh), custom(false)
     36{
     37    SetAspectRatio(-1.0);
     38    for (uint i = 0; i < rr_length; ++i)
     39        refreshRates.push_back((float)rr[i]);
     40
     41    sort(refreshRates.begin(), refreshRates.end());
     42}
     43
    3144DisplayResScreen::DisplayResScreen(const QString &str)
    32     : width(0), height(0), width_mm(0), height_mm(0), aspect(-1.0)
     45    : width(0), height(0), width_mm(0), height_mm(0), aspect(-1.0), custom(false)
    3346{
    3447    refreshRates.clear();
    3548    QStringList slist = QStringList::split(":", str);
     
    4356        height_mm = slist[3].toInt();
    4457        aspect = slist[4].toDouble();
    4558        for (uint i = 5; i<slist.size(); ++i)
    46             refreshRates.push_back(slist[i].toShort());
     59            refreshRates.push_back(slist[i].toFloat());
    4760    }
    4861}
    4962
     
    8093    return dsr;
    8194}
    8295
     96//compares if the float f1 is equal with f2 and returns 1 if true and 0 if false
     97bool DisplayResScreen::compare_rates(float f1, float f2)
     98{
     99        float precision = 0.01;
     100        if (((f1 - precision) < f2) &&
     101            ((f1 + precision) > f2))
     102        {
     103                return true;
     104        }
     105        else
     106        {
     107                return false;
     108        }
     109}
     110
    83111int DisplayResScreen::FindBestMatch(const vector<DisplayResScreen>& dsr,
    84112                                    const DisplayResScreen& d,
    85113                                    short& target_rate)
    86114{
     115        float target;
     116        int i = FindBestMatch(dsr, d, target);
     117        target_rate = target;
     118        return i;
     119}
     120
     121int DisplayResScreen::FindBestMatch(const vector<DisplayResScreen>& dsr,
     122                                    const DisplayResScreen& d,
     123                                    float& target_rate)
     124{
     125  // Amend vector with custom list
    87126    for (uint i=0; i<dsr.size(); ++i)
    88127    {
    89128        if (dsr[i].Width()==d.Width() && dsr[i].Height()==d.Height())
    90129        {
    91             const vector<short>& rates = dsr[i].RefreshRates();
    92             if (rates.size())
     130            const vector<float>& rates = dsr[i].RefreshRates();
     131            if (rates.size() && d.RefreshRate() != 0)
    93132            {
    94                 vector<short>::const_iterator it =
    95                     find(rates.begin(), rates.end(), d.RefreshRate());
    96                 target_rate = (it == rates.end()) ? *(--rates.end()) : *it;
    97                 return i;
    98             }
     133                                for (uint j=0; j < rates.size(); ++j)
     134                                {
     135                                    // Multiple of target_rate will do
     136                                  if (compare_rates(d.RefreshRate(),rates[j]) || (fmod(rates[j],d.RefreshRate()) <= 0.01))
     137                                    {
     138                                                target_rate = rates[j];
     139                                                return i;
     140                                    }
     141                                }
     142                        target_rate = rates[rates.size() - 1];
     143                        }
     144                return i;
    99145        }
    100146    }
    101147    return -1;
  • libs/libmyth/DisplayResOSX.h

     
    1212
    1313  protected:
    1414    bool GetDisplaySize(int &width_mm, int &height_mm) const;
    15     bool SwitchToVideoMode(int width, int height, short framerate);
     15    bool SwitchToVideoMode(int width, int height, float framerate);
    1616   
    1717  private:
    1818    mutable vector<DisplayResScreen> m_video_modes;
  • libs/libmyth/DisplayRes.h

     
    4646     *  \brief Switches to the resolution and refresh rate defined in the
    4747     *         database for the specified video resolution and frame rate.
    4848     */
    49     bool SwitchToVideo(int iwidth, int iheight, short irate = 0);
     49    bool SwitchToVideo(int iwidth, int iheight, short irate = 0, float frate = 0.0);
    5050    /** \brief Switches to the GUI resolution specified.
    5151     *
    5252     *   If which_gui is GUI then this switches to the resolution
     
    110110    /// \brief Returns all video modes supported by the display.
    111111    virtual const vector<DisplayResScreen>& GetVideoModes() const = 0;
    112112    /// \brief Returns refresh rates available at a specific screen resolution.
    113     const vector<short> GetRefreshRates(int width, int height) const;
     113    const vector<float> GetRefreshRatesFloat(int width, int height) const;
     114    const vector<short> GetRefreshRates(int width, int height) const;
    114115    /** @} */
    115116
    116117  protected:
     
    120121   
    121122    // These methods are implemented by the subclasses
    122123    virtual bool GetDisplaySize(int &width_mm, int &height_mm) const = 0;
    123     virtual bool SwitchToVideoMode(int width, int height, short framerate) = 0;
     124    virtual bool SwitchToVideoMode(int width, int height, float framerate) = 0;
    124125
    125126  private:
    126127    DisplayRes(const DisplayRes & rhs); // disable copy constructor;
  • programs/mythfrontend/globalsettings.cpp

     
    24142414    return gc;
    24152415}
    24162416
     2417static HostLineEdit *CustomScreenConfig()
     2418{
     2419    HostLineEdit *gedit = new HostLineEdit("CustomScreenRate");
     2420    gedit->setLabel(QObject::tr("Custom screen rate definition file"));
     2421    gedit->setHelpText(QObject::tr("Custom screen resolution configuration "
     2422                                        "for matching xrandr value."));
     2423    return gedit;
     2424}
     2425 
    24172426static HostSpinBox *VidModeWidth(int idx)
    24182427{
    24192428    HostSpinBox *gs = new HostSpinBox(QString("VidModeWidth%1").arg(idx),
     
    25822591                    rate, SLOT(ChangeResolution(const QString&)));
    25832592        }
    25842593
     2594        ConfigurationGroup* customscreensettings =
     2595            new HorizontalConfigurationGroup(false, false);
     2596
     2597        customscreensettings->addChild(CustomScreenConfig());
     2598
    25852599        ConfigurationGroup* settings = new VerticalConfigurationGroup(false);
     2600
    25862601        settings->addChild(defaultsettings);
    25872602        settings->addChild(overrides);
     2603        settings->addChild(customscreensettings);
    25882604
    25892605        addTarget("1", settings);
    25902606        addTarget("0", new VerticalConfigurationGroup(true));