Skip to content

Commit

Permalink
Media: Internally keep a reference to the last set Media
Browse files Browse the repository at this point in the history
libvlc_media_player_get_media increments the ref count of the media, which may easily
cause a memory leak, as this is very unusual behavior for C# property getter to
have these types of consequences. Users don't have the reflex to dispose every Media returned
by the getter property.

Holding a ref internally in the mediaplayer prevents from incrementing the native ref count
of the media object.

https://code.videolan.org/videolan/LibVLCSharp/-/issues/442
  • Loading branch information
mfkl committed Apr 26, 2021
1 parent f264b8e commit 474d733
Showing 1 changed file with 20 additions and 8 deletions.
28 changes: 20 additions & 8 deletions src/LibVLCSharp/Shared/MediaPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -623,8 +618,11 @@ public MediaPlayer(Media media)
: base(() => Native.LibVLCMediaPlayerNewFromMedia(media.NativeReference), Native.LibVLCMediaPlayerRelease)
{
_gcHandle = GCHandle.Alloc(this);
_media = media;
}

Media? _media;

/// <summary>
/// Get the media used by the media_player.
/// Set the media that will be used by the media_player.
Expand All @@ -635,10 +633,19 @@ public Media? Media
{
get
{
var mediaPtr = Native.LibVLCMediaPlayerGetMedia(NativeReference);
return mediaPtr == IntPtr.Zero ? null : new Media(mediaPtr);
return _media;
}
set
{
if(_media?.NativeReference != IntPtr.Zero)
{
_media?.Dispose();
_media = null;
}

_media = value;
Native.LibVLCMediaPlayerSetMedia(NativeReference, value?.NativeReference ?? IntPtr.Zero);
}
set => Native.LibVLCMediaPlayerSetMedia(NativeReference, value?.NativeReference ?? IntPtr.Zero);
}

/// <summary>
Expand Down Expand Up @@ -2406,6 +2413,11 @@ protected override void Dispose(bool disposing)
{
if (_gcHandle.IsAllocated)
_gcHandle.Free();
if (_media?.NativeReference != IntPtr.Zero)
{
_media?.Dispose();
_media = null;
}
}

base.Dispose(disposing);
Expand Down

0 comments on commit 474d733

Please sign in to comment.