CPF/CPF.Mac/Mac/CoreVideo/CVPixelBuffer.cs
2023-11-21 23:05:03 +08:00

247 lines
9.1 KiB
C#

//
// CVPixelBuffer.cs: Implements the managed CVPixelBuffer
//
// Authors: Mono Team
//
// Copyright 2010 Novell, Inc
// Copyright 2011, 2012 Xamarin Inc
//
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using CPF.Mac.CoreFoundation;
using CPF.Mac.ObjCRuntime;
using CPF.Mac.Foundation;
namespace CPF.Mac.CoreVideo {
[Since (4,0)]
public class CVPixelBuffer : CVImageBuffer {
public static readonly NSString PixelFormatTypeKey;
public static readonly NSString MemoryAllocatorKey;
public static readonly NSString WidthKey;
public static readonly NSString HeightKey;
public static readonly NSString ExtendedPixelsLeftKey;
public static readonly NSString ExtendedPixelsTopKey;
public static readonly NSString ExtendedPixelsRightKey;
public static readonly NSString ExtendedPixelsBottomKey;
public static readonly NSString BytesPerRowAlignmentKey;
public static readonly NSString CGBitmapContextCompatibilityKey;
public static readonly NSString CGImageCompatibilityKey;
public static readonly NSString OpenGLCompatibilityKey;
public static readonly NSString IOSurfacePropertiesKey;
public static readonly NSString PlaneAlignmentKey;
public static readonly NSString OpenGLESCompatibilityKey;
public static readonly int CVImageBufferType;
[DllImport (Constants.CoreVideoLibrary)]
extern static int CVPixelBufferGetTypeID ();
static CVPixelBuffer ()
{
var handle = Dlfcn.dlopen (Constants.CoreVideoLibrary, 0);
if (handle == IntPtr.Zero)
return;
try {
PixelFormatTypeKey = Dlfcn.GetStringConstant (handle, "kCVPixelBufferPixelFormatTypeKey");
MemoryAllocatorKey = Dlfcn.GetStringConstant (handle, "kCVPixelBufferMemoryAllocatorKey");
WidthKey = Dlfcn.GetStringConstant (handle, "kCVPixelBufferWidthKey");
HeightKey = Dlfcn.GetStringConstant (handle, "kCVPixelBufferHeightKey");
ExtendedPixelsLeftKey = Dlfcn.GetStringConstant (handle, "kCVPixelBufferExtendedPixelsLeftKey");
ExtendedPixelsTopKey = Dlfcn.GetStringConstant (handle, "kCVPixelBufferExtendedPixelsTopKey");
ExtendedPixelsRightKey = Dlfcn.GetStringConstant (handle, "kCVPixelBufferExtendedPixelsRightKey");
ExtendedPixelsBottomKey = Dlfcn.GetStringConstant (handle, "kCVPixelBufferExtendedPixelsBottomKey");
BytesPerRowAlignmentKey = Dlfcn.GetStringConstant (handle, "kCVPixelBufferBytesPerRowAlignmentKey");
CGBitmapContextCompatibilityKey = Dlfcn.GetStringConstant (handle, "kCVPixelBufferCGBitmapContextCompatibilityKey");
CGImageCompatibilityKey = Dlfcn.GetStringConstant (handle, "kCVPixelBufferCGImageCompatibilityKey");
OpenGLCompatibilityKey = Dlfcn.GetStringConstant (handle, "kCVPixelBufferOpenGLCompatibilityKey");
IOSurfacePropertiesKey = Dlfcn.GetStringConstant (handle, "kCVPixelBufferIOSurfacePropertiesKey");
PlaneAlignmentKey = Dlfcn.GetStringConstant (handle, "kCVPixelBufferPlaneAlignmentKey");
CVImageBufferType = CVPixelBufferGetTypeID ();
OpenGLESCompatibilityKey = Dlfcn.GetStringConstant (handle, "kCVPixelBufferOpenGLESCompatibilityKey");
}
finally {
Dlfcn.dlclose (handle);
}
}
internal CVPixelBuffer (IntPtr handle) : base (handle)
{
}
[Preserve (Conditional=true)]
internal CVPixelBuffer (IntPtr handle, bool owns) : base (handle, owns)
{
}
#if !COREBUILD
[DllImport (Constants.CoreVideoLibrary)]
extern static CVReturn CVPixelBufferCreate (IntPtr allocator, IntPtr width, IntPtr height, CVPixelFormatType pixelFormatType, IntPtr pixelBufferAttributes, IntPtr pixelBufferOut);
public CVPixelBuffer (Size size, CVPixelFormatType pixelFormat)
: this (size.Width, size.Height, pixelFormat, null)
{
}
public CVPixelBuffer (Size size, CVPixelFormatType pixelFormatType, CVPixelBufferAttributes attributes)
: this (size.Width, size.Height, pixelFormatType, attributes == null ? null : attributes.Dictionary)
{
}
[Advice ("Use constructor with CVPixelBufferAttributes")]
public CVPixelBuffer (int width, int height, CVPixelFormatType pixelFormatType, NSDictionary pixelBufferAttributes)
{
if (width <= 0)
throw new ArgumentOutOfRangeException ("width");
if (height <= 0)
throw new ArgumentOutOfRangeException ("height");
IntPtr pixelBufferOut = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (IntPtr)));
CVReturn ret = CVPixelBufferCreate (IntPtr.Zero, (IntPtr) width, (IntPtr) height, pixelFormatType,
pixelBufferAttributes == null ? IntPtr.Zero : pixelBufferAttributes.Handle, pixelBufferOut);
if (ret != CVReturn.Success) {
Marshal.FreeHGlobal (pixelBufferOut);
throw new ArgumentException (ret.ToString ());
}
this.handle = Marshal.ReadIntPtr (pixelBufferOut);
Marshal.FreeHGlobal (pixelBufferOut);
}
[DllImport (Constants.CoreVideoLibrary)]
extern static CVReturn CVPixelBufferCreateResolvedAttributesDictionary (IntPtr allocator, IntPtr attributes, IntPtr resolvedDictionaryOut);
public NSDictionary GetAttributes (NSDictionary [] attributes)
{
IntPtr resolvedDictionaryOut = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (IntPtr)));
NSArray attributeArray = NSArray.FromNSObjects (attributes);
CVReturn ret = CVPixelBufferCreateResolvedAttributesDictionary (IntPtr.Zero, attributeArray.Handle, resolvedDictionaryOut);
if (ret != CVReturn.Success) {
Marshal.FreeHGlobal (resolvedDictionaryOut);
throw new Exception ("CVPixelBufferCreate returned: " + ret);
}
NSDictionary dictionary = (NSDictionary) Runtime.GetNSObject (Marshal.ReadIntPtr (resolvedDictionaryOut));
Marshal.FreeHGlobal (resolvedDictionaryOut);
return dictionary;
}
#endif
// TODO: CVPixelBufferCreateWithBytes
// TODO: CVPixelBufferCreateWithPlanarBytes
// TODO: CVPixelBufferGetExtendedPixels
// TODO: CVPixelBufferGetTypeID
[DllImport (Constants.CoreVideoLibrary)]
extern static CVReturn CVPixelBufferFillExtendedPixels (IntPtr pixelBuffer);
public CVReturn FillExtendedPixels ()
{
return CVPixelBufferFillExtendedPixels (handle);
}
[DllImport (Constants.CoreVideoLibrary)]
extern static IntPtr CVPixelBufferGetBaseAddress (IntPtr pixelBuffer);
public IntPtr BaseAddress {
get {
return CVPixelBufferGetBaseAddress (handle);
}
}
[DllImport (Constants.CoreVideoLibrary)]
extern static IntPtr CVPixelBufferGetBytesPerRow (IntPtr pixelBuffer);
public int BytesPerRow {
get {
return (int) CVPixelBufferGetBytesPerRow (handle);
}
}
[DllImport (Constants.CoreVideoLibrary)]
extern static IntPtr CVPixelBufferGetDataSize (IntPtr pixelBuffer);
public int DataSize {
get {
return (int) CVPixelBufferGetDataSize (handle);
}
}
[DllImport (Constants.CoreVideoLibrary)]
extern static IntPtr CVPixelBufferGetHeight (IntPtr pixelBuffer);
public int Height {
get {
return (int) CVPixelBufferGetHeight (handle);
}
}
[DllImport (Constants.CoreVideoLibrary)]
extern static IntPtr CVPixelBufferGetWidth (IntPtr pixelBuffer);
public int Width {
get {
return (int) CVPixelBufferGetWidth (handle);
}
}
[DllImport (Constants.CoreVideoLibrary)]
extern static IntPtr CVPixelBufferGetPlaneCount (IntPtr pixelBuffer);
public int PlaneCount {
get {
return (int) CVPixelBufferGetPlaneCount (handle);
}
}
[DllImport (Constants.CoreVideoLibrary)]
extern static bool CVPixelBufferIsPlanar (IntPtr pixelBuffer);
public bool IsPlanar {
get {
return CVPixelBufferIsPlanar (handle);
}
}
[DllImport (Constants.CoreVideoLibrary)]
extern static CVPixelFormatType CVPixelBufferGetPixelFormatType (IntPtr pixelBuffer);
public CVPixelFormatType PixelFormatType {
get {
return CVPixelBufferGetPixelFormatType (handle);
}
}
[DllImport (Constants.CoreVideoLibrary)]
extern static IntPtr CVPixelBufferGetBaseAddressOfPlane (IntPtr pixelBuffer, IntPtr planeIndex);
public IntPtr GetBaseAddress (int planeIndex) {
return CVPixelBufferGetBaseAddressOfPlane (handle, (IntPtr) planeIndex);
}
[DllImport (Constants.CoreVideoLibrary)]
extern static IntPtr CVPixelBufferGetBytesPerRowOfPlane (IntPtr pixelBuffer, IntPtr planeIndex);
public int GetBytesPerRowOfPlane (int planeIndex) {
return (int) CVPixelBufferGetBytesPerRowOfPlane (handle, (IntPtr) planeIndex);
}
[DllImport (Constants.CoreVideoLibrary)]
extern static IntPtr CVPixelBufferGetHeightOfPlane (IntPtr pixelBuffer, IntPtr planeIndex);
public int GetHeightOfPlane (int planeIndex) {
return (int) CVPixelBufferGetHeightOfPlane (handle, (IntPtr) planeIndex);
}
[DllImport (Constants.CoreVideoLibrary)]
extern static IntPtr CVPixelBufferGetWidthtOfPlane (IntPtr pixelBuffer, IntPtr planeIndex);
public int GetWidthtOfPlane (int planeIndex) {
return (int) CVPixelBufferGetWidthtOfPlane (handle, (IntPtr) planeIndex);
}
[DllImport (Constants.CoreVideoLibrary)]
extern static CVReturn CVPixelBufferLockBaseAddress (IntPtr pixelBuffer, CVOptionFlags lockFlags);
public CVReturn Lock (CVOptionFlags lockFlags) {
return CVPixelBufferLockBaseAddress (handle, lockFlags);
}
[DllImport (Constants.CoreVideoLibrary)]
extern static CVReturn CVPixelBufferUnlockBaseAddress (IntPtr pixelBuffer, CVOptionFlags unlockFlags);
public CVReturn Unlock (CVOptionFlags unlockFlags) {
return CVPixelBufferUnlockBaseAddress (handle, unlockFlags);
}
}
}