Ticket #7964: mythtv-smoothsync-extra-trunk-02.patch

File mythtv-smoothsync-extra-trunk-02.patch, 10.0 KB (added by tralph, 14 years ago)

updated for 956b4f277fa23d8d8fc98b82f0911da642b18305

  • mythtv/libs/libmythtv/mythplayer.cpp

    diff --git a/mythtv/libs/libmythtv/mythplayer.cpp b/mythtv/libs/libmythtv/mythplayer.cpp
    index 1b976ff..d6f4670 100644
    a b void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay) 
    17081708
    17091709    float diverge = 0.0f;
    17101710    int frameDelay = m_double_framerate ? frame_interval / 2 : frame_interval;
     1711    int vsync_delay_clock = 0;
    17111712    int64_t currentaudiotime = 0;
    17121713
    17131714    // attempt to reduce fps for standalone PIP
    void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay) 
    17981799        osdLock.unlock();
    17991800        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + QString("AVSync waitforframe %1 %2")
    18001801                .arg(avsync_adjustment).arg(m_double_framerate));
    1801         videosync->WaitForFrame(frameDelay + avsync_adjustment + repeat_delay);
     1802        vsync_delay_clock = videosync->WaitForFrame
     1803                            (frameDelay + avsync_adjustment + repeat_delay);
    18021804        currentaudiotime = AVSyncGetAudiotime();
    18031805        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + "AVSync show");
    18041806        videoOutput->Show(ps);
    void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay) 
    18281830            videoOutput->PrepareFrame(buffer, ps, osd);
    18291831            osdLock.unlock();
    18301832            // Display the second field
    1831             videosync->WaitForFrame(frameDelay + avsync_adjustment);
     1833            vsync_delay_clock = videosync->WaitForFrame(frameDelay + avsync_adjustment);
    18321834            videoOutput->Show(ps);
    18331835        }
    18341836
    void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay) 
    18401842    }
    18411843    else
    18421844    {
    1843         videosync->WaitForFrame(frameDelay);
     1845        vsync_delay_clock = videosync->WaitForFrame(frameDelay);
    18441846        currentaudiotime = AVSyncGetAudiotime();
    18451847    }
    18461848
    void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay) 
    18691871
    18701872    if (audio.HasAudioOut() && normal_speed)
    18711873    {
     1874        // must be sampled here due to Show delays
    18721875        int64_t currentaudiotime = audio.GetAudioTime();
    1873         VERBOSE(VB_TIMESTAMP, LOC + QString(
     1876        VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + QString(
    18741877                    "A/V timecodes audio %1 video %2 frameinterval %3 "
    18751878                    "avdel %4 avg %5 tcoffset %6 "
    1876                     "avp %7 avpen %8")
     1879                    "avp %7 avpen %8 avdc %9")
    18771880                .arg(currentaudiotime)
    18781881                .arg(timecode)
    18791882                .arg(frame_interval)
    1880                 .arg(timecode - currentaudiotime)
     1883                .arg(timecode - currentaudiotime -
     1884                     (int)(vsync_delay_clock*audio.GetStretchFactor()+500)/1000)
    18811885                .arg(avsync_avg)
    18821886                .arg(tc_wrap[TC_AUDIO])
    18831887                .arg(avsync_predictor)
    18841888                .arg(avsync_predictor_enabled)
     1889                .arg(vsync_delay_clock)
    18851890                 );
    18861891        if (currentaudiotime != 0 && timecode != 0)
    18871892        { // currentaudiotime == 0 after a seek
    void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay) 
    19031908            prevtc = timecode;
    19041909            prevrp = repeat_pict;
    19051910
    1906             avsync_delay = (timecode - currentaudiotime) * 1000;//usec
     1911            avsync_delay = (timecode - currentaudiotime) * 1000 -
     1912                            (int)(vsync_delay_clock*audio.GetStretchFactor()); //usec
    19071913            // prevents major jitter when pts resets during dvd title
    19081914            if (avsync_delay > 2000000 && limit_delay)
    19091915                avsync_delay = 90000;
  • mythtv/libs/libmythtv/vsync.cpp

    diff --git a/mythtv/libs/libmythtv/vsync.cpp b/mythtv/libs/libmythtv/vsync.cpp
    index 6e1b891..9d0a005 100644
    a b int VideoSync::CalcDelay() 
    178178        m_nexttrigger = now + ret_val;
    179179    }
    180180
    181     if (ret_val < -m_frame_interval)
     181    if (ret_val < -m_frame_interval && m_frame_interval >= m_refresh_interval)
    182182    {
    183183        ret_val = -m_frame_interval;
    184184
    void DRMVideoSync::Start(void) 
    293293    VideoSync::Start();
    294294}
    295295
    296 void DRMVideoSync::WaitForFrame(int sync_delay)
     296int DRMVideoSync::WaitForFrame(int sync_delay)
    297297{
    298298    // Offset for externally-provided A/V sync delay
    299299    m_nexttrigger += sync_delay;
    void DRMVideoSync::WaitForFrame(int sync_delay) 
    316316    if (m_delay > 0)
    317317    {
    318318        // Wait for any remaining retrace intervals in one pass.
    319         int n = m_delay / m_refresh_interval + 1;
     319        int n = (m_delay + m_refresh_interval - 1) / m_refresh_interval;
    320320
    321321        drm_wait_vblank_t blank;
    322322        blank.request.type = DRM_VBLANK_RELATIVE;
    void DRMVideoSync::WaitForFrame(int sync_delay) 
    327327        //cerr  << " Delay " << m_delay << endl;
    328328    }
    329329
     330    return m_delay;
     331
    330332    KeepPhase();
    331333}
    332334#endif /* !_WIN32 */
    void OpenGLVideoSync::Start(void) 
    397399#endif /* USING_OPENGL_VSYNC */
    398400}
    399401
    400 void OpenGLVideoSync::WaitForFrame(int sync_delay)
     402int OpenGLVideoSync::WaitForFrame(int sync_delay)
    401403{
    402404    (void) sync_delay;
    403405#ifdef USING_OPENGL_VSYNC
    void OpenGLVideoSync::WaitForFrame(int sync_delay) 
    409411        m_delay = CalcDelay();
    410412        if (m_delay > 0)
    411413            usleep(m_delay);
    412         return;
     414        return 0;
    413415    }
    414416
    415417    if (!m_context)
    416         return;
     418        return 0;
    417419
    418420    unsigned int frameNum = m_context->GetVideoSyncCount();
    419421
    void OpenGLVideoSync::WaitForFrame(int sync_delay) 
    427429    // Wait for any remaining retrace intervals in one pass.
    428430    if (m_delay > 0)
    429431    {
    430         uint n = m_delay / m_refresh_interval + 1;
     432        uint n = (m_delay + m_refresh_interval - 1) / m_refresh_interval;
    431433        m_context->WaitForVideoSync((n+1), (frameNum+n)%(n+1), &frameNum);
    432434        m_delay = CalcDelay();
    433435    }
    434436
     437    return m_delay;
     438
    435439    KeepPhase();
    436440#endif /* USING_OPENGL_VSYNC */
    437441}
    bool RTCVideoSync::TryInit(void) 
    479483    return true;
    480484}
    481485
    482 void RTCVideoSync::WaitForFrame(int sync_delay)
     486int RTCVideoSync::WaitForFrame(int sync_delay)
    483487{
    484488    m_nexttrigger += sync_delay;
    485489
    void RTCVideoSync::WaitForFrame(int sync_delay) 
    494498        if ((val < 0) && (m_delay > 0))
    495499            usleep(m_delay);
    496500    }
     501    return 0;
    497502}
    498503#endif /* __linux__ */
    499504
    bool VDPAUVideoSync::TryInit(void) 
    517522    return true;
    518523}
    519524
    520 void VDPAUVideoSync::WaitForFrame(int sync_delay)
     525int VDPAUVideoSync::WaitForFrame(int sync_delay)
    521526{
    522527    // Offset for externally-provided A/V sync delay
    523528    m_nexttrigger += sync_delay;
    void VDPAUVideoSync::WaitForFrame(int sync_delay) 
    528533
    529534    VideoOutputVDPAU *vo = (VideoOutputVDPAU *)(m_video_output);
    530535    vo->SetNextFrameDisplayTimeOffset(m_delay);
     536    return 0;
    531537}
    532538#endif
    533539
    bool BusyWaitVideoSync::TryInit(void) 
    548554    return true;
    549555}
    550556
    551 void BusyWaitVideoSync::WaitForFrame(int sync_delay)
     557int BusyWaitVideoSync::WaitForFrame(int sync_delay)
    552558{
    553559    // Offset for externally-provided A/V sync delay
    554560    m_nexttrigger += sync_delay;
    void BusyWaitVideoSync::WaitForFrame(int sync_delay) 
    577583        if (cnt > 1)
    578584            m_cheat -= 200;
    579585    }
     586    return 0;
    580587}
    581588
    582589USleepVideoSync::USleepVideoSync(VideoOutput *vo,
    bool USleepVideoSync::TryInit(void) 
    594601    return true;
    595602}
    596603
    597 void USleepVideoSync::WaitForFrame(int sync_delay)
     604int USleepVideoSync::WaitForFrame(int sync_delay)
    598605{
    599606    // Offset for externally-provided A/V sync delay
    600607    m_nexttrigger += sync_delay;
    void USleepVideoSync::WaitForFrame(int sync_delay) 
    602609    m_delay = CalcDelay();
    603610    if (m_delay > 0)
    604611        usleep(m_delay);
     612    return 0;
    605613}
    606614
  • mythtv/libs/libmythtv/vsync.h

    diff --git a/mythtv/libs/libmythtv/vsync.h b/mythtv/libs/libmythtv/vsync.h
    index 310d866..3db298b 100644
    a b class VideoSync 
    6464    virtual void Start(void);
    6565
    6666    /** \brief Waits for next a frame or field.
     67     *   Returns delay to real frame timing in usec
    6768     *
    6869     *   Start(void), WaitForFrame(void), and Stop(void) should
    6970     *   always be called from same thread, to prevent bad
    class VideoSync 
    7273     *  \param sync_delay time until the desired frame or field
    7374     *  \sa CalcDelay(void), KeepPhase(void)
    7475     */
    75     virtual void WaitForFrame(int sync_delay) = 0;
     76    virtual int WaitForFrame(int sync_delay) = 0;
    7677
    7778    /// \brief Returns the (minimum) refresh interval of the output device.
    7879    int getRefreshInterval(void) const { return m_refresh_interval; }
    class DRMVideoSync : public VideoSync 
    123124    QString getName(void) const { return QString("DRM"); }
    124125    bool TryInit(void);
    125126    void Start(void);
    126     void WaitForFrame(int sync_delay);
     127    int WaitForFrame(int sync_delay);
    127128
    128129  private:
    129130    int m_dri_fd;
    class OpenGLVideoSync : public VideoSync 
    164165    QString getName(void) const { return QString("SGI OpenGL"); }
    165166    bool TryInit(void);
    166167    void Start(void);
    167     void WaitForFrame(int sync_delay);
     168    int WaitForFrame(int sync_delay);
    168169
    169170  private:
    170171    MythRenderOpenGL  *m_context;
    class RTCVideoSync : public VideoSync 
    192193
    193194    QString getName(void) const { return QString("RTC"); }
    194195    bool TryInit(void);
    195     void WaitForFrame(int sync_delay);
     196    int WaitForFrame(int sync_delay);
    196197
    197198  private:
    198199    int m_rtcfd;
    class VDPAUVideoSync : public VideoSync 
    212213
    213214    QString getName(void) const { return QString("VDPAU"); }
    214215    bool TryInit(void);
    215     void WaitForFrame(int sync_delay);
     216    int WaitForFrame(int sync_delay);
    216217
    217218  private:
    218219};
    class BusyWaitVideoSync : public VideoSync 
    239240
    240241    QString getName(void) const { return QString("USleep with busy wait"); }
    241242    bool TryInit(void);
    242     void WaitForFrame(int sync_delay);
     243    int WaitForFrame(int sync_delay);
    243244
    244245  private:
    245246    int m_cheat;
    class USleepVideoSync : public VideoSync 
    266267
    267268    QString getName(void) const { return QString("USleep"); }
    268269    bool TryInit(void);
    269     void WaitForFrame(int sync_delay);
     270    int WaitForFrame(int sync_delay);
    270271};
    271272#endif /* VSYNC_H_INCLUDED */