Ticket #7964: mythtv_smoothsync-24fixes-p0.patch

File mythtv_smoothsync-24fixes-p0.patch, 24.6 KB (added by tralph, 14 years ago)

combinded and refeshed patch for 0.24-fixes users

  • mythtv/libs/libmythtv/mythplayer.cpp

    diff --git a/mythtv/libs/libmythtv/mythplayer.cpp b/mythtv/libs/libmythtv/mythplayer.cpp
    index 5b13fbc..8a4c621 100644
    a b MythPlayer::MythPlayer(bool muted) 
    237237      // Audio and video synchronization stuff
    238238      videosync(NULL),              avsync_delay(0),
    239239      avsync_adjustment(0),         avsync_avg(0),
     240      avsync_predictor(0),          avsync_predictor_enabled(false),
    240241      refreshrate(0),
    241242      lastsync(false),              repeat_delay(0),
    242243      // Time Code stuff
    void MythPlayer::SetVideoParams(int width, int height, double fps, 
    872873        video_frame_rate = fps;
    873874        float temp_speed = (play_speed == 0.0f) ?
    874875            audio.GetStretchFactor() : play_speed;
    875         frame_interval = (int)(1000000.0f / video_frame_rate / temp_speed);
     876        SetFrameInterval(kScan_Progressive, 1.0 / (video_frame_rate * temp_speed));
    876877    }
    877878
    878879    if (videoOutput)
    int MythPlayer::NextCaptionTrack(int mode) 
    16131614    return NextCaptionTrack(nextmode);
    16141615}
    16151616
     1617void MythPlayer::SetFrameInterval(FrameScanType scan, double frame_period)
     1618{
     1619    frame_interval = (int)(1000000.0f * frame_period + 0.5f);
     1620    if (!avsync_predictor_enabled)
     1621        avsync_predictor = 0;
     1622    avsync_predictor_enabled = false;
     1623
     1624    VERBOSE(VB_PLAYBACK, LOC + QString("SetFrameInterval ps:%1 scan:%2")
     1625            .arg(play_speed).arg(scan)
     1626           );
     1627    if (play_speed < 1 || play_speed > 2 || refreshrate <= 0)
     1628        return;
     1629
     1630    avsync_predictor_enabled = ((frame_interval-(frame_interval/200)) < refreshrate);
     1631}
     1632
     1633void MythPlayer::ResetAVSync(void)
     1634{
     1635    avsync_avg = 0;
     1636    if (!avsync_predictor_enabled || avsync_predictor >= refreshrate)
     1637        avsync_predictor = 0;
     1638    prevtc = 0;
     1639    VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + "A/V sync reset");
     1640}
     1641
    16161642void MythPlayer::InitAVSync(void)
    16171643{
    16181644    videosync->Start();
    void MythPlayer::InitAVSync(void) 
    16361662                       .arg(1000000.0 / frame_interval, 0, 'f', 3);
    16371663        VERBOSE(VB_PLAYBACK, LOC + msg);
    16381664
     1665        SetFrameInterval(m_scan, 1.0 / (video_frame_rate * play_speed));
     1666
    16391667        // try to get preferential scheduling, but ignore if we fail to.
    16401668        myth_nice(-19);
    16411669    }
    16421670}
    16431671
     1672int64_t MythPlayer::AVSyncGetAudiotime(void)
     1673{
     1674    int64_t currentaudiotime = 0;
     1675    if (normal_speed)
     1676    {
     1677        currentaudiotime = audio.GetAudioTime();
     1678    }
     1679    return currentaudiotime;
     1680}
     1681
    16441682#define MAXDIVERGE  3.0f
    16451683#define DIVERGELIMIT 30.0f
    16461684void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay)
    16471685{
    16481686    int repeat_pict  = 0;
    1649     int64_t timecode = audio.GetAudioTime();
     1687    int64_t timecode = 0;
    16501688
    16511689    if (buffer)
    16521690    {
    16531691        repeat_pict = buffer->repeat_pict;
    16541692        timecode    = buffer->timecode;
    16551693    }
     1694    else
     1695        timecode = audio.GetAudioTime();
    16561696
    16571697    float diverge = 0.0f;
    16581698    int frameDelay = m_double_framerate ? frame_interval / 2 : frame_interval;
     1699    int vsync_delay_clock = 0;
     1700    int64_t currentaudiotime = 0;
    16591701
    16601702    // attempt to reduce fps for standalone PIP
    16611703    if (player_ctx->IsPIP() && framesPlayed % 2)
    void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay) 
    16851727    if (kScan_Detect == m_scan || kScan_Ignore == m_scan)
    16861728        ps = kScan_Progressive;
    16871729
     1730    bool dropframe = false;
     1731    QString dbg;
     1732
     1733    if (avsync_predictor_enabled) // && !prebuffering)
     1734    {
     1735        avsync_predictor += frame_interval;
     1736        if (avsync_predictor >= refreshrate)
     1737        {
     1738            int refreshperiodsinframe = avsync_predictor/refreshrate;
     1739            avsync_predictor -= refreshrate * refreshperiodsinframe;
     1740        }
     1741        else
     1742        {
     1743            dropframe = true;
     1744            dbg = "A/V predict drop frame, ";
     1745        }
     1746    }
     1747
    16881748    if (diverge < -MAXDIVERGE)
    16891749    {
     1750        dropframe = true;
    16901751        // If video is way behind of audio, adjust for it...
    1691         QString dbg = QString("Video is %1 frames behind audio (too slow), ")
     1752        dbg = QString("Video is %1 frames behind audio (too slow), ")
    16921753            .arg(-diverge);
     1754    }
    16931755
     1756    if (dropframe)
     1757    {
    16941758        // Reset A/V Sync
    16951759        lastsync = true;
    16961760
     1761        currentaudiotime = AVSyncGetAudiotime();
    16971762        if (!using_null_videoout &&
    16981763            videoOutput->hasHWAcceleration() &&
    16991764           !videoOutput->IsSyncLocked())
    void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay) 
    17201785        osdLock.lock();
    17211786        videoOutput->PrepareFrame(buffer, ps, osd);
    17221787        osdLock.unlock();
    1723         VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("AVSync waitforframe %1 %2")
     1788        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP,
     1789                LOC + QString("AVSync waitforframe %1 %2")
    17241790                .arg(avsync_adjustment).arg(m_double_framerate));
    1725         videosync->WaitForFrame(frameDelay + avsync_adjustment + repeat_delay);
    1726         VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, "AVSync show");
     1791        vsync_delay_clock = videosync->WaitForFrame
     1792                            (frameDelay + avsync_adjustment + repeat_delay);
     1793        currentaudiotime = AVSyncGetAudiotime();
     1794        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + "AVSync show");
    17271795        videoOutput->Show(ps);
    17281796
    17291797        if (videoOutput->IsErrored())
    void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay) 
    17511819            videoOutput->PrepareFrame(buffer, ps, osd);
    17521820            osdLock.unlock();
    17531821            // Display the second field
    1754             videosync->WaitForFrame(frameDelay + avsync_adjustment);
     1822            //videosync->AdvanceTrigger();
     1823            vsync_delay_clock = videosync->WaitForFrame(frameDelay + avsync_adjustment);
    17551824            videoOutput->Show(ps);
    17561825        }
    17571826
    17581827        repeat_delay = frame_interval * repeat_pict * 0.5;
    17591828
    17601829        if (repeat_delay)
    1761             VERBOSE(VB_TIMESTAMP, QString("A/V repeat_pict, adding %1 repeat "
     1830            VERBOSE(VB_TIMESTAMP, LOC + QString("A/V repeat_pict, adding %1 repeat "
    17621831                    "delay").arg(repeat_delay));
    17631832    }
    17641833    else
    17651834    {
    1766         videosync->WaitForFrame(frameDelay);
     1835        vsync_delay_clock = videosync->WaitForFrame(frameDelay);
     1836        currentaudiotime = AVSyncGetAudiotime();
    17671837    }
    17681838
    17691839    if (output_jmeter)
    1770         output_jmeter->RecordCycleTime();
     1840    {
     1841        if (output_jmeter->RecordCycleTime())
     1842        {
     1843            VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + QString("A/V avsync_delay: %1, "
     1844                    "avsync_avg: %2")
     1845                    .arg(avsync_delay / 1000).arg(avsync_avg / 1000)
     1846                    );
     1847        }
     1848    }
    17711849
    17721850    avsync_adjustment = 0;
    17731851
    void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay) 
    17751853    {
    17761854        // If audio is way behind of video, adjust for it...
    17771855        // by cutting the frame rate in half for the length of this frame
    1778         avsync_adjustment = refreshrate;
     1856        //avsync_adjustment = refreshrate;
     1857        avsync_adjustment = frame_interval;
    17791858        lastsync = true;
    17801859        VERBOSE(VB_PLAYBACK, LOC +
    17811860                QString("Video is %1 frames ahead of audio,\n"
    void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay) 
    17841863
    17851864    if (audio.HasAudioOut() && normal_speed)
    17861865    {
     1866        // must be sampled here due to Show delays
    17871867        int64_t currentaudiotime = audio.GetAudioTime();
    1788         VERBOSE(VB_TIMESTAMP, QString(
     1868        VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + QString(
    17891869                    "A/V timecodes audio %1 video %2 frameinterval %3 "
    1790                     "avdel %4 avg %5 tcoffset %6")
     1870                    "avdel %4 avg %5 tcoffset %6"
     1871                    " avp %7 avpen %8"
     1872                    " avdc %9"
     1873                    )
    17911874                .arg(currentaudiotime)
    17921875                .arg(timecode)
    17931876                .arg(frame_interval)
    1794                 .arg(timecode - currentaudiotime)
     1877                .arg(timecode - currentaudiotime - (int)(vsync_delay_clock*audio.GetStretchFactor()+500)/1000)
    17951878                .arg(avsync_avg)
    17961879                .arg(tc_wrap[TC_AUDIO])
     1880                .arg(avsync_predictor)
     1881                .arg(avsync_predictor_enabled)
     1882                .arg(vsync_delay_clock)
    17971883                 );
    17981884        if (currentaudiotime != 0 && timecode != 0)
    17991885        { // currentaudiotime == 0 after a seek
    18001886            // The time at the start of this frame (ie, now) is given by
    18011887            // last->timecode
    1802             int delta = (int)((timecode - prevtc)/play_speed) - (frame_interval / 1000);
    1803             prevtc = timecode;
    1804             //cerr << delta << " ";
    1805 
    1806             // If the timecode is off by a frame (dropped frame) wait to sync
    1807             if (delta > (int) frame_interval / 1200 &&
    1808                 delta < (int) frame_interval / 1000 * 3 &&
    1809                 prevrp == 0)
     1888            if (prevtc != 0)
    18101889            {
    1811                 // wait an extra frame interval
    1812                 avsync_adjustment += frame_interval;
     1890                int delta = (int)((timecode - prevtc)/play_speed) - (frame_interval / 1000);
     1891                // If the timecode is off by a frame (dropped frame) wait to sync
     1892                if (delta > (int) frame_interval / 1200 &&
     1893                    delta < (int) frame_interval / 1000 * 3 &&
     1894                    prevrp == 0)
     1895                {
     1896                    // wait an extra frame interval
     1897                    VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + QString("A/V delay %1").arg(delta));
     1898                    avsync_adjustment += frame_interval;
     1899                    //videosync->AdvanceTrigger();
     1900                    //if (m_double_framerate)
     1901                    //    videosync->AdvanceTrigger();
     1902                }
    18131903            }
     1904            prevtc = timecode;
    18141905            prevrp = repeat_pict;
    18151906
    1816             avsync_delay = (timecode - currentaudiotime) * 1000;//usec
     1907            avsync_delay = (timecode - currentaudiotime) * 1000 - (int)(vsync_delay_clock*audio.GetStretchFactor());  //usec
    18171908            // prevents major jitter when pts resets during dvd title
    18181909            if (avsync_delay > 2000000 && limit_delay)
    18191910                avsync_delay = 90000;
    18201911            avsync_avg = (avsync_delay + (avsync_avg * 3)) / 4;
    18211912
     1913            int avsync_used = avsync_avg;
     1914            if (labs(avsync_used) > labs(avsync_delay))
     1915                avsync_used = avsync_delay;
     1916
    18221917            /* If the audio time codes and video diverge, shift
    18231918               the video by one interlaced field (1/2 frame) */
    18241919            if (!lastsync)
    18251920            {
    1826                 if (avsync_avg > frame_interval * 3 / 2)
     1921                if (avsync_used > refreshrate)
    18271922                {
    18281923                    avsync_adjustment += refreshrate;
    1829                     lastsync = true;
     1924                    //lastsync = true;
     1925                    VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + "A/V avg high extend");
    18301926                }
    1831                 else if (avsync_avg < 0 - frame_interval * 3 / 2)
     1927                else if (avsync_used < 0 - refreshrate)
    18321928                {
    18331929                    avsync_adjustment -= refreshrate;
    1834                     lastsync = true;
     1930                    //lastsync = true;
     1931                    VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + "A/V avg high skip");
    18351932                }
    18361933            }
    18371934            else
    void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay) 
    18391936        }
    18401937        else
    18411938        {
    1842             avsync_avg = 0;
     1939            ResetAVSync();
    18431940        }
    18441941    }
     1942    else
     1943    {
     1944        VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + QString("A/V no sync proc ns:%1").arg(normal_speed));
     1945    }
    18451946}
    18461947
    18471948void MythPlayer::RefreshPauseFrame(void)
    void MythPlayer::ClearAfterSeek(bool clearvideobuffers) 
    34893590    commBreakMap.SetTracker(framesPlayed);
    34903591    commBreakMap.ResetLastSkip();
    34913592    needNewPauseFrame = true;
     3593    ResetAVSync();
    34923594}
    34933595
    34943596void MythPlayer::SetPlayerInfo(TV *tv, QWidget *widget,
  • mythtv/libs/libmythtv/mythplayer.h

    diff --git a/mythtv/libs/libmythtv/mythplayer.h b/mythtv/libs/libmythtv/mythplayer.h
    index 8090e35..f55c8f9 100644
    a b class MPUBLIC MythPlayer 
    515515    void  WrapTimecode(int64_t &timecode, TCTypes tc_type);
    516516    void  InitAVSync(void);
    517517    virtual void AVSync(VideoFrame *buffer, bool limit_delay = false);
     518    void  ResetAVSync(void);
     519    int64_t AVSyncGetAudiotime(void);
     520    void  SetFrameInterval(FrameScanType scan, double speed);
    518521    void  FallbackDeint(void);
    519522    void  CheckExtraAudioDecode(void);
    520523
    class MPUBLIC MythPlayer 
    703706    int        avsync_delay;
    704707    int        avsync_adjustment;
    705708    int        avsync_avg;
     709    int        avsync_predictor;
     710    bool       avsync_predictor_enabled;
    706711    int        refreshrate;
    707712    bool       lastsync;
    708713    bool       decode_extra_audio;
  • mythtv/libs/libmythtv/vsync.cpp

    diff --git a/mythtv/libs/libmythtv/vsync.cpp b/mythtv/libs/libmythtv/vsync.cpp
    index 1f08fc5..75528bc 100644
    a b VideoSync::VideoSync(VideoOutput *video_output, 
    130130                     bool halve_frame_interval) :
    131131    m_video_output(video_output),   m_frame_interval(frameint),
    132132    m_refresh_interval(refreshint), m_interlaced(halve_frame_interval),
    133     m_delay(-1)
     133    m_nexttrigger(0),
     134    m_delay(-1),
     135    m_synchronous(false)
    134136{
    135     bzero(&m_nexttrigger, sizeof(m_nexttrigger));
     137    int fieldint = frameint;
     138    if (halve_frame_interval)
     139        fieldint /= 2;
     140    double sync_factor = fieldint * 2.0f / refreshint;
     141    sync_factor = sync_factor - round(sync_factor);
     142    m_synchronous = (sync_factor >= -0.005) && (sync_factor <= 0.005);
     143    VERBOSE(VB_PLAYBACK, LOC + QString("Set video sync frame interval to %1 (synced:%2)")
     144                                 .arg(m_frame_interval).arg(m_synchronous));
    136145}
    137146
    138 void VideoSync::Start(void)
     147int64_t GetTime(void)
    139148{
    140     gettimeofday(&m_nexttrigger, NULL); // now
     149    struct timeval now_tv;
     150    gettimeofday(&now_tv, NULL); // now
     151    return now_tv.tv_sec * 1000000LL + now_tv.tv_usec;
    141152}
    142153
    143 void VideoSync::OffsetTimeval(struct timeval& tv, int offset)
     154void VideoSync::Start(void)
    144155{
    145     tv.tv_usec += offset;
    146     while (tv.tv_usec > 999999)
    147     {
    148         tv.tv_sec++;
    149         tv.tv_usec -= 1000000;
    150     }
    151     while (tv.tv_usec < 0)
    152     {
    153         tv.tv_sec--;
    154         tv.tv_usec += 1000000;
    155     }
     156    m_nexttrigger = GetTime();
    156157}
    157158
    158159/** \fn VideoSync::CalcDelay()
    void VideoSync::OffsetTimeval(struct timeval& tv, int offset) 
    168169 */
    169170int VideoSync::CalcDelay()
    170171{
    171     struct timeval now;
    172     gettimeofday(&now, NULL);
     172    int64_t now = GetTime();
    173173    //cout << "CalcDelay: next: " << timeval_str(m_nexttrigger) << " now "
    174174    // << timeval_str(now) << endl;
    175175
    176     int ret_val = (m_nexttrigger.tv_sec - now.tv_sec) * 1000000 +
    177                   (m_nexttrigger.tv_usec - now.tv_usec);
     176    int ret_val = m_nexttrigger - now;
    178177
    179178    //cout << "delay " << ret_val << endl;
    180179
    int VideoSync::CalcDelay() 
    186185            ret_val = m_frame_interval * 4;
    187186
    188187        // set nexttrigger to our new target time
    189         m_nexttrigger.tv_sec = now.tv_sec;
    190         m_nexttrigger.tv_usec = now.tv_usec;
    191         OffsetTimeval(m_nexttrigger, ret_val);
     188        m_nexttrigger = now;
     189        m_nexttrigger += ret_val;
    192190    }
    193191
    194     if (ret_val < -m_frame_interval)
     192    if ((ret_val < -m_frame_interval) && (m_frame_interval >= m_refresh_interval))
    195193    {
    196194        ret_val = -m_frame_interval;
    197195
    198196        // set nexttrigger to our new target time
    199         m_nexttrigger.tv_sec = now.tv_sec;
    200         m_nexttrigger.tv_usec = now.tv_usec;
    201         OffsetTimeval(m_nexttrigger, ret_val);
     197        m_nexttrigger = now;
     198        m_nexttrigger += ret_val;
    202199    }
    203200
    204201    return ret_val;
    int VideoSync::CalcDelay() 
    215212void VideoSync::KeepPhase()
    216213{
    217214    // cerr << m_delay << endl;
    218     if (m_delay < -(m_refresh_interval/2))
    219         OffsetTimeval(m_nexttrigger, 200);
    220     else if (m_delay > -500)
    221         OffsetTimeval(m_nexttrigger, -2000);
     215    if (m_synchronous)
     216    {
     217        if (m_delay < -(m_refresh_interval - 500))
     218            m_nexttrigger += 200;
     219        else if (m_delay > -500)
     220            m_nexttrigger += -2000;
     221    }
     222    else
     223    {
     224        if (m_delay < -(m_refresh_interval + 500))
     225            m_nexttrigger += 200;
     226        else if (m_delay >= 0)
     227            m_nexttrigger += -2000;
     228    }
    222229}
    223230
    224231#ifndef _WIN32
    void DRMVideoSync::Start(void) 
    308315    VideoSync::Start();
    309316}
    310317
    311 void DRMVideoSync::WaitForFrame(int sync_delay)
     318int DRMVideoSync::WaitForFrame(int sync_delay)
    312319{
    313320    // Offset for externally-provided A/V sync delay
    314     OffsetTimeval(m_nexttrigger, sync_delay);
     321    m_nexttrigger += sync_delay;
    315322
    316323    m_delay = CalcDelay();
    317324    //cerr << "WaitForFrame at : " << m_delay;
    void DRMVideoSync::WaitForFrame(int sync_delay) 
    331338    if (m_delay > 0)
    332339    {
    333340        // Wait for any remaining retrace intervals in one pass.
    334         int n = m_delay / m_refresh_interval + 1;
     341        int n = (m_delay + m_refresh_interval - 1) / m_refresh_interval;
    335342
    336343        drm_wait_vblank_t blank;
    337344        blank.request.type = DRM_VBLANK_RELATIVE;
    void DRMVideoSync::WaitForFrame(int sync_delay) 
    341348        //cerr << "Wait " << n << " intervals. Count " << blank.request.sequence;
    342349        //cerr  << " Delay " << m_delay << endl;
    343350    }
     351    return m_delay;
    344352
    345353    KeepPhase();
    346354}
    void OpenGLVideoSync::Start(void) 
    412420#endif /* USING_OPENGL_VSYNC */
    413421}
    414422
    415 void OpenGLVideoSync::WaitForFrame(int sync_delay)
     423int OpenGLVideoSync::WaitForFrame(int sync_delay)
    416424{
    417425    (void) sync_delay;
    418426#ifdef USING_OPENGL_VSYNC
     427//#define GLVSYNCDEBUG
     428#ifdef GLVSYNCDEBUG
     429    int refreshcount = 0;
     430#endif
    419431    const QString msg1("First A/V Sync"), msg2("Second A/V Sync");
    420     OffsetTimeval(m_nexttrigger, sync_delay);
     432    m_nexttrigger += sync_delay;
    421433
    422434    if (m_video_output && m_video_output->IsEmbedding())
    423435    {
    424436        m_delay = CalcDelay();
    425437        if (m_delay > 0)
    426438            usleep(m_delay);
    427         return;
     439        return 0;
    428440    }
    429441
    430442    if (!m_context)
    431         return;
     443        return 0;
    432444
    433445    unsigned int frameNum = m_context->GetVideoSyncCount();
    434446
     447#ifdef GLVSYNCDEBUG
     448    int delay1 = m_delay;
     449    int delay2;
     450#endif
    435451    // Always sync to the next retrace execpt when we are very late.
    436452    if ((m_delay = CalcDelay()) > -(m_refresh_interval/2))
    437453    {
     454#ifdef GLVSYNCDEBUG
     455        delay2 = m_delay;
     456#endif
    438457        m_context->WaitForVideoSync(2, (frameNum+1)%2 ,&frameNum);
    439458        m_delay = CalcDelay();
     459#ifdef GLVSYNCDEBUG
     460        refreshcount++;
     461#endif
    440462    }
     463#ifdef GLVSYNCDEBUG
     464    else
     465        delay2 = m_delay;
     466#endif
    441467
     468#ifdef GLVSYNCDEBUG
     469    int delay3 = m_delay;
     470#endif
    442471    // Wait for any remaining retrace intervals in one pass.
    443472    if (m_delay > 0)
    444473    {
    445         uint n = m_delay / m_refresh_interval + 1;
     474        //uint n = m_delay / m_refresh_interval + 1;
     475        uint n = (m_delay + m_refresh_interval - 1) / m_refresh_interval;
    446476        m_context->WaitForVideoSync((n+1), (frameNum+n)%(n+1), &frameNum);
     477#ifdef GLVSYNCDEBUG
     478        refreshcount += (int)n;
     479#endif
    447480        m_delay = CalcDelay();
    448481    }
     482#ifdef GLVSYNCDEBUG
     483    VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, QString("VS: WFF: ri:%1 fi:%2 delay1:%3 delay2:%4 delay3:%5 skip:%6 finaldelay:%7")
     484            .arg(m_refresh_interval)
     485            .arg(m_frame_interval)
     486            .arg(delay1)
     487            .arg(delay2)
     488            .arg(delay3)
     489            .arg(refreshcount)
     490            .arg(m_delay)
     491           );
     492#endif
     493
     494    return m_delay;
    449495
    450496    KeepPhase();
     497#ifdef GLVSYNCDEBUG
     498    VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, "VS: AdvanceTrigger");
     499#endif
    451500#endif /* USING_OPENGL_VSYNC */
    452501}
    453502#endif /* !_WIN32 */
    bool RTCVideoSync::TryInit(void) 
    494543    return true;
    495544}
    496545
    497 void RTCVideoSync::WaitForFrame(int sync_delay)
     546int RTCVideoSync::WaitForFrame(int sync_delay)
    498547{
    499     OffsetTimeval(m_nexttrigger, sync_delay);
     548    m_nexttrigger += sync_delay;
    500549
    501550    m_delay = CalcDelay();
    502551
    void RTCVideoSync::WaitForFrame(int sync_delay) 
    509558        if ((val < 0) && (m_delay > 0))
    510559            usleep(m_delay);
    511560    }
     561    return 0;
    512562}
    513563#endif /* __linux__ */
    514564
    bool VDPAUVideoSync::TryInit(void) 
    532582    return true;
    533583}
    534584
    535 void VDPAUVideoSync::WaitForFrame(int sync_delay)
     585int VDPAUVideoSync::WaitForFrame(int sync_delay)
    536586{
    537587    // Offset for externally-provided A/V sync delay
    538     OffsetTimeval(m_nexttrigger, sync_delay);
     588    m_nexttrigger += sync_delay;
    539589    m_delay = CalcDelay();
    540590
    541591    if (m_delay < 0)
    void VDPAUVideoSync::WaitForFrame(int sync_delay) 
    543593
    544594    VideoOutputVDPAU *vo = (VideoOutputVDPAU *)(m_video_output);
    545595    vo->SetNextFrameDisplayTimeOffset(m_delay);
     596    return 0;
    546597}
    547598#endif
    548599
    bool BusyWaitVideoSync::TryInit(void) 
    563614    return true;
    564615}
    565616
    566 void BusyWaitVideoSync::WaitForFrame(int sync_delay)
     617int BusyWaitVideoSync::WaitForFrame(int sync_delay)
    567618{
    568619    // Offset for externally-provided A/V sync delay
    569     OffsetTimeval(m_nexttrigger, sync_delay);
     620    m_nexttrigger += sync_delay;
    570621
    571622    m_delay = CalcDelay();
    572623
    void BusyWaitVideoSync::WaitForFrame(int sync_delay) 
    592643        if (cnt > 1)
    593644            m_cheat -= 200;
    594645    }
     646    return 0;
    595647}
    596648
    597649USleepVideoSync::USleepVideoSync(VideoOutput *vo,
    bool USleepVideoSync::TryInit(void) 
    609661    return true;
    610662}
    611663
    612 void USleepVideoSync::WaitForFrame(int sync_delay)
     664int USleepVideoSync::WaitForFrame(int sync_delay)
    613665{
    614666    // Offset for externally-provided A/V sync delay
    615     OffsetTimeval(m_nexttrigger, sync_delay);
     667    m_nexttrigger += sync_delay;
    616668
    617669    m_delay = CalcDelay();
    618670    if (m_delay > 0)
    619671        usleep(m_delay);
     672    return 0;
    620673}
    621674
  • mythtv/libs/libmythtv/vsync.h

    diff --git a/mythtv/libs/libmythtv/vsync.h b/mythtv/libs/libmythtv/vsync.h
    index 156cdad..6c185dc 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 VideoSync 
    9293                                 uint frame_interval, uint refresh_interval,
    9394                                 bool interlaced);
    9495  protected:
    95     static void OffsetTimeval(struct timeval& tv, int offset);
    9696    int CalcDelay(void);
    9797    void KeepPhase(void);
    9898
    class VideoSync 
    100100    int m_frame_interval; // of video
    101101    int m_refresh_interval; // of display
    102102    bool m_interlaced;
    103     struct timeval m_nexttrigger;
     103    int64_t m_nexttrigger;
    104104    int m_delay;
     105    bool m_synchronous;
    105106   
    106107    static int m_forceskip;
    107108};
    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 */