Commit 9f3bdca7 authored by Martin Finkel's avatar Martin Finkel

Refactor TrackDescription

parent 0a0b9a65
......@@ -3,13 +3,12 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security;
namespace LibVLCSharp.Shared
{
internal abstract class EventManager
{
internal struct Internal
internal readonly struct Internal
{
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_event_attach")]
internal static extern int LibVLCEventAttach(IntPtr eventManager, EventType eventType, EventCallback eventCallback,
......
......@@ -32,5 +32,13 @@ namespace LibVLCSharp.Shared.Helpers
Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(s.ShortName) as string,
Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(s.LongName) as string,
Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(s.Help) as string);
/// <summary>
/// Helper method that creates a managed type from the internal interop structure.
/// </summary>
/// <param name="s">TrackDescriptionStructure from interop</param>
/// <returns>public TrackDescription to be consumed by the user</returns>
internal static TrackDescription Build(this TrackDescriptionStructure s) =>
new TrackDescription(s.Id, Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(s.Name) as string);
}
}
\ No newline at end of file
......@@ -5,9 +5,9 @@ using System.Text;
namespace LibVLCSharp.Shared.Helpers
{
public static class MarshalUtils
internal static class MarshalUtils
{
internal struct Native
internal readonly struct Native
{
#region Windows
......@@ -43,7 +43,7 @@ namespace LibVLCSharp.Shared.Helpers
const string Write = "w";
}
public static TU[] Retrieve<T, TU>(Func<IntPtr> getRef, Func<IntPtr, T> retrieve,
internal static TU[] Retrieve<T, TU>(Func<IntPtr> getRef, Func<IntPtr, T> retrieve,
Func<T, TU> create, Func<TU, TU> next, Action<IntPtr> releaseRef)
{
var nativeRef = getRef();
......@@ -103,7 +103,7 @@ namespace LibVLCSharp.Shared.Helpers
/// </summary>
/// <param name="args"></param>
/// <returns>Array of pointer you need to release when you're done with Marshal.FreeHGlobal</returns>
public static IntPtr[] ToUtf8(string[] args)
internal static IntPtr[] ToUtf8(string[] args)
{
var utf8Args = new IntPtr[args?.Length ?? 0];
......@@ -125,7 +125,7 @@ namespace LibVLCSharp.Shared.Helpers
/// <typeparam name="T"></typeparam>
/// <param name="ptr"></param>
/// <returns></returns>
public static T PtrToStructure<T>(IntPtr ptr)
internal static T PtrToStructure<T>(IntPtr ptr)
{
#if NETSTANDARD1_1 || NET40
return (T)Marshal.PtrToStructure(ptr, typeof(T));
......@@ -138,7 +138,7 @@ namespace LibVLCSharp.Shared.Helpers
/// Crossplatform dlopen
/// </summary>
/// <returns>true if successful</returns>
public static bool Open(string filename, out IntPtr fileHandle)
internal static bool Open(string filename, out IntPtr fileHandle)
{
fileHandle = IntPtr.Zero;
#if NET40
......@@ -175,7 +175,7 @@ namespace LibVLCSharp.Shared.Helpers
/// </summary>
/// <param name="file handle"></param>
/// <returns>true if successful</returns>
public static bool Close(IntPtr fileHandle)
internal static bool Close(IntPtr fileHandle)
{
#if NET40
switch (Environment.OSVersion.Platform)
......
......@@ -466,7 +466,7 @@ namespace LibVLCSharp.Shared
public AudioOutputDescription[] AudioOutputs => MarshalUtils.Retrieve(() => Native.LibVLCAudioOutputListGet(NativeReference),
ptr => MarshalUtils.PtrToStructure<AudioOutputDescriptionStructure>(ptr),
s => s.Build(),
s => s.NextAudioOutputDescription,
s => s.Next,
Native.LibVLCAudioOutputListRelease);
/// <summary>Gets a list of audio output devices for a given audio output module,</summary>
......
......@@ -1140,40 +1140,14 @@ namespace LibVLCSharp.Shared
/// </summary>
public int AudioTrackCount => Native.LibVLCAudioGetTrackCount(NativeReference);
public TrackDescription[] AudioTrackDescription
{
get
{
var r = Native.LibVLCAudioGetTrackDescription(NativeReference);
return GetTrackDescription(r);
}
}
TrackDescription[] GetTrackDescription(IntPtr trackPtr)
{
if (trackPtr == IntPtr.Zero)
#if NETSTANDARD1_1 || NET40
return new TrackDescription[0];
#else
return Array.Empty<TrackDescription>();
#endif
var trackDescriptions = new List<TrackDescription>();
var track = MarshalUtils.PtrToStructure<TrackDescription>(trackPtr);
while (true)
{
trackDescriptions.Add(track);
if (track.Next != IntPtr.Zero)
{
track = MarshalUtils.PtrToStructure<TrackDescription>(track.Next);
}
else
{
break;
}
}
return trackDescriptions.ToArray();
}
/// <summary>
/// Retrive the audio track description
/// </summary>
public TrackDescription[] AudioTrackDescription => MarshalUtils.Retrieve(() => Native.LibVLCAudioGetTrackDescription(NativeReference),
MarshalUtils.PtrToStructure<TrackDescriptionStructure>,
t => t.Build(),
t => t.Next,
Native.LibVLCTrackDescriptionListRelease);
/// <summary>
/// Get current audio track ID or -1 if no active input.
......@@ -1361,21 +1335,26 @@ namespace LibVLCSharp.Shared
public int Spu => Native.LibVLCVideoGetSpu(NativeReference);
public bool SetSpu(int spu)
{
return Native.LibVLCVideoSetSpu(NativeReference, spu) == 0;
}
/// <summary>
/// Set Spu (subtitle)
/// </summary>
/// <param name="spu">ideo subtitle track to select (id from track description)</param>
/// <returns>true on success, false otherwise</returns>
public bool SetSpu(int spu) => Native.LibVLCVideoSetSpu(NativeReference, spu) == 0;
/// <summary>
/// Get the number of available video subtitles.
/// </summary>
public int SpuCount => Native.LibVLCVideoGetSpuCount(NativeReference);
public TrackDescription[] SpuDescription
{
get
{
var ptr = Native.LibVLCVideoGetSpuDescription(NativeReference);
return GetTrackDescription(ptr);
}
}
/// <summary>
/// Retrieve SpuDescription in a TrackDescription struct
/// </summary>
public TrackDescription[] SpuDescription => MarshalUtils.Retrieve(() => Native.LibVLCVideoGetSpuDescription(NativeReference),
MarshalUtils.PtrToStructure<TrackDescriptionStructure>,
t => t.Build(),
t => t.Next,
Native.LibVLCTrackDescriptionListRelease);
/// <summary>
/// Set new video subtitle file.
......@@ -1384,32 +1363,40 @@ namespace LibVLCSharp.Shared
/// <returns></returns>
public bool SetSubtitleFile(string subtitle) => Native.LibVLCVideoSetSubtitleFile(NativeReference, subtitle) != 0;
/// <summary>
/// Get the current subtitle delay.
/// </summary>
public long SpuDelay => Native.LibVLCVideoGetSpuDelay(NativeReference);
/// <summary>
/// Set the subtitle delay.
/// This affects the timing of when the subtitle will be displayed.
/// Positive values result in subtitles being displayed later, while negative values will result in subtitles being displayed earlier.
/// The subtitle delay will be reset to zero each time the media changes.
/// </summary>
/// <param name="delay">time (in microseconds) the display of subtitles should be delayed</param>
/// <returns>true if successful, false otherwise</returns>
public bool SetSpuDelay(long delay) => Native.LibVLCVideoSetSpuDelay(NativeReference, delay) == 0;
/// <summary>
/// Get the description of available titles.
/// </summary>
public TrackDescription[] TitleDescription
{
get
{
var ptr = Native.LibVLCVideoGetTitleDescription(NativeReference);
return GetTrackDescription(ptr);
}
}
public TrackDescription[] TitleDescription => MarshalUtils.Retrieve(() => Native.LibVLCVideoGetTitleDescription(NativeReference),
MarshalUtils.PtrToStructure<TrackDescriptionStructure>,
t => t.Build(),
t => t.Next,
Native.LibVLCTrackDescriptionListRelease);
/// <summary>
/// Get the description of available chapters for specific title.
/// </summary>
/// <param name="titleIndex">selected title</param>
/// <returns></returns>
public TrackDescription[] ChapterDescription(int titleIndex)
{
var ptr = Native.LibVLCVideoGetChapterDescription(NativeReference, titleIndex);
return GetTrackDescription(ptr);
}
/// <returns>chapter descriptions</returns>
public TrackDescription[] ChapterDescription(int titleIndex) => MarshalUtils.Retrieve(() => Native.LibVLCVideoGetChapterDescription(NativeReference, titleIndex),
MarshalUtils.PtrToStructure<TrackDescriptionStructure>,
t => t.Build(),
t => t.Next,
Native.LibVLCTrackDescriptionListRelease);
/// <summary>
/// Get/Set current crop filter geometry.
......@@ -1439,14 +1426,11 @@ namespace LibVLCSharp.Shared
/// <summary>
/// Get the description of available video tracks.
/// </summary>
public TrackDescription[] VideoTrackDescription
{
get
{
var ptr = Native.LibVLCVideoGetTrackDescription(NativeReference);
return GetTrackDescription(ptr);
}
}
public TrackDescription[] VideoTrackDescription => MarshalUtils.Retrieve(() => Native.LibVLCVideoGetTrackDescription(NativeReference),
MarshalUtils.PtrToStructure<TrackDescriptionStructure>,
t => t.Build(),
t => t.Next,
Native.LibVLCTrackDescriptionListRelease);
/// <summary>
/// Get current video track ID (int) or -1 if no active input.
......
......@@ -6,9 +6,9 @@ namespace LibVLCSharp.Shared.Structures
[StructLayout(LayoutKind.Sequential)]
internal readonly struct AudioOutputDescriptionStructure
{
public readonly IntPtr Name;
public readonly IntPtr Description;
public readonly IntPtr NextAudioOutputDescription;
internal readonly IntPtr Name;
internal readonly IntPtr Description;
internal readonly IntPtr Next;
}
/// <summary>
......
......@@ -6,9 +6,9 @@ namespace LibVLCSharp.Shared.Structures
[StructLayout(LayoutKind.Sequential)]
internal readonly struct AudioOutputDeviceStructure
{
public readonly IntPtr Next;
public readonly IntPtr DeviceIdentifier;
public readonly IntPtr Description;
internal readonly IntPtr Next;
internal readonly IntPtr DeviceIdentifier;
internal readonly IntPtr Description;
}
/// <summary>
......
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace LibVLCSharp.Shared.Structures
{
[StructLayout(LayoutKind.Sequential)]
internal readonly struct TrackDescriptionStructure
{
internal readonly int Id;
internal readonly IntPtr Name;
internal readonly IntPtr Next;
}
/// <summary>
/// <para>Description for video, audio tracks and subtitles. It contains</para>
/// <para>id, name (description string) and pointer to next record.</para>
/// <para>id, name (description string)</para>
/// </summary>
public struct TrackDescription
public readonly struct TrackDescription
{
public int Id { get; set; }
public string Name { get; set; }
public IntPtr Next { get; set; }
/// <summary>
/// Track description Id
/// </summary>
public int Id { get; }
public override bool Equals(object obj)
{
if (!(obj is TrackDescription))
{
return false;
}
var description = (TrackDescription)obj;
return Id == description.Id &&
Name == description.Name &&
EqualityComparer<IntPtr>.Default.Equals(Next, description.Next);
}
/// <summary>
/// Track description
/// </summary>
public string Name { get; }
public override int GetHashCode()
/// <summary>
/// TrackDescription constructor
/// </summary>
/// <param name="id">Track description Id</param>
/// <param name="name">Track description</param>
internal TrackDescription(int id, string name)
{
var hashCode = -485159682;
hashCode = hashCode * -1521134295 + Id.GetHashCode();
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Name);
hashCode = hashCode * -1521134295 + EqualityComparer<IntPtr>.Default.GetHashCode(Next);
return hashCode;
Id = id;
Name = name;
}
}
}
\ 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