Ticket #13536: avsync_rev2_with_filter.diff
| File avsync_rev2_with_filter.diff, 25.4 KB (added by , 7 years ago) |
|---|
-
mythtv/libs/libmythtv/DVD/mythdvdplayer.cpp
diff --git a/mythtv/libs/libmythtv/DVD/mythdvdplayer.cpp b/mythtv/libs/libmythtv/DVD/mythdvdplayer.cpp index 765371ffbe..71514ba6a4 100644
a b void MythDVDPlayer::DisplayLastFrame(void) 237 237 SetScanType(kScan_Progressive); 238 238 DisplayDVDButton(); 239 239 240 AVSync(nullptr , true);240 AVSync(nullptr); 241 241 } 242 242 243 243 bool MythDVDPlayer::FastForward(float Seconds) … … void MythDVDPlayer::ChangeSpeed(void) 457 457 } 458 458 } 459 459 460 void MythDVDPlayer::AVSync(VideoFrame *Frame, bool /*LimitDelay*/)461 {462 MythPlayer::AVSync(Frame, true);463 }464 465 460 long long MythDVDPlayer::CalcMaxFFTime(long long FastFwd, bool Setjump) const 466 461 { 467 462 if ((totalFrames > 0) && player_ctx->m_buffer->IsDVD() && … … void MythDVDPlayer::StillFrameCheck(void) 758 753 player_ctx->m_buffer->DVD()->SkipStillFrame(); 759 754 m_stillFrameLength = 0; 760 755 } 761 else {762 LOG(VB_GENERAL, LOG_INFO, LOC + QString("elapsed %1").arg(elapsedTime));763 }764 756 } 765 757 } 766 758 -
mythtv/libs/libmythtv/DVD/mythdvdplayer.h
diff --git a/mythtv/libs/libmythtv/DVD/mythdvdplayer.h b/mythtv/libs/libmythtv/DVD/mythdvdplayer.h index 90cf3e0f87..d6d8f8c3ae 100644
a b class MythDVDPlayer : public MythPlayer 44 44 bool DecoderGetFrameFFREW(void) override; 45 45 bool DecoderGetFrameREW(void) override; 46 46 void ChangeSpeed(void) override; 47 void AVSync(VideoFrame *Frame, bool LimitDelay = false) override;48 47 void DisplayPauseFrame(void) override; 49 48 void PreProcessNormalFrame(void) override; 50 49 void VideoStart(void) override; -
mythtv/libs/libmythtv/mythplayer.cpp
diff --git a/mythtv/libs/libmythtv/mythplayer.cpp b/mythtv/libs/libmythtv/mythplayer.cpp index f7e039c0cd..c4bc9187e1 100644
a b MythPlayer::MythPlayer(PlayerFlags flags) 156 156 // Debugging variables 157 157 output_jmeter(new Jitterometer(LOC)) 158 158 { 159 max_diverge = float(gCoreContext->GetFloatSetting160 ("PlayerMaxDiverge", 3.0));161 if (max_diverge < 1.0F)162 max_diverge = 1.0F;163 164 159 playerThread = QThread::currentThread(); 165 160 #ifdef Q_OS_ANDROID 166 161 playerThreadId = gettid(); … … MythPlayer::MythPlayer(PlayerFlags flags) 170 165 171 166 vbimode = VBIMode::Parse(gCoreContext->GetSetting("VbiFormat")); 172 167 captionsEnabledbyDefault = gCoreContext->GetBoolSetting("DefaultCCMode"); 173 decode_extra_audio = gCoreContext->GetBoolSetting("DecodeExtraAudio", false);174 168 itvEnabled = gCoreContext->GetBoolSetting("EnableMHEG", false); 175 169 clearSavedPosition = gCoreContext->GetNumSetting("ClearSavedPosition", 1); 176 170 endExitPrompt = gCoreContext->GetNumSetting("EndOfRecordingExitPrompt"); … … MythPlayer::MythPlayer(PlayerFlags flags) 182 176 uint tmp = mypage.toInt(&valid, 16); 183 177 ttPageNum = (valid) ? tmp : ttPageNum; 184 178 cc608.SetTTPageNum(ttPageNum); 185 avsync2adjustms = (int64_t)gCoreContext->GetNumSetting("AVSync2AdjustMS", 10);186 if (avsync2adjustms < 1)187 avsync2adjustms = 1;188 if (avsync2adjustms > 40)189 avsync2adjustms = 40;190 179 m_avTimer.start(); 191 180 } 192 181 … … bool MythPlayer::Play(float speed, bool normal, bool unpauseaudio) 325 314 rtcbase = 0; 326 315 prior_audiotimecode = 0; 327 316 prior_videotimecode = 0; 317 last_fix = 0.0; 328 318 SetEof(kEofStateNone); 329 319 UnpauseBuffer(); 330 320 UnpauseDecoder(); … … void MythPlayer::SetFrameInterval(FrameScanType scan, double frame_period) 1531 1521 if (decoder) 1532 1522 m_fpsMultiplier = decoder->GetfpsMultiplier(); 1533 1523 frame_interval = static_cast<int>(lround(1000000.0 * frame_period) / m_fpsMultiplier); 1534 if (!avsync_predictor_enabled)1535 avsync_predictor = 0;1536 avsync_predictor_enabled = false;1537 1524 1538 1525 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("SetFrameInterval Interval:%1 Speed:%2 Scan:%3 (Multiplier: %4)") 1539 1526 .arg(frame_interval).arg(static_cast<double>(play_speed)).arg(toQString(scan)).arg(m_fpsMultiplier)); 1540 1527 if (play_speed < 1 || play_speed > 2 || refreshrate <= 0) 1541 1528 return; 1542 1543 avsync_predictor_enabled = ((frame_interval - (frame_interval / 200)) < refreshrate);1544 1529 } 1545 1530 1546 1531 void MythPlayer::ResetAVSync(void) 1547 1532 { 1548 1533 avsync_avg = 0; 1549 if (!avsync_predictor_enabled || avsync_predictor >= refreshrate)1550 avsync_predictor = 0;1551 1534 prevtc = 0; 1552 avsync_next = avsync_interval; // Frames till next sync check1553 1535 rtcbase = 0; 1554 1536 prior_audiotimecode = 0; 1555 1537 prior_videotimecode = 0; 1538 last_fix = 0.0; 1556 1539 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, LOC + "A/V sync reset"); 1557 1540 } 1558 1541 … … void MythPlayer::InitAVSync(void) 1560 1543 { 1561 1544 videosync->Start(); 1562 1545 1563 avsync_adjustment = 0;1564 1565 repeat_delay = 0;1566 1567 1546 refreshrate = m_display->GetDisplayInfo(frame_interval).Rate(); 1568 1547 1569 // Number of frames over which to average time divergence1570 avsync_averaging=4;1571 1548 rtcbase = 0; 1572 1549 prior_audiotimecode = 0; 1573 1550 prior_videotimecode = 0; 1574 1575 // Allow override of averaging value 1576 avsync_averaging = gCoreContext->GetNumSetting("AVSyncAveraging", avsync_averaging); // Number of frames to average 1577 if (avsync_averaging < 4) 1578 avsync_averaging = 4; 1579 avsync_interval = avsync_averaging / max_diverge - 1; // Number of frames skip between sync checks 1580 if (avsync_interval < 0) 1581 avsync_interval = 0; 1582 avsync_next = avsync_interval; // Frames till next sync check 1551 last_fix = 0.0; 1583 1552 1584 1553 if (!FlagIsSet(kVideoIsNull)) 1585 1554 { … … void MythPlayer::InitAVSync(void) 1600 1569 } 1601 1570 } 1602 1571 1603 int64_t MythPlayer::AVSyncGetAudiotime(void)1604 {1605 int64_t currentaudiotime = 0;1606 if (normal_speed)1607 {1608 currentaudiotime = audio.GetAudioTime();1609 }1610 return currentaudiotime;1611 }1612 1613 void MythPlayer::AVSync(VideoFrame *buffer, bool limit_delay)1614 {1615 if (gCoreContext->GetBoolSetting("PlaybackAVSync2", false))1616 {1617 AVSync2(buffer);1618 return;1619 }1620 1621 int repeat_pict = 0;1622 int64_t timecode = audio.GetAudioTime();1623 1624 if (buffer)1625 {1626 repeat_pict = buffer->repeat_pict;1627 timecode = buffer->timecode;1628 disp_timecode = buffer->disp_timecode;1629 }1630 1631 bool decoderdeint = buffer && buffer->decoder_deinterlaced;1632 FrameScanType ps = m_scan;1633 if (kScan_Detect == m_scan || kScan_Ignore == m_scan || decoderdeint)1634 {1635 ps = kScan_Progressive;1636 }1637 else if (buffer && is_interlaced(ps))1638 {1639 ps = kScan_Interlaced;1640 buffer->interlaced_reversed = m_scan == kScan_Intr2ndField;1641 }1642 1643 // only display the second field if needed1644 m_double_framerate = is_interlaced(ps) && m_lastDeinterlacer2x;1645 1646 float diverge = 0.0F;1647 int frameDelay = m_double_framerate ? frame_interval / 2 : frame_interval;1648 int vsync_delay_clock = 0;1649 //int64_t currentaudiotime = 0;1650 1651 if (videoOutput->IsErrored())1652 {1653 LOG(VB_GENERAL, LOG_ERR, LOC +1654 "AVSync: Unknown error in videoOutput, aborting playback.");1655 SetErrored(tr("Failed to initialize A/V Sync"));1656 return;1657 }1658 1659 if (normal_speed && avsync_next==0)1660 {1661 diverge = (float)avsync_avg / (float)frame_interval;1662 }1663 1664 if (avsync_next > 0)1665 {1666 avsync_next--;1667 }1668 else1669 {1670 int divisor = int(abs(diverge) - max_diverge - 1.0F);1671 if (divisor < 1)1672 divisor=1;1673 avsync_next = avsync_interval/divisor;1674 }1675 1676 bool max_video_behind = diverge < -max_diverge;1677 bool dropframe = false;1678 QString dbg;1679 1680 if (avsync_predictor_enabled)1681 {1682 avsync_predictor += frame_interval + avsync_adjustment + repeat_delay;1683 if (avsync_predictor >= refreshrate)1684 {1685 int refreshperiodsinframe = avsync_predictor/refreshrate;1686 avsync_predictor -= refreshrate * refreshperiodsinframe;1687 }1688 else1689 {1690 dropframe = !FlagIsSet(kMusicChoice);1691 dbg = QString("A/V predict drop frame, refreshrate %1, avsync_predictor %2, diverge %3, ")1692 .arg(refreshrate).arg(avsync_predictor).arg(diverge);1693 }1694 }1695 1696 if (max_video_behind)1697 {1698 dropframe = !FlagIsSet(kMusicChoice);1699 // If video is way behind of audio, adjust for it...1700 dbg = QString("Video is %1 frames behind audio (too slow), ")1701 .arg(-diverge);1702 }1703 1704 if (!dropframe && avsync_audiopaused)1705 {1706 avsync_audiopaused = false;1707 audio.Pause(false);1708 }1709 1710 if (!dropframe)1711 {1712 // PGB this was orignally in the calling methods1713 // MythPlayer::DisplayNormalFrame and MythDVDPlayer::DisplayLastFrame1714 // Moved here to reduce CPU usage since the OSD was being merged1715 // into frames that were not being displayed, thereby causing1716 // interruptions and slowdowns.1717 osdLock.lock();1718 videoOutput->ProcessFrame(buffer, osd, pip_players, ps);1719 osdLock.unlock();1720 }1721 1722 if (dropframe)1723 {1724 // Reset A/V Sync1725 lastsync = true;1726 //currentaudiotime = AVSyncGetAudiotime();1727 LOG(VB_PLAYBACK, LOG_INFO, LOC + dbg + "dropping frame to catch up.");1728 if (max_video_behind)1729 {1730 audio.Pause(true);1731 avsync_audiopaused = true;1732 }1733 }1734 else if (!FlagIsSet(kVideoIsNull))1735 {1736 // if we get here, we're actually going to do video output1737 osdLock.lock();1738 videoOutput->PrepareFrame(buffer, ps, osd);1739 osdLock.unlock();1740 // Don't wait for sync if this is a secondary PBP otherwise1741 // the primary PBP will become out of sync1742 if (!player_ctx->IsPBP() || player_ctx->IsPrimaryPBP())1743 {1744 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO,1745 LOC + QString("AVSync waitforframe %1 %2 %3")1746 .arg(frameDelay).arg(avsync_adjustment).arg(m_double_framerate));1747 vsync_delay_clock = videosync->WaitForFrame(frameDelay, avsync_adjustment + repeat_delay);1748 }1749 else1750 {1751 vsync_delay_clock = 0;1752 lastsync = true;1753 }1754 //currentaudiotime = AVSyncGetAudiotime();1755 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, LOC + "AVSync show");1756 videoOutput->Show(ps);1757 1758 if (videoOutput->IsErrored())1759 {1760 LOG(VB_GENERAL, LOG_ERR, LOC + "Error condition detected "1761 "in videoOutput after Show(), aborting playback.");1762 SetErrored(tr("Serious error detected in Video Output"));1763 return;1764 }1765 1766 if (m_double_framerate)1767 {1768 // second stage of deinterlacer processing1769 if (ps == kScan_Interlaced)1770 ps = kScan_Intr2ndField;1771 osdLock.lock();1772 // Only double rate CPU deinterlacers require an extra call to ProcessFrame1773 if (GetDoubleRateOption(buffer, DEINT_CPU) && !GetDoubleRateOption(buffer, DEINT_SHADER))1774 videoOutput->ProcessFrame(buffer, osd, pip_players, ps);1775 videoOutput->PrepareFrame(buffer, ps, osd);1776 osdLock.unlock();1777 // Display the second field1778 if (!player_ctx->IsPBP() || player_ctx->IsPrimaryPBP())1779 {1780 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, LOC + QString("AVSync waitforframe %1 %2 %3")1781 .arg(frameDelay).arg(avsync_adjustment).arg(m_double_framerate));1782 vsync_delay_clock = videosync->WaitForFrame(frameDelay, avsync_adjustment);1783 }1784 videoOutput->Show(ps);1785 }1786 1787 repeat_delay = frame_interval * repeat_pict * 0.5;1788 1789 if (repeat_delay)1790 LOG(VB_TIMESTAMP, LOG_INFO, LOC +1791 QString("A/V repeat_pict, adding %1 repeat delay")1792 .arg(repeat_delay));1793 }1794 else1795 {1796 vsync_delay_clock = videosync->WaitForFrame(frameDelay, 0);1797 //currentaudiotime = AVSyncGetAudiotime();1798 }1799 1800 if (output_jmeter && output_jmeter->RecordCycleTime())1801 {1802 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, LOC +1803 QString("A/V avsync_delay: %1, avsync_avg: %2")1804 .arg(avsync_delay / 1000).arg(avsync_avg / 1000));1805 }1806 1807 avsync_adjustment = 0;1808 1809 if (diverge > max_diverge)1810 {1811 // If audio is way behind of video, adjust for it...1812 // by cutting the frame rate in half for the length of this frame1813 avsync_adjustment = frame_interval;1814 lastsync = true;1815 LOG(VB_PLAYBACK, LOG_INFO, LOC +1816 QString("Video is %1 frames ahead of audio,\n"1817 "\t\t\tdoubling video frame interval to slow down.")1818 .arg(diverge));1819 }1820 1821 if (audio.HasAudioOut() && normal_speed)1822 {1823 // must be sampled here due to Show delays1824 int64_t currentaudiotime = audio.GetAudioTime();1825 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, LOC +1826 QString("A/V timecodes audio %1 video %2 frameinterval %3 "1827 "avdel %4 avg %5 tcoffset %6 avp %7 avpen %8 avdc %9 "1828 "diverge %10")1829 .arg(currentaudiotime)1830 .arg(timecode)1831 .arg(frame_interval)1832 .arg(timecode - currentaudiotime -1833 (int)(vsync_delay_clock*audio.GetStretchFactor()+500)/1000)1834 .arg(avsync_avg)1835 .arg(tc_wrap[TC_AUDIO])1836 .arg(avsync_predictor)1837 .arg(avsync_predictor_enabled)1838 .arg(vsync_delay_clock)1839 .arg(diverge)1840 );1841 if (currentaudiotime != 0 && timecode != 0)1842 { // currentaudiotime == 0 after a seek1843 // The time at the start of this frame (ie, now) is given by1844 // last->timecode1845 if (prevtc != 0)1846 {1847 int delta = (int)((timecode - prevtc)/play_speed) -1848 (frame_interval / 1000);1849 // If timecode is off by a frame (dropped frame) wait to sync1850 if (delta > frame_interval / 1200 &&1851 delta < frame_interval / 1000 * 3 &&1852 prevrp == 0)1853 {1854 // wait an extra frame interval1855 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, LOC +1856 QString("A/V delay %1").arg(delta));1857 avsync_adjustment += frame_interval;1858 // If we're duplicating a frame, it may be because1859 // the container frame rate doesn't match the1860 // stream frame rate. In this case, we increment1861 // the fake frame counter so that avformat1862 // timestamp-based seeking will work.1863 if (!decoder->HasPositionMap())1864 ++framesPlayedExtra;1865 }1866 }1867 prevtc = timecode;1868 prevrp = repeat_pict;1869 1870 // usec1871 avsync_delay = (timecode - currentaudiotime) * 1000 -1872 (int)(vsync_delay_clock*audio.GetStretchFactor());1873 1874 // prevents major jitter when pts resets during dvd title1875 if (avsync_delay > 2000000 && limit_delay)1876 avsync_delay = 90000;1877 avsync_avg = (avsync_delay + (avsync_avg * (avsync_averaging-1))) / avsync_averaging;1878 1879 int avsync_used = avsync_avg;1880 if (labs(avsync_used) > labs(avsync_delay))1881 avsync_used = avsync_delay;1882 1883 /* If the audio time codes and video diverge, shift1884 the video by one interlaced field (1/2 frame) */1885 if (!lastsync)1886 {1887 if (avsync_used > refreshrate)1888 {1889 avsync_adjustment += refreshrate;1890 }1891 else if (avsync_used < 0 - refreshrate)1892 {1893 avsync_adjustment -= refreshrate;1894 }1895 }1896 else1897 lastsync = false;1898 }1899 else1900 {1901 ResetAVSync();1902 }1903 }1904 else1905 {1906 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, LOC +1907 QString("A/V no sync proc ns:%1").arg(normal_speed));1908 }1909 }1910 1911 1572 void MythPlayer::WaitForTime(int64_t framedue) 1912 1573 { 1913 1574 int64_t unow = m_avTimer.nsecsElapsed() / 1000; … … void MythPlayer::WaitForTime(int64_t framedue) 1917 1578 } 1918 1579 1919 1580 #define AVSYNC_MAX_LATE 10000000 1920 void MythPlayer::AVSync 2(VideoFrame *buffer)1581 void MythPlayer::AVSync(VideoFrame *buffer) 1921 1582 { 1922 1583 if (videoOutput->IsErrored()) 1923 1584 { … … void MythPlayer::AVSync2(VideoFrame *buffer) 1936 1597 int64_t lateness = 0; 1937 1598 auto playspeed1000 = static_cast<int64_t>(1000.0F / play_speed); 1938 1599 bool reset = false; 1600 // controller gain 1601 static float const s_av_control_gain = 0.04F; 1602 // time weighted exponential filter coefficient 1603 static float const s_sync_fc = 0.6F; 1939 1604 1940 1605 while (framedue == 0) 1941 1606 { … … void MythPlayer::AVSync2(VideoFrame *buffer) 2010 1675 audio_adjustment = 0; 2011 1676 } 2012 1677 int sign = audio_adjustment < 0 ? -1 : 1; 2013 int64_t fix_amount = audio_adjustment * sign; 2014 if (fix_amount > avsync2adjustms) 2015 fix_amount = avsync2adjustms; 2016 // Faster catch-up when off by more than 200 ms 2017 if (audio_adjustment * sign > 200) 2018 // fix the sync within 15 - 20 frames 2019 fix_amount = audio_adjustment * sign / 15; 1678 float fix_amount = (last_fix * s_sync_fc + (1 - s_sync_fc) * audio_adjustment) * sign * s_av_control_gain; 1679 last_fix = fix_amount * sign; 2020 1680 auto speedup1000 = static_cast<int64_t>(1000 * play_speed); 2021 1681 rtcbase -= static_cast<int64_t>(1000000 * fix_amount * sign / speedup1000); 2022 if (audio_adjustment * sign > 20 || (framesPlayed % 400 == 0))1682 if (audio_adjustment * sign > 20) 2023 1683 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("AV Sync: Audio %1 by %2 ms") 2024 1684 .arg(audio_adjustment > 0 ? "ahead" : "behind").arg(abs(audio_adjustment))); 2025 1685 if (audio_adjustment > 200) … … void MythPlayer::AVSync2(VideoFrame *buffer) 2135 1795 2136 1796 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, LOC + 2137 1797 QString("A/V timecodes audio=%1 video=%2 frameinterval=%3 " 2138 "audioadj=%4 tcoffset=%5 unow=%6 udue=%7 ")1798 "audioadj=%4 tcoffset=%5 unow=%6 udue=%7 ") 2139 1799 .arg(prior_audiotimecode) 2140 1800 .arg(prior_videotimecode) 2141 1801 .arg(frame_interval) … … void MythPlayer::DisplayNormalFrame(bool check_prebuffer) 2371 2031 AutoDeint(frame); 2372 2032 detect_letter_box->SwitchTo(frame); 2373 2033 2374 AVSync(frame , false);2034 AVSync(frame); 2375 2035 2376 2036 // If PiP then keep this frame for MythPlayer::GetCurrentFrame 2377 2037 if (!player_ctx->IsPIP()) … … void MythPlayer::VideoStart(void) 2500 2160 SetPlaying(true); 2501 2161 ClearAfterSeek(false); 2502 2162 2503 avsync_delay = 0; 2504 avsync_avg = 0; 2505 avsync_next = avsync_interval; // Frames till next sync check 2163 avsync_avg = 0; // Frames till next sync check 2506 2164 refreshrate = 0; 2507 lastsync = false;2508 2165 2509 2166 EnableFrameRateMonitor(); 2510 2167 refreshrate = frame_interval; … … void MythPlayer::GetPlaybackData(InfoMap &infoMap) 5046 4703 infoMap.insert("storagerate", player_ctx->m_buffer->GetStorageRate()); 5047 4704 infoMap.insert("bufferavail", player_ctx->m_buffer->GetAvailableBuffer()); 5048 4705 infoMap.insert("buffersize", QString::number(player_ctx->m_buffer->GetBufferSize() >> 20)); 5049 if (gCoreContext->GetBoolSetting("PlaybackAVSync2", false)) 5050 { 5051 int avsync = avsync_avg / 1000; 5052 infoMap.insert("avsync", tr("%1 ms").arg(avsync)); 5053 } 5054 else 5055 infoMap.insert("avsync", QString::number((float)avsync_avg / (float)frame_interval, 'f', 2)); 4706 int avsync = avsync_avg / 1000; 4707 infoMap.insert("avsync", tr("%1 ms").arg(avsync)); 4708 5056 4709 if (videoOutput) 5057 4710 { 5058 4711 QString frames = QString("%1/%2").arg(videoOutput->ValidVideoFrames()) -
mythtv/libs/libmythtv/mythplayer.h
diff --git a/mythtv/libs/libmythtv/mythplayer.h b/mythtv/libs/libmythtv/mythplayer.h index 76260cf118..37d3231b44 100644
a b class MTV_PUBLIC MythPlayer 620 620 // Private A/V Sync Stuff 621 621 void WrapTimecode(int64_t &timecode, TCTypes tc_type); 622 622 void InitAVSync(void); 623 virtual void AVSync(VideoFrame *buffer, bool limit_delay = false); 624 // New video sync method 625 void AVSync2(VideoFrame *buffer); 623 virtual void AVSync(VideoFrame *buffer); 626 624 void ResetAVSync(void); 627 int64_t AVSyncGetAudiotime(void);628 625 void SetFrameInterval(FrameScanType scan, double frame_period); 629 void WaitForTime(int64_t framedue);626 void WaitForTime(int64_t framedue); 630 627 631 628 // Private LiveTV stuff 632 629 void SwitchToProgram(void); … … class MTV_PUBLIC MythPlayer 825 822 826 823 // Audio and video synchronization stuff 827 824 VideoSync *videosync {nullptr}; 828 int avsync_delay {0};829 int avsync_adjustment {0};830 825 int avsync_avg {0}; 831 826 int avsync_predictor {0}; 832 bool avsync_predictor_enabled {false};833 827 int refreshrate {0}; 834 bool lastsync {false};835 bool decode_extra_audio {false};836 int repeat_delay {0};837 828 int64_t disp_timecode {0}; 838 829 bool avsync_audiopaused {false}; 839 float max_diverge {3.0F}; // from setting PlayerMaxDiverge default 2 840 // AVSync for Raspberry Pi digital streams 841 int avsync_averaging {4}; // Number of frames to average 842 int avsync_interval {0}; // Number of frames skip between sync checks 843 int avsync_next {0}; // Frames till next sync check 830 int64_t rtcbase {0}; // real time clock base for presentation time (microsecs) 831 int64_t maxtcval {0}; // maximum to date video tc 832 int maxtcframes {0}; // number of frames seen since max to date tc 833 int numdroppedframes {0}; // number of consecutive dropped frames. 834 int64_t prior_audiotimecode {0}; // time code from prior frame 835 int64_t prior_videotimecode {0}; // time code from prior frame 836 float last_fix {0.0F}; //last sync adjustment to prior frame 837 int64_t m_timeOffsetBase {0}; 844 838 845 839 // Time Code stuff 846 840 int prevtc {0}; ///< 32 bit timecode if last VideoFrame shown … … class MTV_PUBLIC MythPlayer 849 843 int64_t tc_lastval[TCTYPESMAX] {}; 850 844 int64_t savedAudioTimecodeOffset {0}; 851 845 852 // AVSync2853 int64_t rtcbase {0}; // real time clock base for presentation time (microsecs)854 int64_t maxtcval {0}; // maximum to date video tc855 int maxtcframes {0}; // number of frames seen since max to date tc856 int64_t avsync2adjustms {10};// number of milliseconds to adjust for av sync errors857 int numdroppedframes {0}; // number of consecutive dropped frames.858 int64_t prior_audiotimecode {0}; // time code from prior frame859 int64_t prior_videotimecode {0}; // time code from prior frame860 int64_t m_timeOffsetBase {0};861 862 846 // LiveTV 863 847 TV *m_tv {nullptr}; 864 848 bool isDummy {false}; -
mythtv/programs/mythfrontend/globalsettings.cpp
diff --git a/mythtv/programs/mythfrontend/globalsettings.cpp b/mythtv/programs/mythfrontend/globalsettings.cpp index acc800d14e..4c79123891 100644
a b static HostTextEditSetting *VAAPIDevice() 111 111 } 112 112 #endif 113 113 114 static HostCheckBoxSetting *PlaybackAVSync2()115 {116 auto *gc = new HostCheckBoxSetting("PlaybackAVSync2");117 118 gc->setLabel(PlaybackSettings::tr("Enable new timestamp based playback speed (AVSync2)"));119 120 gc->setHelpText(PlaybackSettings::tr("Simplified timing and synchronization method. "121 "This may offer smoother video playback. Note there is a setting that can be used "122 "for fine tuning playback (press right arrow)."));123 gc->setValue(false);124 125 return gc;126 }127 128 static HostSpinBoxSetting *AVSync2AdjustMS()129 // was previously *DecodeExtraAudio()130 {131 auto *gc = new HostSpinBoxSetting("AVSync2AdjustMS",1,40,1,1);132 133 gc->setLabel(PlaybackSettings::tr("AVSync2 audio correction (ms)"));134 135 gc->setValue(10);136 137 gc->setHelpText(PlaybackSettings::tr(138 "When using AVSync2, if video playback is speeding up and slowing down every few seconds, reduce "139 "this value. For quicker recovery of audio sync after jumps, increase this value. "140 "Values can be from 1 to 40. Default is 10."));141 return gc;142 }143 144 114 #if CONFIG_DEBUGTYPE 145 115 static HostCheckBoxSetting *FFmpegDemuxer() 146 116 { … … void PlaybackSettings::Load(void) 4277 4247 #ifdef USING_VAAPI 4278 4248 advanced->addChild(VAAPIDevice()); 4279 4249 #endif 4280 HostCheckBoxSetting *avsync2 = PlaybackAVSync2();4281 advanced->addChild(avsync2);4282 avsync2->addTargetedChild("1",AVSync2AdjustMS());4283 4250 4284 4251 addChild(advanced); 4285 4252
