Skip to content

Commit 9adb3dc

Browse files
committed
Fix race condition on FrameGrabberEvent
1 parent 7751c57 commit 9adb3dc

File tree

1 file changed

+48
-29
lines changed

1 file changed

+48
-29
lines changed

CollapseLauncher/Classes/Helper/Background/Loaders/MediaPlayerLoader.cs

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
// ReSharper disable PartialTypeWithSinglePart
3333
// ReSharper disable StringLiteralTypo
3434
// ReSharper disable AsyncVoidMethod
35+
// ReSharper disable BadControlBracesIndent
3536

3637
#nullable enable
3738
namespace CollapseLauncher.Helper.Background.Loaders
@@ -42,7 +43,6 @@ namespace CollapseLauncher.Helper.Background.Loaders
4243
internal sealed partial class MediaPlayerLoader : IBackgroundMediaLoader
4344
{
4445
private readonly Color _currentDefaultColor = Color.FromArgb(0, 0, 0, 0);
45-
private int _isCanvasCurrentlyDrawing;
4646

4747
private FrameworkElement ParentUI { get; }
4848
private Compositor CurrentCompositor { get; }
@@ -65,14 +65,16 @@ private static bool IsUseVideoBgDynamicColorUpdate
6565
private CanvasVirtualImageSource? _currentCanvasVirtualImageSource;
6666
private CanvasBitmap? _currentCanvasBitmap;
6767
private CanvasDevice? _currentCanvasDevice;
68+
private volatile CanvasDrawingSession? _currentCanvasDrawingSession;
6869
private readonly int _currentCanvasWidth;
6970
private readonly int _currentCanvasHeight;
7071
private readonly float _currentCanvasDpi;
7172
private readonly Rect _currentCanvasDrawArea;
7273
private readonly MediaPlayerElement? _currentMediaPlayerFrame;
7374
private readonly Grid _currentMediaPlayerFrameParentGrid;
7475
private readonly ImageUI _currentImage;
75-
private readonly Lock _frameGrabberEventLock = new();
76+
private readonly Lock _currentLock = new();
77+
7678

7779
internal MediaPlayerLoader(
7880
FrameworkElement parentUI,
@@ -261,9 +263,12 @@ public void DisposeMediaModules()
261263

262264
if (IsUseVideoBgDynamicColorUpdate)
263265
{
264-
while (_isCanvasCurrentlyDrawing == 1)
266+
lock (_currentLock)
265267
{
266-
Thread.Sleep(100);
268+
while (_currentCanvasDrawingSession is not null)
269+
{
270+
Thread.Sleep(100);
271+
}
267272
}
268273
}
269274

@@ -327,41 +332,55 @@ await ColorPaletteUtility.ApplyAccentColor(ParentUI,
327332
private static async Task<StorageFile> GetFileAsStorageFile(string filePath)
328333
=> await StorageFile.GetFileFromPathAsync(filePath);
329334

330-
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
335+
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
331336
private async void FrameGrabberEvent(MediaPlayer mediaPlayer, object args)
332-
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
337+
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
333338
{
334-
if (_isCanvasCurrentlyDrawing == 1)
339+
lock (_currentLock)
335340
{
336-
return;
337-
}
338-
339-
lock (_frameGrabberEventLock)
340-
{
341-
_isCanvasCurrentlyDrawing = 1;
342-
CanvasDrawingSession? drawingSession = null;
343-
344-
try
341+
if (_currentCanvasVirtualImageSource is null)
345342
{
346-
mediaPlayer.CopyFrameToVideoSurface(_currentCanvasBitmap);
347-
drawingSession = _currentCanvasVirtualImageSource?.CreateDrawingSession(_currentDefaultColor, _currentCanvasDrawArea);
348-
drawingSession?.DrawImage(_currentCanvasBitmap);
343+
return;
349344
}
350-
catch
351-
#if DEBUG
352-
(Exception e)
345+
346+
if (_currentCanvasDrawingSession is not null)
353347
{
354-
LogWriteLine($"[FrameGrabberEvent] Error while drawing frame to bitmap.\r\n{e}", LogType.Warning, true);
348+
#if DEBUG
349+
LogWriteLine($@"[FrameGrabberEvent] Frame skipped at: {mediaPlayer.Position:hh\:mm\:ss\.ffffff}", LogType.Debug, true);
350+
#endif
351+
return;
355352
}
356-
#else
353+
}
354+
355+
try
356+
{
357+
lock (_currentLock)
357358
{
358-
// ignored
359+
mediaPlayer.CopyFrameToVideoSurface(_currentCanvasBitmap);
360+
_currentCanvasDrawingSession = _currentCanvasVirtualImageSource.CreateDrawingSession(_currentDefaultColor, _currentCanvasDrawArea);
361+
_currentCanvasDrawingSession.DrawImage(_currentCanvasBitmap);
359362
}
360-
#endif
361-
finally
363+
}
364+
catch
365+
#if DEBUG
366+
(Exception e)
367+
{
368+
LogWriteLine($"[FrameGrabberEvent] Error while drawing frame to bitmap.\r\n{e}", LogType.Warning, true);
369+
}
370+
#else
371+
{
372+
// ignored
373+
}
374+
#endif
375+
finally
376+
{
377+
lock (_currentLock)
362378
{
363-
CurrentDispatcherQueue.TryEnqueue(() => drawingSession?.Dispose());
364-
_isCanvasCurrentlyDrawing = 0;
379+
CurrentDispatcherQueue.TryEnqueue(() =>
380+
{
381+
_currentCanvasDrawingSession?.Dispose();
382+
_currentCanvasDrawingSession = null;
383+
});
365384
}
366385
}
367386
}

0 commit comments

Comments
 (0)