aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Nvdec.Vp9/Types/MacroBlockD.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2020-07-12 00:07:01 -0300
committerGitHub <noreply@github.com>2020-07-12 05:07:01 +0200
commit4d02a2d2c0451b4de1f6de3bbce54c457cacebe2 (patch)
tree120fe4fb8cfa1ac1c6ef4c97d92be47e955e8c0f /Ryujinx.Graphics.Nvdec.Vp9/Types/MacroBlockD.cs
parent38b26cf4242999fa7d8c550993ac0940cd03d55f (diff)
New NVDEC and VIC implementation (#1384)
* Initial NVDEC and VIC implementation * Update FFmpeg.AutoGen to 4.3.0 * Add nvdec dependencies for Windows * Unify some VP9 structures * Rename VP9 structure fields * Improvements to Video API * XML docs for Common.Memory * Remove now unused or redundant overloads from MemoryAccessor * NVDEC UV surface read/write scalar paths * Add FIXME comments about hacky things/stuff that will need to be fixed in the future * Cleaned up VP9 memory allocation * Remove some debug logs * Rename some VP9 structs * Remove unused struct * No need to compile Ryujinx.Graphics.Host1x with unsafe anymore * Name AsyncWorkQueue threads to make debugging easier * Make Vp9PictureInfo a ref struct * LayoutConverter no longer needs the depth argument (broken by rebase) * Pooling of VP9 buffers, plus fix a memory leak on VP9 * Really wish VS could rename projects properly... * Address feedback * Remove using * Catch OperationCanceledException * Add licensing informations * Add THIRDPARTY.md to release too Co-authored-by: Thog <me@thog.eu>
Diffstat (limited to 'Ryujinx.Graphics.Nvdec.Vp9/Types/MacroBlockD.cs')
-rw-r--r--Ryujinx.Graphics.Nvdec.Vp9/Types/MacroBlockD.cs179
1 files changed, 179 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.Nvdec.Vp9/Types/MacroBlockD.cs b/Ryujinx.Graphics.Nvdec.Vp9/Types/MacroBlockD.cs
new file mode 100644
index 00000000..f1111528
--- /dev/null
+++ b/Ryujinx.Graphics.Nvdec.Vp9/Types/MacroBlockD.cs
@@ -0,0 +1,179 @@
+using Ryujinx.Common.Memory;
+using Ryujinx.Graphics.Video;
+
+namespace Ryujinx.Graphics.Nvdec.Vp9.Types
+{
+ internal struct MacroBlockD
+ {
+ public Array3<MacroBlockDPlane> Plane;
+ public byte BmodeBlocksWl;
+ public byte BmodeBlocksHl;
+
+ public Ptr<Vp9BackwardUpdates> Counts;
+ public TileInfo Tile;
+
+ public int MiStride;
+
+ // Grid of 8x8 cells is placed over the block.
+ // If some of them belong to the same mbtree-block
+ // they will just have same mi[i][j] value
+ public ArrayPtr<Ptr<ModeInfo>> Mi;
+ public Ptr<ModeInfo> LeftMi;
+ public Ptr<ModeInfo> AboveMi;
+
+ public uint MaxBlocksWide;
+ public uint MaxBlocksHigh;
+
+ public ArrayPtr<Array3<byte>> PartitionProbs;
+
+ /* Distance of MB away from frame edges */
+ public int MbToLeftEdge;
+ public int MbToRightEdge;
+ public int MbToTopEdge;
+ public int MbToBottomEdge;
+
+ public Ptr<Vp9EntropyProbs> Fc;
+
+ /* pointers to reference frames */
+ public Array2<Ptr<RefBuffer>> BlockRefs;
+
+ /* pointer to current frame */
+ public Surface CurBuf;
+
+ public Array3<ArrayPtr<sbyte>> AboveContext;
+ public Array3<Array16<sbyte>> LeftContext;
+
+ public ArrayPtr<sbyte> AboveSegContext;
+ public Array8<sbyte> LeftSegContext;
+
+ /* Bit depth: 8, 10, 12 */
+ public int Bd;
+
+ public bool Lossless;
+ public bool Corrupted;
+
+ public Ptr<InternalErrorInfo> ErrorInfo;
+
+ public int GetPredContextSegId()
+ {
+ sbyte aboveSip = !AboveMi.IsNull ? AboveMi.Value.SegIdPredicted : (sbyte)0;
+ sbyte leftSip = !LeftMi.IsNull ? LeftMi.Value.SegIdPredicted : (sbyte)0;
+
+ return aboveSip + leftSip;
+ }
+
+ public int GetSkipContext()
+ {
+ int aboveSkip = !AboveMi.IsNull ? AboveMi.Value.Skip : 0;
+ int leftSkip = !LeftMi.IsNull ? LeftMi.Value.Skip : 0;
+ return aboveSkip + leftSkip;
+ }
+
+ public int GetPredContextSwitchableInterp()
+ {
+ // Note:
+ // The mode info data structure has a one element border above and to the
+ // left of the entries corresponding to real macroblocks.
+ // The prediction flags in these dummy entries are initialized to 0.
+ int leftType = !LeftMi.IsNull ? LeftMi.Value.InterpFilter : Constants.SwitchableFilters;
+ int aboveType = !AboveMi.IsNull ? AboveMi.Value.InterpFilter : Constants.SwitchableFilters;
+
+ if (leftType == aboveType)
+ {
+ return leftType;
+ }
+ else if (leftType == Constants.SwitchableFilters)
+ {
+ return aboveType;
+ }
+ else if (aboveType == Constants.SwitchableFilters)
+ {
+ return leftType;
+ }
+ else
+ {
+ return Constants.SwitchableFilters;
+ }
+ }
+
+ // The mode info data structure has a one element border above and to the
+ // left of the entries corresponding to real macroblocks.
+ // The prediction flags in these dummy entries are initialized to 0.
+ // 0 - inter/inter, inter/--, --/inter, --/--
+ // 1 - intra/inter, inter/intra
+ // 2 - intra/--, --/intra
+ // 3 - intra/intra
+ public int GetIntraInterContext()
+ {
+ if (!AboveMi.IsNull && !LeftMi.IsNull)
+ { // Both edges available
+ bool aboveIntra = !AboveMi.Value.IsInterBlock();
+ bool leftIntra = !LeftMi.Value.IsInterBlock();
+ return leftIntra && aboveIntra ? 3 : (leftIntra || aboveIntra ? 1 : 0);
+ }
+ else if (!AboveMi.IsNull || !LeftMi.IsNull)
+ { // One edge available
+ return 2 * (!(!AboveMi.IsNull ? AboveMi.Value : LeftMi.Value).IsInterBlock() ? 1 : 0);
+ }
+ return 0;
+ }
+
+ // Returns a context number for the given MB prediction signal
+ // The mode info data structure has a one element border above and to the
+ // left of the entries corresponding to real blocks.
+ // The prediction flags in these dummy entries are initialized to 0.
+ public int GetTxSizeContext()
+ {
+ int maxTxSize = (int)Luts.MaxTxSizeLookup[(int)Mi[0].Value.SbType];
+ int aboveCtx = (!AboveMi.IsNull && AboveMi.Value.Skip == 0) ? (int)AboveMi.Value.TxSize : maxTxSize;
+ int leftCtx = (!LeftMi.IsNull && LeftMi.Value.Skip == 0) ? (int)LeftMi.Value.TxSize : maxTxSize;
+ if (LeftMi.IsNull)
+ {
+ leftCtx = aboveCtx;
+ }
+
+ if (AboveMi.IsNull)
+ {
+ aboveCtx = leftCtx;
+ }
+
+ return (aboveCtx + leftCtx) > maxTxSize ? 1 : 0;
+ }
+
+ public void SetupBlockPlanes(int ssX, int ssY)
+ {
+ int i;
+
+ for (i = 0; i < Constants.MaxMbPlane; i++)
+ {
+ Plane[i].SubsamplingX = i != 0 ? ssX : 0;
+ Plane[i].SubsamplingY = i != 0 ? ssY : 0;
+ }
+ }
+
+ public void SetSkipContext(int miRow, int miCol)
+ {
+ int aboveIdx = miCol * 2;
+ int leftIdx = (miRow * 2) & 15;
+ int i;
+ for (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], 16 - (leftIdx >> pd.SubsamplingY));
+ }
+ }
+
+ internal void SetMiRowCol(ref TileInfo tile, int miRow, int bh, int miCol, int bw, int miRows, int miCols)
+ {
+ MbToTopEdge = -((miRow * Constants.MiSize) * 8);
+ MbToBottomEdge = ((miRows - bh - miRow) * Constants.MiSize) * 8;
+ MbToLeftEdge = -((miCol * Constants.MiSize) * 8);
+ MbToRightEdge = ((miCols - bw - miCol) * Constants.MiSize) * 8;
+
+ // Are edges available for intra prediction?
+ AboveMi = (miRow != 0) ? Mi[-MiStride] : Ptr<ModeInfo>.Null;
+ LeftMi = (miCol > tile.MiColStart) ? Mi[-1] : Ptr<ModeInfo>.Null;
+ }
+ }
+}