mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-06-02 10:29:14 +00:00
Memory Changes part 2 (ryubing/ryujinx!123)
See merge request ryubing/ryujinx!123
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
{
|
||||
@@ -28,13 +29,16 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
{
|
||||
ModeRefDeltaEnabled = true;
|
||||
ModeRefDeltaUpdate = true;
|
||||
|
||||
Span<sbyte> refDeltasSpan = RefDeltas.AsSpan();
|
||||
Span<sbyte> modeDeltasSpan = ModeDeltas.AsSpan();
|
||||
|
||||
RefDeltas[Constants.IntraFrame] = 1;
|
||||
RefDeltas[Constants.LastFrame] = 0;
|
||||
RefDeltas[Constants.GoldenFrame] = -1;
|
||||
RefDeltas[Constants.AltRefFrame] = -1;
|
||||
ModeDeltas[0] = 0;
|
||||
ModeDeltas[1] = 0;
|
||||
refDeltasSpan[Constants.IntraFrame] = 1;
|
||||
refDeltasSpan[Constants.LastFrame] = 0;
|
||||
refDeltasSpan[Constants.GoldenFrame] = -1;
|
||||
refDeltasSpan[Constants.AltRefFrame] = -1;
|
||||
modeDeltasSpan[0] = 0;
|
||||
modeDeltasSpan[1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using Ryujinx.Graphics.Video;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
{
|
||||
@@ -147,10 +148,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
|
||||
public void SetupBlockPlanes(int ssX, int ssY)
|
||||
{
|
||||
Span<MacroBlockDPlane> planeSpan = Plane.AsSpan();
|
||||
|
||||
for (int i = 0; i < Constants.MaxMbPlane; i++)
|
||||
{
|
||||
Plane[i].SubsamplingX = i != 0 ? ssX : 0;
|
||||
Plane[i].SubsamplingY = i != 0 ? ssY : 0;
|
||||
planeSpan[i].SubsamplingX = i != 0 ? ssX : 0;
|
||||
planeSpan[i].SubsamplingY = i != 0 ? ssY : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,12 +161,16 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
{
|
||||
int aboveIdx = miCol * 2;
|
||||
int leftIdx = (miRow * 2) & 15;
|
||||
|
||||
Span<MacroBlockDPlane> planeSpan = Plane.AsSpan();
|
||||
Span<ArrayPtr<sbyte>> aboveContextSpan = AboveContext.AsSpan();
|
||||
Span<Array16<sbyte>> leftContextSpan = LeftContext.AsSpan();
|
||||
|
||||
for (int i = 0; i < Constants.MaxMbPlane; ++i)
|
||||
{
|
||||
ref MacroBlockDPlane pd = ref Plane[i];
|
||||
pd.AboveContext = AboveContext[i].Slice(aboveIdx >> pd.SubsamplingX);
|
||||
pd.LeftContext = new ArrayPtr<sbyte>(ref LeftContext[i][leftIdx >> pd.SubsamplingY],
|
||||
ref MacroBlockDPlane pd = ref planeSpan[i];
|
||||
pd.AboveContext = aboveContextSpan[i].Slice(aboveIdx >> pd.SubsamplingX);
|
||||
pd.LeftContext = new ArrayPtr<sbyte>(ref leftContextSpan[i][leftIdx >> pd.SubsamplingY],
|
||||
16 - (leftIdx >> pd.SubsamplingY));
|
||||
}
|
||||
}
|
||||
@@ -182,9 +189,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
|
||||
public unsafe void DecResetSkipContext()
|
||||
{
|
||||
Span<MacroBlockDPlane> planeSpan = Plane.AsSpan();
|
||||
|
||||
for (int i = 0; i < Constants.MaxMbPlane; i++)
|
||||
{
|
||||
ref MacroBlockDPlane pd = ref Plane[i];
|
||||
ref MacroBlockDPlane pd = ref planeSpan[i];
|
||||
MemoryUtil.Fill(pd.AboveContext.ToPointer(), (sbyte)0, pd.N4W);
|
||||
MemoryUtil.Fill(pd.LeftContext.ToPointer(), (sbyte)0, pd.N4H);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
@@ -65,36 +66,41 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
|
||||
public Mv MvPredQ4(int idx)
|
||||
{
|
||||
Span<BModeInfo> bmiSpan = Bmi.AsSpan();
|
||||
|
||||
Mv res = new()
|
||||
{
|
||||
Row = (short)ReconInter.RoundMvCompQ4(
|
||||
Bmi[0].Mv[idx].Row + Bmi[1].Mv[idx].Row +
|
||||
Bmi[2].Mv[idx].Row + Bmi[3].Mv[idx].Row),
|
||||
bmiSpan[0].Mv[idx].Row + bmiSpan[1].Mv[idx].Row +
|
||||
bmiSpan[2].Mv[idx].Row + bmiSpan[3].Mv[idx].Row),
|
||||
Col = (short)ReconInter.RoundMvCompQ4(
|
||||
Bmi[0].Mv[idx].Col + Bmi[1].Mv[idx].Col +
|
||||
Bmi[2].Mv[idx].Col + Bmi[3].Mv[idx].Col)
|
||||
bmiSpan[0].Mv[idx].Col + bmiSpan[1].Mv[idx].Col +
|
||||
bmiSpan[2].Mv[idx].Col + bmiSpan[3].Mv[idx].Col)
|
||||
};
|
||||
return res;
|
||||
}
|
||||
|
||||
public Mv MvPredQ2(int idx, int block0, int block1)
|
||||
{
|
||||
Span<BModeInfo> bmiSpan = Bmi.AsSpan();
|
||||
|
||||
Mv res = new()
|
||||
{
|
||||
Row = (short)ReconInter.RoundMvCompQ2(
|
||||
Bmi[block0].Mv[idx].Row +
|
||||
Bmi[block1].Mv[idx].Row),
|
||||
bmiSpan[block0].Mv[idx].Row +
|
||||
bmiSpan[block1].Mv[idx].Row),
|
||||
Col = (short)ReconInter.RoundMvCompQ2(
|
||||
Bmi[block0].Mv[idx].Col +
|
||||
Bmi[block1].Mv[idx].Col)
|
||||
bmiSpan[block0].Mv[idx].Col +
|
||||
bmiSpan[block1].Mv[idx].Col)
|
||||
};
|
||||
return res;
|
||||
}
|
||||
|
||||
// Performs mv sign inversion if indicated by the reference frame combination.
|
||||
public Mv ScaleMv(int refr, sbyte thisRefFrame, ref Array4<sbyte> refSignBias)
|
||||
public Mv ScaleMv(int refr, sbyte thisRefFrame, Span<sbyte> refSignBias)
|
||||
{
|
||||
Mv mv = Mv[refr];
|
||||
|
||||
if (refSignBias[RefFrame[refr]] != refSignBias[thisRefFrame])
|
||||
{
|
||||
mv.Row *= -1;
|
||||
|
||||
@@ -99,10 +99,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
}
|
||||
else
|
||||
{
|
||||
Span<Array2<uint>> bitsSpan = counts.Bits[comp].AsSpan();
|
||||
|
||||
int b = c + Constants.Class0Bits - 1; // Number of bits
|
||||
for (int i = 0; i < b; ++i)
|
||||
{
|
||||
counts.Bits[comp][i][(d >> i) & 1] += (uint)incr;
|
||||
bitsSpan[i][(d >> i) & 1] += (uint)incr;
|
||||
}
|
||||
|
||||
counts.Fp[comp][f] += (uint)incr;
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
public Array8<uint> FeatureMask;
|
||||
public int AqAvOffset;
|
||||
|
||||
public static byte GetPredProbSegId(ref Array3<byte> segPredProbs, ref MacroBlockD xd)
|
||||
public static byte GetPredProbSegId(ReadOnlySpan<byte> segPredProbs, ref MacroBlockD xd)
|
||||
{
|
||||
return segPredProbs[xd.GetPredContextSegId()];
|
||||
}
|
||||
@@ -105,9 +105,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
UpdateMap = rb.ReadBit() != 0;
|
||||
if (UpdateMap)
|
||||
{
|
||||
Span<byte> segTreeProbSpan = fc.SegTreeProb.AsSpan();
|
||||
Span<byte> segPredProbSpan = fc.SegPredProb.AsSpan();
|
||||
|
||||
for (int i = 0; i < SegTreeProbs; i++)
|
||||
{
|
||||
fc.SegTreeProb[i] = rb.ReadBit() != 0
|
||||
segTreeProbSpan[i] = rb.ReadBit() != 0
|
||||
? (byte)rb.ReadLiteral(8)
|
||||
: (byte)Prob.MaxProb;
|
||||
}
|
||||
@@ -117,7 +120,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
{
|
||||
for (int i = 0; i < PredictionProbs; i++)
|
||||
{
|
||||
fc.SegPredProb[i] = rb.ReadBit() != 0
|
||||
segPredProbSpan[i] = rb.ReadBit() != 0
|
||||
? (byte)rb.ReadLiteral(8)
|
||||
: (byte)Prob.MaxProb;
|
||||
}
|
||||
@@ -126,7 +129,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
{
|
||||
for (int i = 0; i < PredictionProbs; i++)
|
||||
{
|
||||
fc.SegPredProb[i] = Prob.MaxProb;
|
||||
segPredProbSpan[i] = Prob.MaxProb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,9 +155,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
|
||||
public bool CompoundReferenceAllowed()
|
||||
{
|
||||
Span<sbyte> refFrameSignBiasSpan = RefFrameSignBias.AsSpan();
|
||||
|
||||
for (int i = 1; i < Constants.RefsPerFrame; ++i)
|
||||
{
|
||||
if (RefFrameSignBias[i + 1] != RefFrameSignBias[1])
|
||||
if (refFrameSignBiasSpan[i + 1] != refFrameSignBiasSpan[1])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -173,13 +175,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
|
||||
public readonly int GetFreeFb()
|
||||
{
|
||||
ref Array12<RefCntBuffer> frameBufs = ref BufferPool.Value.FrameBufs;
|
||||
Span<RefCntBuffer> frameBuffs = BufferPool.Value.FrameBufs.AsSpan();
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < Constants.FrameBuffers; ++i)
|
||||
{
|
||||
if (frameBufs[i].RefCount == 0)
|
||||
if (frameBuffs[i].RefCount == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -187,7 +189,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
|
||||
if (i != Constants.FrameBuffers)
|
||||
{
|
||||
frameBufs[i].RefCount = 1;
|
||||
frameBuffs[i].RefCount = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -240,25 +242,29 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
|
||||
private void AllocSegMap(MemoryAllocator allocator, int segMapSize)
|
||||
{
|
||||
Span<ArrayPtr<byte>> segMapArraySpan = SegMapArray.AsSpan();
|
||||
|
||||
for (int i = 0; i < Constants.NumPingPongBuffers; ++i)
|
||||
{
|
||||
SegMapArray[i] = allocator.Allocate<byte>(segMapSize);
|
||||
segMapArraySpan[i] = allocator.Allocate<byte>(segMapSize);
|
||||
}
|
||||
|
||||
// Init the index.
|
||||
SegMapIdx = 0;
|
||||
PrevSegMapIdx = 1;
|
||||
|
||||
CurrentFrameSegMap = SegMapArray[SegMapIdx];
|
||||
LastFrameSegMap = SegMapArray[PrevSegMapIdx];
|
||||
CurrentFrameSegMap = segMapArraySpan[SegMapIdx];
|
||||
LastFrameSegMap = segMapArraySpan[PrevSegMapIdx];
|
||||
}
|
||||
|
||||
private void FreeSegMap(MemoryAllocator allocator)
|
||||
{
|
||||
Span<ArrayPtr<byte>> segMapArraySpan = SegMapArray.AsSpan();
|
||||
|
||||
for (int i = 0; i < Constants.NumPingPongBuffers; ++i)
|
||||
{
|
||||
allocator.Free(SegMapArray[i]);
|
||||
SegMapArray[i] = ArrayPtr<byte>.Null;
|
||||
allocator.Free(segMapArraySpan[i]);
|
||||
segMapArraySpan[i] = ArrayPtr<byte>.Null;
|
||||
}
|
||||
|
||||
CurrentFrameSegMap = ArrayPtr<byte>.Null;
|
||||
@@ -366,18 +372,21 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
|
||||
internal void InitMacroBlockD(ref MacroBlockD xd, ArrayPtr<int> dqcoeff)
|
||||
{
|
||||
Span<MacroBlockDPlane> planeSpan = xd.Plane.AsSpan();
|
||||
Span<ArrayPtr<sbyte>> aboveContextSpan = xd.AboveContext.AsSpan();
|
||||
|
||||
for (int i = 0; i < Constants.MaxMbPlane; ++i)
|
||||
{
|
||||
xd.Plane[i].DqCoeff = dqcoeff;
|
||||
xd.AboveContext[i] = AboveContext.Slice(i * 2 * TileInfo.MiColsAlignedToSb(MiCols));
|
||||
planeSpan[i].DqCoeff = dqcoeff;
|
||||
aboveContextSpan[i] = AboveContext.Slice(i * 2 * TileInfo.MiColsAlignedToSb(MiCols));
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
MemoryUtil.Copy(ref xd.Plane[i].SegDequant, ref YDequant);
|
||||
MemoryUtil.Copy(ref planeSpan[i].SegDequant, ref YDequant);
|
||||
}
|
||||
else
|
||||
{
|
||||
MemoryUtil.Copy(ref xd.Plane[i].SegDequant, ref UvDequant);
|
||||
MemoryUtil.Copy(ref planeSpan[i].SegDequant, ref UvDequant);
|
||||
}
|
||||
|
||||
xd.Fc = new Ptr<Vp9EntropyProbs>(ref Fc.Value);
|
||||
@@ -395,32 +404,43 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
// Build y/uv dequant values based on segmentation.
|
||||
if (Seg.Enabled)
|
||||
{
|
||||
Span<Array2<short>> yDequantSpan1 = YDequant.AsSpan();
|
||||
Span<Array2<short>> uvDequantSpan1 = UvDequant.AsSpan();
|
||||
|
||||
for (int i = 0; i < Constants.MaxSegments; ++i)
|
||||
{
|
||||
Span<short> yDequantSpan2 = yDequantSpan1[i].AsSpan();
|
||||
Span<short> uvDequantSpan2 = uvDequantSpan1[i].AsSpan();
|
||||
|
||||
int qindex = Seg.GetQIndex(i, BaseQindex);
|
||||
YDequant[i][0] = QuantCommon.DcQuant(qindex, YDcDeltaQ, BitDepth);
|
||||
YDequant[i][1] = QuantCommon.AcQuant(qindex, 0, BitDepth);
|
||||
UvDequant[i][0] = QuantCommon.DcQuant(qindex, UvDcDeltaQ, BitDepth);
|
||||
UvDequant[i][1] = QuantCommon.AcQuant(qindex, UvAcDeltaQ, BitDepth);
|
||||
yDequantSpan2[0] = QuantCommon.DcQuant(qindex, YDcDeltaQ, BitDepth);
|
||||
yDequantSpan2[1] = QuantCommon.AcQuant(qindex, 0, BitDepth);
|
||||
uvDequantSpan2[0] = QuantCommon.DcQuant(qindex, UvDcDeltaQ, BitDepth);
|
||||
uvDequantSpan2[1] = QuantCommon.AcQuant(qindex, UvAcDeltaQ, BitDepth);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Span<short> yDequantSpan = YDequant[0].AsSpan();
|
||||
Span<short> uvDequantSpan = UvDequant[0].AsSpan();
|
||||
|
||||
int qindex = BaseQindex;
|
||||
// When segmentation is disabled, only the first value is used. The
|
||||
// remaining are don't cares.
|
||||
YDequant[0][0] = QuantCommon.DcQuant(qindex, YDcDeltaQ, BitDepth);
|
||||
YDequant[0][1] = QuantCommon.AcQuant(qindex, 0, BitDepth);
|
||||
UvDequant[0][0] = QuantCommon.DcQuant(qindex, UvDcDeltaQ, BitDepth);
|
||||
UvDequant[0][1] = QuantCommon.AcQuant(qindex, UvAcDeltaQ, BitDepth);
|
||||
yDequantSpan[0] = QuantCommon.DcQuant(qindex, YDcDeltaQ, BitDepth);
|
||||
yDequantSpan[1] = QuantCommon.AcQuant(qindex, 0, BitDepth);
|
||||
uvDequantSpan[0] = QuantCommon.DcQuant(qindex, UvDcDeltaQ, BitDepth);
|
||||
uvDequantSpan[1] = QuantCommon.AcQuant(qindex, UvAcDeltaQ, BitDepth);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetupScaleFactors()
|
||||
{
|
||||
Span<RefBuffer> frameRefsSpan = FrameRefs.AsSpan();
|
||||
|
||||
for (int i = 0; i < Constants.RefsPerFrame; ++i)
|
||||
{
|
||||
ref RefBuffer refBuf = ref FrameRefs[i];
|
||||
ref RefBuffer refBuf = ref frameRefsSpan[i];
|
||||
refBuf.Sf.SetupScaleFactorsForFrame(refBuf.Buf.Width, refBuf.Buf.Height, Width, Height);
|
||||
}
|
||||
}
|
||||
@@ -431,26 +451,34 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
|
||||
if (ReferenceMode == ReferenceMode.Select)
|
||||
{
|
||||
Span<byte> compInterProbSpan = fc.CompInterProb.AsSpan();
|
||||
|
||||
for (int i = 0; i < Constants.CompInterContexts; ++i)
|
||||
{
|
||||
r.DiffUpdateProb(ref fc.CompInterProb[i]);
|
||||
r.DiffUpdateProb(ref compInterProbSpan[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (ReferenceMode != ReferenceMode.Compound)
|
||||
{
|
||||
Span<Array2<byte>> singleRefProbSpan1 = fc.SingleRefProb.AsSpan();
|
||||
|
||||
for (int i = 0; i < Constants.RefContexts; ++i)
|
||||
{
|
||||
r.DiffUpdateProb(ref fc.SingleRefProb[i][0]);
|
||||
r.DiffUpdateProb(ref fc.SingleRefProb[i][1]);
|
||||
Span<byte> singleRefProbSpan2 = singleRefProbSpan1[i].AsSpan();
|
||||
|
||||
r.DiffUpdateProb(ref singleRefProbSpan2[0]);
|
||||
r.DiffUpdateProb(ref singleRefProbSpan2[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (ReferenceMode != ReferenceMode.Single)
|
||||
{
|
||||
Span<byte> compRefProbSpan = fc.CompRefProb.AsSpan();
|
||||
|
||||
for (int i = 0; i < Constants.RefContexts; ++i)
|
||||
{
|
||||
r.DiffUpdateProb(ref fc.CompRefProb[i]);
|
||||
r.DiffUpdateProb(ref compRefProbSpan[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -469,99 +497,124 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
|
||||
public void SetupCompoundReferenceMode()
|
||||
{
|
||||
if (RefFrameSignBias[Constants.LastFrame] == RefFrameSignBias[Constants.GoldenFrame])
|
||||
Span<sbyte> refFrameSignBiasSpan = RefFrameSignBias.AsSpan();
|
||||
Span<sbyte> compVarRefSpan = CompVarRef.AsSpan();
|
||||
|
||||
if (refFrameSignBiasSpan[Constants.LastFrame] == refFrameSignBiasSpan[Constants.GoldenFrame])
|
||||
{
|
||||
CompFixedRef = Constants.AltRefFrame;
|
||||
CompVarRef[0] = Constants.LastFrame;
|
||||
CompVarRef[1] = Constants.GoldenFrame;
|
||||
compVarRefSpan[0] = Constants.LastFrame;
|
||||
compVarRefSpan[1] = Constants.GoldenFrame;
|
||||
}
|
||||
else if (RefFrameSignBias[Constants.LastFrame] == RefFrameSignBias[Constants.AltRefFrame])
|
||||
else if (refFrameSignBiasSpan[Constants.LastFrame] == refFrameSignBiasSpan[Constants.AltRefFrame])
|
||||
{
|
||||
CompFixedRef = Constants.GoldenFrame;
|
||||
CompVarRef[0] = Constants.LastFrame;
|
||||
CompVarRef[1] = Constants.AltRefFrame;
|
||||
compVarRefSpan[0] = Constants.LastFrame;
|
||||
compVarRefSpan[1] = Constants.AltRefFrame;
|
||||
}
|
||||
else
|
||||
{
|
||||
CompFixedRef = Constants.LastFrame;
|
||||
CompVarRef[0] = Constants.GoldenFrame;
|
||||
CompVarRef[1] = Constants.AltRefFrame;
|
||||
compVarRefSpan[0] = Constants.GoldenFrame;
|
||||
compVarRefSpan[1] = Constants.AltRefFrame;
|
||||
}
|
||||
}
|
||||
|
||||
public readonly void InitMvProbs()
|
||||
{
|
||||
Fc.Value.Joints[0] = 32;
|
||||
Fc.Value.Joints[1] = 64;
|
||||
Fc.Value.Joints[2] = 96;
|
||||
Span<byte> jointsSpan = Fc.Value.Joints.AsSpan();
|
||||
Span<byte> signSpan = Fc.Value.Sign.AsSpan();
|
||||
Span<Array10<byte>> classesSpan = Fc.Value.Classes.AsSpan();
|
||||
Span<byte> classes0Span = classesSpan[0].AsSpan();
|
||||
Span<byte> classes1Span = classesSpan[1].AsSpan();
|
||||
Span<Array1<byte>> class0Span = Fc.Value.Class0.AsSpan();
|
||||
Span<Array10<byte>> bitsSpan = Fc.Value.Bits.AsSpan();
|
||||
Span<byte> bits0Span = bitsSpan[0].AsSpan();
|
||||
Span<byte> bits1Span = bitsSpan[1].AsSpan();
|
||||
Span<Array2<Array3<byte>>> class0FpSpan = Fc.Value.Class0Fp.AsSpan();
|
||||
Span<Array3<byte>> class0Fp0Span = class0FpSpan[0].AsSpan();
|
||||
Span<Array3<byte>> class0Fp1Span = class0FpSpan[1].AsSpan();
|
||||
Span<byte> class0Fp00Span = class0Fp0Span[0].AsSpan();
|
||||
Span<byte> class0Fp01Span = class0Fp0Span[1].AsSpan();
|
||||
Span<byte> class0Fp10Span = class0Fp1Span[0].AsSpan();
|
||||
Span<byte> class0Fp11Span = class0Fp1Span[1].AsSpan();
|
||||
Span<Array3<byte>> fpSpan = Fc.Value.Fp.AsSpan();
|
||||
Span<byte> fp0Span = fpSpan[0].AsSpan();
|
||||
Span<byte> fp1Span = fpSpan[1].AsSpan();
|
||||
Span<byte> class0HpSpan = Fc.Value.Class0Hp.AsSpan();
|
||||
Span<byte> hpSpan = Fc.Value.Hp.AsSpan();
|
||||
|
||||
jointsSpan[0] = 32;
|
||||
jointsSpan[1] = 64;
|
||||
jointsSpan[2] = 96;
|
||||
|
||||
Fc.Value.Sign[0] = 128;
|
||||
Fc.Value.Classes[0][0] = 224;
|
||||
Fc.Value.Classes[0][1] = 144;
|
||||
Fc.Value.Classes[0][2] = 192;
|
||||
Fc.Value.Classes[0][3] = 168;
|
||||
Fc.Value.Classes[0][4] = 192;
|
||||
Fc.Value.Classes[0][5] = 176;
|
||||
Fc.Value.Classes[0][6] = 192;
|
||||
Fc.Value.Classes[0][7] = 198;
|
||||
Fc.Value.Classes[0][8] = 198;
|
||||
Fc.Value.Classes[0][9] = 245;
|
||||
Fc.Value.Class0[0][0] = 216;
|
||||
Fc.Value.Bits[0][0] = 136;
|
||||
Fc.Value.Bits[0][1] = 140;
|
||||
Fc.Value.Bits[0][2] = 148;
|
||||
Fc.Value.Bits[0][3] = 160;
|
||||
Fc.Value.Bits[0][4] = 176;
|
||||
Fc.Value.Bits[0][5] = 192;
|
||||
Fc.Value.Bits[0][6] = 224;
|
||||
Fc.Value.Bits[0][7] = 234;
|
||||
Fc.Value.Bits[0][8] = 234;
|
||||
Fc.Value.Bits[0][9] = 240;
|
||||
Fc.Value.Class0Fp[0][0][0] = 128;
|
||||
Fc.Value.Class0Fp[0][0][1] = 128;
|
||||
Fc.Value.Class0Fp[0][0][2] = 64;
|
||||
Fc.Value.Class0Fp[0][1][0] = 96;
|
||||
Fc.Value.Class0Fp[0][1][1] = 112;
|
||||
Fc.Value.Class0Fp[0][1][2] = 64;
|
||||
Fc.Value.Fp[0][0] = 64;
|
||||
Fc.Value.Fp[0][1] = 96;
|
||||
Fc.Value.Fp[0][2] = 64;
|
||||
Fc.Value.Class0Hp[0] = 160;
|
||||
Fc.Value.Hp[0] = 128;
|
||||
signSpan[0] = 128;
|
||||
classes0Span[0] = 224;
|
||||
classes0Span[1] = 144;
|
||||
classes0Span[2] = 192;
|
||||
classes0Span[3] = 168;
|
||||
classes0Span[4] = 192;
|
||||
classes0Span[5] = 176;
|
||||
classes0Span[6] = 192;
|
||||
classes0Span[7] = 198;
|
||||
classes0Span[8] = 198;
|
||||
classes0Span[9] = 245;
|
||||
class0Span[0][0] = 216;
|
||||
bits0Span[0] = 136;
|
||||
bits0Span[1] = 140;
|
||||
bits0Span[2] = 148;
|
||||
bits0Span[3] = 160;
|
||||
bits0Span[4] = 176;
|
||||
bits0Span[5] = 192;
|
||||
bits0Span[6] = 224;
|
||||
bits0Span[7] = 234;
|
||||
bits0Span[8] = 234;
|
||||
bits0Span[9] = 240;
|
||||
class0Fp00Span[0] = 128;
|
||||
class0Fp00Span[1] = 128;
|
||||
class0Fp00Span[2] = 64;
|
||||
class0Fp01Span[0] = 96;
|
||||
class0Fp01Span[1] = 112;
|
||||
class0Fp01Span[2] = 64;
|
||||
fp0Span[0] = 64;
|
||||
fp0Span[1] = 96;
|
||||
fp0Span[2] = 64;
|
||||
class0HpSpan[0] = 160;
|
||||
hpSpan[0] = 128;
|
||||
|
||||
Fc.Value.Sign[1] = 128;
|
||||
Fc.Value.Classes[1][0] = 216;
|
||||
Fc.Value.Classes[1][1] = 128;
|
||||
Fc.Value.Classes[1][2] = 176;
|
||||
Fc.Value.Classes[1][3] = 160;
|
||||
Fc.Value.Classes[1][4] = 176;
|
||||
Fc.Value.Classes[1][5] = 176;
|
||||
Fc.Value.Classes[1][6] = 192;
|
||||
Fc.Value.Classes[1][7] = 198;
|
||||
Fc.Value.Classes[1][8] = 198;
|
||||
Fc.Value.Classes[1][9] = 208;
|
||||
Fc.Value.Class0[1][0] = 208;
|
||||
Fc.Value.Bits[1][0] = 136;
|
||||
Fc.Value.Bits[1][1] = 140;
|
||||
Fc.Value.Bits[1][2] = 148;
|
||||
Fc.Value.Bits[1][3] = 160;
|
||||
Fc.Value.Bits[1][4] = 176;
|
||||
Fc.Value.Bits[1][5] = 192;
|
||||
Fc.Value.Bits[1][6] = 224;
|
||||
Fc.Value.Bits[1][7] = 234;
|
||||
Fc.Value.Bits[1][8] = 234;
|
||||
Fc.Value.Bits[1][9] = 240;
|
||||
Fc.Value.Class0Fp[1][0][0] = 128;
|
||||
Fc.Value.Class0Fp[1][0][1] = 128;
|
||||
Fc.Value.Class0Fp[1][0][2] = 64;
|
||||
Fc.Value.Class0Fp[1][1][0] = 96;
|
||||
Fc.Value.Class0Fp[1][1][1] = 112;
|
||||
Fc.Value.Class0Fp[1][1][2] = 64;
|
||||
Fc.Value.Fp[1][0] = 64;
|
||||
Fc.Value.Fp[1][1] = 96;
|
||||
Fc.Value.Fp[1][2] = 64;
|
||||
Fc.Value.Class0Hp[1] = 160;
|
||||
Fc.Value.Hp[1] = 128;
|
||||
signSpan[1] = 128;
|
||||
classes1Span[0] = 216;
|
||||
classes1Span[1] = 128;
|
||||
classes1Span[2] = 176;
|
||||
classes1Span[3] = 160;
|
||||
classes1Span[4] = 176;
|
||||
classes1Span[5] = 176;
|
||||
classes1Span[6] = 192;
|
||||
classes1Span[7] = 198;
|
||||
classes1Span[8] = 198;
|
||||
classes1Span[9] = 208;
|
||||
class0Span[1][0] = 208;
|
||||
bits1Span[0] = 136;
|
||||
bits1Span[1] = 140;
|
||||
bits1Span[2] = 148;
|
||||
bits1Span[3] = 160;
|
||||
bits1Span[4] = 176;
|
||||
bits1Span[5] = 192;
|
||||
bits1Span[6] = 224;
|
||||
bits1Span[7] = 234;
|
||||
bits1Span[8] = 234;
|
||||
bits1Span[9] = 240;
|
||||
class0Fp10Span[0] = 128;
|
||||
class0Fp10Span[1] = 128;
|
||||
class0Fp10Span[2] = 64;
|
||||
class0Fp11Span[0] = 96;
|
||||
class0Fp11Span[1] = 112;
|
||||
class0Fp11Span[2] = 64;
|
||||
fp1Span[0] = 64;
|
||||
fp1Span[1] = 96;
|
||||
fp1Span[2] = 64;
|
||||
class0HpSpan[1] = 160;
|
||||
hpSpan[1] = 128;
|
||||
}
|
||||
|
||||
public void AdaptMvProbs(bool allowHp)
|
||||
@@ -576,41 +629,74 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
counts.Joints.AsSpan(),
|
||||
fc.Joints.AsSpan());
|
||||
|
||||
Span<byte> fSignSpan = fc.Sign.AsSpan();
|
||||
Span<byte> pSignSpan = preFc.Sign.AsSpan();
|
||||
Span<Array2<uint>> cSignSpan = counts.Sign.AsSpan();
|
||||
Span<Array10<byte>> fClassesSpan = fc.Classes.AsSpan();
|
||||
Span<Array10<byte>> pClassesSpan = preFc.Classes.AsSpan();
|
||||
Span<Array11<uint>> cClassesSpan = counts.Classes.AsSpan();
|
||||
Span<Array1<byte>> fClass0Span = fc.Class0.AsSpan();
|
||||
Span<Array1<byte>> pClass0Span = preFc.Class0.AsSpan();
|
||||
Span<Array2<uint>> cClass0Span = counts.Class0.AsSpan();
|
||||
Span<Array10<byte>> fBitsSpan1 = fc.Bits.AsSpan();
|
||||
Span<Array10<byte>> pBitsSpan1 = preFc.Bits.AsSpan();
|
||||
Span<Array10<Array2<uint>>> cBitsSpan1 = counts.Bits.AsSpan();
|
||||
Span<Array2<Array3<byte>>> fClass0FpSpan1 = fc.Class0Fp.AsSpan();
|
||||
Span<Array2<Array3<byte>>> pClass0FpSpan1 = preFc.Class0Fp.AsSpan();
|
||||
Span<Array2<Array4<uint>>> cClass0FpSpan1 = counts.Class0Fp.AsSpan();
|
||||
Span<Array3<byte>> fFpSpan = fc.Fp.AsSpan();
|
||||
Span<Array3<byte>> pFpSpan = preFc.Fp.AsSpan();
|
||||
Span<Array4<uint>> cFpSpan = counts.Fp.AsSpan();
|
||||
Span<byte> fClass0HpSpan = fc.Class0Hp.AsSpan();
|
||||
Span<byte> pClass0HpSpan = preFc.Class0Hp.AsSpan();
|
||||
Span<Array2<uint>> cClass0HpSpan = counts.Class0Hp.AsSpan();
|
||||
Span<byte> fHpSpan = fc.Hp.AsSpan();
|
||||
Span<byte> pHpSpan = preFc.Hp.AsSpan();
|
||||
Span<Array2<uint>> cHpSpan = counts.Hp.AsSpan();
|
||||
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
fc.Sign[i] = Prob.ModeMvMergeProbs(preFc.Sign[i], ref counts.Sign[i]);
|
||||
fSignSpan[i] = Prob.ModeMvMergeProbs(pSignSpan[i], cSignSpan[i].AsSpan());
|
||||
Prob.VpxTreeMergeProbs(
|
||||
EntropyMv.ClassTree,
|
||||
preFc.Classes[i].AsSpan(),
|
||||
counts.Classes[i].AsSpan(),
|
||||
fc.Classes[i].AsSpan());
|
||||
pClassesSpan[i].AsSpan(),
|
||||
cClassesSpan[i].AsSpan(),
|
||||
fClassesSpan[i].AsSpan());
|
||||
Prob.VpxTreeMergeProbs(
|
||||
EntropyMv.Class0Tree,
|
||||
preFc.Class0[i].AsSpan(),
|
||||
counts.Class0[i].AsSpan(),
|
||||
fc.Class0[i].AsSpan());
|
||||
pClass0Span[i].AsSpan(),
|
||||
cClass0Span[i].AsSpan(),
|
||||
fClass0Span[i].AsSpan());
|
||||
|
||||
Span<byte> fBitsSpan2 = fBitsSpan1[i].AsSpan();
|
||||
Span<byte> pBitsSpan2 = pBitsSpan1[i].AsSpan();
|
||||
Span<Array2<uint>> cBitsSpan2 = cBitsSpan1[i].AsSpan();
|
||||
|
||||
for (int j = 0; j < EntropyMv.OffsetBits; ++j)
|
||||
{
|
||||
fc.Bits[i][j] = Prob.ModeMvMergeProbs(preFc.Bits[i][j], ref counts.Bits[i][j]);
|
||||
fBitsSpan2[j] = Prob.ModeMvMergeProbs(pBitsSpan2[j], cBitsSpan2[j].AsSpan());
|
||||
}
|
||||
|
||||
Span<Array3<byte>> fClass0FpSpan2 = fClass0FpSpan1[i].AsSpan();
|
||||
Span<Array3<byte>> pClass0FpSpan2 = pClass0FpSpan1[i].AsSpan();
|
||||
Span<Array4<uint>> cClass0FpSpan2 = cClass0FpSpan1[i].AsSpan();
|
||||
|
||||
for (int j = 0; j < EntropyMv.Class0Size; ++j)
|
||||
{
|
||||
Prob.VpxTreeMergeProbs(
|
||||
EntropyMv.FpTree,
|
||||
preFc.Class0Fp[i][j].AsSpan(),
|
||||
counts.Class0Fp[i][j].AsSpan(),
|
||||
fc.Class0Fp[i][j].AsSpan());
|
||||
pClass0FpSpan2[j].AsSpan(),
|
||||
cClass0FpSpan2[j].AsSpan(),
|
||||
fClass0FpSpan2[j].AsSpan());
|
||||
}
|
||||
|
||||
Prob.VpxTreeMergeProbs(EntropyMv.FpTree, preFc.Fp[i].AsSpan(), counts.Fp[i].AsSpan(),
|
||||
fc.Fp[i].AsSpan());
|
||||
Prob.VpxTreeMergeProbs(EntropyMv.FpTree, pFpSpan[i].AsSpan(), cFpSpan[i].AsSpan(),
|
||||
fFpSpan[i].AsSpan());
|
||||
|
||||
if (allowHp)
|
||||
{
|
||||
fc.Class0Hp[i] = Prob.ModeMvMergeProbs(preFc.Class0Hp[i], ref counts.Class0Hp[i]);
|
||||
fc.Hp[i] = Prob.ModeMvMergeProbs(preFc.Hp[i], ref counts.Hp[i]);
|
||||
fClass0HpSpan[i] = Prob.ModeMvMergeProbs(pClass0HpSpan[i], cClass0HpSpan[i].AsSpan());
|
||||
fHpSpan[i] = Prob.ModeMvMergeProbs(pHpSpan[i], cHpSpan[i].AsSpan());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -769,75 +855,115 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
ref Vp9EntropyProbs preFc = ref FrameContexts[(int)FrameContextIdx];
|
||||
ref Vp9BackwardUpdates counts = ref Counts.Value;
|
||||
|
||||
Span<byte> fIntraInterProbSpan = fc.IntraInterProb.AsSpan();
|
||||
Span<byte> pIntraInterProbSpan = preFc.IntraInterProb.AsSpan();
|
||||
Span<Array2<uint>> cIntraInterSpan = counts.IntraInter.AsSpan();
|
||||
|
||||
for (int i = 0; i < Constants.IntraInterContexts; i++)
|
||||
{
|
||||
fc.IntraInterProb[i] = Prob.ModeMvMergeProbs(preFc.IntraInterProb[i], ref counts.IntraInter[i]);
|
||||
fIntraInterProbSpan[i] = Prob.ModeMvMergeProbs(pIntraInterProbSpan[i], cIntraInterSpan[i].AsSpan());
|
||||
}
|
||||
|
||||
Span<byte> fCompInterProbSpan = fc.CompInterProb.AsSpan();
|
||||
Span<byte> pCompInterProbSpan = preFc.CompInterProb.AsSpan();
|
||||
Span<Array2<uint>> cCompInterSpan = counts.CompInter.AsSpan();
|
||||
|
||||
for (int i = 0; i < Constants.CompInterContexts; i++)
|
||||
{
|
||||
fc.CompInterProb[i] = Prob.ModeMvMergeProbs(preFc.CompInterProb[i], ref counts.CompInter[i]);
|
||||
fCompInterProbSpan[i] = Prob.ModeMvMergeProbs(pCompInterProbSpan[i], cCompInterSpan[i].AsSpan());
|
||||
}
|
||||
|
||||
Span<byte> fCompRefProbSpan = fc.CompRefProb.AsSpan();
|
||||
Span<byte> pCompRefProbSpan = preFc.CompRefProb.AsSpan();
|
||||
Span<Array2<uint>> cCompRefSpan = counts.CompRef.AsSpan();
|
||||
|
||||
for (int i = 0; i < Constants.RefContexts; i++)
|
||||
{
|
||||
fc.CompRefProb[i] = Prob.ModeMvMergeProbs(preFc.CompRefProb[i], ref counts.CompRef[i]);
|
||||
fCompRefProbSpan[i] = Prob.ModeMvMergeProbs(pCompRefProbSpan[i], cCompRefSpan[i].AsSpan());
|
||||
}
|
||||
|
||||
Span<Array2<byte>> fSingleRefProbSpan1 = fc.SingleRefProb.AsSpan();
|
||||
Span<Array2<byte>> pSingleRefProbSpan1 = preFc.SingleRefProb.AsSpan();
|
||||
Span<Array2<Array2<uint>>> cSingleRefSpan1 = counts.SingleRef.AsSpan();
|
||||
|
||||
for (int i = 0; i < Constants.RefContexts; i++)
|
||||
{
|
||||
Span<byte> fSingleRefProbSpan2 = fSingleRefProbSpan1[i].AsSpan();
|
||||
Span<byte> pSingleRefProbSpan2 = pSingleRefProbSpan1[i].AsSpan();
|
||||
Span<Array2<uint>> cSingleRefSpan2 = cSingleRefSpan1[i].AsSpan();
|
||||
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
fc.SingleRefProb[i][j] =
|
||||
Prob.ModeMvMergeProbs(preFc.SingleRefProb[i][j], ref counts.SingleRef[i][j]);
|
||||
fSingleRefProbSpan2[j] =
|
||||
Prob.ModeMvMergeProbs(pSingleRefProbSpan2[j], cSingleRefSpan2[j].AsSpan());
|
||||
}
|
||||
}
|
||||
|
||||
Span<Array3<byte>> fInterModeProbSpan = fc.InterModeProb.AsSpan();
|
||||
Span<Array3<byte>> pInterModeProbSpan = preFc.InterModeProb.AsSpan();
|
||||
Span<Array4<uint>> cInterModeSpan = counts.InterMode.AsSpan();
|
||||
|
||||
for (int i = 0; i < Constants.InterModeContexts; i++)
|
||||
{
|
||||
Prob.VpxTreeMergeProbs(
|
||||
EntropyMode.InterModeTree,
|
||||
preFc.InterModeProb[i].AsSpan(),
|
||||
counts.InterMode[i].AsSpan(),
|
||||
fc.InterModeProb[i].AsSpan());
|
||||
pInterModeProbSpan[i].AsSpan(),
|
||||
cInterModeSpan[i].AsSpan(),
|
||||
fInterModeProbSpan[i].AsSpan());
|
||||
}
|
||||
|
||||
Span<Array9<byte>> fYModeProbSpan = fc.YModeProb.AsSpan();
|
||||
Span<Array9<byte>> pYModeProbSpan = preFc.YModeProb.AsSpan();
|
||||
Span<Array10<uint>> cYModeSpan = counts.YMode.AsSpan();
|
||||
|
||||
for (int i = 0; i < EntropyMode.BlockSizeGroups; i++)
|
||||
{
|
||||
Prob.VpxTreeMergeProbs(
|
||||
EntropyMode.IntraModeTree,
|
||||
preFc.YModeProb[i].AsSpan(),
|
||||
counts.YMode[i].AsSpan(),
|
||||
fc.YModeProb[i].AsSpan());
|
||||
pYModeProbSpan[i].AsSpan(),
|
||||
cYModeSpan[i].AsSpan(),
|
||||
fYModeProbSpan[i].AsSpan());
|
||||
}
|
||||
|
||||
Span<Array9<byte>> fUvModeProbSpan = fc.UvModeProb.AsSpan();
|
||||
Span<Array9<byte>> pUvModeProbSpan = preFc.UvModeProb.AsSpan();
|
||||
Span<Array10<uint>> cUvModeSpan = counts.UvMode.AsSpan();
|
||||
|
||||
for (int i = 0; i < Constants.IntraModes; ++i)
|
||||
{
|
||||
Prob.VpxTreeMergeProbs(
|
||||
EntropyMode.IntraModeTree,
|
||||
preFc.UvModeProb[i].AsSpan(),
|
||||
counts.UvMode[i].AsSpan(),
|
||||
fc.UvModeProb[i].AsSpan());
|
||||
pUvModeProbSpan[i].AsSpan(),
|
||||
cUvModeSpan[i].AsSpan(),
|
||||
fUvModeProbSpan[i].AsSpan());
|
||||
}
|
||||
|
||||
Span<Array3<byte>> fPartitionProbSpan = fc.PartitionProb.AsSpan();
|
||||
Span<Array3<byte>> pPartitionProbSpan = preFc.PartitionProb.AsSpan();
|
||||
Span<Array4<uint>> cPartitionSpan = counts.Partition.AsSpan();
|
||||
|
||||
for (int i = 0; i < Constants.PartitionContexts; i++)
|
||||
{
|
||||
Prob.VpxTreeMergeProbs(
|
||||
EntropyMode.PartitionTree,
|
||||
preFc.PartitionProb[i].AsSpan(),
|
||||
counts.Partition[i].AsSpan(),
|
||||
fc.PartitionProb[i].AsSpan());
|
||||
pPartitionProbSpan[i].AsSpan(),
|
||||
cPartitionSpan[i].AsSpan(),
|
||||
fPartitionProbSpan[i].AsSpan());
|
||||
}
|
||||
|
||||
if (InterpFilter == Constants.Switchable)
|
||||
{
|
||||
Span<Array2<byte>> fSwitchableInterpProbSpan = fc.SwitchableInterpProb.AsSpan();
|
||||
Span<Array2<byte>> pSwitchableInterpProbSpan = preFc.SwitchableInterpProb.AsSpan();
|
||||
Span<Array3<uint>> cSwitchableInterpSpan = counts.SwitchableInterp.AsSpan();
|
||||
|
||||
for (int i = 0; i < Constants.SwitchableFilterContexts; i++)
|
||||
{
|
||||
Prob.VpxTreeMergeProbs(
|
||||
EntropyMode.SwitchableInterpTree,
|
||||
preFc.SwitchableInterpProb[i].AsSpan(),
|
||||
counts.SwitchableInterp[i].AsSpan(),
|
||||
fc.SwitchableInterpProb[i].AsSpan());
|
||||
pSwitchableInterpProbSpan[i].AsSpan(),
|
||||
cSwitchableInterpSpan[i].AsSpan(),
|
||||
fSwitchableInterpProbSpan[i].AsSpan());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -846,34 +972,62 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
Array1<Array2<uint>> branchCt8X8P = new();
|
||||
Array2<Array2<uint>> branchCt16X16P = new();
|
||||
Array3<Array2<uint>> branchCt32X32P = new();
|
||||
|
||||
Span<Array2<uint>> branchCt8X8PSpan = branchCt8X8P.AsSpan();
|
||||
Span<Array2<uint>> branchCt16X16PSpan = branchCt16X16P.AsSpan();
|
||||
Span<Array2<uint>> branchCt32X32PSpan = branchCt32X32P.AsSpan();
|
||||
|
||||
Span<Array2<uint>> tx8x8Span = counts.Tx8x8.AsSpan();
|
||||
Span<Array2<uint>> tx16x16Span = counts.Tx8x8.AsSpan();
|
||||
Span<Array2<uint>> tx32x32Span = counts.Tx8x8.AsSpan();
|
||||
|
||||
//There is no need for a Span2, as there is only ever 1 iteration
|
||||
Span<Array1<byte>> fTx8x8ProbSpan = fc.Tx8x8Prob.AsSpan();
|
||||
Span<Array1<byte>> pTx8x8ProbSpan = preFc.Tx8x8Prob.AsSpan();
|
||||
|
||||
Span<Array2<byte>> fTx16x16ProbSpan1 = fc.Tx16x16Prob.AsSpan();
|
||||
Span<Array2<byte>> pTx16x16ProbSpan1 = preFc.Tx16x16Prob.AsSpan();
|
||||
|
||||
Span<Array3<byte>> fTx32x32ProbSpan1 = fc.Tx32x32Prob.AsSpan();
|
||||
Span<Array3<byte>> pTx32x32ProbSpan1 = preFc.Tx32x32Prob.AsSpan();
|
||||
|
||||
for (int i = 0; i < EntropyMode.TxSizeContexts; ++i)
|
||||
{
|
||||
EntropyMode.TxCountsToBranchCounts8X8(counts.Tx8x8[i].AsSpan(), ref branchCt8X8P);
|
||||
EntropyMode.TxCountsToBranchCounts8X8(tx8x8Span[i].AsSpan(), branchCt8X8P.AsSpan());
|
||||
for (int j = 0; j < (int)TxSize.TxSizes - 3; ++j)
|
||||
{
|
||||
fc.Tx8x8Prob[i][j] = Prob.ModeMvMergeProbs(preFc.Tx8x8Prob[i][j], ref branchCt8X8P[j]);
|
||||
fTx8x8ProbSpan[i][j] = Prob.ModeMvMergeProbs(pTx8x8ProbSpan[i][j], branchCt8X8PSpan[j].AsSpan());
|
||||
}
|
||||
|
||||
Span<byte> fTx16x16ProbSpan2 = fTx16x16ProbSpan1[i].AsSpan();
|
||||
Span<byte> pTx16x16ProbSpan2 = pTx16x16ProbSpan1[i].AsSpan();
|
||||
|
||||
EntropyMode.TxCountsToBranchCounts16X16(counts.Tx16x16[i].AsSpan(), ref branchCt16X16P);
|
||||
EntropyMode.TxCountsToBranchCounts16X16(tx16x16Span[i].AsSpan(), branchCt16X16P.AsSpan());
|
||||
for (int j = 0; j < (int)TxSize.TxSizes - 2; ++j)
|
||||
{
|
||||
fc.Tx16x16Prob[i][j] =
|
||||
Prob.ModeMvMergeProbs(preFc.Tx16x16Prob[i][j], ref branchCt16X16P[j]);
|
||||
fTx16x16ProbSpan2[j] =
|
||||
Prob.ModeMvMergeProbs(pTx16x16ProbSpan2[j], branchCt16X16PSpan[j].AsSpan());
|
||||
}
|
||||
|
||||
Span<byte> fTx32x32ProbSpan2 = fTx32x32ProbSpan1[i].AsSpan();
|
||||
Span<byte> pTx32x32ProbSpan2 = pTx32x32ProbSpan1[i].AsSpan();
|
||||
|
||||
EntropyMode.TxCountsToBranchCounts32X32(counts.Tx32x32[i].AsSpan(), ref branchCt32X32P);
|
||||
EntropyMode.TxCountsToBranchCounts32X32(tx32x32Span[i].AsSpan(), branchCt32X32P.AsSpan());
|
||||
for (int j = 0; j < (int)TxSize.TxSizes - 1; ++j)
|
||||
{
|
||||
fc.Tx32x32Prob[i][j] =
|
||||
Prob.ModeMvMergeProbs(preFc.Tx32x32Prob[i][j], ref branchCt32X32P[j]);
|
||||
fTx32x32ProbSpan2[j] =
|
||||
Prob.ModeMvMergeProbs(pTx32x32ProbSpan2[j], branchCt32X32PSpan[j].AsSpan());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Span<byte> fSkipProbSpan = fc.SkipProb.AsSpan();
|
||||
Span<byte> pSkipProbSpan = preFc.SkipProb.AsSpan();
|
||||
Span<Array2<uint>> cSkipSpan = counts.Skip.AsSpan();
|
||||
|
||||
for (int i = 0; i < Constants.SkipContexts; ++i)
|
||||
{
|
||||
fc.SkipProb[i] = Prob.ModeMvMergeProbs(preFc.SkipProb[i], ref counts.Skip[i]);
|
||||
fSkipProbSpan[i] = Prob.ModeMvMergeProbs(pSkipProbSpan[i], cSkipSpan[i].AsSpan());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -916,13 +1070,19 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
{
|
||||
ref MvRef mv = ref PrevFrameMvs[i];
|
||||
|
||||
mv.Mv[0].Row = mvs[i].Mvs[0].Row;
|
||||
mv.Mv[0].Col = mvs[i].Mvs[0].Col;
|
||||
mv.Mv[1].Row = mvs[i].Mvs[1].Row;
|
||||
mv.Mv[1].Col = mvs[i].Mvs[1].Col;
|
||||
Span<Mv> mvSpan = mv.Mv.AsSpan();
|
||||
Span<Vp9Mv> mvsSpan = mvs[i].Mvs.AsSpan();
|
||||
|
||||
mv.RefFrame[0] = (sbyte)mvs[i].RefFrames[0];
|
||||
mv.RefFrame[1] = (sbyte)mvs[i].RefFrames[1];
|
||||
mvSpan[0].Row = mvsSpan[0].Row;
|
||||
mvSpan[0].Col = mvsSpan[0].Col;
|
||||
mvSpan[1].Row = mvsSpan[1].Row;
|
||||
mvSpan[1].Col = mvsSpan[1].Col;
|
||||
|
||||
Span<sbyte> refFrameSpan = mv.RefFrame.AsSpan();
|
||||
Span<int> refFramesSpan = mvs[i].RefFrames.AsSpan();
|
||||
|
||||
refFrameSpan[0] = (sbyte)refFramesSpan[0];
|
||||
refFrameSpan[1] = (sbyte)refFramesSpan[1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -937,47 +1097,76 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
for (int i = 0; i < mvs.Length; i++)
|
||||
{
|
||||
ref MvRef mv = ref CurFrameMvs[i];
|
||||
|
||||
Span<Mv> mvSpan = mv.Mv.AsSpan();
|
||||
Span<Vp9Mv> mvsSpan = mvs[i].Mvs.AsSpan();
|
||||
|
||||
mvs[i].Mvs[0].Row = mv.Mv[0].Row;
|
||||
mvs[i].Mvs[0].Col = mv.Mv[0].Col;
|
||||
mvs[i].Mvs[1].Row = mv.Mv[1].Row;
|
||||
mvs[i].Mvs[1].Col = mv.Mv[1].Col;
|
||||
mvsSpan[0].Row = mvSpan[0].Row;
|
||||
mvsSpan[0].Col = mvSpan[0].Col;
|
||||
mvsSpan[1].Row = mvSpan[1].Row;
|
||||
mvsSpan[1].Col = mvSpan[1].Col;
|
||||
|
||||
Span<sbyte> refFrameSpan = mv.RefFrame.AsSpan();
|
||||
Span<int> refFramesSpan = mvs[i].RefFrames.AsSpan();
|
||||
|
||||
mvs[i].RefFrames[0] = mv.RefFrame[0];
|
||||
mvs[i].RefFrames[1] = mv.RefFrame[1];
|
||||
refFramesSpan[0] = refFrameSpan[0];
|
||||
refFramesSpan[1] = refFrameSpan[1];
|
||||
}
|
||||
}
|
||||
|
||||
private void AdaptCoefProbs(byte txSize, uint countSat, uint updateFactor)
|
||||
{
|
||||
ref Vp9EntropyProbs preFc = ref FrameContexts[(int)FrameContextIdx];
|
||||
ref Array2<Array2<Array6<Array6<Array3<byte>>>>> probs = ref Fc.Value.CoefProbs[txSize];
|
||||
ref Array2<Array2<Array6<Array6<Array3<byte>>>>> preProbs = ref preFc.CoefProbs[txSize];
|
||||
ref Array2<Array2<Array6<Array6<Array4<uint>>>>> counts = ref Counts.Value.Coef[txSize];
|
||||
ref Array2<Array2<Array6<Array6<uint>>>> eobCounts = ref Counts.Value.EobBranch[txSize];
|
||||
Span<Array2<Array6<Array6<Array3<byte>>>>> probsSpan1 = Fc.Value.CoefProbs[txSize].AsSpan();
|
||||
Span<Array2<Array6<Array6<Array3<byte>>>>> preProbsSpan1 = preFc.CoefProbs[txSize].AsSpan();
|
||||
Span<Array2<Array6<Array6<Array4<uint>>>>> countsSpan1 = Counts.Value.Coef[txSize].AsSpan();
|
||||
Span<Array2<Array6<Array6<uint>>>> eobCountsSpan1 = Counts.Value.EobBranch[txSize].AsSpan();
|
||||
|
||||
for (int i = 0; i < Constants.PlaneTypes; ++i)
|
||||
{
|
||||
Span<Array6<Array6<Array3<byte>>>> probsSpan2 = probsSpan1[i].AsSpan();
|
||||
Span<Array6<Array6<Array3<byte>>>> preProbsSpan2 = preProbsSpan1[i].AsSpan();
|
||||
Span<Array6<Array6<Array4<uint>>>> countsSpan2 = countsSpan1[i].AsSpan();
|
||||
Span<Array6<Array6<uint>>> eobCountsSpan2 = eobCountsSpan1[i].AsSpan();
|
||||
|
||||
for (int j = 0; j < Entropy.RefTypes; ++j)
|
||||
{
|
||||
Span<Array6<Array3<byte>>> probsSpan3 = probsSpan2[j].AsSpan();
|
||||
Span<Array6<Array3<byte>>> preProbsSpan3 = preProbsSpan2[j].AsSpan();
|
||||
Span<Array6<Array4<uint>>> countsSpan3 = countsSpan2[j].AsSpan();
|
||||
Span<Array6<uint>> eobCountsSpan3 = eobCountsSpan2[j].AsSpan();
|
||||
|
||||
for (int k = 0; k < Entropy.CoefBands; ++k)
|
||||
{
|
||||
Span<Array3<byte>> probsSpan4 = probsSpan3[k].AsSpan();
|
||||
Span<Array3<byte>> preProbsSpan4 = preProbsSpan3[k].AsSpan();
|
||||
Span<Array4<uint>> countsSpan4 = countsSpan3[k].AsSpan();
|
||||
Span<uint> eobCountsSpan4 = eobCountsSpan3[k].AsSpan();
|
||||
|
||||
for (int l = 0; l < Entropy.BAND_COEFF_CONTEXTS(k); ++l)
|
||||
{
|
||||
int n0 = (int)counts[i][j][k][l][Entropy.ZeroToken];
|
||||
int n1 = (int)counts[i][j][k][l][Entropy.OneToken];
|
||||
int n2 = (int)counts[i][j][k][l][Entropy.TwoToken];
|
||||
int neob = (int)counts[i][j][k][l][Entropy.EobModelToken];
|
||||
Span<byte> probsSpan5 = probsSpan4[l].AsSpan();
|
||||
Span<byte> preProbsSpan5 = preProbsSpan4[l].AsSpan();
|
||||
Span<uint> countsSpan5 = countsSpan4[l].AsSpan();
|
||||
|
||||
int n0 = (int)countsSpan5[Entropy.ZeroToken];
|
||||
int n1 = (int)countsSpan5[Entropy.OneToken];
|
||||
int n2 = (int)countsSpan5[Entropy.TwoToken];
|
||||
int neob = (int)countsSpan5[Entropy.EobModelToken];
|
||||
Array3<Array2<uint>> branchCt = new();
|
||||
branchCt[0][0] = (uint)neob;
|
||||
branchCt[0][1] = (uint)(eobCounts[i][j][k][l] - neob);
|
||||
branchCt[1][0] = (uint)n0;
|
||||
branchCt[1][1] = (uint)(n1 + n2);
|
||||
branchCt[2][0] = (uint)n1;
|
||||
branchCt[2][1] = (uint)n2;
|
||||
Span<Array2<uint>> branchCtSpan = branchCt.AsSpan();
|
||||
Span<uint> branchCt0Span = branchCtSpan[0].AsSpan();
|
||||
Span<uint> branchCt1Span = branchCtSpan[1].AsSpan();
|
||||
Span<uint> branchCt2Span = branchCtSpan[2].AsSpan();
|
||||
branchCt0Span[0] = (uint)neob;
|
||||
branchCt0Span[1] = (uint)(eobCountsSpan4[l] - neob);
|
||||
branchCt1Span[0] = (uint)n0;
|
||||
branchCt1Span[1] = (uint)(n1 + n2);
|
||||
branchCt2Span[0] = (uint)n1;
|
||||
branchCt2Span[1] = (uint)n2;
|
||||
for (int m = 0; m < Entropy.UnconstrainedNodes; ++m)
|
||||
{
|
||||
probs[i][j][k][l][m] = Prob.MergeProbs(preProbs[i][j][k][l][m], ref branchCt[m],
|
||||
probsSpan5[m] = Prob.MergeProbs(preProbsSpan5[m], branchCt[m].AsSpan(),
|
||||
countSat, updateFactor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using Ryujinx.Graphics.Video;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
@@ -16,20 +17,20 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
public int NeedResync; // Wait for key/intra-only frame.
|
||||
public int HoldRefBuf; // Hold the reference buffer.
|
||||
|
||||
private static void DecreaseRefCount(int idx, ref Array12<RefCntBuffer> frameBufs, ref BufferPool pool)
|
||||
private static void DecreaseRefCount(int idx, Span<RefCntBuffer> frameBuffs, ref BufferPool pool)
|
||||
{
|
||||
if (idx >= 0 && frameBufs[idx].RefCount > 0)
|
||||
if (idx >= 0 && frameBuffs[idx].RefCount > 0)
|
||||
{
|
||||
--frameBufs[idx].RefCount;
|
||||
--frameBuffs[idx].RefCount;
|
||||
// A worker may only get a free framebuffer index when calling GetFreeFb.
|
||||
// But the private buffer is not set up until finish decoding header.
|
||||
// So any error happens during decoding header, the frame_bufs will not
|
||||
// have valid priv buffer.
|
||||
if (frameBufs[idx].Released == 0 && frameBufs[idx].RefCount == 0 &&
|
||||
!frameBufs[idx].RawFrameBuffer.Priv.IsNull)
|
||||
if (frameBuffs[idx].Released == 0 && frameBuffs[idx].RefCount == 0 &&
|
||||
!frameBuffs[idx].RawFrameBuffer.Priv.IsNull)
|
||||
{
|
||||
FrameBuffers.ReleaseFrameBuffer(pool.CbPriv, ref frameBufs[idx].RawFrameBuffer);
|
||||
frameBufs[idx].Released = 1;
|
||||
FrameBuffers.ReleaseFrameBuffer(pool.CbPriv, ref frameBuffs[idx].RawFrameBuffer);
|
||||
frameBuffs[idx].Released = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,22 +44,32 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
cm.CheckMemError(ref cm.FrameContexts,
|
||||
allocator.Allocate<Vp9EntropyProbs>(Constants.FrameContexts));
|
||||
|
||||
Span<Array10<Array9<byte>>> cKfYModeProbSpan1 = cm.Fc.Value.KfYModeProb.AsSpan();
|
||||
|
||||
for (int i = 0; i < EntropyMode.KfYModeProb.Length; i++)
|
||||
{
|
||||
Span<Array9<byte>> cKfYModeProbSpan2 = cKfYModeProbSpan1[i].AsSpan();
|
||||
|
||||
for (int j = 0; j < EntropyMode.KfYModeProb[i].Length; j++)
|
||||
{
|
||||
Span<byte> cKfYModeProbSpan3 = cKfYModeProbSpan2[j].AsSpan();
|
||||
|
||||
for (int k = 0; k < EntropyMode.KfYModeProb[i][j].Length; k++)
|
||||
{
|
||||
cm.Fc.Value.KfYModeProb[i][j][k] = EntropyMode.KfYModeProb[i][j][k];
|
||||
cKfYModeProbSpan3[k] = EntropyMode.KfYModeProb[i][j][k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Span<Array9<byte>> cKfUvModeProbSpan1 = cm.Fc.Value.KfUvModeProb.AsSpan();
|
||||
|
||||
for (int i = 0; i < EntropyMode.KfUvModeProb.Length; i++)
|
||||
{
|
||||
Span<byte> cKfUvModeProbSpan2 = cKfUvModeProbSpan1[i].AsSpan();
|
||||
|
||||
for (int j = 0; j < EntropyMode.KfUvModeProb[i].Length; j++)
|
||||
{
|
||||
cm.Fc.Value.KfUvModeProb[i][j] = EntropyMode.KfUvModeProb[i][j];
|
||||
cKfUvModeProbSpan2[j] = EntropyMode.KfUvModeProb[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,12 +99,16 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
[57, 15, 9], // l split, a not split
|
||||
[12, 3, 3] // a/l both split
|
||||
];
|
||||
|
||||
Span<Array3<byte>> cKfPartitionProbSpan1 = cm.Fc.Value.KfPartitionProb.AsSpan();
|
||||
|
||||
for (int i = 0; i < kfPartitionProbs.Length; i++)
|
||||
{
|
||||
Span<byte> cKfPartitionProbSpan2 = cKfPartitionProbSpan1[i].AsSpan();
|
||||
|
||||
for (int j = 0; j < kfPartitionProbs[i].Length; j++)
|
||||
{
|
||||
cm.Fc.Value.KfPartitionProb[i][j] = kfPartitionProbs[i][j];
|
||||
cKfPartitionProbSpan2[j] = kfPartitionProbs[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,11 +116,14 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
|
||||
NeedResync = 1;
|
||||
|
||||
Span<int> refFrameMapSpan = cm.RefFrameMap.AsSpan();
|
||||
Span<int> nextRefFrameMapSpan = cm.NextRefFrameMap.AsSpan();
|
||||
|
||||
// Initialize the references to not point to any frame buffers.
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
cm.RefFrameMap[i] = -1;
|
||||
cm.NextRefFrameMap[i] = -1;
|
||||
refFrameMapSpan[i] = -1;
|
||||
nextRefFrameMapSpan[i] = -1;
|
||||
}
|
||||
|
||||
cm.CurrentVideoFrame = 0;
|
||||
@@ -124,30 +142,34 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
int refIndex = 0, mask;
|
||||
ref Vp9Common cm = ref Common;
|
||||
ref BufferPool pool = ref cm.BufferPool.Value;
|
||||
ref Array12<RefCntBuffer> frameBufs = ref cm.BufferPool.Value.FrameBufs;
|
||||
Span<RefCntBuffer> frameBufs = cm.BufferPool.Value.FrameBufs.AsSpan();
|
||||
|
||||
Span<int> refFrameMapSpan = cm.RefFrameMap.AsSpan();
|
||||
Span<int> nextRefFrameMapSpan = cm.NextRefFrameMap.AsSpan();
|
||||
Span<RefBuffer> frameRefsSpan = cm.FrameRefs.AsSpan();
|
||||
|
||||
for (mask = RefreshFrameFlags; mask != 0; mask >>= 1)
|
||||
{
|
||||
int oldIdx = cm.RefFrameMap[refIndex];
|
||||
int oldIdx = refFrameMapSpan[refIndex];
|
||||
// Current thread releases the holding of reference frame.
|
||||
DecreaseRefCount(oldIdx, ref frameBufs, ref pool);
|
||||
DecreaseRefCount(oldIdx, frameBufs, ref pool);
|
||||
|
||||
// Release the reference frame in reference map.
|
||||
if ((mask & 1) != 0)
|
||||
{
|
||||
DecreaseRefCount(oldIdx, ref frameBufs, ref pool);
|
||||
DecreaseRefCount(oldIdx, frameBufs, ref pool);
|
||||
}
|
||||
|
||||
cm.RefFrameMap[refIndex] = cm.NextRefFrameMap[refIndex];
|
||||
refFrameMapSpan[refIndex] = nextRefFrameMapSpan[refIndex];
|
||||
++refIndex;
|
||||
}
|
||||
|
||||
// Current thread releases the holding of reference frame.
|
||||
for (; refIndex < Constants.RefFrames && cm.ShowExistingFrame == 0; ++refIndex)
|
||||
{
|
||||
int oldIdx = cm.RefFrameMap[refIndex];
|
||||
DecreaseRefCount(oldIdx, ref frameBufs, ref pool);
|
||||
cm.RefFrameMap[refIndex] = cm.NextRefFrameMap[refIndex];
|
||||
int oldIdx = refFrameMapSpan[refIndex];
|
||||
DecreaseRefCount(oldIdx, frameBufs, ref pool);
|
||||
refFrameMapSpan[refIndex] = nextRefFrameMapSpan[refIndex];
|
||||
}
|
||||
|
||||
HoldRefBuf = 0;
|
||||
@@ -158,7 +180,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
// Invalidate these references until the next frame starts.
|
||||
for (refIndex = 0; refIndex < 3; refIndex++)
|
||||
{
|
||||
cm.FrameRefs[refIndex].Idx = RefBuffer.InvalidIdx;
|
||||
frameRefsSpan[refIndex].Idx = RefBuffer.InvalidIdx;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,7 +188,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
{
|
||||
ref Vp9Common cm = ref Common;
|
||||
ref BufferPool pool = ref cm.BufferPool.Value;
|
||||
ref Array12<RefCntBuffer> frameBufs = ref cm.BufferPool.Value.FrameBufs;
|
||||
Span<RefCntBuffer> frameBufs = cm.BufferPool.Value.FrameBufs.AsSpan();
|
||||
ArrayPtr<byte> source = psource;
|
||||
CodecErr retcode = 0;
|
||||
cm.Error.ErrorCode = CodecErr.Ok;
|
||||
@@ -177,10 +199,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
// We do not know if the missing frame(s) was supposed to update
|
||||
// any of the reference buffers, but we act conservative and
|
||||
// mark only the last buffer as corrupted.
|
||||
|
||||
Span<RefBuffer> frameRefsSpan = cm.FrameRefs.AsSpan();
|
||||
|
||||
if (cm.FrameRefs[0].Idx > 0)
|
||||
if (frameRefsSpan[0].Idx > 0)
|
||||
{
|
||||
cm.FrameRefs[0].Buf.Corrupted = 1;
|
||||
frameRefsSpan[0].Buf.Corrupted = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,8 +303,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
ArrayPtr<byte> dataStart = data;
|
||||
CodecErr res;
|
||||
Array8<uint> frameSizes = new();
|
||||
|
||||
res = Decoder.ParseSuperframeIndex(data, (ulong)data.Length, ref frameSizes, out int frameCount);
|
||||
Span<uint> frameSizesSpan = frameSizes.AsSpan();
|
||||
|
||||
res = Decoder.ParseSuperframeIndex(data, (ulong)data.Length, frameSizesSpan, out int frameCount);
|
||||
if (res != CodecErr.Ok)
|
||||
{
|
||||
return res;
|
||||
@@ -292,7 +317,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
for (int i = 0; i < frameCount; ++i)
|
||||
{
|
||||
ArrayPtr<byte> dataStartCopy = dataStart;
|
||||
uint frameSize = frameSizes[i];
|
||||
uint frameSize = frameSizesSpan[i];
|
||||
if (frameSize > (uint)dataStart.Length)
|
||||
{
|
||||
return CodecErr.CorruptFrame;
|
||||
@@ -343,7 +368,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
||||
return data[0];
|
||||
}
|
||||
|
||||
public static CodecErr ParseSuperframeIndex(ArrayPtr<byte> data, ulong dataSz, ref Array8<uint> sizes, out int count)
|
||||
public static CodecErr ParseSuperframeIndex(ArrayPtr<byte> data, ulong dataSz, Span<uint> sizes, out int count)
|
||||
{
|
||||
// A chunk ending with a byte matching 0xc0 is an invalid chunk unless
|
||||
// it is a super frame index. If the last byte of real video compression
|
||||
|
||||
Reference in New Issue
Block a user