diff options
Diffstat (limited to 'Ryujinx.Graphics.Nvdec')
-rw-r--r-- | Ryujinx.Graphics.Nvdec/H264Decoder.cs | 19 | ||||
-rw-r--r-- | Ryujinx.Graphics.Nvdec/Image/SurfaceWriter.cs | 49 | ||||
-rw-r--r-- | Ryujinx.Graphics.Nvdec/Types/H264/PictureInfo.cs | 6 |
3 files changed, 70 insertions, 4 deletions
diff --git a/Ryujinx.Graphics.Nvdec/H264Decoder.cs b/Ryujinx.Graphics.Nvdec/H264Decoder.cs index 69eeb494..6efeb899 100644 --- a/Ryujinx.Graphics.Nvdec/H264Decoder.cs +++ b/Ryujinx.Graphics.Nvdec/H264Decoder.cs @@ -31,7 +31,24 @@ namespace Ryujinx.Graphics.Nvdec if (decoder.Decode(ref info, outputSurface, bitstream)) { - SurfaceWriter.Write(rm.Gmm, outputSurface, lumaOffset, chromaOffset); + if (outputSurface.Field == FrameField.Progressive) + { + SurfaceWriter.Write( + rm.Gmm, + outputSurface, + lumaOffset + pictureInfo.LumaFrameOffset, + chromaOffset + pictureInfo.ChromaFrameOffset); + } + else + { + SurfaceWriter.WriteInterlaced( + rm.Gmm, + outputSurface, + lumaOffset + pictureInfo.LumaTopFieldOffset, + chromaOffset + pictureInfo.ChromaTopFieldOffset, + lumaOffset + pictureInfo.LumaBottomFieldOffset, + chromaOffset + pictureInfo.ChromaBottomFieldOffset); + } } rm.Cache.Put(outputSurface); diff --git a/Ryujinx.Graphics.Nvdec/Image/SurfaceWriter.cs b/Ryujinx.Graphics.Nvdec/Image/SurfaceWriter.cs index 5c294621..cc5c251b 100644 --- a/Ryujinx.Graphics.Nvdec/Image/SurfaceWriter.cs +++ b/Ryujinx.Graphics.Nvdec/Image/SurfaceWriter.cs @@ -38,6 +38,55 @@ namespace Ryujinx.Graphics.Nvdec.Image surface.UvHeight); } + public static void WriteInterlaced( + MemoryManager gmm, + ISurface surface, + uint lumaTopOffset, + uint chromaTopOffset, + uint lumaBottomOffset, + uint chromaBottomOffset) + { + int lumaSize = GetBlockLinearSize(surface.Width, surface.Height / 2, 1); + + using var lumaTop = gmm.GetWritableRegion(ExtendOffset(lumaTopOffset), lumaSize); + using var lumaBottom = gmm.GetWritableRegion(ExtendOffset(lumaBottomOffset), lumaSize); + + WriteLuma( + lumaTop.Memory.Span, + surface.YPlane.AsSpan(), + surface.Stride * 2, + surface.Width, + surface.Height / 2); + + WriteLuma( + lumaBottom.Memory.Span, + surface.YPlane.AsSpan().Slice(surface.Stride), + surface.Stride * 2, + surface.Width, + surface.Height / 2); + + int chromaSize = GetBlockLinearSize(surface.UvWidth, surface.UvHeight / 2, 2); + + using var chromaTop = gmm.GetWritableRegion(ExtendOffset(chromaTopOffset), chromaSize); + using var chromaBottom = gmm.GetWritableRegion(ExtendOffset(chromaBottomOffset), chromaSize); + + WriteChroma( + chromaTop.Memory.Span, + surface.UPlane.AsSpan(), + surface.VPlane.AsSpan(), + surface.UvStride * 2, + surface.UvWidth, + surface.UvHeight / 2); + + WriteChroma( + chromaBottom.Memory.Span, + surface.UPlane.AsSpan().Slice(surface.UvStride), + surface.VPlane.AsSpan().Slice(surface.UvStride), + surface.UvStride * 2, + surface.UvWidth, + surface.UvHeight / 2); + } + private static void WriteLuma(Span<byte> dst, ReadOnlySpan<byte> src, int srcStride, int width, int height) { LayoutConverter.ConvertLinearToBlockLinear(dst, width, height, srcStride, 1, 2, src); diff --git a/Ryujinx.Graphics.Nvdec/Types/H264/PictureInfo.cs b/Ryujinx.Graphics.Nvdec/Types/H264/PictureInfo.cs index 326c40ae..7c779dff 100644 --- a/Ryujinx.Graphics.Nvdec/Types/H264/PictureInfo.cs +++ b/Ryujinx.Graphics.Nvdec/Types/H264/PictureInfo.cs @@ -26,10 +26,10 @@ namespace Ryujinx.Graphics.Nvdec.Types.H264 public uint Transform8x8ModeFlag; public uint LumaPitch; public uint ChromaPitch; - public uint LumaTopOffset; - public uint LumaBottomOffset; + public uint LumaTopFieldOffset; + public uint LumaBottomFieldOffset; public uint LumaFrameOffset; - public uint ChromaTopOffset; + public uint ChromaTopFieldOffset; public uint ChromaBottomFieldOffset; public uint ChromaFrameOffset; public uint HistBufferSize; |