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); }
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); }