[.NET/CoreMedia] Use [UnmanagedCallersOnly] instead of [MonoPInvokeCallback] Partial Fix for #10470 (#15934)

This commit is contained in:
Steve Hawley 2022-09-13 09:29:37 -04:00 коммит произвёл GitHub
Родитель 878d16efb5
Коммит 227baba0b9
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 124 добавлений и 9 удалений

Просмотреть файл

@ -61,13 +61,25 @@ namespace CoreMedia {
struct CMBufferCallbacks {
internal uint version;
internal IntPtr refcon;
#if NET
internal unsafe delegate* unmanaged<IntPtr, IntPtr, CMTime> XgetDecodeTimeStamp;
internal unsafe delegate* unmanaged<IntPtr, IntPtr, CMTime> XgetPresentationTimeStamp;
internal unsafe delegate* unmanaged<IntPtr, IntPtr, CMTime> XgetDuration;
internal unsafe delegate* unmanaged<IntPtr, IntPtr, bool> XisDataReady;
internal unsafe delegate* unmanaged<IntPtr, IntPtr, IntPtr, int> 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<IntPtr, IntPtr, nint> XgetSize;
#else
internal BufferGetSizeCallback? XgetSize;
#endif
}
// A version with no delegates, just native pointers
@ -124,17 +136,34 @@ namespace CoreMedia {
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 @@ namespace CoreMedia {
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 @@ namespace CoreMedia {
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 @@ namespace CoreMedia {
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 @@ namespace CoreMedia {
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 @@ namespace CoreMedia {
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 @@ namespace CoreMedia {
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)
{

Просмотреть файл

@ -35,8 +35,15 @@ namespace CoreMedia {
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 @@ namespace CoreMedia {
[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<IntPtr, nuint, IntPtr> Allocate;
public unsafe delegate* unmanaged<IntPtr, IntPtr, nuint, void> 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 @@ namespace CoreMedia {
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)
{

Просмотреть файл

@ -139,14 +139,23 @@ namespace CoreMedia {
[DllImport(Constants.CoreMediaLibrary)]
unsafe static extern CMSampleBufferError CMSampleBufferCallForEachSample (
/* CMSampleBufferRef */ IntPtr sbuf,
#if NET
delegate* unmanaged<IntPtr, int, IntPtr, CMSampleBufferError> 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 @@ namespace CoreMedia {
GCHandle h = GCHandle.Alloc (Tuple.Create (callback, this));
try {
#if NET
unsafe {
return CMSampleBufferCallForEachSample (Handle, &ForEachSampleHandler, (IntPtr) h);
}
#else
return CMSampleBufferCallForEachSample (Handle, ForEachSampleHandler, (IntPtr) h);
#endif
} finally {
h.Free ();
}
@ -586,18 +601,32 @@ namespace CoreMedia {
// however there was already a similar call that we did not bound (not sure why)
// and can provide the same feature (since iOS 4 not 8.0)
[DllImport(Constants.CoreMediaLibrary)]
#if NET
extern unsafe static /* OSStatus */ CMSampleBufferError CMSampleBufferSetInvalidateCallback (
#else
extern static /* OSStatus */ CMSampleBufferError CMSampleBufferSetInvalidateCallback (
#endif
/* CMSampleBufferRef */ IntPtr sbuf,
#if NET
delegate* unmanaged<IntPtr, ulong, void> 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 @@ namespace CoreMedia {
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 @@ namespace CoreMedia {
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)]