Ticket #5643: adjust_rate3-trunk.patch

File adjust_rate3-trunk.patch, 37.5 KB (added by jyavenard@…, 15 years ago)

For trunk (20573)

  • mythtv/libs/libmythtv/NuppelVideoPlayer.cpp

     
    741741            GetDecoder()->GetVideoCodecPrivate(),
    742742            pipState,
    743743            video_disp_dim, video_aspect,
    744             widget->winId(), display_rect, 0 /*embedid*/);
     744            widget->winId(), display_rect, (video_frame_rate * play_speed),
     745            0 /*embedid*/);
    745746
    746747        if (!videoOutput)
    747748        {
  • mythtv/libs/libmythtv/videoout_d3d.cpp

     
    453453
    454454bool VideoOutputD3D::Init(int width, int height, float aspect,
    455455                          WId winid, int winx, int winy, int winw,
    456                           int winh, WId embedid)
     456                          int winh, float video_prate, WId embedid)
    457457{
    458458    VERBOSE(VB_PLAYBACK, LOC +
    459459            "Init w=" << width << " h=" << height);
     
    464464                  kPrebufferFramesNormal, kPrebufferFramesSmall,
    465465                  kKeepPrebuffer);
    466466
    467     VideoOutput::Init(width, height, aspect, winid,
    468                       winx, winy, winw, winh, embedid);
     467    VideoOutput::Init(width, height, aspect, winid, winx,
     468                      winy, winw, winh, video_prate, embedid);
    469469
    470470    m_hWnd = winid;
    471471
  • mythtv/libs/libmythtv/videoout_quartz.cpp

     
    12161216}
    12171217
    12181218bool VideoOutputQuartz::Init(int width, int height, float aspect,
    1219                              WId winid, int winx, int winy,
    1220                              int winw, int winh, WId embedid)
     1219                             WId winid, int winx, int winy, int winw,
     1220                             int winh, float video_prate, WId embedid)
    12211221{
    12221222    VERBOSE(VB_PLAYBACK, LOC +
    12231223            QString("Init(WxH %1x%2, aspect=%3, winid=%4\n\t\t\t"
     
    12401240                  kPrebufferFramesNormal, kPrebufferFramesSmall,
    12411241                  kKeepPrebuffer);
    12421242    VideoOutput::Init(width, height, aspect, winid,
    1243                       winx, winy, winw, winh, embedid);
     1243                      winx, winy, winw, winh, video_prate,
     1244                      embedid);
    12441245
    12451246    const QSize video_dim = windows[0].GetVideoDim();
    12461247    data->srcWidth  = video_dim.width();
     
    14071408
    14081409void VideoOutputQuartz::SetVideoFrameRate(float playback_fps)
    14091410{
     1411    video_prate = playback_fps;
    14101412    VERBOSE(VB_PLAYBACK, "SetVideoFrameRate("<<playback_fps<<")");
    14111413}
    14121414
  • mythtv/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
    2627    void ProcessFrame(VideoFrame *frame, OSD *osd,
    2728                      FilterChain *filterList,
  • mythtv/libs/libmythtv/videoout_directfb.cpp

     
    354354
    355355bool VideoOutputDirectfb::Init(int width, int height, float aspect, WId winid,
    356356                               int winx, int winy, int winw, int winh,
    357                                WId embedid)
     357                               float video_prate, WId embedid)
    358358{
    359359    // Hack to avoid embedded video output...
    360360    if ((winw < 320) || (winh < 240))
     
    652652                           display_visible_rect.y(),
    653653                           display_visible_rect.width(),
    654654                           display_visible_rect.height(),
    655                            embedid))
     655                           video_prate, embedid))
    656656    {
    657657        return false;
    658658    }
  • mythtv/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();
  • mythtv/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
  • mythtv/libs/libmythtv/videoout_null.cpp

     
    118118
    119119bool VideoOutputNull::Init(int width, int height, float aspect,
    120120                           WId winid, int winx, int winy, int winw,
    121                            int winh, WId embedid)
     121                           int winh, float video_prate, WId embedid)
    122122{
    123123    if ((width <= 0) || (height <= 0))
    124124        return false;
    125125
    126126    QMutexLocker locker(&global_lock);
    127127
    128     VideoOutput::Init(width, height, aspect, winid,
    129                       winx, winy, winw, winh, embedid);
     128    VideoOutput::Init(width, height, aspect, winid, winx,
     129                      winy, winw, winh, video_prate, embedid);
    130130
    131131    vbuffers.Init(kNumBuffers, true, kNeedFreeFrames,
    132132                  kPrebufferFramesNormal, kPrebufferFramesSmall,
  • mythtv/libs/libmythtv/videooutbase.cpp

     
    6666        PIPState pipState,
    6767        const QSize   &video_dim, float        video_aspect,
    6868        WId            win_id,    const QRect &display_rect,
    69         WId            embed_id)
     69        float          video_prate,     WId     embed_id)
    7070{
    7171    (void) codec_priv;
    7272
     
    178178        if (vo)
    179179        {
    180180            vo->SetPIPState(pipState);
     181            vo->video_prate = video_prate;
    181182            if (vo->Init(
    182183                    video_dim.width(), video_dim.height(), video_aspect,
    183184                    win_id, display_rect.x(), display_rect.y(),
    184                     display_rect.width(), display_rect.height(), embed_id))
     185                    display_rect.width(), display_rect.height(),
     186                    video_prate, embed_id))
    185187            {
    186188                return vo;
    187189            }
     
    351353 * \return true if successful, false otherwise.
    352354 */
    353355bool VideoOutput::Init(int width, int height, float aspect, WId winid,
    354                        int winx, int winy, int winw, int winh, WId embedid)
     356                       int winx, int winy, int winw, int winh,
     357                       float video_prate, WId embedid)
    355358{
    356359    (void)winid;
    357360    (void)embedid;
     
    382385
    383386void VideoOutput::SetVideoFrameRate(float playback_fps)
    384387{
     388    video_prate = playback_fps;
    385389    if (db_vdisp_profile)
    386390        db_vdisp_profile->SetOutput(playback_fps);
    387391}
  • mythtv/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,
  • mythtv/libs/libmythtv/videoout_xv.h

     
    5757   ~VideoOutputXv();
    5858
    5959    bool Init(int width, int height, float aspect, WId winid,
    60               int winx, int winy, int winw, int winh, WId embedid = 0);
     60              int winx, int winy, int winw, int winh,
     61              float video_prate, WId embedid = 0);
    6162
    6263    bool SetDeinterlacingEnabled(bool);
    6364    bool SetupDeinterlace(bool interlaced, const QString& ovrf="");
  • mythtv/libs/libmythtv/videoout_xv.cpp

     
    387387    if ((width == 1920 || width == 1440) && height == 1088)
    388388        height = 1080; // ATSC 1920x1080
    389389
    390     if (display_res && display_res->SwitchToVideo(width, height))
     390    if (display_res && display_res->SwitchToVideo(width, height,
     391                                                  (short) roundf(video_prate),
     392                                                  video_prate))
    391393    {
    392394        // Switching to custom display resolution succeeded
    393395        // Make a note of the new size
     
    15991601}
    16001602
    16011603/**
    1602  * \fn VideoOutputXv::Init(int,int,float,WId,int,int,int,int,WId)
     1604 * \fn VideoOutputXv::Init(int,int,float,WId,int,int,int,int,float,WId)
    16031605 * Initializes class for video output.
    16041606 *
    16051607 * \return success or failure.
    16061608 */
    16071609bool VideoOutputXv::Init(
    1608     int width, int height, float aspect,
    1609     WId winid, int winx, int winy, int winw, int winh, WId embedid)
     1610    int width, int height, float aspect, WId winid, int winx,
     1611    int winy, int winw, int winh, float video_prate, WId embedid)
    16101612{
    16111613    windows[0].SetNeedRepaint(true);
    16121614
     
    16631665    // Basic setup
    16641666    VideoOutput::Init(width, height, aspect,
    16651667                      winid, winx, winy, winw, winh,
    1666                       embedid);
     1668                      video_prate, embedid);
    16671669
    16681670    // Set resolution/measurements (check XRandR, Xinerama, config settings)
    16691671    InitDisplayMeasurements(width, height);
  • mythtv/libs/libmythtv/videooutbase.h

     
    4848        PIPState       pipState,
    4949        const QSize   &video_dim, float        video_aspect,
    5050        WId            win_id,    const QRect &display_rect,
    51         WId            embed_id);
     51        float video_prate,        WId          embed_id);
    5252
    5353    VideoOutput();
    5454    virtual ~VideoOutput();
    5555
    5656    virtual bool Init(int width, int height, float aspect,
    5757                      WId winid, int winx, int winy, int winw,
    58                       int winh, WId embedid = 0);
     58                      int winh, float video_prate, WId embedid = 0);
    5959    virtual void InitOSD(OSD *osd);
    6060    virtual void SetVideoFrameRate(float);
    6161
     
    297297
    298298    VideoDisplayProfile *db_vdisp_profile;
    299299
     300    float   video_prate;  ///< Playback frame rate of video
     301
    300302    // Picture-in-Picture
    301303    QSize   pip_desired_display_size;
    302304    QSize   pip_display_size;
  • mythtv/libs/libmythtv/videoout_ivtv.cpp

     
    406406
    407407bool VideoOutputIvtv::Init(int width, int height, float aspect,
    408408                           WId winid, int winx, int winy, int winw,
    409                            int winh, WId embedid)
     409                           int winh, float video_prate, WId embedid)
    410410{
    411411    VERBOSE(VB_PLAYBACK, LOC + "Init() -- begin");
    412412
     
    415415    videoDevice = gContext->GetSetting("PVR350VideoDev");
    416416
    417417    VideoOutput::Init(width, height, aspect, winid, winx, winy, winw, winh,
    418                       embedid);
     418                      video_prate, embedid);
    419419
    420420    windows[0].SetAllowPreviewEPG(true);
    421421
  • mythtv/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
    1819    void ProcessFrame(VideoFrame *frame, OSD *osd,
    1920                      FilterChain *filterList,
  • mythtv/libs/libmythtv/videoout_dx.cpp

     
    160160}
    161161
    162162bool VideoOutputDX::Init(int width, int height, float aspect,
    163                            WId winid, int winx, int winy, int winw,
    164                            int winh, WId embedid)
     163                         WId winid, int winx, int winy, int winw,
     164                         int winh, float video_prate, WId embedid)
    165165{
    166166    db_vdisp_profile->SetVideoRenderer("directx");
    167167
    168168    vbuffers.Init(kNumBuffers, true, kNeedFreeFrames,
    169169                  kPrebufferFramesNormal, kPrebufferFramesSmall,
    170170                  kKeepPrebuffer);
    171     VideoOutput::Init(width, height, aspect, winid,
    172                       winx, winy, winw, winh, embedid);
     171    VideoOutput::Init(width, height, aspect, winid, winx,
     172                      winy, winw, winh, video_prate, embedid);
    173173
    174174    wnd = winid;
    175175
  • mythtv/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..
  • mythtv/libs/libmythui/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 std::vector<DisplayResScreen> m_video_modes;
  • mythtv/libs/libmythui/DisplayRes.cpp

     
    3838    // Initialize GUI mode
    3939    mode[GUI].Init();
    4040    tW = tH = 0;
    41     GetMythDB()->GetResolutionSetting("GuiVidMode", tW, tH);
     41    GetMythDB()->GetResolutionSetting("GuiVidMode", tW, tH, tAspect, tRate);
    4242    GetDisplaySize(tW_mm, tH_mm);
    4343    GetMythDB()->GetResolutionSetting("DisplaySize", tW_mm, tH_mm);
    44     mode[GUI] = DisplayResScreen(tW, tH, tW_mm, tH_mm, -1.0, 0);
     44    mode[GUI] = DisplayResScreen(tW, tH, tW_mm, tH_mm, -1.0, (float)tRate);
    4545
    4646
    4747    // Initialize default VIDEO mode
    4848    tW = tH = 0;
    4949    GetMythDB()->GetResolutionSetting("TVVidMode", tW, tH, tAspect, tRate);
    50     mode[VIDEO] = DisplayResScreen(tW, tH, tW_mm, tH_mm, tAspect, tRate);
     50    mode[VIDEO] = DisplayResScreen(tW, tH, tW_mm, tH_mm, tAspect, (float)tRate);
    5151
    5252
    5353    // Initialize video override mode
     
    6565            break;
    6666
    6767        uint key = DisplayResScreen::CalcKey(iw, ih, irate);
    68         DisplayResScreen scr(ow, oh, tW_mm, tH_mm, oaspect, orate);
     68        DisplayResScreen scr(ow, oh, tW_mm, tH_mm, oaspect, (float)orate);
    6969        in_size_to_output_mode[key] = scr;           
    7070    }
    7171
     
    8383    return true;
    8484}
    8585
    86 bool DisplayRes::SwitchToVideo(int iwidth, int iheight, short irate)
     86bool DisplayRes::SwitchToVideo(int iwidth, int iheight, short irate, float frate)
    8787{
    8888    tmode next_mode = VIDEO; // default VIDEO mode
    8989    DisplayResScreen next = mode[next_mode];
    9090
     91    // If requested refresh rate is 0, attempt to match video fps
     92    if (next.RefreshRate() == 0)
     93    {
     94        VERBOSE(VB_PLAYBACK, QString("*** Trying to match best resolution %1Hz") .arg(frate));
     95        next.AddRefreshRate(frate);
     96    }
     97
    9198    // try to find video override mode
    9299    uint key = DisplayResScreen::CalcKey(iwidth, iheight, irate);
    93100    DisplayResMapCIt it = in_size_to_output_mode.find(key);
     
    95102        mode[next_mode = CUSTOM_VIDEO] = next = it->second;
    96103
    97104    // need to change video mode?
    98     short target_rate = 0;
     105    float target_rate = 0.0;
    99106    DisplayResScreen::FindBestMatch(GetVideoModes(), next, target_rate);
    100     bool chg = !(next == last) || !(last.RefreshRate() == target_rate);
     107    bool chg = !(next == last) || !(DisplayResScreen::compare_rates(last.RefreshRate(),target_rate));
    101108
    102109    VERBOSE(VB_PLAYBACK, QString("Trying %1x%2 %3 Hz")
    103110            .arg(next.Width()).arg(next.Height()).arg(target_rate));
     
    129136    DisplayResScreen next = mode[next_mode];
    130137
    131138    // need to change video mode?
    132     short target_rate = 0;
     139    float target_rate = 0.0;
    133140    DisplayResScreen::FindBestMatch(GetVideoModes(), next, target_rate);
    134     bool chg = !(next == last) || !(last.RefreshRate() == target_rate);
     141    // If GuiVidModeRefreshRate is 0, assume any refresh rate is good enough.
     142    bool chg = (!(next == last) || (next.RefreshRate() !=0
     143                && !(DisplayResScreen::compare_rates(last.RefreshRate(), target_rate))));
    135144
    136145    VERBOSE(VB_PLAYBACK, QString("Trying %1x%2 %3 Hz")
    137146            .arg(next.Width()).arg(next.Height()).arg(target_rate));
     
    155164bool DisplayRes::SwitchToCustomGUI(int width, int height, short rate)
    156165{
    157166    mode[CUSTOM_GUI] = DisplayResScreen(width, height, mode[GUI].Width_mm(),
    158                                         mode[GUI].Height_mm(), -1.0, rate);
     167                                        mode[GUI].Height_mm(), -1.0, (float)rate);
    159168    return SwitchToGUI(CUSTOM_GUI);
    160169}
    161170
    162 const std::vector<short> DisplayRes::GetRefreshRates(int width,
    163                                                      int height) const {
    164     short tr;
    165     std::vector<short> empty;
     171const std::vector<short> DisplayRes::GetRefreshRates(int width, int height) const {
     172    std::vector<short> srates;
     173    std::vector<float> rates = GetRefreshRatesFloat(width, height);
    166174
    167     const DisplayResScreen drs(width, height, 0, 0, -1.0, 0);
     175    for (int i=0; i<rates.size(); i++)
     176        srates.push_back((short) rates[i]);
     177    return srates;
     178}
     179const std::vector<float> DisplayRes::GetRefreshRatesFloat(int width, int height) const {
     180    float tr;
     181    std::vector<float> empty;
     182
     183    const DisplayResScreen drs(width, height, 0, 0, -1.0, 0.0);
    168184    const DisplayResVector& drv = GetVideoModes();
    169185    int t = DisplayResScreen::FindBestMatch(drv, drs, tr);
    170186    if (t < 0)
  • mythtv/libs/libmythui/DisplayResOSX.cpp

     
    6464    return d;
    6565}
    6666
    67 bool DisplayResOSX::SwitchToVideoMode(int width, int height, short refreshrate)
     67bool DisplayResOSX::SwitchToVideoMode(int width, int height, float refreshrate)
    6868{
    6969    CGDirectDisplayID d = mythtv_display();
    7070    CFDictionaryRef dispMode = NULL;
     
    7373    // find mode that matches the desired size
    7474    if (refreshrate)
    7575        dispMode = CGDisplayBestModeForParametersAndRefreshRate(
    76             d, 32, width, height, (CGRefreshRate)(refreshrate), &match);
     76            d, 32, width, height, (CGRefreshRate)((short)refreshrate), &match);
    7777
    7878    if (!match)
    7979        dispMode =
     
    120120
    121121        if (screen_map.find(key)==screen_map.end())
    122122            screen_map[key] = DisplayResScreen(width, height,
    123                                                0, 0, -1.0, refresh);
     123                                               0, 0, -1.0, (float) refresh);
    124124        else
    125125            screen_map[key].AddRefreshRate(refresh);
    126126    }
  • mythtv/libs/libmythui/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 std::vector<DisplayResScreen> m_video_modes;
  • mythtv/libs/libmythui/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 std::vector<short>& refreshRates);
     21                     const std::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 std::vector<short>& RefreshRates() const { return refreshRates; }
     37    inline float RefreshRate() const;
     38    const std::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        std::sort(refreshRates.begin(), refreshRates.end());
    4145    }
     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    std::map<float, short> realRates;
    4255
    4356    // Converters & comparitors
    4457    QString toString() const;
     
    5063    static std::vector<DisplayResScreen> Convert(const QStringList& slist);
    5164    static int FindBestMatch(const std::vector<DisplayResScreen>& dsr,
    5265                             const DisplayResScreen& d,
     66                             float& target_rate);
     67    static int FindBestMatch(const std::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     std::vector<short> refreshRates;
     77    std::vector<float> refreshRates;
     78    bool custom;        // Set if resolution was defined manually
    6179};
    6280
    6381typedef std::vector<DisplayResScreen>          DisplayResVector;
     
    85103    return aspect;
    86104}
    87105
    88 inline short DisplayResScreen::RefreshRate() const
     106inline float DisplayResScreen::RefreshRate() const
    89107{
    90108    if (refreshRates.size() >= 1)
    91109        return refreshRates[0];
    92     else return 0;
     110    else return 0.0;
    93111}
    94112
    95113inline bool DisplayResScreen::operator < (const DisplayResScreen& b) const
  • mythtv/libs/libmythui/DisplayResX.cpp

     
    11#include <iostream>
    22
    3 #include "util-x11.h"
    4 
    5 #include <X11/extensions/Xrandr.h> // this has to be after util-x11.h (Qt bug)
    6 
     3#include "config.h"
    74#include "DisplayResX.h"
     5#include "mythverbose.h"
     6#include "mythdb.h"
    87
    98using std::cerr;
    109using std::endl;
    1110
     11#include <QRegExp>
     12#include <QIODevice>
     13#include <QFileInfo>
     14
     15#include "util-x11.h"
     16
     17#include <X11/extensions/Xrandr.h> // this has to be after util-x11.h (Qt bug)
     18
    1219static XRRScreenConfiguration *GetScreenConfig(Display*& display);
    1320
    1421DisplayResX::DisplayResX(void)
     
    3340    return false;
    3441}
    3542
    36 bool DisplayResX::SwitchToVideoMode(int width, int height, short desired_rate)
     43bool DisplayResX::SwitchToVideoMode(int width, int height, float desired_rate)
    3744{
    38     short rate;
     45    float rate;
     46    short finalrate;
     47
    3948    DisplayResScreen desired_screen(width, height, 0, 0, -1.0, desired_rate);
    4049    int idx = DisplayResScreen::FindBestMatch(m_video_modes_unsorted,
    4150                                              desired_screen, rate);
     
    5059        Rotation rot;
    5160        XRRConfigCurrentConfiguration(cfg, &rot);
    5261       
     62        // Search real xrandr rate for desired_rate
     63        finalrate = (short) rate;
     64        for (uint i=0; i < m_video_modes.size(); i++) {
     65            if ((m_video_modes[i].Width() == width) && (m_video_modes[i].Height() == height))
     66            {
     67                if (m_video_modes[i].Custom())
     68                {
     69                    finalrate = m_video_modes[i].realRates[rate];
     70                    VERBOSE(VB_PLAYBACK, QString("CustomRate Found, set %1Hz as %2") .arg(rate) .arg(finalrate));
     71                }
     72                break;
     73            }
     74        }
     75               
    5376        Window root = DefaultRootWindow(display);
    5477        Status status = XRRSetScreenConfigAndRate(display, cfg, root, idx,
    55                                                   rot, rate, CurrentTime);
     78                                                  rot, finalrate, CurrentTime);
    5679       
    5780        XRRFreeScreenConfigInfo(cfg);
    5881        XCloseDisplay(display);
     
    88111                             rates, num_rates);
    89112        m_video_modes.push_back(scr);
    90113    }
     114
     115    QString customscreen = GetMythDB()->GetSetting("CustomScreenRate");
     116    if (GetMythDB()->GetNumSetting("UseVideoModes", 0) && !customscreen.size());
     117    {
     118        QFileInfo fi(customscreen);
     119        QFile file(customscreen);
     120
     121        if (!fi.exists() || !fi.isFile())
     122        {
     123            VERBOSE(VB_PLAYBACK, QString("CustomScreenRate: \"%1\" failed: does not exist or isn't a file")
     124                    .arg(customscreen));
     125        }
     126        else if ( file.open(QIODevice::ReadOnly) ) {
     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                pos = regexp.indexIn(stream.readLine());
     133                if (pos > -1) {
     134                    int w = regexp.cap(1).toInt();
     135                    int h = regexp.cap(2).toInt();
     136                    float hz = regexp.cap(3).toFloat();
     137                    int xrandrhz = regexp.cap(4).toShort();
     138                    int found = -1;
     139                    VERBOSE(VB_PLAYBACK, QString("Found definition for %1x%2 @ %3Hz (xrandr: %4)")
     140                            .arg(w) .arg(h) .arg(hz) .arg(xrandrhz));
     141                    // find if video mode already exist, and remove refresh rates for custom one
     142                    for (int i=0; i < m_video_modes.size(); i++) {
     143                        if ((m_video_modes[i].Width() == w) && (m_video_modes[i].Height() == h))
     144                        {
     145                            found = i;
     146                            if (!m_video_modes[i].Custom())
     147                            {
     148                                m_video_modes[i].ClearRefreshRates();
     149                                m_video_modes[i].SetCustom(true);
     150                            }
     151                            m_video_modes[i].AddRefreshRate(hz);
     152                            m_video_modes[i].realRates[hz] = xrandrhz;
     153                            break;
     154                        }
     155                    }
     156                    if (found < 0)
     157                    {
     158                        DisplayResScreen scr(w, h, 0, 0, -1.0, hz);
     159                        scr.SetCustom(true);
     160                        m_video_modes.push_back(scr);
     161                    }
     162                }
     163            }
     164            file.close();
     165        }
     166    }
     167
    91168    m_video_modes_unsorted = m_video_modes;
    92169    std::sort(m_video_modes.begin(), m_video_modes.end());
    93170
  • mythtv/libs/libmythui/DisplayResScreen.cpp

     
    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 float* rr, uint rr_length)
     24    : width(w), height(h), width_mm(mw), height_mm(mh), custom(false)
    2425{
    2526    SetAspectRatio(-1.0);
    2627    for (uint i = 0; i < rr_length; ++i)
     
    2930    std::sort(refreshRates.begin(), refreshRates.end());
    3031}
    3132
     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    std::sort(refreshRates.begin(), refreshRates.end());
     42}
     43
    3244DisplayResScreen::DisplayResScreen(const QString &str)
    3345    : width(0), height(0), width_mm(0), height_mm(0), aspect(-1.0)
    3446{
     
    4456        height_mm = slist[3].toInt();
    4557        aspect = slist[4].toDouble();
    4658        for (int i = 5; i<slist.size(); ++i)
    47             refreshRates.push_back(slist[i].toShort());
     59            refreshRates.push_back(slist[i].toFloat());
    4860    }
    4961}
    5062
     
    8193    return dsr;
    8294}
    8395
     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
    84111int DisplayResScreen::FindBestMatch(const std::vector<DisplayResScreen>& dsr,
    85112                                    const DisplayResScreen& d,
    86113                                    short& target_rate)
    87114{
     115        float target;
     116        int i = FindBestMatch(dsr, d, target);
     117        target_rate = target;
     118        return i;
     119}
     120
     121int DisplayResScreen::FindBestMatch(const std::vector<DisplayResScreen>& dsr,
     122                                    const DisplayResScreen& d,
     123                                    float& target_rate)
     124{
     125  // Amend vector with custom list
    88126    for (uint i=0; i<dsr.size(); ++i)
    89127    {
    90128        if (dsr[i].Width()==d.Width() && dsr[i].Height()==d.Height())
    91129        {
    92             const std::vector<short>& rates = dsr[i].RefreshRates();
    93             if (rates.size())
     130            const std::vector<float>& rates = dsr[i].RefreshRates();
     131            if (rates.size() && d.RefreshRate() != 0)
    94132            {
    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;
    99             }
     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              // Can't find exact frame rate, so try rounding to the nearest integer, so 23.97Hz will work with 24Hz etc
     143              for (uint j=0; j < rates.size(); ++j)
     144                {
     145                  float rounded = (float) ((int) (rates[j] + 0.5));
     146                  // Multiple of target_rate will do
     147                  if (compare_rates(d.RefreshRate(),rounded) || (fmod(rounded,d.RefreshRate()) <= 0.01))
     148                    {
     149                      target_rate = rounded;
     150                      return i;
     151                    }
     152                }
     153              target_rate = rates[rates.size() - 1];
     154            }
     155            return i;
    100156        }
    101157    }
    102158    return -1;
  • mythtv/libs/libmythui/DisplayRes.h

     
    4040     *  \brief Switches to the resolution and refresh rate defined in the
    4141     *         database for the specified video resolution and frame rate.
    4242     */
    43     bool SwitchToVideo(int iwidth, int iheight, short irate = 0);
     43    bool SwitchToVideo(int iwidth, int iheight, short irate = 0, float frate = 0.0);
    4444    /** \brief Switches to the GUI resolution specified.
    4545     *
    4646     *   If which_gui is GUI then this switches to the resolution
     
    104104    /// \brief Returns all video modes supported by the display.
    105105    virtual const std::vector<DisplayResScreen>& GetVideoModes() const = 0;
    106106    /// \brief Returns refresh rates available at a specific screen resolution.
    107     const std::vector<short> GetRefreshRates(int width, int height) const;
     107    const std::vector<float> GetRefreshRatesFloat(int width, int height) const;
     108    const std::vector<short> GetRefreshRates(int width, int height) const;
    108109    /** @} */
    109110
    110111  protected:
     
    114115   
    115116    // These methods are implemented by the subclasses
    116117    virtual bool GetDisplaySize(int &width_mm, int &height_mm) const = 0;
    117     virtual bool SwitchToVideoMode(int width, int height, short framerate) = 0;
     118    virtual bool SwitchToVideoMode(int width, int height, float framerate) = 0;
    118119
    119120  private:
    120121    DisplayRes(const DisplayRes & rhs); // disable copy constructor;
  • mythtv/programs/mythfrontend/globalsettings.cpp

     
    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);
     2711
    26972712        settings->addChild(defaultsettings);
    26982713        settings->addChild(overrides);
     2714        settings->addChild(customscreensettings);
    26992715
    27002716        addTarget("1", settings);
    27012717        addTarget("0", new VerticalConfigurationGroup(true));