From 4d02a2d2c0451b4de1f6de3bbce54c457cacebe2 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sun, 12 Jul 2020 00:07:01 -0300 Subject: New NVDEC and VIC implementation (#1384) * Initial NVDEC and VIC implementation * Update FFmpeg.AutoGen to 4.3.0 * Add nvdec dependencies for Windows * Unify some VP9 structures * Rename VP9 structure fields * Improvements to Video API * XML docs for Common.Memory * Remove now unused or redundant overloads from MemoryAccessor * NVDEC UV surface read/write scalar paths * Add FIXME comments about hacky things/stuff that will need to be fixed in the future * Cleaned up VP9 memory allocation * Remove some debug logs * Rename some VP9 structs * Remove unused struct * No need to compile Ryujinx.Graphics.Host1x with unsafe anymore * Name AsyncWorkQueue threads to make debugging easier * Make Vp9PictureInfo a ref struct * LayoutConverter no longer needs the depth argument (broken by rebase) * Pooling of VP9 buffers, plus fix a memory leak on VP9 * Really wish VS could rename projects properly... * Address feedback * Remove using * Catch OperationCanceledException * Add licensing informations * Add THIRDPARTY.md to release too Co-authored-by: Thog --- Ryujinx.Graphics.Video/H264PictureInfo.cs | 47 ++++++++++++++++++++++ Ryujinx.Graphics.Video/IDecoder.cs | 11 +++++ Ryujinx.Graphics.Video/IH264Decoder.cs | 9 +++++ Ryujinx.Graphics.Video/ISurface.cs | 18 +++++++++ Ryujinx.Graphics.Video/IVp9Decoder.cs | 14 +++++++ Ryujinx.Graphics.Video/Plane.cs | 42 +++++++++++++++++++ .../Ryujinx.Graphics.Video.csproj | 11 +++++ Ryujinx.Graphics.Video/Vp9BackwardUpdates.cs | 32 +++++++++++++++ Ryujinx.Graphics.Video/Vp9EntropyProbs.cs | 36 +++++++++++++++++ Ryujinx.Graphics.Video/Vp9Mv.cs | 8 ++++ Ryujinx.Graphics.Video/Vp9MvRef.cs | 11 +++++ Ryujinx.Graphics.Video/Vp9PictureInfo.cs | 39 ++++++++++++++++++ 12 files changed, 278 insertions(+) create mode 100644 Ryujinx.Graphics.Video/H264PictureInfo.cs create mode 100644 Ryujinx.Graphics.Video/IDecoder.cs create mode 100644 Ryujinx.Graphics.Video/IH264Decoder.cs create mode 100644 Ryujinx.Graphics.Video/ISurface.cs create mode 100644 Ryujinx.Graphics.Video/IVp9Decoder.cs create mode 100644 Ryujinx.Graphics.Video/Plane.cs create mode 100644 Ryujinx.Graphics.Video/Ryujinx.Graphics.Video.csproj create mode 100644 Ryujinx.Graphics.Video/Vp9BackwardUpdates.cs create mode 100644 Ryujinx.Graphics.Video/Vp9EntropyProbs.cs create mode 100644 Ryujinx.Graphics.Video/Vp9Mv.cs create mode 100644 Ryujinx.Graphics.Video/Vp9MvRef.cs create mode 100644 Ryujinx.Graphics.Video/Vp9PictureInfo.cs (limited to 'Ryujinx.Graphics.Video') diff --git a/Ryujinx.Graphics.Video/H264PictureInfo.cs b/Ryujinx.Graphics.Video/H264PictureInfo.cs new file mode 100644 index 00000000..3b2c2fff --- /dev/null +++ b/Ryujinx.Graphics.Video/H264PictureInfo.cs @@ -0,0 +1,47 @@ +using Ryujinx.Common.Memory; + +namespace Ryujinx.Graphics.Video +{ + public struct H264PictureInfo + { + public Array2 FieldOrderCnt; + public bool IsReference; + public ushort ChromaFormatIdc; + public ushort FrameNum; + public bool FieldPicFlag; + public bool BottomFieldFlag; + public uint NumRefFrames; + public bool MbAdaptiveFrameFieldFlag; + public bool ConstrainedIntraPredFlag; + public bool WeightedPredFlag; + public uint WeightedBipredIdc; + public bool FrameMbsOnlyFlag; + public bool Transform8x8ModeFlag; + public int ChromaQpIndexOffset; + public int SecondChromaQpIndexOffset; + public int PicInitQpMinus26; + public uint NumRefIdxL0ActiveMinus1; + public uint NumRefIdxL1ActiveMinus1; + public uint Log2MaxFrameNumMinus4; + public uint PicOrderCntType; + public uint Log2MaxPicOrderCntLsbMinus4; + public bool DeltaPicOrderAlwaysZeroFlag; + public bool Direct8x8InferenceFlag; + public bool EntropyCodingModeFlag; + public bool PicOrderPresentFlag; + public bool DeblockingFilterControlPresentFlag; + public bool RedundantPicCntPresentFlag; + public uint NumSliceGroupsMinus1; + public uint SliceGroupMapType; + public uint SliceGroupChangeRateMinus1; + // TODO: Slice group map + public bool FmoAsoEnable; + public bool ScalingMatrixPresent; + public Array6> ScalingLists4x4; + public Array2> ScalingLists8x8; + public uint FrameType; + public uint PicWidthInMbsMinus1; + public uint PicHeightInMapUnitsMinus1; + public bool QpprimeYZeroTransformBypassFlag; + } +} diff --git a/Ryujinx.Graphics.Video/IDecoder.cs b/Ryujinx.Graphics.Video/IDecoder.cs new file mode 100644 index 00000000..5957af08 --- /dev/null +++ b/Ryujinx.Graphics.Video/IDecoder.cs @@ -0,0 +1,11 @@ +using System; + +namespace Ryujinx.Graphics.Video +{ + public interface IDecoder : IDisposable + { + bool IsHardwareAccelerated { get; } + + ISurface CreateSurface(int width, int height); + } +} diff --git a/Ryujinx.Graphics.Video/IH264Decoder.cs b/Ryujinx.Graphics.Video/IH264Decoder.cs new file mode 100644 index 00000000..127b9412 --- /dev/null +++ b/Ryujinx.Graphics.Video/IH264Decoder.cs @@ -0,0 +1,9 @@ +using System; + +namespace Ryujinx.Graphics.Video +{ + public interface IH264Decoder : IDecoder + { + bool Decode(ref H264PictureInfo pictureInfo, ISurface output, ReadOnlySpan bitstream); + } +} diff --git a/Ryujinx.Graphics.Video/ISurface.cs b/Ryujinx.Graphics.Video/ISurface.cs new file mode 100644 index 00000000..fb66f31a --- /dev/null +++ b/Ryujinx.Graphics.Video/ISurface.cs @@ -0,0 +1,18 @@ +using System; + +namespace Ryujinx.Graphics.Video +{ + public interface ISurface : IDisposable + { + Plane YPlane { get; } + Plane UPlane { get; } + Plane VPlane { get; } + + int Width { get; } + int Height { get; } + int Stride { get; } + int UvWidth { get; } + int UvHeight { get; } + int UvStride { get; } + } +} diff --git a/Ryujinx.Graphics.Video/IVp9Decoder.cs b/Ryujinx.Graphics.Video/IVp9Decoder.cs new file mode 100644 index 00000000..ac79bc42 --- /dev/null +++ b/Ryujinx.Graphics.Video/IVp9Decoder.cs @@ -0,0 +1,14 @@ +using System; + +namespace Ryujinx.Graphics.Video +{ + public interface IVp9Decoder : IDecoder + { + bool Decode( + ref Vp9PictureInfo pictureInfo, + ISurface output, + ReadOnlySpan bitstream, + ReadOnlySpan mvsIn, + Span mvsOut); + } +} diff --git a/Ryujinx.Graphics.Video/Plane.cs b/Ryujinx.Graphics.Video/Plane.cs new file mode 100644 index 00000000..c0aca59c --- /dev/null +++ b/Ryujinx.Graphics.Video/Plane.cs @@ -0,0 +1,42 @@ +using System; +using System.Diagnostics.CodeAnalysis; + +namespace Ryujinx.Graphics.Video +{ + public struct Plane : IEquatable + { + public IntPtr Pointer { get; } + public int Length { get; } + + public Plane(IntPtr pointer, int length) + { + Pointer = pointer; + Length = length; + } + + public override bool Equals(object obj) + { + return obj is Plane other && Equals(other); + } + + public bool Equals([AllowNull] Plane other) + { + return Pointer == other.Pointer && Length == other.Length; + } + + public override int GetHashCode() + { + return HashCode.Combine(Pointer, Length); + } + + public static bool operator ==(Plane left, Plane right) + { + return left.Equals(right); + } + + public static bool operator !=(Plane left, Plane right) + { + return !(left == right); + } + } +} diff --git a/Ryujinx.Graphics.Video/Ryujinx.Graphics.Video.csproj b/Ryujinx.Graphics.Video/Ryujinx.Graphics.Video.csproj new file mode 100644 index 00000000..6710726c --- /dev/null +++ b/Ryujinx.Graphics.Video/Ryujinx.Graphics.Video.csproj @@ -0,0 +1,11 @@ + + + + netcoreapp3.1 + + + + + + + diff --git a/Ryujinx.Graphics.Video/Vp9BackwardUpdates.cs b/Ryujinx.Graphics.Video/Vp9BackwardUpdates.cs new file mode 100644 index 00000000..a3aa4de7 --- /dev/null +++ b/Ryujinx.Graphics.Video/Vp9BackwardUpdates.cs @@ -0,0 +1,32 @@ +using Ryujinx.Common.Memory; + +namespace Ryujinx.Graphics.Video +{ + public struct Vp9BackwardUpdates + { + public Array4> YMode; + public Array10> UvMode; + public Array16> Partition; + public Array4>>>>> Coef; + public Array4>>>> EobBranch; + public Array4> SwitchableInterp; + public Array7> InterMode; + public Array4> IntraInter; + public Array5> CompInter; + public Array5>> SingleRef; + public Array5> CompRef; + public Array2> Tx32x32; + public Array2> Tx16x16; + public Array2> Tx8x8; + public Array3> Skip; + public Array4 Joints; + public Array2> Sign; + public Array2> Classes; + public Array2> Class0; + public Array2>> Bits; + public Array2>> Class0Fp; + public Array2> Fp; + public Array2> Class0Hp; + public Array2> Hp; + } +} diff --git a/Ryujinx.Graphics.Video/Vp9EntropyProbs.cs b/Ryujinx.Graphics.Video/Vp9EntropyProbs.cs new file mode 100644 index 00000000..10b997a5 --- /dev/null +++ b/Ryujinx.Graphics.Video/Vp9EntropyProbs.cs @@ -0,0 +1,36 @@ +using Ryujinx.Common.Memory; + +namespace Ryujinx.Graphics.Video +{ + public struct Vp9EntropyProbs + { + public Array10>> KfYModeProb; + public Array7 SegTreeProb; + public Array3 SegPredProb; + public Array10> KfUvModeProb; + public Array4> YModeProb; + public Array10> UvModeProb; + public Array16> KfPartitionProb; + public Array16> PartitionProb; + public Array4>>>>> CoefProbs; + public Array4> SwitchableInterpProb; + public Array7> InterModeProb; + public Array4 IntraInterProb; + public Array5 CompInterProb; + public Array5> SingleRefProb; + public Array5 CompRefProb; + public Array2> Tx32x32Prob; + public Array2> Tx16x16Prob; + public Array2> Tx8x8Prob; + public Array3 SkipProb; + public Array3 Joints; + public Array2 Sign; + public Array2> Classes; + public Array2> Class0; + public Array2> Bits; + public Array2>> Class0Fp; + public Array2> Fp; + public Array2 Class0Hp; + public Array2 Hp; + } +} diff --git a/Ryujinx.Graphics.Video/Vp9Mv.cs b/Ryujinx.Graphics.Video/Vp9Mv.cs new file mode 100644 index 00000000..9de41058 --- /dev/null +++ b/Ryujinx.Graphics.Video/Vp9Mv.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.Graphics.Video +{ + public struct Vp9Mv + { + public short Row; + public short Col; + } +} diff --git a/Ryujinx.Graphics.Video/Vp9MvRef.cs b/Ryujinx.Graphics.Video/Vp9MvRef.cs new file mode 100644 index 00000000..6f2d8e81 --- /dev/null +++ b/Ryujinx.Graphics.Video/Vp9MvRef.cs @@ -0,0 +1,11 @@ +using Ryujinx.Common.Memory; + +namespace Ryujinx.Graphics.Video +{ + // This must match the structure used by NVDEC, do not modify. + public struct Vp9MvRef + { + public Array2 Mvs; + public Array2 RefFrames; + } +} diff --git a/Ryujinx.Graphics.Video/Vp9PictureInfo.cs b/Ryujinx.Graphics.Video/Vp9PictureInfo.cs new file mode 100644 index 00000000..a5cc2b45 --- /dev/null +++ b/Ryujinx.Graphics.Video/Vp9PictureInfo.cs @@ -0,0 +1,39 @@ +using Ryujinx.Common.Memory; + +namespace Ryujinx.Graphics.Video +{ + public ref struct Vp9PictureInfo + { + public ISurface LastReference; + public ISurface GoldenReference; + public ISurface AltReference; + public bool IsKeyFrame; + public bool IntraOnly; + public Array4 RefFrameSignBias; + public int BaseQIndex; + public int YDcDeltaQ; + public int UvDcDeltaQ; + public int UvAcDeltaQ; + public bool Lossless; + public int TransformMode; + public bool AllowHighPrecisionMv; + public int InterpFilter; + public int ReferenceMode; + public sbyte CompFixedRef; + public Array2 CompVarRef; + public int Log2TileCols; + public int Log2TileRows; + public bool SegmentEnabled; + public bool SegmentMapUpdate; + public bool SegmentMapTemporalUpdate; + public int SegmentAbsDelta; + public Array8 SegmentFeatureEnable; + public Array8> SegmentFeatureData; + public bool ModeRefDeltaEnabled; + public bool UsePrevInFindMvRefs; + public Array4 RefDeltas; + public Array2 ModeDeltas; + public Vp9EntropyProbs Entropy; + public Vp9BackwardUpdates BackwardUpdateCounts; + } +} -- cgit v1.2.3