public static CVPixelBuffer? Create (nint width, nint height, CVPixelFormatType pixelFormatType, byte[][] planes, nint[] planeWidths, nint[] planeHeights, nint[] planeBytesPerRow, CVPixelBufferAttributes pixelBufferAttributes, out CVReturn status) { IntPtr handle; IntPtr[] addresses; PlaneData data; GCHandle data_handle; if (planes == null) throw new ArgumentNullException (nameof (planes)); if (planeWidths == null) throw new ArgumentNullException (nameof (planeWidths)); if (planeHeights == null) throw new ArgumentNullException (nameof (planeHeights)); if (planeBytesPerRow == null) throw new ArgumentNullException (nameof (planeBytesPerRow)); var planeCount = planes.Length; if (planeWidths.Length != planeCount) throw new ArgumentOutOfRangeException (nameof (planeWidths), "The length of planeWidths does not match the number of planes"); if (planeHeights.Length != planeCount) throw new ArgumentOutOfRangeException (nameof (planeWidths), "The length of planeHeights does not match the number of planes"); if (planeBytesPerRow.Length != planeCount) throw new ArgumentOutOfRangeException (nameof (planeWidths), "The length of planeBytesPerRow does not match the number of planes"); addresses = new IntPtr [planeCount]; data = new PlaneData (); data.dataHandles = new GCHandle [planeCount]; for (int i = 0; i < planeCount; i++) { data.dataHandles[i] = GCHandle.Alloc (planes [i], GCHandleType.Pinned); // This can't use unsafe code because we need to get the pointer for an unbound number of objects. addresses[i] = data.dataHandles[i].AddrOfPinnedObject (); } data_handle = GCHandle.Alloc (data); IntPtr data_handle_ptr = GCHandle.ToIntPtr (data_handle); status = CVPixelBufferCreateWithPlanarBytes (IntPtr.Zero, width, height, pixelFormatType, IntPtr.Zero, 0, planeCount, addresses, planeWidths, planeHeights, planeBytesPerRow, releasePlanarBytesCallback, data_handle_ptr, DictionaryContainerHelper.GetHandle (pixelBufferAttributes), out handle); if (status != CVReturn.Success) { ReleasePlanarBytesCallback (data_handle_ptr, IntPtr.Zero, 0, 0, IntPtr.Zero); return null; } return new CVPixelBuffer (handle, true); }
public static CVPixelBuffer? Create (nint width, nint height, CVPixelFormatType pixelFormatType, byte[] data, nint bytesPerRow, CVPixelBufferAttributes pixelBufferAttributes, out CVReturn status) { IntPtr handle; GCHandle gchandle; if (data == null) throw new ArgumentNullException (nameof (data)); if (data.Length < height * bytesPerRow) throw new ArgumentOutOfRangeException (nameof (data), "The length of data is smaller than height * bytesPerRow"); gchandle = GCHandle.Alloc (data, GCHandleType.Pinned); // This requires a pinned GCHandle, because unsafe code is scoped to the current block, and the address of the byte array will be used after this function returns. status = CVPixelBufferCreateWithBytes (IntPtr.Zero, width, height, pixelFormatType, gchandle.AddrOfPinnedObject (), bytesPerRow, releaseBytesCallback, GCHandle.ToIntPtr (gchandle), DictionaryContainerHelper.GetHandle (pixelBufferAttributes), out handle); if (status != CVReturn.Success) { gchandle.Free (); return null; } return new CVPixelBuffer (handle, true); }
public static CVPixelBuffer Create(nint width, nint height, CVPixelFormatType pixelFormatType, byte[] data, nint bytesPerRow, CVPixelBufferAttributes pixelBufferAttributes, out CVReturn status) { IntPtr handle; GCHandle gchandle; if (data == null) { throw new ArgumentNullException(nameof(data)); } if (data.Length < height * bytesPerRow) { throw new ArgumentOutOfRangeException(nameof(data), "The length of data is smaller than height * bytesPerRow"); } gchandle = GCHandle.Alloc(data, GCHandleType.Pinned); status = CVPixelBufferCreateWithBytes(IntPtr.Zero, width, height, pixelFormatType, gchandle.AddrOfPinnedObject(), bytesPerRow, releaseBytesCallback, GCHandle.ToIntPtr(gchandle), DictionaryContainerHelper.GetHandle(pixelBufferAttributes), out handle); if (status != CVReturn.Success) { gchandle.Free(); return(null); } return(new CVPixelBuffer(handle, true)); }