Skip to content

Commit

Permalink
[CoreMedia] Make the P/Invokes in CMFormatDescription have blittable …
Browse files Browse the repository at this point in the history
…signatures. (#20329)

Contributes towards #15684.
  • Loading branch information
rolfbjarne committed Mar 19, 2024
1 parent ab3fc14 commit 120d6e3
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 56 deletions.
134 changes: 91 additions & 43 deletions src/CoreMedia/CMFormatDescription.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#nullable enable

using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Collections.Generic;

Expand Down Expand Up @@ -139,12 +140,14 @@ public static nint GetTypeID ()
}

[DllImport (Constants.CoreMediaLibrary)]
extern static /* OSStatus */ CMFormatDescriptionError CMFormatDescriptionCreate (/* CFAllocatorRef */ IntPtr allocator, CMMediaType mediaType, /* FourCharCode */ uint mediaSubtype, /* CFDictionaryRef */ IntPtr extensions, /* CMFormatDescriptionRef* */ out IntPtr descOut);
unsafe extern static /* OSStatus */ CMFormatDescriptionError CMFormatDescriptionCreate (/* CFAllocatorRef */ IntPtr allocator, CMMediaType mediaType, /* FourCharCode */ uint mediaSubtype, /* CFDictionaryRef */ IntPtr extensions, /* CMFormatDescriptionRef* */ IntPtr* descOut);

