Esempio n. 1
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);
        }
Esempio n. 2
0
        public unsafe void FrameArrivedHost(FrameInformation frame)
        {
            var rgbSize     = frame.GetRgba32Size();
            var width       = frame.Info.Width;
            var rgba32Pitch = width * 4;
            var buffer      = _swap.GetBackBuffer <Texture2D>(0);

            // TODO: Pool the buffer.
            var destHost = new byte[rgbSize];

            fixed(byte *destHostPtr = destHost)
            {
                _device.ImmediateContext.UpdateSubresource(
                    buffer, 0, null, (IntPtr)destHostPtr, rgba32Pitch, 0);
            }

            _swap?.Present(1, PresentFlags.None);
        }
Esempio n. 3
0
        private static void SaveAsBitmap(
            FrameInformation frame,
            string filename)
        {
            var width  = frame.Info.Width;
            var height = frame.Info.Height;

            using var bitmap = new Bitmap(
                      width, height,
                      PixelFormat.Format32bppRgb);

            var locked = bitmap.LockBits(
                new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                ImageLockMode.WriteOnly, bitmap.PixelFormat);

            frame.DecodeToHostRgba32((byte *)locked.Scan0);

            bitmap.UnlockBits(locked);
            bitmap.Save(filename, ImageFormat.Bmp);
        }
Esempio n. 4
0
        public void FrameArrived(FrameInformation frame)
        {
            if (_disposed)
            {
                return;
            }

            using var _ = _context.Push();

            // TODO: This does need to detect configuration changes.
            // https://en.wikipedia.org/wiki/Double-checked_locking
            if (!_hasSwap)
            {
                lock (_createdSwapSync)
                {
                    if (!_hasSwap)
                    {
                        CreateSwap(frame);
                        _hasSwap = true;
                    }
                }
            }

            switch (frame.Buffer.MemoryType)
            {
            case CuMemoryType.Host:
                FrameArrivedHost(frame);
                break;

            case CuMemoryType.Device:
                FrameArrivedDevice(frame);
                break;

            default:
                throw new ArgumentOutOfRangeException(
                          nameof(frame.Buffer.MemoryType),
                          frame.Buffer.MemoryType,
                          "Unsupported memory type.");
            }
        }
Esempio n. 5
0
        private void CreateSwap(FrameInformation frame)
        {
            var sc = new SwapChainDescription
            {
                BufferCount     = 1,
                ModeDescription = new ModeDescription(
                    frame.Info.Width, frame.Info.Height,
                    new Rational(30, 1), Format.B8G8R8A8_UNorm),
                IsWindowed        = true,
                OutputHandle      = Hwnd,
                SampleDescription = new SampleDescription(1, 0),
                Usage             = Usage.RenderTargetOutput,
                Flags             = SwapChainFlags.None
            };

            Device.CreateWithSwapChain(
                _adapter, DeviceCreationFlags.Debug,
                sc, out _device, out _swap);

            var buffer = _swap.GetBackBuffer <Texture2D>(0);

            _resource = CuGraphicsResource.Register(buffer.NativePointer);
            _resource.SetMapFlags(CuGraphicsMapResources.WriteDiscard);
        }
Esempio n. 6
0
        private CuCallbackResult VideoDisplayCallback(
            IntPtr data, IntPtr infoPtr)
        {
            using var _ = _context.Push();

            if (CuVideoParseDisplayInfo.IsFinalFrame(infoPtr, out var info))
            {
                if (!_framesChannel.Writer.TryWrite(
                        FrameInformation.FinalFrame))
                {
                    _renderingCompleted.Set();
                }

                return(CuCallbackResult.Success);
            }

            var processingParam = new CuVideoProcParams
            {
                ProgressiveFrame = info.ProgressiveFrame,
                SecondField      = info.RepeatFirstField + 1,
                TopFieldFirst    = info.TopFieldFirst,
                UnpairedField    = info.RepeatFirstField < 0 ? 1 : 0
            };

            using var frame = _decoder.MapVideoFrame(
                      info.PictureIndex, ref processingParam,
                      out var pitch);

            var yuvInfo = _info.GetYuvInformation(pitch);
            var status  = _decoder.GetDecodeStatus(info.PictureIndex);

            if (status != CuVideoDecodeStatus.Success)
            {
                // TODO: Determine what to do in this situation. This condition
                // is non-exceptional but may require different handling?
            }

            var frameByteSize = _info.GetFrameByteSize(
                pitch, out var chromaHeight);

            var destMemoryType = _useHostMemory
                ? CuMemoryType.Host
                : CuMemoryType.Device;

            AllocateNv12FrameBuffer(
                destMemoryType, frameByteSize,
                out var frameDevicePtr, out var frameLocalPtr);

            var byteWidth = _info.Width * _info.GetBytesPerPixel();

            // Copy luma
            var memcopy = new CuMemcopy2D
            {
                SrcMemoryType = CuMemoryType.Device,
                SrcDevice     = frame,
                SrcPitch      = (IntPtr)pitch,
                DstMemoryType = destMemoryType,
                DstDevice     = frameDevicePtr,
                DstHost       = frameLocalPtr,
                DstPitch      = (IntPtr)byteWidth,
                WidthInBytes  = (IntPtr)byteWidth,
                Height        = (IntPtr)_info.Height
            };

            memcopy.Memcpy2D();

            // Copy chroma
            memcopy.SrcDevice = new CuDevicePtr(frame.Handle + pitch * _info.Height);
            memcopy.DstDevice = new CuDevicePtr(frameDevicePtr.Handle + byteWidth * _info.Height);
            memcopy.DstHost   = frameLocalPtr + byteWidth * _info.Height;
            memcopy.Height    = (IntPtr)chromaHeight;
            memcopy.Memcpy2D();

            var bufferStorage = new BufferStorage(
                frameLocalPtr, destMemoryType,
                frameDevicePtr, frameByteSize);

            var frameInfo = new FrameInformation(
                bufferStorage, pitch, _info, yuvInfo);

            if (!_framesChannel.Writer.TryWrite(frameInfo))
            {
                _nv12BufferPool.Free(ref bufferStorage);
            }

            return(CuCallbackResult.Success);
        }