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