private void AllocateNv12FrameBuffer( CuMemoryType type, IntPtr frameByteSize, out CuDeviceMemory frameDevicePtr, out IntPtr frameLocalPtr) { frameDevicePtr = default; frameLocalPtr = default; var pooled = _nv12BufferPool.Get(); if (pooled != null) { // Only use exact size matches to allow memory reduction when // sizing down. if (pooled.Size == frameByteSize && pooled.MemoryType == type) { frameLocalPtr = pooled.Bytes; frameDevicePtr = pooled.DeviceMemory; return; } // The memory type or size has changed. Deallocate the old // buffer and allocate new. pooled.Dispose(); } if (type == CuMemoryType.Host) { frameLocalPtr = Marshal.AllocHGlobal(frameByteSize); return; } frameDevicePtr = CuDeviceMemory.Allocate(frameByteSize); }
public unsafe void DecodeToHostRgba32(byte *destinationPtr) { var width = Info.Width; var height = Info.Height; var buffer = Buffer; const int rgbBpp = 4; var rgbSize = GetRgba32Size(); switch (buffer.MemoryType) { case CuMemoryType.Host: LibYuvSharp.LibYuv.NV12ToARGB( (byte *)buffer.Bytes, YuvInfo.LumaPitch, (byte *)buffer.Bytes + YuvInfo.ChromaOffset, YuvInfo.ChromaPitch, destinationPtr, width * rgbBpp, width, height); break; case CuMemoryType.Device: using (var destPtr = CuDeviceMemory.Allocate(rgbSize)) { LibCudaLibrary.Nv12ToBGRA32( buffer.DeviceMemory.Handle, width, destPtr, width * rgbBpp, width, height); destPtr.CopyToHost(destinationPtr, rgbSize); } break; default: throw new ArgumentOutOfRangeException(nameof(buffer.MemoryType)); } }
public void FrameArrivedDevice(FrameInformation frame) { using var _ = _resource.Map(); var resourceArray = _resource.GetMappedArray(); var rgbSize = frame.GetRgba32Size(); var width = frame.Info.Width; var rgba32Pitch = width * 4; var rgba32PitchPtr = (IntPtr)rgba32Pitch; using (var destPtr = CuDeviceMemory.Allocate(rgbSize)) { frame.DecodeToDeviceRgba32(destPtr); var memcopy = new CuMemcopy2D { SrcMemoryType = CuMemoryType.Device, SrcDevice = destPtr, SrcPitch = rgba32PitchPtr, DstMemoryType = CuMemoryType.Array, DstArray = resourceArray, WidthInBytes = rgba32PitchPtr, Height = (IntPtr)frame.Info.Height }; memcopy.Memcpy2D(); } _swap?.Present(1, PresentFlags.None); }
public void DecodeToDeviceRgba32( IntPtr destinationPtr, Size?resize = null) { var width = Info.Width; var height = Info.Height; var buffer = Buffer; const int rgbBpp = 4; var source = buffer.DeviceMemory; var hasNewSource = false; try { // This code path does not appear to properly resize the // window. if (resize.HasValue) { var newWidth = resize.Value.Width; var newHeight = resize.Value.Height; // This buffer size allocation is incorrect but should be // oversized enough to be fine. source = CuDeviceMemory.Allocate( newWidth * newHeight * rgbBpp); hasNewSource = true; LibCudaLibrary.ResizeNv12( source, newWidth, newWidth, newHeight, buffer.DeviceMemory, Pitch, width, height, CuDevicePtr.Empty); width = newWidth; height = newHeight; } switch (buffer.MemoryType) { case CuMemoryType.Device: LibCudaLibrary.Nv12ToBGRA32( source, width, destinationPtr, width * rgbBpp, width, height); break; default: throw new ArgumentOutOfRangeException( nameof(buffer.MemoryType), buffer.MemoryType, "Unsupported memory type."); } } finally { if (hasNewSource) { source.Dispose(); } } }