diff --git a/src/LibVLCSharp.Tests/LibVLCAPICoverage.cs b/src/LibVLCSharp.Tests/LibVLCAPICoverage.cs index 0822249b8..62cbd4aa4 100644 --- a/src/LibVLCSharp.Tests/LibVLCAPICoverage.cs +++ b/src/LibVLCSharp.Tests/LibVLCAPICoverage.cs @@ -93,7 +93,8 @@ public async Task CheckLibVLCCoverage() List notImplementedOnPurpose = new List { "libvlc_printerr", "libvlc_vprinterr", "libvlc_clock", "libvlc_dialog_get_context", "libvlc_dialog_set_context", - "libvlc_event_type_name", "libvlc_log_get_object", "libvlc_vlm", "libvlc_media_list_player", "libvlc_media_library" + "libvlc_event_type_name", "libvlc_log_get_object", "libvlc_vlm", "libvlc_media_list_player", "libvlc_media_library", + "libvlc_media_player_get_media" }; List exclude = new List(); @@ -141,4 +142,4 @@ public async Task CheckLibVLCCoverage() Assert.Zero(missingApisCount); } } -} \ No newline at end of file +} diff --git a/src/LibVLCSharp.Tests/MediaPlayerTests.cs b/src/LibVLCSharp.Tests/MediaPlayerTests.cs index 8e3caf224..132738fb5 100644 --- a/src/LibVLCSharp.Tests/MediaPlayerTests.cs +++ b/src/LibVLCSharp.Tests/MediaPlayerTests.cs @@ -208,5 +208,18 @@ public void SetMediaPlayerRole() Assert.True(mp.SetRole(MediaPlayerRole.None)); Assert.AreEqual(MediaPlayerRole.None, mp.Role); } + + [Test] + public void MediaRefCountTestFail() + { + var media1 = new Media(_libVLC, new Uri(RealStreamMediaPath)); + var media2 = new Media(_libVLC, new Uri(RealStreamMediaPath)); + + var mp = new MediaPlayer(media1); + media1.Dispose(); + Debug.WriteLine(mp.Media.Mrl); + + mp.Media = media2; + } } } diff --git a/src/LibVLCSharp/Shared/MediaPlayer.cs b/src/LibVLCSharp/Shared/MediaPlayer.cs index 0bbbb4b53..cde650de6 100644 --- a/src/LibVLCSharp/Shared/MediaPlayer.cs +++ b/src/LibVLCSharp/Shared/MediaPlayer.cs @@ -34,11 +34,6 @@ readonly struct Native internal static extern void LibVLCMediaPlayerSetMedia(IntPtr mediaPlayer, IntPtr media); - [DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl, - EntryPoint = "libvlc_media_player_get_media")] - internal static extern IntPtr LibVLCMediaPlayerGetMedia(IntPtr mediaPlayer); - - [DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_media_player_event_manager")] internal static extern IntPtr LibVLCMediaPlayerEventManager(IntPtr mediaPlayer); @@ -623,8 +618,11 @@ public MediaPlayer(Media media) : base(() => Native.LibVLCMediaPlayerNewFromMedia(media.NativeReference), Native.LibVLCMediaPlayerRelease) { _gcHandle = GCHandle.Alloc(this); + _media = media; } + Media? _media; + /// /// Get the media used by the media_player. /// Set the media that will be used by the media_player. @@ -633,12 +631,24 @@ public MediaPlayer(Media media) /// public Media? Media { - get + get => _media; + set { - var mediaPtr = Native.LibVLCMediaPlayerGetMedia(NativeReference); - return mediaPtr == IntPtr.Zero ? null : new Media(mediaPtr); + if(_media != null) + { + _media.Dispose(); + _media = null; + } + + _media = value; + + if(_media != null) + { + _media.Retain(); + } + + Native.LibVLCMediaPlayerSetMedia(NativeReference, _media?.NativeReference ?? IntPtr.Zero); } - set => Native.LibVLCMediaPlayerSetMedia(NativeReference, value?.NativeReference ?? IntPtr.Zero); } /// @@ -653,11 +663,9 @@ public Media? Media /// true if successful public bool Play() { - var media = Media; - if(media != null) + if(_media != null) { - media.AddOption(Configuration); - media.Dispose(); + _media.AddOption(Configuration); } return Native.LibVLCMediaPlayerPlay(NativeReference) == 0; } @@ -2408,6 +2416,12 @@ protected override void Dispose(bool disposing) { if (_gcHandle.IsAllocated) _gcHandle.Free(); + + if (_media != null) + { + _media?.Dispose(); + _media = null; + } } base.Dispose(disposing);