H264Decoder.cs 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. using Ryujinx.Graphics.Nvdec.FFmpeg.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. public static void Decode(NvdecDecoderContext context, ResourceManager rm, ref NvdecRegisters state)
  12. {
  13. PictureInfo pictureInfo = rm.Gmm.DeviceRead<PictureInfo>(state.SetPictureInfoOffset);
  14. H264PictureInfo info = pictureInfo.Convert();
  15. ReadOnlySpan<byte> bitstream = rm.Gmm.DeviceGetSpan(state.SetBitstreamOffset, (int)pictureInfo.BitstreamSize);
  16. int width = (int)pictureInfo.PicWidthInMbs * MbSizeInPixels;
  17. int height = (int)pictureInfo.PicHeightInMbs * MbSizeInPixels;
  18. int surfaceIndex = (int)pictureInfo.OutputSurfaceIndex;
  19. uint lumaOffset = state.SetSurfaceLumaOffset[surfaceIndex];
  20. uint chromaOffset = state.SetSurfaceChromaOffset[surfaceIndex];
  21. Decoder decoder = context.GetH264Decoder();
  22. ISurface outputSurface = rm.Cache.Get(decoder, 0, 0, width, height);
  23. if (decoder.Decode(ref info, outputSurface, bitstream))
  24. {
  25. if (outputSurface.Field == FrameField.Progressive)
  26. {
  27. SurfaceWriter.Write(
  28. rm.Gmm,
  29. outputSurface,
  30. lumaOffset + pictureInfo.LumaFrameOffset,
  31. chromaOffset + pictureInfo.ChromaFrameOffset);
  32. }
  33. else
  34. {
  35. SurfaceWriter.WriteInterlaced(
  36. rm.Gmm,
  37. outputSurface,
  38. lumaOffset + pictureInfo.LumaTopFieldOffset,
  39. chromaOffset + pictureInfo.ChromaTopFieldOffset,
  40. lumaOffset + pictureInfo.LumaBottomFieldOffset,
  41. chromaOffset + pictureInfo.ChromaBottomFieldOffset);
  42. }
  43. }
  44. rm.Cache.Put(outputSurface);
  45. }
  46. }
  47. }