public static CMFormatDescription? Create (CMMediaType mediaType, uint mediaSubtype, out CMFormatDescriptionError error)
{
IntPtr handle;
error = CMFormatDescriptionCreate (IntPtr.Zero, mediaType, mediaSubtype, IntPtr.Zero, out handle);
unsafe {
error = CMFormatDescriptionCreate (IntPtr.Zero, mediaType, mediaSubtype, IntPtr.Zero, &handle);
}
if (error != CMFormatDescriptionError.None)
return null;

Expand Down Expand Up @@ -192,26 +195,32 @@ public AudioStreamBasicDescription? AudioStreamBasicDescription {
}

[DllImport (Constants.CoreMediaLibrary)]
extern static /* AudioChannelLayout* */ IntPtr CMAudioFormatDescriptionGetChannelLayout (/* CMAudioFormatDescriptionRef */ IntPtr desc, /* size_t* */ out nint size);
unsafe extern static /* AudioChannelLayout* */ IntPtr CMAudioFormatDescriptionGetChannelLayout (/* CMAudioFormatDescriptionRef */ IntPtr desc, /* size_t* */ nint* size);

public AudioChannelLayout? AudioChannelLayout {
get {
nint size;
var res = CMAudioFormatDescriptionGetChannelLayout (Handle, out size);
IntPtr res;
unsafe {
res = CMAudioFormatDescriptionGetChannelLayout (Handle, &size);
}
if (res == IntPtr.Zero || size == 0)
return null;
return AudioChannelLayout.FromHandle (res);
}
}

[DllImport (Constants.CoreMediaLibrary)]
extern static /* AudioFormatListItem* */ IntPtr CMAudioFormatDescriptionGetFormatList (/* CMAudioFormatDescriptionRef */ IntPtr desc, /* size_t* */ out nint size);
unsafe extern static /* AudioFormatListItem* */ IntPtr CMAudioFormatDescriptionGetFormatList (/* CMAudioFormatDescriptionRef */ IntPtr desc, /* size_t* */ nint* size);

public AudioFormat []? AudioFormats {
get {
unsafe {
nint size;
var v = CMAudioFormatDescriptionGetFormatList (Handle, out size);
IntPtr v;
unsafe {
v = CMAudioFormatDescriptionGetFormatList (Handle, &size);
}
if (v == IntPtr.Zero)
return null;
var items = size / sizeof (AudioFormat);
Expand All @@ -225,12 +234,15 @@ public AudioFormat []? AudioFormats {
}

[DllImport (Constants.CoreMediaLibrary)]
extern static /* const void* */ IntPtr CMAudioFormatDescriptionGetMagicCookie (/* CMAudioFormatDescriptionRef */ IntPtr desc, /* size_t* */ out nint size);
unsafe extern static /* const void* */ IntPtr CMAudioFormatDescriptionGetMagicCookie (/* CMAudioFormatDescriptionRef */ IntPtr desc, /* size_t* */ nint* size);

public byte []? AudioMagicCookie {
get {
nint size;
var h = CMAudioFormatDescriptionGetMagicCookie (Handle, out size);
IntPtr h;
unsafe {
h = CMAudioFormatDescriptionGetMagicCookie (Handle, &size);
}
if (h == IntPtr.Zero)
return null;

Expand Down Expand Up @@ -274,17 +286,16 @@ public AudioFormat AudioRichestDecodableFormat {
internal extern static CMVideoDimensions CMVideoFormatDescriptionGetDimensions (/* CMVideoFormatDescriptionRef */ IntPtr videoDesc);

[DllImport (Constants.CoreMediaLibrary)]
internal extern static CGRect CMVideoFormatDescriptionGetCleanAperture (/* CMVideoFormatDescriptionRef */ IntPtr videoDesc, /* Boolean */ [MarshalAs (UnmanagedType.I1)] bool originIsAtTopLeft);
internal extern static CGRect CMVideoFormatDescriptionGetCleanAperture (/* CMVideoFormatDescriptionRef */ IntPtr videoDesc, /* Boolean */ byte originIsAtTopLeft);

[DllImport (Constants.CoreMediaLibrary)]
internal extern static /* CFArrayRef */ IntPtr CMVideoFormatDescriptionGetExtensionKeysCommonWithImageBuffers ();

[DllImport (Constants.CoreMediaLibrary)]
internal extern static CGSize CMVideoFormatDescriptionGetPresentationDimensions (/* CMVideoFormatDescriptionRef */ IntPtr videoDesc, /* Boolean */ [MarshalAs (UnmanagedType.I1)] bool usePixelAspectRatio, /* Boolean */ [MarshalAs (UnmanagedType.I1)] bool useCleanAperture);
internal extern static CGSize CMVideoFormatDescriptionGetPresentationDimensions (/* CMVideoFormatDescriptionRef */ IntPtr videoDesc, /* Boolean */ byte usePixelAspectRatio, /* Boolean */ byte useCleanAperture);

[DllImport (Constants.CoreMediaLibrary)]
[return: MarshalAs (UnmanagedType.I1)]
internal extern static /* Boolean */ bool CMVideoFormatDescriptionMatchesImageBuffer (/* CMVideoFormatDescriptionRef */ IntPtr videoDesc, /* CVImageBufferRef */ IntPtr imageBuffer);
internal extern static /* Boolean */ byte CMVideoFormatDescriptionMatchesImageBuffer (/* CMVideoFormatDescriptionRef */ IntPtr videoDesc, /* CVImageBufferRef */ IntPtr imageBuffer);

#endif
}
Expand Down Expand Up @@ -324,18 +335,21 @@ internal CMVideoFormatDescription (NativeHandle handle, bool owns)

#if !COREBUILD
[DllImport (Constants.CoreMediaLibrary)]
static extern /* OSStatus */ CMFormatDescriptionError CMVideoFormatDescriptionCreate (
unsafe static extern /* OSStatus */ CMFormatDescriptionError CMVideoFormatDescriptionCreate (
/* CFAllocatorRef */ IntPtr allocator,
CMVideoCodecType codecType,
/* int32_t */ int width,
/* int32_t */ int height,
/* CFDictionaryRef */ IntPtr extensions,
/* CMVideoFormatDescriptionRef* */ out IntPtr outDesc);
/* CMVideoFormatDescriptionRef* */ IntPtr* outDesc);

static IntPtr CreateCMVideoFormatDescription (CMVideoCodecType codecType, CMVideoDimensions size)
{
IntPtr handle;
var error = CMVideoFormatDescriptionCreate (IntPtr.Zero, codecType, size.Width, size.Height, IntPtr.Zero, out handle);
CMFormatDescriptionError error;
unsafe {
error = CMVideoFormatDescriptionCreate (IntPtr.Zero, codecType, size.Width, size.Height, IntPtr.Zero, &handle);
}
if (error != CMFormatDescriptionError.None)
ObjCRuntime.ThrowHelper.ThrowArgumentException (error.ToString ());
return handle;
Expand All @@ -353,18 +367,20 @@ public CMVideoDimensions Dimensions {
}

[DllImport (Constants.CoreMediaLibrary)]
static extern /* OSStatus */ CMFormatDescriptionError CMVideoFormatDescriptionCreateForImageBuffer (
unsafe static extern /* OSStatus */ CMFormatDescriptionError CMVideoFormatDescriptionCreateForImageBuffer (
/* CFAllocatorRef */ IntPtr allocator,
/* CVImageBufferRef */ IntPtr imageBuffer,
/* CMVideoFormatDescriptionRef* */ out IntPtr outDesc);
/* CMVideoFormatDescriptionRef* */ IntPtr* outDesc);

public static CMVideoFormatDescription? CreateForImageBuffer (CVImageBuffer imageBuffer, out CMFormatDescriptionError error)
{
if (imageBuffer is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (imageBuffer));

IntPtr desc;
error = CMVideoFormatDescriptionCreateForImageBuffer (IntPtr.Zero, imageBuffer.Handle, out desc);
unsafe {
error = CMVideoFormatDescriptionCreateForImageBuffer (IntPtr.Zero, imageBuffer.Handle, &desc);
}
if (error != CMFormatDescriptionError.None)
return null;

Expand All @@ -378,13 +394,13 @@ public CMVideoDimensions Dimensions {
[SupportedOSPlatform ("tvos")]
#endif
[DllImport (Constants.CoreMediaLibrary)]
static extern /* OSStatus */ CMFormatDescriptionError CMVideoFormatDescriptionCreateFromH264ParameterSets (
unsafe static extern /* OSStatus */ CMFormatDescriptionError CMVideoFormatDescriptionCreateFromH264ParameterSets (
/* CFAllocatorRef */ IntPtr allocator,
/* size_t */ nuint parameterSetCount,
/* const uint8_t* const* */ IntPtr [] parameterSetPointers,
/* size_t* */ nuint [] parameterSetSizes,
/* const uint8_t* const* */ IntPtr* parameterSetPointers,
/* size_t* */ nuint* parameterSetSizes,
/* int */ int NALUnitHeaderLength,
/* CMFormatDescriptionRef* */ out IntPtr formatDescriptionOut);
/* CMFormatDescriptionRef* */ IntPtr* formatDescriptionOut);

#if NET
[SupportedOSPlatform ("ios")]
Expand Down Expand Up @@ -415,7 +431,13 @@ public CMVideoDimensions Dimensions {
}

IntPtr desc;
error = CMVideoFormatDescriptionCreateFromH264ParameterSets (IntPtr.Zero, (nuint) parameterSets.Count, parameterSetPtrs, parameterSetSizes, nalUnitHeaderLength, out desc);
unsafe {
fixed (IntPtr* parameterSetPtrsPtr = parameterSetPtrs) {
fixed (nuint* parameterSetSizesPtr = parameterSetSizes) {
error = CMVideoFormatDescriptionCreateFromH264ParameterSets (IntPtr.Zero, (nuint) parameterSets.Count, parameterSetPtrsPtr, parameterSetSizesPtr, nalUnitHeaderLength, &desc);
}
}
}
if (error != CMFormatDescriptionError.None)
return null;

Expand All @@ -435,13 +457,13 @@ public CMVideoDimensions Dimensions {
[SupportedOSPlatform ("tvos")]
#endif
[DllImport (Constants.CoreMediaLibrary)]
static extern /* OSStatus */ CMFormatDescriptionError CMVideoFormatDescriptionGetH264ParameterSetAtIndex (
unsafe static extern /* OSStatus */ CMFormatDescriptionError CMVideoFormatDescriptionGetH264ParameterSetAtIndex (
/* CMFormatDescriptionRef */ IntPtr videoDesc,
/* size_t */ nuint parameterSetIndex,
/* const uint8_t** */ out IntPtr parameterSetPointerOut,
/* size_t* */ out nuint parameterSetSizeOut,
/* size_t* */ out nuint parameterSetCountOut,
/* int* */ out int nalUnitHeaderLengthOut);
/* const uint8_t** */ IntPtr* parameterSetPointerOut,
/* size_t* */ nuint* parameterSetSizeOut,
/* size_t* */ nuint* parameterSetCountOut,
/* int* */ int* nalUnitHeaderLengthOut);

#if NET
[SupportedOSPlatform ("ios")]
Expand All @@ -453,7 +475,17 @@ public CMVideoDimensions Dimensions {
{
IntPtr ret;
nuint parameterSetSizeOut;
error = CMVideoFormatDescriptionGetH264ParameterSetAtIndex (GetCheckedHandle (), index, out ret, out parameterSetSizeOut, out parameterSetCount, out nalUnitHeaderLength);
parameterSetCount = default;
nalUnitHeaderLength = default;
unsafe {
error = CMVideoFormatDescriptionGetH264ParameterSetAtIndex (
GetCheckedHandle (),
index,
&ret,
&parameterSetSizeOut,
(nuint*) Unsafe.AsPointer<nuint> (ref parameterSetCount),
(int*) Unsafe.AsPointer<int> (ref nalUnitHeaderLength));
}
if (error != CMFormatDescriptionError.None)
return null;

Expand All @@ -465,12 +497,12 @@ public CMVideoDimensions Dimensions {

public CGRect GetCleanAperture (bool originIsAtTopLeft)
{
return CMVideoFormatDescriptionGetCleanAperture (Handle, originIsAtTopLeft);
return CMVideoFormatDescriptionGetCleanAperture (Handle, originIsAtTopLeft.AsByte ());
}

public CGSize GetPresentationDimensions (bool usePixelAspectRatio, bool useCleanAperture)
{
return CMVideoFormatDescriptionGetPresentationDimensions (Handle, usePixelAspectRatio, useCleanAperture);
return CMVideoFormatDescriptionGetPresentationDimensions (Handle, usePixelAspectRatio.AsByte (), useCleanAperture.AsByte ());
}

public static NSObject? []? GetExtensionKeysCommonWithImageBuffers ()
Expand All @@ -483,7 +515,7 @@ public bool VideoMatchesImageBuffer (CVImageBuffer imageBuffer)
{
if (imageBuffer is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (imageBuffer));
return CMVideoFormatDescriptionMatchesImageBuffer (Handle, imageBuffer.Handle);
return CMVideoFormatDescriptionMatchesImageBuffer (Handle, imageBuffer.Handle) != 0;
}

#if NET
Expand All @@ -493,14 +525,14 @@ public bool VideoMatchesImageBuffer (CVImageBuffer imageBuffer)
[SupportedOSPlatform ("maccatalyst")]
#endif
[DllImport (Constants.CoreMediaLibrary)]
static extern /* OSStatus */ CMFormatDescriptionError CMVideoFormatDescriptionCreateFromHEVCParameterSets (
unsafe static extern /* OSStatus */ CMFormatDescriptionError CMVideoFormatDescriptionCreateFromHEVCParameterSets (
/* CFAllocatorRef */ IntPtr allocator,
/* size_t */ nuint parameterSetCount,
/* const uint8_t* const* */ IntPtr [] parameterSetPointers,
/* size_t* */ nuint [] parameterSetSizes,
/* const uint8_t* const* */ IntPtr* parameterSetPointers,
/* size_t* */ nuint* parameterSetSizes,
/* int */ int NALUnitHeaderLength,
/* CFDictionaryRef */ IntPtr extensions,
/* CMFormatDescriptionRef* */ out IntPtr formatDescriptionOut);
/* CMFormatDescriptionRef* */ IntPtr* formatDescriptionOut);

#if NET
[SupportedOSPlatform ("ios")]
Expand Down Expand Up @@ -531,7 +563,13 @@ public bool VideoMatchesImageBuffer (CVImageBuffer imageBuffer)
}

IntPtr desc;
error = CMVideoFormatDescriptionCreateFromHEVCParameterSets (IntPtr.Zero, (nuint) parameterSets.Count, parameterSetPtrs, parameterSetSizes, nalUnitHeaderLength, extensions.GetHandle (), out desc);
unsafe {
fixed (IntPtr* parameterSetPtrsPtr = parameterSetPtrs) {
fixed (nuint* parameterSetSizesPtr = parameterSetSizes) {
error = CMVideoFormatDescriptionCreateFromHEVCParameterSets (IntPtr.Zero, (nuint) parameterSets.Count, parameterSetPtrsPtr, parameterSetSizesPtr, nalUnitHeaderLength, extensions.GetHandle (), &desc);
}
}
}
if (error != CMFormatDescriptionError.None || desc == IntPtr.Zero)
return null;

Expand All @@ -551,13 +589,13 @@ public bool VideoMatchesImageBuffer (CVImageBuffer imageBuffer)
[SupportedOSPlatform ("maccatalyst")]
#endif
[DllImport (Constants.CoreMediaLibrary)]
static extern /* OSStatus */ CMFormatDescriptionError CMVideoFormatDescriptionGetHEVCParameterSetAtIndex (
unsafe static extern /* OSStatus */ CMFormatDescriptionError CMVideoFormatDescriptionGetHEVCParameterSetAtIndex (
/* CMFormatDescriptionRef */ IntPtr videoDesc,
/* size_t */ nuint parameterSetIndex,
/* const uint8_t** */ out IntPtr parameterSetPointerOut,
/* size_t* */ out nuint parameterSetSizeOut,
/* size_t* */ out nuint parameterSetCountOut,
/* int* */ out int nalUnitHeaderLengthOut);
/* const uint8_t** */ IntPtr* parameterSetPointerOut,
/* size_t* */ nuint* parameterSetSizeOut,
/* size_t* */ nuint* parameterSetCountOut,
/* int* */ int* nalUnitHeaderLengthOut);

#if NET
[SupportedOSPlatform ("ios")]
Expand All @@ -569,7 +607,17 @@ public bool VideoMatchesImageBuffer (CVImageBuffer imageBuffer)
{
IntPtr ret;
nuint parameterSetSizeOut;
error = CMVideoFormatDescriptionGetHEVCParameterSetAtIndex (GetCheckedHandle (), index, out ret, out parameterSetSizeOut, out parameterSetCount, out nalUnitHeaderLength);
parameterSetCount = default;
nalUnitHeaderLength = default;
unsafe {
error = CMVideoFormatDescriptionGetHEVCParameterSetAtIndex (
GetCheckedHandle (),
index,
&ret,
&parameterSetSizeOut,
(nuint*) Unsafe.AsPointer<nuint> (ref parameterSetCount),
(int*) Unsafe.AsPointer<int> (ref nalUnitHeaderLength));
}
if (error != CMFormatDescriptionError.None)
return null;

Expand Down
Loading

8 comments on commit 120d6e3

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📚 [CI Build] Artifacts 📚

Packages generated

View packages

Pipeline on Agent
Hash: [CI build]

Please sign in to comment.