Beispiel #1
0
        public static void Decode(NvdecDecoderContext context, ResourceManager rm, ref NvdecRegisters state)
        {
            PictureInfo     pictureInfo = rm.Gmm.DeviceRead <PictureInfo>(state.SetPictureInfoOffset);
            H264PictureInfo info        = pictureInfo.Convert();

            ReadOnlySpan <byte> bitstream = rm.Gmm.DeviceGetSpan(state.SetBitstreamOffset, (int)pictureInfo.BitstreamSize);

            int width  = (int)pictureInfo.PicWidthInMbs * MbSizeInPixels;
            int height = (int)pictureInfo.PicHeightInMbs * MbSizeInPixels;

            int surfaceIndex = (int)pictureInfo.OutputSurfaceIndex;

            uint lumaOffset   = state.SetSurfaceLumaOffset[surfaceIndex];
            uint chromaOffset = state.SetSurfaceChromaOffset[surfaceIndex];

            Decoder decoder = context.GetH264Decoder();

            ISurface outputSurface = rm.Cache.Get(decoder, 0, 0, width, height);

            if (decoder.Decode(ref info, outputSurface, bitstream))
            {
                SurfaceWriter.Write(rm.Gmm, outputSurface, lumaOffset, chromaOffset);
            }

            rm.Cache.Put(outputSurface);
        }
Beispiel #2
0
        public unsafe static void Decode(NvdecDevice device, ResourceManager rm, ref NvdecRegisters state)
        {
            PictureInfo     pictureInfo = rm.Gmm.DeviceRead <PictureInfo>(state.SetPictureInfoOffset);
            H264PictureInfo info        = pictureInfo.Convert();

            ReadOnlySpan <byte> bitstream = rm.Gmm.DeviceGetSpan(state.SetBitstreamOffset, (int)pictureInfo.BitstreamSize);

            int width  = (int)pictureInfo.PicWidthInMbs * MbSizeInPixels;
            int height = (int)pictureInfo.PicHeightInMbs * MbSizeInPixels;

            ISurface outputSurface = rm.Cache.Get(_decoder, CodecId.H264, 0, 0, width, height);

            if (_decoder.Decode(ref info, outputSurface, bitstream))
            {
                int li = (int)pictureInfo.LumaOutputSurfaceIndex;
                int ci = (int)pictureInfo.ChromaOutputSurfaceIndex;

                uint lumaOffset   = state.SetSurfaceLumaOffset[li];
                uint chromaOffset = state.SetSurfaceChromaOffset[ci];

                SurfaceWriter.Write(rm.Gmm, outputSurface, lumaOffset, chromaOffset);

                device.OnFrameDecoded(CodecId.H264, lumaOffset, chromaOffset);
            }

            rm.Cache.Put(outputSurface);
        }
