Mv.cs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. using Ryujinx.Common.Memory;
  2. using Ryujinx.Graphics.Video;
  3. using System;
  4. using System.Diagnostics;
  5. namespace Ryujinx.Graphics.Nvdec.Vp9.Types
  6. {
  7. internal struct Mv
  8. {
  9. public short Row;
  10. public short Col;
  11. private static ReadOnlySpan<byte> LogInBase2 =>
  12. [
  13. 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5,
  14. 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6,
  15. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  16. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  17. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  18. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  19. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  20. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  21. 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  22. 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  23. 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  24. 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  25. 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  26. 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  27. 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
  28. 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
  29. 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
  30. 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
  31. 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
  32. 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
  33. 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
  34. 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
  35. 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
  36. 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
  37. 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
  38. 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
  39. 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
  40. 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
  41. 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
  42. 9, 9, 9, 9, 9, 9, 9, 9, 9, 10
  43. ];
  44. public bool UseHp()
  45. {
  46. const int KMvRefThresh = 64; // Threshold for use of high-precision 1/8 mv
  47. return Math.Abs(Row) < KMvRefThresh && Math.Abs(Col) < KMvRefThresh;
  48. }
  49. public static bool JointVertical(MvJointType type)
  50. {
  51. return type == MvJointType.Hzvnz || type == MvJointType.Hnzvnz;
  52. }
  53. public static bool JointHorizontal(MvJointType type)
  54. {
  55. return type == MvJointType.Hnzvz || type == MvJointType.Hnzvnz;
  56. }
  57. private static int ClassBase(MvClassType c)
  58. {
  59. return c != 0 ? Constants.Class0Size << ((int)c + 2) : 0;
  60. }
  61. private static MvClassType GetClass(int z, Ptr<int> offset)
  62. {
  63. MvClassType c = z >= Constants.Class0Size * 4096 ? MvClassType.Class10 : (MvClassType)LogInBase2[z >> 3];
  64. if (!offset.IsNull)
  65. {
  66. offset.Value = z - ClassBase(c);
  67. }
  68. return c;
  69. }
  70. private static void IncComponent(int v, ref Vp9BackwardUpdates counts, int comp, int incr, int usehp)
  71. {
  72. int o = 0;
  73. Debug.Assert(v != 0); /* Should not be zero */
  74. int s = v < 0 ? 1 : 0;
  75. counts.Sign[comp][s] += (uint)incr;
  76. int z = (s != 0 ? -v : v) - 1 /* Magnitude - 1 */;
  77. int c = (int)GetClass(z, new Ptr<int>(ref o));
  78. counts.Classes[comp][c] += (uint)incr;
  79. int d = o >> 3 /* Int mv data */;
  80. int f = (o >> 1) & 3 /* Fractional pel mv data */;
  81. int e = o & 1 /* High precision mv data */;
  82. if (c == (int)MvClassType.Class0)
  83. {
  84. counts.Class0[comp][d] += (uint)incr;
  85. counts.Class0Fp[comp][d][f] += (uint)incr;
  86. counts.Class0Hp[comp][e] += (uint)(usehp * incr);
  87. }
  88. else
  89. {
  90. int b = c + Constants.Class0Bits - 1; // Number of bits
  91. for (int i = 0; i < b; ++i)
  92. {
  93. counts.Bits[comp][i][(d >> i) & 1] += (uint)incr;
  94. }
  95. counts.Fp[comp][f] += (uint)incr;
  96. counts.Hp[comp][e] += (uint)(usehp * incr);
  97. }
  98. }
  99. public MvJointType GetJoint()
  100. {
  101. if (Row == 0)
  102. {
  103. return Col == 0 ? MvJointType.Zero : MvJointType.Hnzvz;
  104. }
  105. return Col == 0 ? MvJointType.Hzvnz : MvJointType.Hnzvnz;
  106. }
  107. internal void Inc(Ptr<Vp9BackwardUpdates> counts)
  108. {
  109. if (!counts.IsNull)
  110. {
  111. MvJointType j = GetJoint();
  112. ++counts.Value.Joints[(int)j];
  113. if (JointVertical(j))
  114. {
  115. IncComponent(Row, ref counts.Value, 0, 1, 1);
  116. }
  117. if (JointHorizontal(j))
  118. {
  119. IncComponent(Col, ref counts.Value, 1, 1, 1);
  120. }
  121. }
  122. }
  123. public void Clamp(int minCol, int maxCol, int minRow, int maxRow)
  124. {
  125. Col = (short)Math.Clamp(Col, minCol, maxCol);
  126. Row = (short)Math.Clamp(Row, minRow, maxRow);
  127. }
  128. private const int Border = 16 << 3; // Allow 16 pels in 1/8th pel units
  129. public void ClampRef(ref MacroBlockD xd)
  130. {
  131. Clamp(
  132. xd.MbToLeftEdge - Border,
  133. xd.MbToRightEdge + Border,
  134. xd.MbToTopEdge - Border,
  135. xd.MbToBottomEdge + Border);
  136. }
  137. public void LowerPrecision(bool allowHp)
  138. {
  139. bool useHp = allowHp && UseHp();
  140. if (!useHp)
  141. {
  142. if ((Row & 1) != 0)
  143. {
  144. Row += (short)(Row > 0 ? -1 : 1);
  145. }
  146. if ((Col & 1) != 0)
  147. {
  148. Col += (short)(Col > 0 ? -1 : 1);
  149. }
  150. }
  151. }
  152. public bool IsValid()
  153. {
  154. return Row is > Constants.MvLow and < Constants.MvUpp &&
  155. Col is > Constants.MvLow and < Constants.MvUpp;
  156. }
  157. }
  158. }