/ src / Ryujinx.Graphics.Nvdec / H264Decoder.cs
H264Decoder.cs
 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  
 7  namespace Ryujinx.Graphics.Nvdec
 8  {
 9      static class H264Decoder
10      {
11          private const int MbSizeInPixels = 16;
12  
13          public static void Decode(NvdecDecoderContext context, ResourceManager rm, ref NvdecRegisters state)
14          {
15              PictureInfo pictureInfo = rm.MemoryManager.DeviceRead<PictureInfo>(state.SetDrvPicSetupOffset);
16              H264PictureInfo info = pictureInfo.Convert();
17  
18              ReadOnlySpan<byte> bitstream = rm.MemoryManager.DeviceGetSpan(state.SetInBufBaseOffset, (int)pictureInfo.BitstreamSize);
19  
20              int width = (int)pictureInfo.PicWidthInMbs * MbSizeInPixels;
21              int height = (int)pictureInfo.PicHeightInMbs * MbSizeInPixels;
22  
23              int surfaceIndex = (int)pictureInfo.OutputSurfaceIndex;
24  
25              uint lumaOffset = state.SetPictureLumaOffset[surfaceIndex];
26              uint chromaOffset = state.SetPictureChromaOffset[surfaceIndex];
27  
28              Decoder decoder = context.GetH264Decoder();
29  
30              ISurface outputSurface = rm.Cache.Get(decoder, 0, 0, width, height);
31  
32              if (decoder.Decode(ref info, outputSurface, bitstream))
33              {
34                  if (outputSurface.Field == FrameField.Progressive)
35                  {
36                      SurfaceWriter.Write(
37                          rm.MemoryManager,
38                          outputSurface,
39                          lumaOffset + pictureInfo.LumaFrameOffset,
40                          chromaOffset + pictureInfo.ChromaFrameOffset);
41                  }
42                  else
43                  {
44                      SurfaceWriter.WriteInterlaced(
45                          rm.MemoryManager,
46                          outputSurface,
47                          lumaOffset + pictureInfo.LumaTopFieldOffset,
48                          chromaOffset + pictureInfo.ChromaTopFieldOffset,
49                          lumaOffset + pictureInfo.LumaBottomFieldOffset,
50                          chromaOffset + pictureInfo.ChromaBottomFieldOffset);
51                  }
52              }
53  
54              rm.Cache.Put(outputSurface);
55          }
56      }
57  }