mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2025-06-28 13:50:46 -07:00
Support NVDEC H264 interlaced video decoding and VIC deinterlacing (#3225)
* Support NVDEC H264 interlaced video decoding and VIC deinterlacing * Remove unused code
This commit is contained in:
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user