MacroBlockD.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. using Ryujinx.Common.Memory;
  2. using Ryujinx.Graphics.Video;
  3. namespace Ryujinx.Graphics.Nvdec.Vp9.Types
  4. {
  5. internal struct MacroBlockD
  6. {
  7. public Array3<MacroBlockDPlane> Plane;
  8. public byte BmodeBlocksWl;
  9. public byte BmodeBlocksHl;
  10. public Ptr<Vp9BackwardUpdates> Counts;
  11. public TileInfo Tile;
  12. public int MiStride;
  13. // Grid of 8x8 cells is placed over the block.
  14. // If some of them belong to the same mbtree-block
  15. // they will just have same mi[i][j] value
  16. public ArrayPtr<Ptr<ModeInfo>> Mi;
  17. public Ptr<ModeInfo> LeftMi;
  18. public Ptr<ModeInfo> AboveMi;
  19. public uint MaxBlocksWide;
  20. public uint MaxBlocksHigh;
  21. public ArrayPtr<Array3<byte>> PartitionProbs;
  22. /* Distance of MB away from frame edges */
  23. public int MbToLeftEdge;
  24. public int MbToRightEdge;
  25. public int MbToTopEdge;
  26. public int MbToBottomEdge;
  27. public Ptr<Vp9EntropyProbs> Fc;
  28. /* pointers to reference frames */
  29. public Array2<Ptr<RefBuffer>> BlockRefs;
  30. /* pointer to current frame */
  31. public Surface CurBuf;
  32. public Array3<ArrayPtr<sbyte>> AboveContext;
  33. public Array3<Array16<sbyte>> LeftContext;
  34. public ArrayPtr<sbyte> AboveSegContext;
  35. public Array8<sbyte> LeftSegContext;
  36. /* Bit depth: 8, 10, 12 */
  37. public int Bd;
  38. public bool Lossless;
  39. public bool Corrupted;
  40. public Ptr<InternalErrorInfo> ErrorInfo;
  41. public int GetPredContextSegId()
  42. {
  43. sbyte aboveSip = !AboveMi.IsNull ? AboveMi.Value.SegIdPredicted : (sbyte)0;
  44. sbyte leftSip = !LeftMi.IsNull ? LeftMi.Value.SegIdPredicted : (sbyte)0;
  45. return aboveSip + leftSip;
  46. }
  47. public int GetSkipContext()
  48. {
  49. int aboveSkip = !AboveMi.IsNull ? AboveMi.Value.Skip : 0;
  50. int leftSkip = !LeftMi.IsNull ? LeftMi.Value.Skip : 0;
  51. return aboveSkip + leftSkip;
  52. }
  53. public int GetPredContextSwitchableInterp()
  54. {
  55. // Note:
  56. // The mode info data structure has a one element border above and to the
  57. // left of the entries corresponding to real macroblocks.
  58. // The prediction flags in these dummy entries are initialized to 0.
  59. int leftType = !LeftMi.IsNull ? LeftMi.Value.InterpFilter : Constants.SwitchableFilters;
  60. int aboveType = !AboveMi.IsNull ? AboveMi.Value.InterpFilter : Constants.SwitchableFilters;
  61. if (leftType == aboveType)
  62. {
  63. return leftType;
  64. }
  65. else if (leftType == Constants.SwitchableFilters)
  66. {
  67. return aboveType;
  68. }
  69. else if (aboveType == Constants.SwitchableFilters)
  70. {
  71. return leftType;
  72. }
  73. else
  74. {
  75. return Constants.SwitchableFilters;
  76. }
  77. }
  78. // The mode info data structure has a one element border above and to the
  79. // left of the entries corresponding to real macroblocks.
  80. // The prediction flags in these dummy entries are initialized to 0.
  81. // 0 - inter/inter, inter/--, --/inter, --/--
  82. // 1 - intra/inter, inter/intra
  83. // 2 - intra/--, --/intra
  84. // 3 - intra/intra
  85. public int GetIntraInterContext()
  86. {
  87. if (!AboveMi.IsNull && !LeftMi.IsNull)
  88. { // Both edges available
  89. bool aboveIntra = !AboveMi.Value.IsInterBlock();
  90. bool leftIntra = !LeftMi.Value.IsInterBlock();
  91. return leftIntra && aboveIntra ? 3 : (leftIntra || aboveIntra ? 1 : 0);
  92. }
  93. else if (!AboveMi.IsNull || !LeftMi.IsNull)
  94. { // One edge available
  95. return 2 * (!(!AboveMi.IsNull ? AboveMi.Value : LeftMi.Value).IsInterBlock() ? 1 : 0);
  96. }
  97. return 0;
  98. }
  99. // Returns a context number for the given MB prediction signal
  100. // The mode info data structure has a one element border above and to the
  101. // left of the entries corresponding to real blocks.
  102. // The prediction flags in these dummy entries are initialized to 0.
  103. public int GetTxSizeContext()
  104. {
  105. int maxTxSize = (int)Luts.MaxTxSizeLookup[(int)Mi[0].Value.SbType];
  106. int aboveCtx = (!AboveMi.IsNull && AboveMi.Value.Skip == 0) ? (int)AboveMi.Value.TxSize : maxTxSize;
  107. int leftCtx = (!LeftMi.IsNull && LeftMi.Value.Skip == 0) ? (int)LeftMi.Value.TxSize : maxTxSize;
  108. if (LeftMi.IsNull)
  109. {
  110. leftCtx = aboveCtx;
  111. }
  112. if (AboveMi.IsNull)
  113. {
  114. aboveCtx = leftCtx;
  115. }
  116. return (aboveCtx + leftCtx) > maxTxSize ? 1 : 0;
  117. }
  118. public void SetupBlockPlanes(int ssX, int ssY)
  119. {
  120. int i;
  121. for (i = 0; i < Constants.MaxMbPlane; i++)
  122. {
  123. Plane[i].SubsamplingX = i != 0 ? ssX : 0;
  124. Plane[i].SubsamplingY = i != 0 ? ssY : 0;
  125. }
  126. }
  127. public void SetSkipContext(int miRow, int miCol)
  128. {
  129. int aboveIdx = miCol * 2;
  130. int leftIdx = (miRow * 2) & 15;
  131. int i;
  132. for (i = 0; i < Constants.MaxMbPlane; ++i)
  133. {
  134. ref MacroBlockDPlane pd = ref Plane[i];
  135. pd.AboveContext = AboveContext[i].Slice(aboveIdx >> pd.SubsamplingX);
  136. pd.LeftContext = new ArrayPtr<sbyte>(ref LeftContext[i][leftIdx >> pd.SubsamplingY], 16 - (leftIdx >> pd.SubsamplingY));
  137. }
  138. }
  139. internal void SetMiRowCol(ref TileInfo tile, int miRow, int bh, int miCol, int bw, int miRows, int miCols)
  140. {
  141. MbToTopEdge = -((miRow * Constants.MiSize) * 8);
  142. MbToBottomEdge = ((miRows - bh - miRow) * Constants.MiSize) * 8;
  143. MbToLeftEdge = -((miCol * Constants.MiSize) * 8);
  144. MbToRightEdge = ((miCols - bw - miCol) * Constants.MiSize) * 8;
  145. // Are edges available for intra prediction?
  146. AboveMi = (miRow != 0) ? Mi[-MiStride] : Ptr<ModeInfo>.Null;
  147. LeftMi = (miCol > tile.MiColStart) ? Mi[-1] : Ptr<ModeInfo>.Null;
  148. }
  149. }
  150. }