Beispiel #3
0
        public bool Decode(ref H264PictureInfo pictureInfo, ISurface output, ReadOnlySpan <byte> bitstream)
        {
            Surface outSurf = (Surface)output;

            if (outSurf.RequestedWidth != _oldOutputWidth ||
                outSurf.RequestedHeight != _oldOutputHeight)
            {
                _context.Dispose();
                _context = new FFmpegContext(AVCodecID.AV_CODEC_ID_H264);

                _oldOutputWidth  = outSurf.RequestedWidth;
                _oldOutputHeight = outSurf.RequestedHeight;
            }

            Span <byte> bs = Prepend(bitstream, SpsAndPpsReconstruction.Reconstruct(ref pictureInfo, _workBuffer));

            return(_context.DecodeFrame(outSurf, bs) == 0);
        }
        public static Span <byte> Reconstruct(ref H264PictureInfo pictureInfo, byte[] workBuffer)
        {
            H264BitStreamWriter writer = new H264BitStreamWriter(workBuffer);

            // Sequence Parameter Set.
            writer.WriteU(1, 24);
            writer.WriteU(0, 1);
            writer.WriteU(3, 2);
            writer.WriteU(7, 5);
            writer.WriteU(100, 8); // Profile idc
            writer.WriteU(0, 8);   // Reserved
            writer.WriteU(31, 8);  // Level idc
            writer.WriteUe(0);     // Seq parameter set id
            writer.WriteUe(pictureInfo.ChromaFormatIdc);

            if (pictureInfo.ChromaFormatIdc == 3)
            {
                writer.WriteBit(false); // Separate colour plane flag
            }

            writer.WriteUe(0);      // Bit depth luma minus 8
            writer.WriteUe(0);      // Bit depth chroma minus 8
            writer.WriteBit(pictureInfo.QpprimeYZeroTransformBypassFlag);
            writer.WriteBit(false); // Scaling matrix present flag

            writer.WriteUe(pictureInfo.Log2MaxFrameNumMinus4);
            writer.WriteUe(pictureInfo.PicOrderCntType);

            if (pictureInfo.PicOrderCntType == 0)
            {
                writer.WriteUe(pictureInfo.Log2MaxPicOrderCntLsbMinus4);
            }
            else if (pictureInfo.PicOrderCntType == 1)
            {
                writer.WriteBit(pictureInfo.DeltaPicOrderAlwaysZeroFlag);

                writer.WriteSe(0); // Offset for non-ref pic
                writer.WriteSe(0); // Offset for top to bottom field
                writer.WriteUe(0); // Num ref frames in pic order cnt cycle
            }

            writer.WriteUe(16);     // Max num ref frames
            writer.WriteBit(false); // Gaps in frame num value allowed flag
            writer.WriteUe(pictureInfo.PicWidthInMbsMinus1);
            writer.WriteUe(pictureInfo.PicHeightInMapUnitsMinus1);
            writer.WriteBit(pictureInfo.FrameMbsOnlyFlag);

            if (!pictureInfo.FrameMbsOnlyFlag)
            {
                writer.WriteBit(pictureInfo.MbAdaptiveFrameFieldFlag);
            }

            writer.WriteBit(pictureInfo.Direct8x8InferenceFlag);
            writer.WriteBit(false); // Frame cropping flag
            writer.WriteBit(false); // VUI parameter present flag

            writer.End();

            // Picture Parameter Set.
            writer.WriteU(1, 24);
            writer.WriteU(0, 1);
            writer.WriteU(3, 2);
            writer.WriteU(8, 5);

            writer.WriteUe(0); // Pic parameter set id
            writer.WriteUe(0); // Seq parameter set id

            writer.WriteBit(pictureInfo.EntropyCodingModeFlag);
            writer.WriteBit(pictureInfo.PicOrderPresentFlag);
            writer.WriteUe(0); // Num slice groups minus 1
            writer.WriteUe(pictureInfo.NumRefIdxL0ActiveMinus1);
            writer.WriteUe(pictureInfo.NumRefIdxL1ActiveMinus1);
            writer.WriteBit(pictureInfo.WeightedPredFlag);
            writer.WriteU(pictureInfo.WeightedBipredIdc, 2);
            writer.WriteSe(pictureInfo.PicInitQpMinus26);
            writer.WriteSe(0); // Pic init qs minus 26
            writer.WriteSe(pictureInfo.ChromaQpIndexOffset);
            writer.WriteBit(pictureInfo.DeblockingFilterControlPresentFlag);
            writer.WriteBit(pictureInfo.ConstrainedIntraPredFlag);
            writer.WriteBit(pictureInfo.RedundantPicCntPresentFlag);
            writer.WriteBit(pictureInfo.Transform8x8ModeFlag);

            writer.WriteBit(pictureInfo.ScalingMatrixPresent);

            if (pictureInfo.ScalingMatrixPresent)
            {
                for (int index = 0; index < 6; index++)
                {
                    writer.WriteBit(true);

                    WriteScalingList(ref writer, pictureInfo.ScalingLists4x4[index]);
                }

                if (pictureInfo.Transform8x8ModeFlag)
                {
                    for (int index = 0; index < 2; index++)
                    {
                        writer.WriteBit(true);

                        WriteScalingList(ref writer, pictureInfo.ScalingLists8x8[index]);
                    }
                }
            }

            writer.WriteSe(pictureInfo.SecondChromaQpIndexOffset);

            writer.End();

            return(writer.AsSpan());
        }
Beispiel #5
0
        public bool Decode(ref H264PictureInfo pictureInfo, ISurface output, ReadOnlySpan <byte> bitstream)
        {
            Span <byte> bs = Prepend(bitstream, SpsAndPpsReconstruction.Reconstruct(ref pictureInfo, _workBuffer));

            return(_context.DecodeFrame((Surface)output, bs) == 0);
        }