Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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));
            }
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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();
                }
            }
        }