Commit 493ae7c8 authored by Martin Finkel's avatar Martin Finkel

Refactor AudioOutputDevice and create Helpers folder

parent 3d5e98ed
......@@ -76,8 +76,8 @@ namespace LibVLCSharp.Tests
foreach (var audioOutputDevice in audioOutputDevices)
{
//Debug.WriteLine(audioOutputDevice.Description);
Debug.WriteLine(audioOutputDevice.Device);
Debug.WriteLine(audioOutputDevice.Description);
Debug.WriteLine(audioOutputDevice.DeviceIdentifier);
}
}
......
using System;
using LibVLCSharp.Shared.Helpers;
using System;
using System.Runtime.InteropServices;
namespace LibVLCSharp.Shared
......
using System;
using LibVLCSharp.Shared.Helpers;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
......
using System;
using LibVLCSharp.Shared.Helpers;
namespace LibVLCSharp.Shared
{
......
using System;
using LibVLCSharp.Shared.Helpers;
namespace LibVLCSharp.Shared
{
......
using System;
using LibVLCSharp.Shared.Helpers;
namespace LibVLCSharp.Shared
{
......
using System;
using LibVLCSharp.Shared.Helpers;
using System;
namespace LibVLCSharp.Shared
{
......
using System;
using LibVLCSharp.Shared.Helpers;
namespace LibVLCSharp.Shared
{
......
using LibVLCSharp.Shared.Structures;
namespace LibVLCSharp.Shared.Helpers
{
internal static class MarshalExtensions
{
/// <summary>
/// Helper method that creates a managed type from the internal interop structure.
/// </summary>
/// <param name="s">AudioOutputDescriptionStructure from interop</param>
/// <returns>public AudioOutputDescription to be consumed by the user</returns>
internal static AudioOutputDescription Build(this AudioOutputDescriptionStructure s) => new AudioOutputDescription
{
Name = Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(s.Name) as string,
Description = Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(s.Description) as string,
};
/// <summary>
/// Helper method that creates a managed type from the internal interop structure.
/// </summary>
/// <param name="s">AudioOutputDeviceStructure from interop</param>
/// <returns>public AudioOutputDevice to be consumed by the user</returns>
internal static AudioOutputDevice Build(this AudioOutputDeviceStructure s) => new AudioOutputDevice
{
DeviceIdentifier = Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(s.DeviceIdentifier) as string,
Description = Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(s.Description) as string,
};
}
}
\ No newline at end of file
......@@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace LibVLCSharp.Shared
namespace LibVLCSharp.Shared.Helpers
{
public static class MarshalUtils
{
......
......@@ -4,7 +4,7 @@ using System.Runtime.InteropServices;
using System.Text;
// taken from https://github.com/nikki-nn4/NimDemo
namespace LibVLCSharp.Shared
namespace LibVLCSharp.Shared.Helpers
{
/// <summary>
/// Marshal unicode string param to utf-8 string,usage:[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8StringMarshaler))]
......
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security;
using System.Threading;
using System.Threading.Tasks;
using LibVLCSharp.Shared.Helpers;
using LibVLCSharp.Shared.Structures;
namespace LibVLCSharp.Shared
......@@ -109,7 +109,7 @@ namespace LibVLCSharp.Shared
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_output_device_list_get")]
internal static extern IntPtr LibVLCAudioOutputDeviceListGet(IntPtr libVLC, [MarshalAs(UnmanagedType.LPStr)] string aout);
internal static extern IntPtr LibVLCAudioOutputDeviceListGet(IntPtr libVLC, IntPtr aout);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_output_device_list_release")]
......@@ -455,16 +455,10 @@ namespace LibVLCSharp.Shared
/// <para>libvlc_module_description_t</para>
/// <para>libvlc_module_description_list_release</para>
/// </remarks>
public ModuleDescription[] VideoFilters
{
get
{
return MarshalUtils.Retrieve(() => Native.LibVLCVideoFilterListGet(NativeReference),
public ModuleDescription[] VideoFilters => MarshalUtils.Retrieve(() => Native.LibVLCVideoFilterListGet(NativeReference),
MarshalUtils.PtrToStructure<ModuleDescription.Internal>,
intern => ModuleDescription.__CreateInstance(intern),
module => module.Next, Native.LibVLCModuleDescriptionListRelease);
}
}
/// <summary>Gets the list of available audio output modules.</summary>
/// <returns>list of available audio outputs. It must be freed with</returns>
......@@ -475,15 +469,9 @@ namespace LibVLCSharp.Shared
/// </remarks>
public AudioOutputDescription[] AudioOutputs => MarshalUtils.Retrieve(() => Native.LibVLCAudioOutputListGet(NativeReference),
ptr => MarshalUtils.PtrToStructure<AudioOutputDescriptionStructure>(ptr),
s => CreateAudioOutputDescription(s),
s => s.Build(),
s => s.NextAudioOutputDescription,
Native.LibVLCAudioOutputListRelease);
AudioOutputDescription CreateAudioOutputDescription(AudioOutputDescriptionStructure s) => new AudioOutputDescription
{
Name = Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(s.Name) as string,
Description = Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(s.Description) as string,
};
/// <summary>Gets a list of audio output devices for a given audio output module,</summary>
/// <param name="audioOutputName">
......@@ -505,14 +493,11 @@ namespace LibVLCSharp.Shared
/// <para>explicit audio device.</para>
/// <para>LibVLC 2.1.0 or later.</para>
/// </remarks>
public AudioOutputDevice[] AudioOutputDevices(string audioOutputName)
{
return MarshalUtils.Retrieve(() => Native.LibVLCAudioOutputDeviceListGet(NativeReference, audioOutputName),
MarshalUtils.PtrToStructure<AudioOutputDevice.Internal>,
s => AudioOutputDevice.__CreateInstance(s),
device => device.Next, Native.LibVLCAudioOutputDeviceListRelease);
}
public AudioOutputDevice[] AudioOutputDevices(string audioOutputName) => MarshalUtils.Retrieve(() => Native.LibVLCAudioOutputDeviceListGet(NativeReference, Utf8StringMarshaler.GetInstance().MarshalManagedToNative(audioOutputName)),
MarshalUtils.PtrToStructure<AudioOutputDeviceStructure>,
s => s.Build(),
device => device.Next,
Native.LibVLCAudioOutputDeviceListRelease);
/// <summary>Get media discoverer services by category</summary>
/// <param name="category">category of services to fetch</param>
......
using System;
using LibVLCSharp.Shared.Helpers;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
......
using System;
using LibVLCSharp.Shared.Helpers;
using System;
using System.Runtime.InteropServices;
namespace LibVLCSharp.Shared
......
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using LibVLCSharp.Shared.Helpers;
using LibVLCSharp.Shared.Structures;
namespace LibVLCSharp.Shared
......
using System;
using LibVLCSharp.Shared.Helpers;
using System;
using System.Runtime.InteropServices;
using System.Security;
......
......@@ -3,112 +3,17 @@ using System.Runtime.InteropServices;
namespace LibVLCSharp.Shared.Structures
{
/// <summary>Description for audio output device.</summary>
public unsafe class AudioOutputDevice : IDisposable
[StructLayout(LayoutKind.Sequential)]
internal struct AudioOutputDeviceStructure
{
[StructLayout(LayoutKind.Explicit, Size = 24)]
public partial struct Internal
{
[FieldOffset(0)]
internal IntPtr next;
[FieldOffset(8)]
internal IntPtr device;
[FieldOffset(16)]
internal IntPtr description;
}
public IntPtr NativeReference { get; protected set; }
protected int __PointerAdjustment;
internal static readonly global::System.Collections.Concurrent.ConcurrentDictionary<IntPtr, AudioOutputDevice> NativeToManagedMap = new global::System.Collections.Concurrent.ConcurrentDictionary<IntPtr, AudioOutputDevice>();
protected void*[] __OriginalVTables;
protected bool __ownsNativeInstance;
internal static AudioOutputDevice __CreateInstance(global::System.IntPtr native, bool skipVTables = false)
{
return new AudioOutputDevice(native.ToPointer(), skipVTables);
}
internal static AudioOutputDevice __CreateInstance(AudioOutputDevice.Internal native, bool skipVTables = false)
{
return new AudioOutputDevice(native, skipVTables);
}
private static void* __CopyValue(AudioOutputDevice.Internal native)
{
var ret = Marshal.AllocHGlobal(sizeof(AudioOutputDevice.Internal));
*(AudioOutputDevice.Internal*)ret = native;
return ret.ToPointer();
}
private AudioOutputDevice(AudioOutputDevice.Internal native, bool skipVTables = false)
: this(__CopyValue(native), skipVTables)
{
__ownsNativeInstance = true;
NativeToManagedMap[NativeReference] = this;
}
protected AudioOutputDevice(void* native, bool skipVTables = false)
{
if (native == null)
return;
NativeReference = new global::System.IntPtr(native);
}
public AudioOutputDevice()
{
NativeReference = Marshal.AllocHGlobal(sizeof(AudioOutputDevice.Internal));
__ownsNativeInstance = true;
NativeToManagedMap[NativeReference] = this;
}
public AudioOutputDevice(AudioOutputDevice _0)
{
NativeReference = Marshal.AllocHGlobal(sizeof(AudioOutputDevice.Internal));
__ownsNativeInstance = true;
NativeToManagedMap[NativeReference] = this;
*((AudioOutputDevice.Internal*)NativeReference) = *((AudioOutputDevice.Internal*)_0.NativeReference);
}
public void Dispose()
{
Dispose(disposing: true);
}
public virtual void Dispose(bool disposing)
{
if (NativeReference == IntPtr.Zero)
return;
AudioOutputDevice __dummy;
NativeToManagedMap.TryRemove(NativeReference, out __dummy);
if (__ownsNativeInstance)
Marshal.FreeHGlobal(NativeReference);
NativeReference = IntPtr.Zero;
}
public AudioOutputDevice Next
{
get
{
AudioOutputDevice __result0;
if (((AudioOutputDevice.Internal*)NativeReference)->next == IntPtr.Zero) __result0 = null;
else if (AudioOutputDevice.NativeToManagedMap.ContainsKey(((AudioOutputDevice.Internal*)NativeReference)->next))
__result0 = (AudioOutputDevice)AudioOutputDevice.NativeToManagedMap[((AudioOutputDevice.Internal*)NativeReference)->next];
else __result0 = AudioOutputDevice.__CreateInstance(((AudioOutputDevice.Internal*)NativeReference)->next);
return __result0;
}
set
{
((AudioOutputDevice.Internal*)NativeReference)->next = ReferenceEquals(value, null) ? global::System.IntPtr.Zero : value.NativeReference;
}
}
public string Device => (string)Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(((Internal*)NativeReference)->device);
public IntPtr Next;
public IntPtr DeviceIdentifier;
public IntPtr Description;
}
public string Description => (string)Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(((Internal*)NativeReference)->description);
public class AudioOutputDevice
{
public string DeviceIdentifier;
public string Description;
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment