Ticket #13176: 20171120_#13176_mythplayer-Fix-issues-with-vsync2.patch

File 20171120_#13176_mythplayer-Fix-issues-with-vsync2.patch, 16.8 KB (added by Peter Bennett, 3 years ago)

Patch fixed for applying to master branch

  • mythtv/libs/libmythtv/mythplayer.cpp

    diff --git a/mythtv/libs/libmythtv/mythplayer.cpp b/mythtv/libs/libmythtv/mythplayer.cpp
    index 2a30cb9..3320553 100644
    a b void MythPlayer::SetVideoParams(int width, int height, double fps, 
    816816        if (ffrew_skip != 0 && ffrew_skip != 1)
    817817        {
    818818            UpdateFFRewSkip();
    819             videosync->setFrameInterval(frame_interval);
    820819        }
    821820        else
    822821        {
    void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay) 
    18901889
    18911890    if (avsync_predictor_enabled)
    18921891    {
    1893         avsync_predictor += frame_interval;
     1892        avsync_predictor += frame_interval + avsync_adjustment + repeat_delay;
    18941893        if (avsync_predictor >= refreshrate)
    18951894        {
    18961895            int refreshperiodsinframe = avsync_predictor/refreshrate;
    void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay) 
    19561955            LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO,
    19571956                LOC + QString("AVSync waitforframe %1 %2")
    19581957                    .arg(avsync_adjustment).arg(m_double_framerate));
    1959             vsync_delay_clock = videosync->WaitForFrame
    1960                                 (frameDelay + avsync_adjustment + repeat_delay);
     1958            vsync_delay_clock = videosync->WaitForFrame(frameDelay, avsync_adjustment + repeat_delay);
    19611959        }
    19621960        else
    19631961        {
    void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay) 
    19941992            osdLock.unlock();
    19951993            // Display the second field
    19961994            if (!player_ctx->IsPBP() || player_ctx->IsPrimaryPBP())
    1997                 vsync_delay_clock = videosync->WaitForFrame(frameDelay +
    1998                                                         avsync_adjustment);
     1995                vsync_delay_clock = videosync->WaitForFrame(frameDelay, avsync_adjustment);
    19991996            videoOutput->Show(ps);
    20001997        }
    20011998
    void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay) 
    20082005    }
    20092006    else
    20102007    {
    2011         vsync_delay_clock = videosync->WaitForFrame(frameDelay);
     2008        vsync_delay_clock = videosync->WaitForFrame(frameDelay, 0);
    20122009        //currentaudiotime = AVSyncGetAudiotime();
    20132010    }
    20142011
    void MythPlayer::VideoStart(void) 
    24502447
    24512448    if (player_ctx->IsPIP() && FlagIsSet(kVideoIsNull))
    24522449    {
    2453         videosync = new DummyVideoSync(videoOutput, fr_int, 0, false);
     2450        videosync = new DummyVideoSync(videoOutput, 0);
    24542451    }
    24552452    else if (FlagIsSet(kVideoIsNull))
    24562453    {
    2457         videosync = new USleepVideoSync(videoOutput, fr_int, 0, false);
     2454        videosync = new USleepVideoSync(videoOutput, 0);
    24582455    }
    24592456    else if (videoOutput)
    24602457    {
    void MythPlayer::VideoStart(void) 
    24652462
    24662463        m_double_process = videoOutput->IsExtraProcessingRequired();
    24672464
    2468         videosync = VideoSync::BestMethod(
    2469             videoOutput, (uint)fr_int, (uint)rf_int, m_double_framerate);
     2465        videosync = VideoSync::BestMethod(videoOutput, (uint)rf_int);
    24702466
    24712467        // Make sure video sync can do it
    24722468        if (videosync != NULL && m_double_framerate)
    void MythPlayer::VideoStart(void) 
    24822478    }
    24832479    if (!videosync)
    24842480    {
    2485         videosync = new BusyWaitVideoSync(
    2486             videoOutput, fr_int, rf_int, m_double_framerate);
     2481        videosync = new BusyWaitVideoSync(videoOutput, rf_int);
    24872482    }
    24882483
    24892484    InitAVSync();
    void MythPlayer::ChangeSpeed(void) 
    37513746    normal_speed = next_normal_speed;
    37523747
    37533748    bool skip_changed = UpdateFFRewSkip();
    3754     videosync->setFrameInterval(frame_interval);
    37553749
    37563750    if (skip_changed && videoOutput)
    37573751    {
  • mythtv/libs/libmythtv/vsync.cpp

    diff --git a/mythtv/libs/libmythtv/vsync.cpp b/mythtv/libs/libmythtv/vsync.cpp
    index c03e70f..db62191 100644
    a b int VideoSync::m_forceskip = 0; 
    5959#define TESTVIDEOSYNC(NAME) \
    6060    do { if (++m_forceskip > skip) \
    6161    { \
    62         trial = new NAME (video_output,     frame_interval, \
    63                           refresh_interval, halve_frame_interval); \
     62        trial = new NAME (video_output, refresh_interval); \
    6463        if (trial->TryInit()) \
    6564        { \
    6665            m_forceskip = skip; \
    int VideoSync::m_forceskip = 0; 
    7271
    7372#define LOC QString("VSYNC: ")
    7473
    75 /** \fn VideoSync::BestMethod(VideoOutput*,uint,uint,bool)
     74/** \fn VideoSync::BestMethod(VideoOutput*,uint)
    7675 *  \brief Returns the most sophisticated video sync method available.
    7776 */
    7877VideoSync *VideoSync::BestMethod(VideoOutput *video_output,
    79                                  uint frame_interval, uint refresh_interval,
    80                                  bool halve_frame_interval)
     78                                 uint refresh_interval)
    8179{
    8280    VideoSync *trial = NULL;
    8381    tryingVideoSync  = true;
    VideoSync *VideoSync::BestMethod(VideoOutput *video_output, 
    110108    return NULL;
    111109}
    112110
    113 /** \fn VideoSync::VideoSync(VideoOutput*,int,int,bool)
    114  *  \brief Used by BestMethod(VideoOutput*,uint,uint,bool) to initialize
     111/** \fn VideoSync::VideoSync(VideoOutput*,int)
     112 *  \brief Used by BestMethod(VideoOutput*,uint) to initialize
    115113 *         video synchronization method.
    116114 */
    117 VideoSync::VideoSync(VideoOutput *video_output,
    118                      int frameint, int refreshint,
    119                      bool halve_frame_interval) :
    120     m_video_output(video_output),   m_frame_interval(frameint),
    121     m_refresh_interval(refreshint), m_interlaced(halve_frame_interval),
     115VideoSync::VideoSync(VideoOutput *video_output, int refreshint) :
     116    m_video_output(video_output), m_refresh_interval(refreshint),
    122117    m_nexttrigger(0), m_delay(-1)
    123118{
    124119}
    void VideoSync::Start(void) 
    135130    m_nexttrigger = GetTime();
    136131}
    137132
    138 /** \fn VideoSync::CalcDelay()
     133/** \fn VideoSync::CalcDelay(int)
    139134 *  \brief Calculates the delay to the next frame.
    140135 *
    141136 *   Regardless of the timing method, if delay is greater than four full
    void VideoSync::Start(void) 
    146141 *   Also prevent the nexttrigger from falling too far in the past in case
    147142 *   we are trying to speed up video output faster than possible.
    148143 */
    149 int VideoSync::CalcDelay()
     144int VideoSync::CalcDelay(int nominal_frame_interval)
    150145{
    151146    int64_t now = GetTime();
    152147#if 0
    int VideoSync::CalcDelay() 
    160155    LOG(VB_GENERAL, LOG_DEBUG, QString("delay %1").arg(ret_val));
    161156#endif
    162157
    163     if (ret_val > m_frame_interval * 4)
     158    if (ret_val > nominal_frame_interval * 4)
    164159    {
    165         if (m_interlaced)
    166             ret_val = (m_frame_interval / 2) * 4;
    167         else
    168             ret_val = m_frame_interval * 4;
     160        ret_val = nominal_frame_interval * 4;
    169161
    170162        // set nexttrigger to our new target time
    171163        m_nexttrigger = now + ret_val;
    172164    }
    173165
    174     if (ret_val < -m_frame_interval && m_frame_interval >= m_refresh_interval)
     166    if (ret_val < -nominal_frame_interval && nominal_frame_interval >= m_refresh_interval)
    175167    {
    176         ret_val = -m_frame_interval;
     168        ret_val = -nominal_frame_interval;
    177169
    178170        // set nexttrigger to our new target time
    179171        m_nexttrigger = now + ret_val;
    static int drmWaitVBlank(int fd, drm_wait_vblank_t *vbl) 
    242234
    243235const char *DRMVideoSync::sm_dri_dev = "/dev/dri/card0";
    244236
    245 DRMVideoSync::DRMVideoSync(VideoOutput *vo, int fr, int ri, bool intl) :
    246     VideoSync(vo, fr, ri, intl)
     237DRMVideoSync::DRMVideoSync(VideoOutput *vo, int ri) :
     238    VideoSync(vo, ri)
    247239{
    248240    m_dri_fd = -1;
    249241}
    void DRMVideoSync::Start(void) 
    291283    VideoSync::Start();
    292284}
    293285
    294 int DRMVideoSync::WaitForFrame(int sync_delay)
     286int DRMVideoSync::WaitForFrame(int nominal_frame_interval, int extra_delay)
    295287{
    296288    // Offset for externally-provided A/V sync delay
    297     m_nexttrigger += sync_delay;
     289    m_nexttrigger += nominal_frame_interval + extra_delay;
    298290
    299     m_delay = CalcDelay();
     291    m_delay = CalcDelay(nominal_frame_interval);
    300292#if 0
    301293    LOG(VB_GENERAL, LOG_DEBUG, QString("WaitForFrame at : %1").arg(m_delay));
    302294#endif
    int DRMVideoSync::WaitForFrame(int sync_delay) 
    308300        blank.request.type = DRM_VBLANK_RELATIVE;
    309301        blank.request.sequence = 1;
    310302        drmWaitVBlank(m_dri_fd, &blank);
    311         m_delay = CalcDelay();
     303        m_delay = CalcDelay(nominal_frame_interval);
    312304#if 0
    313305        LOG(VB_GENERAL, LOG_DEBUG, QString("Delay at sync: %1").arg(m_delay));
    314306#endif
    int DRMVideoSync::WaitForFrame(int sync_delay) 
    323315        blank.request.type = DRM_VBLANK_RELATIVE;
    324316        blank.request.sequence = n;
    325317        drmWaitVBlank(m_dri_fd, &blank);
    326         m_delay = CalcDelay();
     318        m_delay = CalcDelay(nominal_frame_interval);
    327319#if 0
    328320        LOG(VB_GENERAL, LOG_DEBUG,
    329321            QString("Wait %1 intervals. Count %2 Delay %3")
    int DRMVideoSync::WaitForFrame(int sync_delay) 
    337329
    338330#ifdef __linux__
    339331#define RTCRATE 1024
    340 RTCVideoSync::RTCVideoSync(VideoOutput *vo, int fi, int ri, bool intr) :
    341     VideoSync(vo, fi, ri, intr)
     332RTCVideoSync::RTCVideoSync(VideoOutput *vo, int ri) :
     333    VideoSync(vo, ri)
    342334{
    343335    m_rtcfd = -1;
    344336}
    bool RTCVideoSync::TryInit(void) 
    377369    return true;
    378370}
    379371
    380 int RTCVideoSync::WaitForFrame(int sync_delay)
     372int RTCVideoSync::WaitForFrame(int nominal_frame_interval, int extra_delay)
    381373{
    382     m_nexttrigger += sync_delay;
     374    m_nexttrigger += nominal_frame_interval + extra_delay;
    383375
    384     m_delay = CalcDelay();
     376    m_delay = CalcDelay(nominal_frame_interval);
    385377
    386378    unsigned long rtcdata;
    387379    while (m_delay > 0)
    388380    {
    389381        ssize_t val = read(m_rtcfd, &rtcdata, sizeof(rtcdata));
    390         m_delay = CalcDelay();
     382        m_delay = CalcDelay(nominal_frame_interval);
    391383
    392384        if ((val < 0) && (m_delay > 0))
    393385            std::this_thread::sleep_for(std::chrono::microseconds(m_delay));
    int RTCVideoSync::WaitForFrame(int sync_delay) 
    396388}
    397389#endif /* __linux__ */
    398390
    399 BusyWaitVideoSync::BusyWaitVideoSync(VideoOutput *vo,
    400                                      int fr, int ri, bool intl) :
    401     VideoSync(vo, fr, ri, intl)
     391BusyWaitVideoSync::BusyWaitVideoSync(VideoOutput *vo, int ri) :
     392    VideoSync(vo, ri)
    402393{
    403394    m_cheat = 5000;
    404395    m_fudge = 0;
    bool BusyWaitVideoSync::TryInit(void) 
    413404    return true;
    414405}
    415406
    416 int BusyWaitVideoSync::WaitForFrame(int sync_delay)
     407int BusyWaitVideoSync::WaitForFrame(int nominal_frame_interval, int extra_delay)
    417408{
    418409    // Offset for externally-provided A/V sync delay
    419     m_nexttrigger += sync_delay;
     410    m_nexttrigger += nominal_frame_interval + extra_delay;
    420411
    421     m_delay = CalcDelay();
     412    m_delay = CalcDelay(nominal_frame_interval);
    422413
    423414    if (m_delay > 0)
    424415    {
    int BusyWaitVideoSync::WaitForFrame(int sync_delay) 
    431422
    432423        // If late, draw the frame ASAP.  If early, hold the CPU until
    433424        // half as late as the previous frame (fudge).
    434         m_delay = CalcDelay();
    435         m_fudge = min(m_fudge, m_frame_interval);
     425        m_delay = CalcDelay(nominal_frame_interval);
     426        m_fudge = min(m_fudge, nominal_frame_interval);
    436427        while (m_delay + m_fudge > 0)
    437428        {
    438             m_delay = CalcDelay();
     429            m_delay = CalcDelay(nominal_frame_interval);
    439430            cnt++;
    440431        }
    441432        m_fudge = abs(m_delay / 2);
    int BusyWaitVideoSync::WaitForFrame(int sync_delay) 
    445436    return 0;
    446437}
    447438
    448 USleepVideoSync::USleepVideoSync(VideoOutput *vo,
    449                                  int fr, int ri, bool intl) :
    450     VideoSync(vo, fr, ri, intl)
     439USleepVideoSync::USleepVideoSync(VideoOutput *vo, int ri) :
     440    VideoSync(vo, ri)
    451441{
    452442}
    453443
    bool USleepVideoSync::TryInit(void) 
    460450    return true;
    461451}
    462452
    463 int USleepVideoSync::WaitForFrame(int sync_delay)
     453int USleepVideoSync::WaitForFrame(int nominal_frame_interval, int extra_delay)
    464454{
    465455    // Offset for externally-provided A/V sync delay
    466     m_nexttrigger += sync_delay;
     456    m_nexttrigger += nominal_frame_interval + extra_delay;
    467457
    468     m_delay = CalcDelay();
     458    m_delay = CalcDelay(nominal_frame_interval);
    469459    if (m_delay > 0)
    470460        std::this_thread::sleep_for(std::chrono::microseconds(m_delay));
    471461    return 0;
  • mythtv/libs/libmythtv/vsync.h

    diff --git a/mythtv/libs/libmythtv/vsync.h b/mythtv/libs/libmythtv/vsync.h
    index 56ab9f9..2e0b79b 100644
    a b class VideoSync 
    4646// virtual base class
    4747{
    4848  public:
    49     VideoSync(VideoOutput*, int fi, int ri, bool intr);
     49    VideoSync(VideoOutput*, int ri);
    5050    virtual ~VideoSync() {}
    5151
    5252    /// \brief Returns name of instanciated VSync method.
    class VideoSync 
    6969     *   always be called from same thread, to prevent bad
    7070     *   interactions with threads.
    7171     *
    72      *  \param sync_delay time until the desired frame or field
    73      *  \sa CalcDelay(void), KeepPhase(void)
     72     *  \param nominal_frame_interval the frame interval normally expected
     73     *  \param extra_delay extra time beyond nominal until the desired frame or field
     74     *  \sa CalcDelay(int), KeepPhase(void)
    7475     */
    75     virtual int WaitForFrame(int sync_delay) = 0;
     76    virtual int WaitForFrame(int nominal_frame_interval, int extra_delay) = 0;
    7677
    7778    /// \brief Returns the (minimum) refresh interval of the output device.
    7879    int getRefreshInterval(void) const { return m_refresh_interval; }
    7980    /// \brief Sets the refresh interval of the output device.
    8081    void setRefreshInterval(int ri) { m_refresh_interval = ri; }
    8182
    82     virtual void setFrameInterval(int fi) { m_frame_interval = fi; };
    83 
    8483    /** \brief Stops VSync; must be called from main thread.
    8584     *
    8685     *   Start(void), WaitForFrame(void), and Stop(void) should
    class VideoSync 
    9089    virtual void Stop(void) {}
    9190
    9291    // documented in vsync.cpp
    93     static VideoSync *BestMethod(VideoOutput*,
    94                                  uint frame_interval, uint refresh_interval,
    95                                  bool interlaced);
     92    static VideoSync *BestMethod(VideoOutput *, uint refresh_interval);
     93
    9694  protected:
    9795    int64_t GetTime(void);
    98     int CalcDelay(void);
     96    int CalcDelay(int nominal_frame_interval);
    9997    void KeepPhase(void) MDEPRECATED;
    10098
    10199    VideoOutput *m_video_output;
    102     int m_frame_interval; // of video
    103100    int m_refresh_interval; // of display
    104     bool m_interlaced;
    105101    int64_t m_nexttrigger;
    106102    int m_delay;
    107103   
    class VideoSync 
    118114class DRMVideoSync : public VideoSync
    119115{
    120116  public:
    121     DRMVideoSync(VideoOutput*,
    122                  int frame_interval, int refresh_interval, bool interlaced);
     117    DRMVideoSync(VideoOutput *, int refresh_interval);
    123118    ~DRMVideoSync();
    124119
    125120    QString getName(void) const { return QString("DRM"); }
    126121    bool TryInit(void);
    127122    void Start(void);
    128     int WaitForFrame(int sync_delay);
     123    int WaitForFrame(int nominal_frame_interval, int extra_delay) override;
    129124
    130125  private:
    131126    int m_dri_fd;
    class DRMVideoSync : public VideoSync 
    148143class RTCVideoSync : public VideoSync
    149144{
    150145  public:
    151     RTCVideoSync(VideoOutput*,
    152                  int frame_interval, int refresh_interval, bool interlaced);
     146    RTCVideoSync(VideoOutput *, int refresh_interval);
    153147    ~RTCVideoSync();
    154148
    155149    QString getName(void) const { return QString("RTC"); }
    156150    bool TryInit(void);
    157     int WaitForFrame(int sync_delay);
     151    int WaitForFrame(int nominal_frame_interval, int extra_delay) override;
    158152
    159153  private:
    160154    int m_rtcfd;
    class RTCVideoSync : public VideoSync 
    174168class BusyWaitVideoSync : public VideoSync
    175169{
    176170  public:
    177     BusyWaitVideoSync(VideoOutput*,
    178                       int frame_interval, int refresh_interval,
    179                       bool interlaced);
     171    BusyWaitVideoSync(VideoOutput *, int refresh_interval);
    180172    ~BusyWaitVideoSync();
    181173
    182174    QString getName(void) const { return QString("USleep with busy wait"); }
    183175    bool TryInit(void);
    184     int WaitForFrame(int sync_delay);
     176    int WaitForFrame(int nominal_frame_interval, int extra_delay) override;
    185177
    186178  private:
    187179    int m_cheat;
    class BusyWaitVideoSync : public VideoSync 
    201193class USleepVideoSync : public VideoSync
    202194{
    203195  public:
    204     USleepVideoSync(VideoOutput*,
    205                     int frame_interval, int refresh_interval,
    206                     bool interlaced);
     196    USleepVideoSync(VideoOutput *, int refresh_interval);
    207197    ~USleepVideoSync();
    208198
    209199    QString getName(void) const { return QString("USleep"); }
    210200    bool TryInit(void);
    211     int WaitForFrame(int sync_delay);
     201    int WaitForFrame(int nominal_frame_interval, int extra_delay) override;
    212202};
    213203
    214204class DummyVideoSync : public VideoSync
    215205{
    216206  public:
    217     DummyVideoSync(VideoOutput* vo, int fr, int ri, bool intl)
    218      : VideoSync(vo, fr, ri, intl) { }
     207    DummyVideoSync(VideoOutput* vo, int ri) : VideoSync(vo, ri) { }
    219208    ~DummyVideoSync() { }
    220209
    221210    QString getName(void) const { return QString("Dummy"); }
    222211    bool TryInit(void) { return true; }
    223     int WaitForFrame(int /*sync_delay*/) { return 0; }
     212    int WaitForFrame(int nominal_frame_interval, int extra_delay) override { return 0; }
    224213};
    225214#endif /* VSYNC_H_INCLUDED */