[.NET/CoreMedia] Use [UnmanagedCallersOnly] instead of [MonoPInvokeCallback] Partial Fix for #10470 (#15934)
This commit is contained in:
Родитель
878d16efb5
Коммит
227baba0b9
|
@ -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)]
|
||||
|
|
Загрузка…
Ссылка в новой задаче