From 501159aa88942460057356243a6bd9c920300b15 Mon Sep 17 00:00:00 2001 From: SuRGeoNix Date: Tue, 23 Jul 2024 02:26:16 +0300 Subject: [PATCH] Renderer: Fixes an issue (from last commit with the non-waitable swap chain) which ensures no frame drops during important UI updates (such as refresh layout, slide show, frame stepping etc.) and allows it mainly only during playback Player: Fixes a possible issue with GetBufferedDuration (for MaxLatency) --- .../MediaFramework/MediaRenderer/Renderer.Present.cs | 12 ++++++------ .../MediaRenderer/Renderer.SwapChain.cs | 2 +- FlyleafLib/MediaPlayer/Player.Screamers.cs | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/FlyleafLib/MediaFramework/MediaRenderer/Renderer.Present.cs b/FlyleafLib/MediaFramework/MediaRenderer/Renderer.Present.cs index 2006c6cf..7426ac0a 100644 --- a/FlyleafLib/MediaFramework/MediaRenderer/Renderer.Present.cs +++ b/FlyleafLib/MediaFramework/MediaRenderer/Renderer.Present.cs @@ -19,13 +19,13 @@ public unsafe partial class Renderer long lastPresentRequestAt= 0; object lockPresentTask = new(); - public bool Present(VideoFrame frame) + public bool Present(VideoFrame frame, bool forceWait = true) { if (Monitor.TryEnter(lockDevice, frame.timestamp == 0 ? 100 : 5)) // Allow more time for first frame { try { - PresentInternal(frame); + PresentInternal(frame, forceWait); VideoDecoder.DisposeFrame(LastFrame); LastFrame = frame; @@ -95,7 +95,7 @@ public void Present() isPresenting = false; }); } - internal void PresentInternal(VideoFrame frame) + internal void PresentInternal(VideoFrame frame, bool forceWait = true) { if (SCDisposed) return; @@ -116,7 +116,7 @@ internal void PresentInternal(VideoFrame frame) vpsa[0].InputSurface = vpiv; vc.VideoProcessorBlt(vp, vpov, 0, 1, vpsa); - swapChain.Present(Config.Video.VSync, Config.Video.PresentFlags); + swapChain.Present(Config.Video.VSync, forceWait ? PresentFlags.None : Config.Video.PresentFlags); vpiv.Dispose(); } @@ -144,7 +144,7 @@ internal void PresentInternal(VideoFrame frame) context.OMSetBlendState(curPSCase == PSCase.RGBPacked ? blendStateAlpha : null); } - swapChain.Present(Config.Video.VSync, Config.Video.PresentFlags); + swapChain.Present(Config.Video.VSync, forceWait ? PresentFlags.None : Config.Video.PresentFlags); } child?.PresentInternal(frame); @@ -245,7 +245,7 @@ public void RefreshLayout() else if (Config.Video.ClearScreen) { context.ClearRenderTargetView(backBufferRtv, Config.Video._BackgroundColor); - swapChain.Present(Config.Video.VSync, PresentFlags.DoNotWait); + swapChain.Present(Config.Video.VSync, PresentFlags.None); } } catch (Exception e) diff --git a/FlyleafLib/MediaFramework/MediaRenderer/Renderer.SwapChain.cs b/FlyleafLib/MediaFramework/MediaRenderer/Renderer.SwapChain.cs index b71f9e42..bd40d92d 100644 --- a/FlyleafLib/MediaFramework/MediaRenderer/Renderer.SwapChain.cs +++ b/FlyleafLib/MediaFramework/MediaRenderer/Renderer.SwapChain.cs @@ -190,7 +190,7 @@ public void DisposeSwapChain() try { context.ClearRenderTargetView(backBufferRtv, Config.Video._BackgroundColor); - swapChain.Present(Config.Video.VSync, PresentFlags.DoNotWait); + swapChain.Present(Config.Video.VSync, PresentFlags.None); } catch { } } diff --git a/FlyleafLib/MediaPlayer/Player.Screamers.cs b/FlyleafLib/MediaPlayer/Player.Screamers.cs index 1fe20719..4c6760ce 100644 --- a/FlyleafLib/MediaPlayer/Player.Screamers.cs +++ b/FlyleafLib/MediaPlayer/Player.Screamers.cs @@ -538,7 +538,7 @@ private void Screamer() { if (CanTrace) Log.Trace($"[V] Presenting {TicksToTime(vFrame.timestamp)}"); - if (decoder.VideoDecoder.Renderer.Present(vFrame)) + if (decoder.VideoDecoder.Renderer.Present(vFrame, false)) Video.framesDisplayed++; else Video.framesDropped++; @@ -705,7 +705,7 @@ private void ChangeSpeedWithoutBuffering(double newSpeed) private long GetBufferedDuration() { var decoder = VideoDecoder.Frames.IsEmpty ? 0 : VideoDecoder.Frames.ToArray()[^1].timestamp - vFrame.timestamp; - var demuxer = VideoDemuxer.VideoPackets.LastTimestamp == ffmpeg.AV_NOPTS_VALUE + var demuxer = VideoDemuxer.VideoPackets.IsEmpty || VideoDemuxer.VideoPackets.LastTimestamp == ffmpeg.AV_NOPTS_VALUE ? 0 : (VideoDemuxer.VideoPackets.LastTimestamp - VideoDemuxer.StartTime) - vFrame.timestamp; @@ -920,7 +920,7 @@ private void ScreamerReverse() Thread.Sleep(sleepMs); } - decoder.VideoDecoder.Renderer.Present(vFrame); + decoder.VideoDecoder.Renderer.Present(vFrame, false); if (!MainDemuxer.IsHLSLive && seeks.IsEmpty) { curTime = (long) (vFrame.timestamp * Speed);