Prob.cs
1 using Ryujinx.Graphics.Nvdec.Vp9.Common; 2 using System; 3 using System.Diagnostics; 4 5 namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp 6 { 7 internal static class Prob 8 { 9 public const int MaxProb = 255; 10 11 private static byte GetProb(uint num, uint den) 12 { 13 Debug.Assert(den != 0); 14 { 15 int p = (int)(((ulong)num * 256 + (den >> 1)) / den); 16 // (p > 255) ? 255 : (p < 1) ? 1 : p; 17 int clippedProb = p | ((255 - p) >> 23) | (p == 0 ? 1 : 0); 18 19 return (byte)clippedProb; 20 } 21 } 22 23 /* This function assumes prob1 and prob2 are already within [1,255] range. */ 24 public static byte WeightedProb(int prob1, int prob2, int factor) 25 { 26 return (byte)BitUtils.RoundPowerOfTwo(prob1 * (256 - factor) + prob2 * factor, 8); 27 } 28 29 // MODE_MV_MAX_UPDATE_FACTOR (128) * count / MODE_MV_COUNT_SAT; 30 private static readonly uint[] _countToUpdateFactor = { 31 0, 6, 12, 19, 25, 32, 38, 44, 51, 57, 64, 32 70, 76, 83, 89, 96, 102, 108, 115, 121, 128, 33 }; 34 35 private const int ModeMvCountSat = 20; 36 37 public static byte ModeMvMergeProbs(byte preProb, uint ct0, uint ct1) 38 { 39 uint den = ct0 + ct1; 40 if (den == 0) 41 { 42 return preProb; 43 } 44 else 45 { 46 uint count = Math.Min(den, ModeMvCountSat); 47 uint factor = _countToUpdateFactor[(int)count]; 48 byte prob = GetProb(ct0, den); 49 50 return WeightedProb(preProb, prob, (int)factor); 51 } 52 } 53 54 private static uint TreeMergeProbsImpl( 55 uint i, 56 sbyte[] tree, 57 ReadOnlySpan<byte> preProbs, 58 ReadOnlySpan<uint> counts, 59 Span<byte> probs) 60 { 61 int l = tree[i]; 62 uint leftCount = (l <= 0) ? counts[-l] : TreeMergeProbsImpl((uint)l, tree, preProbs, counts, probs); 63 int r = tree[i + 1]; 64 uint rightCount = (r <= 0) ? counts[-r] : TreeMergeProbsImpl((uint)r, tree, preProbs, counts, probs); 65 probs[(int)(i >> 1)] = ModeMvMergeProbs(preProbs[(int)(i >> 1)], leftCount, rightCount); 66 67 return leftCount + rightCount; 68 } 69 70 public static void TreeMergeProbs(sbyte[] tree, ReadOnlySpan<byte> preProbs, ReadOnlySpan<uint> counts, Span<byte> probs) 71 { 72 TreeMergeProbsImpl(0, tree, preProbs, counts, probs); 73 } 74 } 75 }