예제 #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);
        }
예제 #2
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);
        }