H264Decoder.cs 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. using Ryujinx.Graphics.Nvdec.H264;
  2. using Ryujinx.Graphics.Nvdec.Image;
  3. using Ryujinx.Graphics.Nvdec.Types.H264;
  4. using Ryujinx.Graphics.Video;
  5. using System;
  6. namespace Ryujinx.Graphics.Nvdec
  7. {
  8. static class H264Decoder
  9. {
  10. private const int MbSizeInPixels = 16;
  11. private static readonly Decoder _decoder = new Decoder();
  12. public unsafe static void Decode(NvdecDevice device, ResourceManager rm, ref NvdecRegisters state)
  13. {
  14. PictureInfo pictureInfo = rm.Gmm.DeviceRead<PictureInfo>(state.SetPictureInfoOffset);
  15. H264PictureInfo info = pictureInfo.Convert();
  16. ReadOnlySpan<byte> bitstream = rm.Gmm.DeviceGetSpan(state.SetBitstreamOffset, (int)pictureInfo.BitstreamSize);
  17. int width = (int)pictureInfo.PicWidthInMbs * MbSizeInPixels;
  18. int height = (int)pictureInfo.PicHeightInMbs * MbSizeInPixels;
  19. ISurface outputSurface = rm.Cache.Get(_decoder, CodecId.H264, 0, 0, width, height);
  20. if (_decoder.Decode(ref info, outputSurface, bitstream))
  21. {
  22. int li = (int)pictureInfo.LumaOutputSurfaceIndex;
  23. int ci = (int)pictureInfo.ChromaOutputSurfaceIndex;
  24. uint lumaOffset = state.SetSurfaceLumaOffset[li];
  25. uint chromaOffset = state.SetSurfaceChromaOffset[ci];
  26. SurfaceWriter.Write(rm.Gmm, outputSurface, lumaOffset, chromaOffset);
  27. device.OnFrameDecoded(CodecId.H264, lumaOffset, chromaOffset);
  28. }
  29. rm.Cache.Put(outputSurface);
  30. }
  31. }
  32. }