Пример #1
0
		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);
		}
Пример #2
0
		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);
		}
Пример #3
0
        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));
        }