Mv.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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 => new byte[]
  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,
  14. 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
  15. 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 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, 6, 6, 6,
  17. 6, 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,
  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,
  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,
  20. 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,
  21. 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,
  22. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 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,
  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,
  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,
  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,
  27. 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,
  28. 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,
  29. 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,
  30. 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,
  31. 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,
  32. 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,
  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,
  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,
  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,
  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,
  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,
  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,
  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,
  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,
  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,
  42. 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,
  43. 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,
  44. 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,
  45. 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,
  46. 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,
  47. 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,
  48. 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,
  49. 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,
  50. 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,
  51. 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,
  52. 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10
  53. };
  54. public bool UseMvHp()
  55. {
  56. const int kMvRefThresh = 64; // Threshold for use of high-precision 1/8 mv
  57. return Math.Abs(Row) < kMvRefThresh && Math.Abs(Col) < kMvRefThresh;
  58. }
  59. public static bool MvJointVertical(MvJointType type)
  60. {
  61. return type == MvJointType.MvJointHzvnz || type == MvJointType.MvJointHnzvnz;
  62. }
  63. public static bool MvJointHorizontal(MvJointType type)
  64. {
  65. return type == MvJointType.MvJointHnzvz || type == MvJointType.MvJointHnzvnz;
  66. }
  67. private static int MvClassBase(MvClassType c)
  68. {
  69. return c != 0 ? Constants.Class0Size << ((int)c + 2) : 0;
  70. }
  71. private static MvClassType GetMvClass(int z, Ptr<int> offset)
  72. {
  73. MvClassType c = (z >= Constants.Class0Size * 4096) ? MvClassType.MvClass10 : (MvClassType)LogInBase2[z >> 3];
  74. if (!offset.IsNull)
  75. {
  76. offset.Value = z - MvClassBase(c);
  77. }
  78. return c;
  79. }
  80. private static void IncMvComponent(int v, ref Vp9BackwardUpdates counts, int comp, int incr, int usehp)
  81. {
  82. int s, z, c, o = 0, d, e, f;
  83. Debug.Assert(v != 0); /* Should not be zero */
  84. s = v < 0 ? 1 : 0;
  85. counts.Sign[comp][s] += (uint)incr;
  86. z = (s != 0 ? -v : v) - 1; /* Magnitude - 1 */
  87. c = (int)GetMvClass(z, new Ptr<int>(ref o));
  88. counts.Classes[comp][c] += (uint)incr;
  89. d = (o >> 3); /* Int mv data */
  90. f = (o >> 1) & 3; /* Fractional pel mv data */
  91. e = (o & 1); /* High precision mv data */
  92. if (c == (int)MvClassType.MvClass0)
  93. {
  94. counts.Class0[comp][d] += (uint)incr;
  95. counts.Class0Fp[comp][d][f] += (uint)incr;
  96. counts.Class0Hp[comp][e] += (uint)(usehp * incr);
  97. }
  98. else
  99. {
  100. int i;
  101. int b = c + Constants.Class0Bits - 1; // Number of bits
  102. for (i = 0; i < b; ++i)
  103. {
  104. counts.Bits[comp][i][((d >> i) & 1)] += (uint)incr;
  105. }
  106. counts.Fp[comp][f] += (uint)incr;
  107. counts.Hp[comp][e] += (uint)(usehp * incr);
  108. }
  109. }
  110. private MvJointType GetMvJoint()
  111. {
  112. if (Row == 0)
  113. {
  114. return Col == 0 ? MvJointType.MvJointZero : MvJointType.MvJointHnzvz;
  115. }
  116. else
  117. {
  118. return Col == 0 ? MvJointType.MvJointHzvnz : MvJointType.MvJointHnzvnz;
  119. }
  120. }
  121. internal void IncMv(Ptr<Vp9BackwardUpdates> counts)
  122. {
  123. if (!counts.IsNull)
  124. {
  125. MvJointType j = GetMvJoint();
  126. ++counts.Value.Joints[(int)j];
  127. if (MvJointVertical(j))
  128. {
  129. IncMvComponent(Row, ref counts.Value, 0, 1, 1);
  130. }
  131. if (MvJointHorizontal(j))
  132. {
  133. IncMvComponent(Col, ref counts.Value, 1, 1, 1);
  134. }
  135. }
  136. }
  137. public void ClampMv(int minCol, int maxCol, int minRow, int maxRow)
  138. {
  139. Col = (short)Math.Clamp(Col, minCol, maxCol);
  140. Row = (short)Math.Clamp(Row, minRow, maxRow);
  141. }
  142. private const int MvBorder = (16 << 3); // Allow 16 pels in 1/8th pel units
  143. public void ClampMvRef(ref MacroBlockD xd)
  144. {
  145. ClampMv(
  146. xd.MbToLeftEdge - MvBorder,
  147. xd.MbToRightEdge + MvBorder,
  148. xd.MbToTopEdge - MvBorder,
  149. xd.MbToBottomEdge + MvBorder);
  150. }
  151. public void LowerMvPrecision(bool allowHP)
  152. {
  153. bool useHP = allowHP && UseMvHp();
  154. if (!useHP)
  155. {
  156. if ((Row & 1) != 0)
  157. {
  158. Row += (short)(Row > 0 ? -1 : 1);
  159. }
  160. if ((Col & 1) != 0)
  161. {
  162. Col += (short)(Col > 0 ? -1 : 1);
  163. }
  164. }
  165. }
  166. }
  167. }