diff options
author | CrystalP <crystalp@kodi.tv> | 2023-11-19 21:32:00 -0500 |
---|---|---|
committer | CrystalP <crystalp@kodi.tv> | 2023-12-08 22:31:28 -0500 |
commit | d3903fbd009a55329a4b0718486aef36ccf393e3 (patch) | |
tree | 907e1513dc0ad177bdee67b3b4a094cbd9f99551 | |
parent | 5e70594e16bf1ac2738e82d66129c1c7aff68656 (diff) |
[VideoPlayer] Use probed interlaced flags to double initial refresh rate
When starting the playback of an interlaced stream, instead of switching to the probed refresh rate,
go directly to 2x the probed refresh rate as videoplayer would otherwise switch to 2x refresh rate
a few seconds later anyway, resulting in some black frames while the screen adjusts and audio drop out or a pitch change.
Does not work for ts streams because of special opening by demuxer, which loses most of the probed data.
Addressing that is beyond the scope of this change.
-rw-r--r-- | xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h | 1 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 5 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/DVDStreamInfo.cpp | 4 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/DVDStreamInfo.h | 1 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/VideoPlayer.cpp | 6 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp | 5 |
6 files changed, 20 insertions, 2 deletions
diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h index af5ff8e513..a1d229b5b6 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h @@ -129,6 +129,7 @@ public: ~CDemuxStreamVideo() override = default; int iFpsScale = 0; // scale of 1000 and a rate of 29970 will result in 29.97 fps int iFpsRate = 0; + bool interlaced = false; // unknown or progressive => false, otherwise true. int iHeight = 0; // height of the stream reported by the demuxer int iWidth = 0; // width of the stream reported by the demuxer double fAspect = 0; // display aspect of stream diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp index 9499a383fb..1aebc3dcbc 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp @@ -1672,6 +1672,11 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int streamIdx) st->iFpsScale = 0; } + st->interlaced = pStream->codecpar->field_order == AV_FIELD_TT || + pStream->codecpar->field_order == AV_FIELD_BB || + pStream->codecpar->field_order == AV_FIELD_TB || + pStream->codecpar->field_order == AV_FIELD_BT; + st->iWidth = pStream->codecpar->width; st->iHeight = pStream->codecpar->height; st->fAspect = SelectAspect(pStream, st->bForcedAspect); diff --git a/xbmc/cores/VideoPlayer/DVDStreamInfo.cpp b/xbmc/cores/VideoPlayer/DVDStreamInfo.cpp index f387301e56..35af75e305 100644 --- a/xbmc/cores/VideoPlayer/DVDStreamInfo.cpp +++ b/xbmc/cores/VideoPlayer/DVDStreamInfo.cpp @@ -52,6 +52,7 @@ void CDVDStreamInfo::Clear() fpsscale = 0; fpsrate = 0; + interlaced = false; height = 0; width = 0; aspect = 0.0; @@ -100,6 +101,7 @@ bool CDVDStreamInfo::Equal(const CDVDStreamInfo& right, int compare) // clang-format off if (fpsscale != right.fpsscale || fpsrate != right.fpsrate + || interlaced != right.interlaced || height != right.height || width != right.width || stills != right.stills @@ -215,6 +217,7 @@ void CDVDStreamInfo::Assign(const CDVDStreamInfo& right, bool withextradata) // VIDEO fpsscale = right.fpsscale; fpsrate = right.fpsrate; + interlaced = right.interlaced; height = right.height; width = right.width; aspect = right.aspect; @@ -286,6 +289,7 @@ void CDVDStreamInfo::Assign(const CDemuxStream& right, bool withextradata) const CDemuxStreamVideo *stream = static_cast<const CDemuxStreamVideo*>(&right); fpsscale = stream->iFpsScale; fpsrate = stream->iFpsRate; + interlaced = stream->interlaced; height = stream->iHeight; width = stream->iWidth; aspect = stream->fAspect; diff --git a/xbmc/cores/VideoPlayer/DVDStreamInfo.h b/xbmc/cores/VideoPlayer/DVDStreamInfo.h index b3d0eb6bf4..1da58a7e6a 100644 --- a/xbmc/cores/VideoPlayer/DVDStreamInfo.h +++ b/xbmc/cores/VideoPlayer/DVDStreamInfo.h @@ -58,6 +58,7 @@ public: // VIDEO int fpsscale; // scale of 1001 and a rate of 60000 will result in 59.94 fps int fpsrate; + bool interlaced; int height; // height of the stream reported by the demuxer int width; // width of the stream reported by the demuxer double aspect; // display aspect as reported by demuxer diff --git a/xbmc/cores/VideoPlayer/VideoPlayer.cpp b/xbmc/cores/VideoPlayer/VideoPlayer.cpp index 0974c2d985..2acaa7f78d 100644 --- a/xbmc/cores/VideoPlayer/VideoPlayer.cpp +++ b/xbmc/cores/VideoPlayer/VideoPlayer.cpp @@ -3745,7 +3745,11 @@ bool CVideoPlayer::OpenVideoStream(CDVDStreamInfo& hint, bool reset) { if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(CSettings::SETTING_VIDEOPLAYER_ADJUSTREFRESHRATE) != ADJUST_REFRESHRATE_OFF) { - double framerate = DVD_TIME_BASE / CDVDCodecUtils::NormalizeFrameduration((double)DVD_TIME_BASE * hint.fpsscale / hint.fpsrate); + const double framerate = + DVD_TIME_BASE / + CDVDCodecUtils::NormalizeFrameduration( + (double)DVD_TIME_BASE * ((hint.interlaced ? 2 : 1) * hint.fpsscale) / hint.fpsrate); + RESOLUTION res = CResolutionUtils::ChooseBestResolution(static_cast<float>(framerate), hint.width, hint.height, !hint.stereo_mode.empty()); CServiceBroker::GetWinSystem()->GetGfxContext().SetVideoResolution(res, false); m_renderManager.TriggerUpdateResolution(framerate, hint.width, hint.height, hint.stereo_mode); diff --git a/xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp b/xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp index e4f0e993de..52bc38d24c 100644 --- a/xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp +++ b/xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp @@ -172,7 +172,10 @@ void CVideoPlayerVideo::OpenStream(CDVDStreamInfo& hint, std::unique_ptr<CDVDVid //reported fps is usually not completely correct if (hint.fpsrate && hint.fpsscale) { - m_fFrameRate = DVD_TIME_BASE / CDVDCodecUtils::NormalizeFrameduration((double)DVD_TIME_BASE * hint.fpsscale / hint.fpsrate); + m_fFrameRate = DVD_TIME_BASE / CDVDCodecUtils::NormalizeFrameduration( + (double)DVD_TIME_BASE * + ((hint.interlaced ? 2 : 1) * hint.fpsscale) / hint.fpsrate); + m_bFpsInvalid = false; m_processInfo.SetVideoFps(static_cast<float>(m_fFrameRate)); } |