diff --git a/src/CoreMedia/CMBufferQueue.cs b/src/CoreMedia/CMBufferQueue.cs index 39115a989149..738ca2a93fd2 100644 --- a/src/CoreMedia/CMBufferQueue.cs +++ b/src/CoreMedia/CMBufferQueue.cs @@ -61,13 +61,25 @@ public class CMBufferQueue : NativeObject struct CMBufferCallbacks { internal uint version; internal IntPtr refcon; +#if NET + internal unsafe delegate* unmanaged XgetDecodeTimeStamp; + internal unsafe delegate* unmanaged XgetPresentationTimeStamp; + internal unsafe delegate* unmanaged XgetDuration; + internal unsafe delegate* unmanaged XisDataReady; + internal unsafe delegate* unmanaged Xcompare; +#else internal BufferGetTimeCallback? XgetDecodeTimeStamp; internal BufferGetTimeCallback? XgetPresentationTimeStamp; internal BufferGetTimeCallback? XgetDuration; internal BufferGetBooleanCallback? XisDataReady; internal BufferCompareCallback? Xcompare; +#endif internal IntPtr cfStringPtr_dataBecameReadyNotification; +#if NET + internal unsafe delegate* unmanaged XgetSize; +#else internal BufferGetSizeCallback? XgetSize; +#endif } // A version with no delegates, just native pointers @@ -124,17 +136,34 @@ protected override void Dispose (bool disposing) CMBufferGetBool? isDataReady, CMBufferCompare? compare, NSString dataBecameReadyNotification, CMBufferGetSize? getTotalSize) { var bq = new CMBufferQueue (count); +#if NET + CMBufferCallbacks cbacks; + unsafe { + cbacks = new CMBufferCallbacks () { + version = (uint) (getTotalSize is null ? 0 : 1), + refcon = GCHandle.ToIntPtr (bq.gch), + XgetDecodeTimeStamp = getDecodeTimeStamp is not null ? &GetDecodeTimeStamp : null, + XgetPresentationTimeStamp = getPresentationTimeStamp is not null ? &GetPresentationTimeStamp : null, + XgetDuration = getDuration is not null ? &GetDuration : null, + XisDataReady = isDataReady is not null ? &GetDataReady : null, + Xcompare = compare is not null ? &Compare : null, + cfStringPtr_dataBecameReadyNotification = dataBecameReadyNotification is null ? IntPtr.Zero : dataBecameReadyNotification.Handle, + XgetSize = getTotalSize is not null ? &GetTotalSize : null + }; + } +#else var cbacks = new CMBufferCallbacks () { version = (uint) (getTotalSize is null ? 0 : 1), refcon = GCHandle.ToIntPtr (bq.gch), - XgetDecodeTimeStamp = getDecodeTimeStamp is null ? (BufferGetTimeCallback?) null : GetDecodeTimeStamp, - XgetPresentationTimeStamp = getPresentationTimeStamp is null ? (BufferGetTimeCallback?) null : GetPresentationTimeStamp, - XgetDuration = getDuration is null ? (BufferGetTimeCallback?) null : GetDuration, - XisDataReady = isDataReady is null ? (BufferGetBooleanCallback?) null : GetDataReady, - Xcompare = compare is null ? (BufferCompareCallback?) null : Compare, + XgetDecodeTimeStamp = getDecodeTimeStamp is not null ? GetDecodeTimeStamp : null, + XgetPresentationTimeStamp = getPresentationTimeStamp is not null ? GetPresentationTimeStamp : null, + XgetDuration = getDuration is not null ? GetDuration : null, + XisDataReady = isDataReady is not null ? GetDataReady : null, + Xcompare = compare is not null ? Compare : null, cfStringPtr_dataBecameReadyNotification = dataBecameReadyNotification is null ? IntPtr.Zero : dataBecameReadyNotification.Handle, - XgetSize = getTotalSize is null ? (BufferGetSizeCallback?) null : GetTotalSize + XgetSize = getTotalSize is not null ? GetTotalSize : null }; +#endif bq.getDecodeTimeStamp = getDecodeTimeStamp; bq.getPresentationTimeStamp = getPresentationTimeStamp; @@ -322,8 +351,12 @@ INativeObject Surface (IntPtr v) return queueObjects [v]; } +#if NET + [UnmanagedCallersOnly] +#else #if !MONOMAC [MonoPInvokeCallback (typeof (BufferGetTimeCallback))] +#endif #endif static CMTime GetDecodeTimeStamp (IntPtr buffer, IntPtr refcon) { @@ -333,8 +366,12 @@ static CMTime GetDecodeTimeStamp (IntPtr buffer, IntPtr refcon) return queue.getDecodeTimeStamp (queue.Surface (buffer)); } +#if NET + [UnmanagedCallersOnly] +#else #if !MONOMAC [MonoPInvokeCallback (typeof (BufferGetTimeCallback))] +#endif #endif static CMTime GetPresentationTimeStamp (IntPtr buffer, IntPtr refcon) { @@ -344,8 +381,12 @@ static CMTime GetPresentationTimeStamp (IntPtr buffer, IntPtr refcon) return queue.getPresentationTimeStamp (queue.Surface (buffer)); } +#if NET + [UnmanagedCallersOnly] +#else #if !MONOMAC [MonoPInvokeCallback (typeof (BufferGetTimeCallback))] +#endif #endif static CMTime GetDuration (IntPtr buffer, IntPtr refcon) { @@ -355,8 +396,12 @@ static CMTime GetDuration (IntPtr buffer, IntPtr refcon) return queue.getDuration (queue.Surface (buffer)); } +#if NET + [UnmanagedCallersOnly] +#else #if !MONOMAC [MonoPInvokeCallback (typeof (BufferGetBooleanCallback))] +#endif #endif static bool GetDataReady (IntPtr buffer, IntPtr refcon) { @@ -366,8 +411,12 @@ static bool GetDataReady (IntPtr buffer, IntPtr refcon) return queue.isDataReady (queue.Surface (buffer)); } +#if NET + [UnmanagedCallersOnly] +#else #if !MONOMAC [MonoPInvokeCallback (typeof (BufferCompareCallback))] +#endif #endif static int Compare (IntPtr buffer1, IntPtr buffer2, IntPtr refcon) { @@ -377,8 +426,12 @@ static int Compare (IntPtr buffer1, IntPtr buffer2, IntPtr refcon) return queue.compare (queue.Surface (buffer1), queue.Surface (buffer2)); } +#if NET + [UnmanagedCallersOnly] +#else #if !MONOMAC [MonoPInvokeCallback (typeof (BufferGetSizeCallback))] +#endif #endif static nint GetTotalSize (IntPtr buffer, IntPtr refcon) { diff --git a/src/CoreMedia/CMCustomBlockAllocator.cs b/src/CoreMedia/CMCustomBlockAllocator.cs index 18994c7c2322..ded49438cb02 100644 --- a/src/CoreMedia/CMCustomBlockAllocator.cs +++ b/src/CoreMedia/CMCustomBlockAllocator.cs @@ -35,8 +35,15 @@ public CMCustomBlockAllocator () gch = GCHandle.Alloc (this); // kCMBlockBufferCustomBlockSourceVersion = 0 <- this is the only and current value Cblock.Version = 0; +#if NET + unsafe { + Cblock.Allocate = &AllocateCallback; + Cblock.Free = &FreeCallback; + } +#else Cblock.Allocate = static_AllocateCallback; Cblock.Free = static_FreeCallback; +#endif Cblock.RefCon = GCHandle.ToIntPtr (gch); } @@ -44,20 +51,31 @@ public CMCustomBlockAllocator () [StructLayout (LayoutKind.Sequential, Pack = 4)] // it's 28 bytes (not 32) on 64 bits iOS internal struct CMBlockBufferCustomBlockSource { public uint Version; +#if NET + public unsafe delegate* unmanaged Allocate; + public unsafe delegate* unmanaged Free; +#else public CMAllocateCallback Allocate; public CMFreeCallback Free; +#endif public IntPtr RefCon; } internal CMBlockBufferCustomBlockSource Cblock; +#if !NET internal delegate IntPtr CMAllocateCallback (/* void* */ IntPtr refCon, /* size_t */ nuint sizeInBytes); internal delegate void CMFreeCallback (/* void* */ IntPtr refCon, /* void* */ IntPtr doomedMemoryBlock, /* size_t */ nuint sizeInBytes); static CMAllocateCallback static_AllocateCallback = AllocateCallback; static CMFreeCallback static_FreeCallback = FreeCallback; +#endif +#if NET + [UnmanagedCallersOnly] +#else #if !MONOMAC [MonoPInvokeCallback (typeof (CMAllocateCallback))] +#endif #endif static IntPtr AllocateCallback (IntPtr refCon, nuint sizeInBytes) { @@ -72,8 +90,12 @@ public virtual IntPtr Allocate (nuint sizeInBytes) return Marshal.AllocHGlobal ((int)sizeInBytes); } +#if NET + [UnmanagedCallersOnly] +#else #if !MONOMAC [MonoPInvokeCallback (typeof (CMFreeCallback))] +#endif #endif static void FreeCallback (IntPtr refCon, IntPtr doomedMemoryBlock, nuint sizeInBytes) { diff --git a/src/CoreMedia/CMSampleBuffer.cs b/src/CoreMedia/CMSampleBuffer.cs index ea535461d40b..61b2951cd32d 100644 --- a/src/CoreMedia/CMSampleBuffer.cs +++ b/src/CoreMedia/CMSampleBuffer.cs @@ -139,14 +139,23 @@ unsafe static extern OSStatus CMSampleBufferCreateCopyWithNewTiming ( [DllImport(Constants.CoreMediaLibrary)] unsafe static extern CMSampleBufferError CMSampleBufferCallForEachSample ( /* CMSampleBufferRef */ IntPtr sbuf, +#if NET + delegate* unmanaged callback, +#else CMSampleBufferCallForEachSampleCallback callback, +#endif /* void* */ IntPtr refcon); - +#if !NET delegate CMSampleBufferError CMSampleBufferCallForEachSampleCallback (/* CMSampleBufferRef */ IntPtr sampleBuffer, int index, /* void* */ IntPtr refcon); +#endif +#if NET + [UnmanagedCallersOnly] +#else #if !MONOMAC [MonoPInvokeCallback (typeof (CMSampleBufferCallForEachSampleCallback))] +#endif #endif static CMSampleBufferError ForEachSampleHandler (IntPtr sbuf, int index, IntPtr refCon) { @@ -165,7 +174,13 @@ public CMSampleBufferError CallForEachSample (Func invalidateCallback, +#else /* CMSampleBufferInvalidateCallback */ CMSampleBufferInvalidateCallback? invalidateCallback, +#endif /* uint64_t */ ulong invalidateRefCon); +#if !NET delegate void CMSampleBufferInvalidateCallback (/* CMSampleBufferRef */ IntPtr sbuf, /* uint64_t */ ulong invalidateRefCon); static CMSampleBufferInvalidateCallback invalidate_handler = InvalidateHandler; +#endif +#if NET + [UnmanagedCallersOnly] +#else #if !MONOMAC [MonoPInvokeCallback (typeof (CMSampleBufferInvalidateCallback))] +#endif #endif static void InvalidateHandler (IntPtr sbuf, ulong invalidateRefCon) { @@ -612,8 +641,13 @@ public CMSampleBufferError SetInvalidateCallback (Action invalid if (invalidateHandler is null) { if (invalidate.IsAllocated) invalidate.Free (); - - return CMSampleBufferSetInvalidateCallback (Handle, null, 0); +#if NET + unsafe { +#endif + return CMSampleBufferSetInvalidateCallback (Handle, null, 0); +#if NET + } +#endif } // only one callback can be assigned - and ObjC does not let you re-assign a different one, @@ -623,7 +657,13 @@ public CMSampleBufferError SetInvalidateCallback (Action invalid return CMSampleBufferError.RequiredParameterMissing; invalidate = GCHandle.Alloc (Tuple.Create (invalidateHandler, this)); +#if NET + unsafe { + return CMSampleBufferSetInvalidateCallback (Handle, &InvalidateHandler, (ulong)(IntPtr)invalidate); + } +#else return CMSampleBufferSetInvalidateCallback (Handle, invalidate_handler, (ulong)(IntPtr)invalidate); +#endif } [DllImport(Constants.CoreMediaLibrary)]