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

File mythtv_smoothsync.13-24fixes-p0.patch, 12.4 KB (added by jpoet, 13 years ago)

version 13 against 0.24-fixes r27341

  • libs/libmythtv/mythplayer.cpp

    old new MythPlayer::MythPlayer(bool muted) 
    238238      // Audio and video synchronization stuff
    239239      videosync(NULL),              avsync_delay(0),
    240240      avsync_adjustment(0),         avsync_avg(0),
     241      avsync_predictor(0),          avsync_predictor_enabled(false),
    241242      refreshrate(0),
    242243      lastsync(false),              repeat_delay(0),
    243244      // Time Code stuff
    void MythPlayer::SetVideoParams(int widt 
    876877        video_frame_rate = fps;
    877878        float temp_speed = (play_speed == 0.0f) ?
    878879            audio.GetStretchFactor() : play_speed;
    879         frame_interval = (int)(1000000.0f / video_frame_rate / temp_speed);
     880        SetFrameInterval(kScan_Progressive, 1.0 / (video_frame_rate * temp_speed));
    880881    }
    881882
    882883    if (videoOutput)
    int MythPlayer::NextCaptionTrack(int mod 
    16371638    return NextCaptionTrack(nextmode);
    16381639}
    16391640
     1641void MythPlayer::SetFrameInterval(FrameScanType scan, double frame_period)
     1642{
     1643    frame_interval = (int)(1000000.0f * frame_period + 0.5f);
     1644    if (!avsync_predictor_enabled)
     1645        avsync_predictor = 0;
     1646    avsync_predictor_enabled = false;
     1647
     1648    VERBOSE(VB_PLAYBACK, LOC + QString("SetFrameInterval ps:%1 scan:%2")
     1649            .arg(play_speed).arg(scan)
     1650           );
     1651    if (play_speed < 1 || play_speed > 2 || refreshrate <= 0)
     1652        return;
     1653
     1654    avsync_predictor_enabled = ((frame_interval-(frame_interval/200)) < refreshrate);
     1655}
     1656
     1657void MythPlayer::ResetAVSync(void)
     1658{
     1659    avsync_avg = 0;
     1660    if (!avsync_predictor_enabled || avsync_predictor >= refreshrate)
     1661        avsync_predictor = 0;
     1662    prevtc = 0;
     1663    VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + "A/V sync reset");
     1664}
     1665
    16401666void MythPlayer::InitAVSync(void)
    16411667{
    16421668    videosync->Start();
    void MythPlayer::InitAVSync(void) 
    16601686                       .arg(1000000.0 / frame_interval, 0, 'f', 3);
    16611687        VERBOSE(VB_PLAYBACK, LOC + msg);
    16621688
     1689        SetFrameInterval(m_scan, 1.0 / (video_frame_rate * play_speed));
     1690
    16631691        // try to get preferential scheduling, but ignore if we fail to.
    16641692        myth_nice(-19);
    16651693    }
    16661694}
    16671695
     1696int64_t MythPlayer::AVSyncGetAudiotime(void)
     1697{
     1698    int64_t currentaudiotime = 0;
     1699    if (normal_speed)
     1700    {
     1701        currentaudiotime = audio.GetAudioTime();
     1702    }
     1703    return currentaudiotime;
     1704}
     1705
    16681706#define MAXDIVERGE  3.0f
    16691707#define DIVERGELIMIT 30.0f
    16701708void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay)
    16711709{
    16721710    int repeat_pict  = 0;
    1673     int64_t timecode = audio.GetAudioTime();
     1711    int64_t timecode = 0;
    16741712
    16751713    if (buffer)
    16761714    {
    16771715        repeat_pict = buffer->repeat_pict;
    16781716        timecode    = buffer->timecode;
    16791717    }
     1718    else
     1719        timecode = audio.GetAudioTime();
    16801720
    16811721    float diverge = 0.0f;
    16821722    int frameDelay = m_double_framerate ? frame_interval / 2 : frame_interval;
     1723    int vsync_delay_clock = 0;
     1724    int64_t currentaudiotime = 0;
    16831725
    16841726    // attempt to reduce fps for standalone PIP
    16851727    if (player_ctx->IsPIP() && framesPlayed % 2)
    void MythPlayer::AVSync(VideoFrame *buff 
    17091751    if (kScan_Detect == m_scan || kScan_Ignore == m_scan)
    17101752        ps = kScan_Progressive;
    17111753
     1754    bool dropframe = false;
     1755    QString dbg;
     1756
     1757    if (avsync_predictor_enabled) // && !prebuffering)
     1758    {
     1759        avsync_predictor += frame_interval;
     1760        if (avsync_predictor >= refreshrate)
     1761        {
     1762            int refreshperiodsinframe = avsync_predictor/refreshrate;
     1763            avsync_predictor -= refreshrate * refreshperiodsinframe;
     1764        }
     1765        else
     1766        {
     1767            dropframe = true;
     1768            dbg = "A/V predict drop frame, ";
     1769        }
     1770    }
     1771
    17121772    if (diverge < -MAXDIVERGE)
    17131773    {
     1774        dropframe = true;
    17141775        // If video is way behind of audio, adjust for it...
    1715         QString dbg = QString("Video is %1 frames behind audio (too slow), ")
     1776        dbg = QString("Video is %1 frames behind audio (too slow), ")
    17161777            .arg(-diverge);
     1778    }
    17171779
     1780    if (dropframe)
     1781    {
    17181782        // Reset A/V Sync
    17191783        lastsync = true;
    17201784
     1785        currentaudiotime = AVSyncGetAudiotime();
    17211786        if (!using_null_videoout &&
    17221787            videoOutput->hasHWAcceleration() &&
    17231788           !videoOutput->IsSyncLocked())
    void MythPlayer::AVSync(VideoFrame *buff 
    17441809        osdLock.lock();
    17451810        videoOutput->PrepareFrame(buffer, ps, osd);
    17461811        osdLock.unlock();
    1747         VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("AVSync waitforframe %1 %2")
     1812        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP,
     1813                LOC + QString("AVSync waitforframe %1 %2")
    17481814                .arg(avsync_adjustment).arg(m_double_framerate));
    1749         videosync->WaitForFrame(frameDelay + avsync_adjustment + repeat_delay);
    1750         VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, "AVSync show");
     1815        vsync_delay_clock = videosync->WaitForFrame
     1816                            (frameDelay + avsync_adjustment + repeat_delay);
     1817        currentaudiotime = AVSyncGetAudiotime();
     1818        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + "AVSync show");
    17511819        videoOutput->Show(ps);
    17521820
    17531821        if (videoOutput->IsErrored())
    void MythPlayer::AVSync(VideoFrame *buff 
    17751843            videoOutput->PrepareFrame(buffer, ps, osd);
    17761844            osdLock.unlock();
    17771845            // Display the second field
    1778             videosync->WaitForFrame(frameDelay + avsync_adjustment);
     1846            //videosync->AdvanceTrigger();
     1847            vsync_delay_clock = videosync->WaitForFrame(frameDelay + avsync_adjustment);
    17791848            videoOutput->Show(ps);
    17801849        }
    17811850
    17821851        repeat_delay = frame_interval * repeat_pict * 0.5;
    17831852
    17841853        if (repeat_delay)
    1785             VERBOSE(VB_TIMESTAMP, QString("A/V repeat_pict, adding %1 repeat "
     1854            VERBOSE(VB_TIMESTAMP, LOC + QString("A/V repeat_pict, adding %1 repeat "
    17861855                    "delay").arg(repeat_delay));
    17871856    }
    17881857    else
    17891858    {
    1790         videosync->WaitForFrame(frameDelay);
     1859        vsync_delay_clock = videosync->WaitForFrame(frameDelay);
     1860        currentaudiotime = AVSyncGetAudiotime();
    17911861    }
    17921862
    17931863    if (output_jmeter)
    1794         output_jmeter->RecordCycleTime();
     1864    {
     1865        if (output_jmeter->RecordCycleTime())
     1866        {
     1867            VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + QString("A/V avsync_delay: %1, "
     1868                    "avsync_avg: %2")
     1869                    .arg(avsync_delay / 1000).arg(avsync_avg / 1000)
     1870                    );
     1871        }
     1872    }
    17951873
    17961874    avsync_adjustment = 0;
    17971875
    void MythPlayer::AVSync(VideoFrame *buff 
    17991877    {
    18001878        // If audio is way behind of video, adjust for it...
    18011879        // by cutting the frame rate in half for the length of this frame
    1802         avsync_adjustment = refreshrate;
     1880        //avsync_adjustment = refreshrate;
     1881        avsync_adjustment = frame_interval;
    18031882        lastsync = true;
    18041883        VERBOSE(VB_PLAYBACK, LOC +
    18051884                QString("Video is %1 frames ahead of audio,\n"
    void MythPlayer::AVSync(VideoFrame *buff 
    18081887
    18091888    if (audio.HasAudioOut() && normal_speed)
    18101889    {
     1890        // must be sampled here due to Show delays
    18111891        int64_t currentaudiotime = audio.GetAudioTime();
    1812         VERBOSE(VB_TIMESTAMP, QString(
     1892        VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + QString(
    18131893                    "A/V timecodes audio %1 video %2 frameinterval %3 "
    1814                     "avdel %4 avg %5 tcoffset %6")
     1894                    "avdel %4 avg %5 tcoffset %6"
     1895                    " avp %7 avpen %8"
     1896                    " avdc %9"
     1897                    )
    18151898                .arg(currentaudiotime)
    18161899                .arg(timecode)
    18171900                .arg(frame_interval)
    1818                 .arg(timecode - currentaudiotime)
     1901                .arg(timecode - currentaudiotime - (int)(vsync_delay_clock*audio.GetStretchFactor()+500)/1000)
    18191902                .arg(avsync_avg)
    18201903                .arg(tc_wrap[TC_AUDIO])
     1904                .arg(avsync_predictor)
     1905                .arg(avsync_predictor_enabled)
     1906                .arg(vsync_delay_clock)
    18211907                 );
    18221908        if (currentaudiotime != 0 && timecode != 0)
    18231909        { // currentaudiotime == 0 after a seek
    18241910            // The time at the start of this frame (ie, now) is given by
    18251911            // last->timecode
    1826             int delta = (int)((timecode - prevtc)/play_speed) - (frame_interval / 1000);
    1827             prevtc = timecode;
    1828             //cerr << delta << " ";
    1829 
    1830             // If the timecode is off by a frame (dropped frame) wait to sync
    1831             if (delta > (int) frame_interval / 1200 &&
    1832                 delta < (int) frame_interval / 1000 * 3 &&
    1833                 prevrp == 0)
     1912            if (prevtc != 0)
    18341913            {
    1835                 // wait an extra frame interval
    1836                 avsync_adjustment += frame_interval;
     1914                int delta = (int)((timecode - prevtc)/play_speed) - (frame_interval / 1000);
     1915                // If the timecode is off by a frame (dropped frame) wait to sync
     1916                if (delta > (int) frame_interval / 1200 &&
     1917                    delta < (int) frame_interval / 1000 * 3 &&
     1918                    prevrp == 0)
     1919                {
     1920                    // wait an extra frame interval
     1921                    VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + QString("A/V delay %1").arg(delta));
     1922                    avsync_adjustment += frame_interval;
     1923                    //videosync->AdvanceTrigger();
     1924                    //if (m_double_framerate)
     1925                    //    videosync->AdvanceTrigger();
     1926                }
    18371927            }
     1928            prevtc = timecode;
    18381929            prevrp = repeat_pict;
    18391930
    1840             avsync_delay = (timecode - currentaudiotime) * 1000;//usec
     1931            avsync_delay = (timecode - currentaudiotime) * 1000 - (int)(vsync_delay_clock*audio.GetStretchFactor());  //usec
    18411932            // prevents major jitter when pts resets during dvd title
    18421933            if (avsync_delay > 2000000 && limit_delay)
    18431934                avsync_delay = 90000;
    18441935            avsync_avg = (avsync_delay + (avsync_avg * 3)) / 4;
    18451936
     1937            int avsync_used = avsync_avg;
     1938            if (labs(avsync_used) > labs(avsync_delay))
     1939                avsync_used = avsync_delay;
     1940
    18461941            /* If the audio time codes and video diverge, shift
    18471942               the video by one interlaced field (1/2 frame) */
    18481943            if (!lastsync)
    18491944            {
    1850                 if (avsync_avg > frame_interval * 3 / 2)
     1945                if (avsync_used > refreshrate)
    18511946                {
    18521947                    avsync_adjustment += refreshrate;
    1853                     lastsync = true;
     1948                    //lastsync = true;
     1949                    VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + "A/V avg high extend");
    18541950                }
    1855                 else if (avsync_avg < 0 - frame_interval * 3 / 2)
     1951                else if (avsync_used < 0 - refreshrate)
    18561952                {
    18571953                    avsync_adjustment -= refreshrate;
    1858                     lastsync = true;
     1954                    //lastsync = true;
     1955                    VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + "A/V avg high skip");
    18591956                }
    18601957            }
    18611958            else
    void MythPlayer::AVSync(VideoFrame *buff 
    18631960        }
    18641961        else
    18651962        {
    1866             avsync_avg = 0;
     1963            ResetAVSync();
    18671964        }
    18681965    }
     1966    else
     1967    {
     1968        VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + QString("A/V no sync proc ns:%1").arg(normal_speed));
     1969    }
    18691970}
    18701971
    18711972void MythPlayer::RefreshPauseFrame(void)
    void MythPlayer::ClearAfterSeek(bool cle 
    35003601    commBreakMap.SetTracker(framesPlayed);
    35013602    commBreakMap.ResetLastSkip();
    35023603    needNewPauseFrame = true;
     3604    ResetAVSync();
    35033605}
    35043606
    35053607void MythPlayer::SetPlayerInfo(TV *tv, QWidget *widget,
  • libs/libmythtv/mythplayer.h

    old new 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;