From 071ed1ff801356a2a3660f4c19057ab912cc57e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gran=C3=A5sen?= Date: Mon, 28 May 2018 11:45:52 +0200 Subject: [PATCH 1/2] Turned VlcOptions into a dependencyproperty so the options can be set in XAML. --- Meta.Vlc.Wpf/ApiManager.cs | 5 +++-- Meta.Vlc.Wpf/VlcPlayer.DependencyProperties.cs | 7 ++++--- Meta.Vlc.Wpf/VlcPlayer.cs | 5 +++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Meta.Vlc.Wpf/ApiManager.cs b/Meta.Vlc.Wpf/ApiManager.cs index 87c1ffa..0c9abbb 100644 --- a/Meta.Vlc.Wpf/ApiManager.cs +++ b/Meta.Vlc.Wpf/ApiManager.cs @@ -3,6 +3,7 @@ // Version: 20160214 using System; +using System.Linq; using System.Collections.Generic; namespace Meta.Vlc.Wpf @@ -45,7 +46,7 @@ public static void ReleaseAll() /// /// The options when initialize LibVlc. /// - public static String[] VlcOption { get; private set; } + public static IList VlcOption { get; private set; } /// /// The list of VLC. @@ -61,7 +62,7 @@ public static Vlc DefaultVlc { if (_defaultVlc == null) { - Vlcs.Add(_defaultVlc = new Vlc(VlcOption)); + Vlcs.Add(_defaultVlc = new Vlc(VlcOption.ToArray())); } return _defaultVlc; diff --git a/Meta.Vlc.Wpf/VlcPlayer.DependencyProperties.cs b/Meta.Vlc.Wpf/VlcPlayer.DependencyProperties.cs index 7711849..95b359d 100644 --- a/Meta.Vlc.Wpf/VlcPlayer.DependencyProperties.cs +++ b/Meta.Vlc.Wpf/VlcPlayer.DependencyProperties.cs @@ -3,6 +3,7 @@ // Version: 20160327 using System; +using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.Windows.Media; @@ -32,14 +33,14 @@ public String LibVlcPath /// /// The options of LibVlc, it is a DependencyProperty. /// - public String[] VlcOption + public IList VlcOption { - get { return (String[]) GetValue(VlcOptionProperty); } + get { return (IList) GetValue(VlcOptionProperty); } set { SetValue(VlcOptionProperty, value); } } public static readonly DependencyProperty VlcOptionProperty = - DependencyProperty.Register("VlcOption", typeof (String[]), typeof (VlcPlayer), null); + DependencyProperty.Register("VlcOption", typeof (IList), typeof (VlcPlayer), new PropertyMetadata(new List())); #endregion VlcOption diff --git a/Meta.Vlc.Wpf/VlcPlayer.cs b/Meta.Vlc.Wpf/VlcPlayer.cs index 1510a65..b4e4d04 100644 --- a/Meta.Vlc.Wpf/VlcPlayer.cs +++ b/Meta.Vlc.Wpf/VlcPlayer.cs @@ -6,6 +6,7 @@ using System.ComponentModel; using System.Diagnostics; using System.IO; +using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.InteropServices; @@ -178,7 +179,7 @@ protected override void OnInitialized(EventArgs e) } else { - Initialize(libVlcPath, libVlcOption); + Initialize(libVlcPath, libVlcOption.ToArray()); } } else @@ -204,7 +205,7 @@ protected override void OnInitialized(EventArgs e) libVlcOption = vlcSettingsAttribute.VlcOption; } - Initialize(libVlcPath, libVlcOption); + Initialize(libVlcPath, libVlcOption.ToArray()); } } From e28590c307dd73ed4f5150214da2f20778065b81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Gran=C3=A5sen?= Date: Mon, 28 May 2018 12:09:17 +0200 Subject: [PATCH 2/2] This fixes a race condition when creating multiple VLC controls. Previously two different controls could get different versions of the CommonDispatcher if one tried to access it while the other was in the while loop, which would eventually lead to one of the controls getting the wrong Dispatcher and thereby crash when accessing ImageSource later. --- Meta.Vlc.Wpf/ThreadSeparatedImage.cs | 37 +++++++++++++++------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/Meta.Vlc.Wpf/ThreadSeparatedImage.cs b/Meta.Vlc.Wpf/ThreadSeparatedImage.cs index 52f42f8..4a31426 100644 --- a/Meta.Vlc.Wpf/ThreadSeparatedImage.cs +++ b/Meta.Vlc.Wpf/ThreadSeparatedImage.cs @@ -15,31 +15,34 @@ namespace Meta.Vlc.Wpf public sealed class ThreadSeparatedImage : ThreadSeparatedControlHost { private static Dispatcher _commonDispatcher; + private static object _staticLock = new object(); public static Dispatcher CommonDispatcher { get { - if (_commonDispatcher == null) + lock (_staticLock) { - Thread separateThread = new Thread(() => + if (_commonDispatcher == null) { - Dispatcher.Run(); - }) - { - IsBackground = true - }; - separateThread.SetApartmentState(ApartmentState.STA); - separateThread.Priority = ThreadPriority.Highest; - - separateThread.Start(); - - while (Dispatcher.FromThread(separateThread) == null) - { - Thread.Sleep(50); + Thread separateThread = new Thread(() => + { + Dispatcher.Run(); + }) + { + IsBackground = true + }; + separateThread.SetApartmentState(ApartmentState.STA); + separateThread.Priority = ThreadPriority.Highest; + + separateThread.Start(); + + while (Dispatcher.FromThread(separateThread) == null) + { + Thread.Sleep(50); + } + _commonDispatcher = Dispatcher.FromThread(separateThread); } - _commonDispatcher = Dispatcher.FromThread(separateThread); } - return _commonDispatcher; } }