| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536 |
- using Ryujinx.Graphics.Nvdec.Vp9.Common;
- using Ryujinx.Graphics.Nvdec.Vp9.Types;
- using System;
- using static Ryujinx.Graphics.Nvdec.Vp9.Dsp.InvTxfm;
- namespace Ryujinx.Graphics.Nvdec.Vp9
- {
- internal static class Idct
- {
- private delegate void Transform1D(ReadOnlySpan<int> input, Span<int> output);
- private delegate void HighbdTransform1D(ReadOnlySpan<int> input, Span<int> output, int bd);
- private struct Transform2D
- {
- public Transform1D Cols, Rows; // Vertical and horizontal
- public Transform2D(Transform1D cols, Transform1D rows)
- {
- Cols = cols;
- Rows = rows;
- }
- }
- private struct HighbdTransform2D
- {
- public HighbdTransform1D Cols, Rows; // Vertical and horizontal
- public HighbdTransform2D(HighbdTransform1D cols, HighbdTransform1D rows)
- {
- Cols = cols;
- Rows = rows;
- }
- }
- private static readonly Transform2D[] Iht4 = new Transform2D[]
- {
- new Transform2D(Idct4, Idct4), // DCT_DCT = 0
- new Transform2D(Iadst4, Idct4), // ADST_DCT = 1
- new Transform2D(Idct4, Iadst4), // DCT_ADST = 2
- new Transform2D(Iadst4, Iadst4) // ADST_ADST = 3
- };
- public static void Iht4x416Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int txType)
- {
- int i, j;
- Span<int> output = stackalloc int[4 * 4];
- Span<int> outptr = output;
- Span<int> tempIn = stackalloc int[4];
- Span<int> tempOut = stackalloc int[4];
- // Inverse transform row vectors
- for (i = 0; i < 4; ++i)
- {
- Iht4[txType].Rows(input, outptr);
- input = input.Slice(4);
- outptr = outptr.Slice(4);
- }
- // Inverse transform column vectors
- for (i = 0; i < 4; ++i)
- {
- for (j = 0; j < 4; ++j)
- {
- tempIn[j] = output[j * 4 + i];
- }
- Iht4[txType].Cols(tempIn, tempOut);
- for (j = 0; j < 4; ++j)
- {
- dest[j * stride + i] = ClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 4));
- }
- }
- }
- private static readonly Transform2D[] Iht8 = new Transform2D[]
- {
- new Transform2D(Idct8, Idct8), // DCT_DCT = 0
- new Transform2D(Iadst8, Idct8), // ADST_DCT = 1
- new Transform2D(Idct8, Iadst8), // DCT_ADST = 2
- new Transform2D(Iadst8, Iadst8) // ADST_ADST = 3
- };
- public static void Iht8x864Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int txType)
- {
- int i, j;
- Span<int> output = stackalloc int[8 * 8];
- Span<int> outptr = output;
- Span<int> tempIn = stackalloc int[8];
- Span<int> tempOut = stackalloc int[8];
- Transform2D ht = Iht8[txType];
- // Inverse transform row vectors
- for (i = 0; i < 8; ++i)
- {
- ht.Rows(input, outptr);
- input = input.Slice(8);
- outptr = outptr.Slice(8);
- }
- // Inverse transform column vectors
- for (i = 0; i < 8; ++i)
- {
- for (j = 0; j < 8; ++j)
- {
- tempIn[j] = output[j * 8 + i];
- }
- ht.Cols(tempIn, tempOut);
- for (j = 0; j < 8; ++j)
- {
- dest[j * stride + i] = ClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 5));
- }
- }
- }
- private static readonly Transform2D[] Iht16 = new Transform2D[]
- {
- new Transform2D(Idct16, Idct16), // DCT_DCT = 0
- new Transform2D(Iadst16, Idct16), // ADST_DCT = 1
- new Transform2D(Idct16, Iadst16), // DCT_ADST = 2
- new Transform2D(Iadst16, Iadst16) // ADST_ADST = 3
- };
- public static void Iht16x16256Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int txType)
- {
- int i, j;
- Span<int> output = stackalloc int[16 * 16];
- Span<int> outptr = output;
- Span<int> tempIn = stackalloc int[16];
- Span<int> tempOut = stackalloc int[16];
- Transform2D ht = Iht16[txType];
- // Rows
- for (i = 0; i < 16; ++i)
- {
- ht.Rows(input, outptr);
- input = input.Slice(16);
- outptr = outptr.Slice(16);
- }
- // Columns
- for (i = 0; i < 16; ++i)
- {
- for (j = 0; j < 16; ++j)
- {
- tempIn[j] = output[j * 16 + i];
- }
- ht.Cols(tempIn, tempOut);
- for (j = 0; j < 16; ++j)
- {
- dest[j * stride + i] = ClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 6));
- }
- }
- }
- // Idct
- public static void Idct4x4Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
- {
- if (eob > 1)
- {
- Idct4x416Add(input, dest, stride);
- }
- else
- {
- Idct4x41Add(input, dest, stride);
- }
- }
- public static void Iwht4x4Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
- {
- if (eob > 1)
- {
- Iwht4x416Add(input, dest, stride);
- }
- else
- {
- Iwht4x41Add(input, dest, stride);
- }
- }
- public static void Idct8x8Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
- {
- // If dc is 1, then input[0] is the reconstructed value, do not need
- // dequantization. Also, when dc is 1, dc is counted in eobs, namely eobs >=1.
- // The calculation can be simplified if there are not many non-zero dct
- // coefficients. Use eobs to decide what to do.
- if (eob == 1)
- {
- // DC only DCT coefficient
- Idct8x81Add(input, dest, stride);
- }
- else if (eob <= 12)
- {
- Idct8x812Add(input, dest, stride);
- }
- else
- {
- Idct8x864Add(input, dest, stride);
- }
- }
- public static void Idct16x16Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
- {
- /* The calculation can be simplified if there are not many non-zero dct
- * coefficients. Use eobs to separate different cases. */
- if (eob == 1) /* DC only DCT coefficient. */
- {
- Idct16x161Add(input, dest, stride);
- }
- else if (eob <= 10)
- {
- Idct16x1610Add(input, dest, stride);
- }
- else if (eob <= 38)
- {
- Idct16x1638Add(input, dest, stride);
- }
- else
- {
- Idct16x16256Add(input, dest, stride);
- }
- }
- public static void Idct32x32Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
- {
- if (eob == 1)
- {
- Idct32x321Add(input, dest, stride);
- }
- else if (eob <= 34)
- {
- // Non-zero coeff only in upper-left 8x8
- Idct32x3234Add(input, dest, stride);
- }
- else if (eob <= 135)
- {
- // Non-zero coeff only in upper-left 16x16
- Idct32x32135Add(input, dest, stride);
- }
- else
- {
- Idct32x321024Add(input, dest, stride);
- }
- }
- // Iht
- public static void Iht4x4Add(TxType txType, ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
- {
- if (txType == TxType.DctDct)
- {
- Idct4x4Add(input, dest, stride, eob);
- }
- else
- {
- Iht4x416Add(input, dest, stride, (int)txType);
- }
- }
- public static void Iht8x8Add(TxType txType, ReadOnlySpan<int> input, Span<byte> dest, int stride, int eob)
- {
- if (txType == TxType.DctDct)
- {
- Idct8x8Add(input, dest, stride, eob);
- }
- else
- {
- Iht8x864Add(input, dest, stride, (int)txType);
- }
- }
- public static void Iht16x16Add(TxType txType, ReadOnlySpan<int> input, Span<byte> dest,
- int stride, int eob)
- {
- if (txType == TxType.DctDct)
- {
- Idct16x16Add(input, dest, stride, eob);
- }
- else
- {
- Iht16x16256Add(input, dest, stride, (int)txType);
- }
- }
- private static readonly HighbdTransform2D[] HighbdIht4 = new HighbdTransform2D[]
- {
- new HighbdTransform2D(HighbdIdct4, HighbdIdct4), // DCT_DCT = 0
- new HighbdTransform2D(HighbdIadst4, HighbdIdct4), // ADST_DCT = 1
- new HighbdTransform2D(HighbdIdct4, HighbdIadst4), // DCT_ADST = 2
- new HighbdTransform2D(HighbdIadst4, HighbdIadst4) // ADST_ADST = 3
- };
- public static void HighbdIht4x416Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int txType, int bd)
- {
- int i, j;
- Span<int> output = stackalloc int[4 * 4];
- Span<int> outptr = output;
- Span<int> tempIn = stackalloc int[4];
- Span<int> tempOut = stackalloc int[4];
- // Inverse transform row vectors.
- for (i = 0; i < 4; ++i)
- {
- HighbdIht4[txType].Rows(input, outptr, bd);
- input = input.Slice(4);
- outptr = outptr.Slice(4);
- }
- // Inverse transform column vectors.
- for (i = 0; i < 4; ++i)
- {
- for (j = 0; j < 4; ++j)
- {
- tempIn[j] = output[j * 4 + i];
- }
- HighbdIht4[txType].Cols(tempIn, tempOut, bd);
- for (j = 0; j < 4; ++j)
- {
- dest[j * stride + i] = HighbdClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 4), bd);
- }
- }
- }
- private static readonly HighbdTransform2D[] HighIht8 = new HighbdTransform2D[]
- {
- new HighbdTransform2D(HighbdIdct8, HighbdIdct8), // DCT_DCT = 0
- new HighbdTransform2D(HighbdIadst8, HighbdIdct8), // ADST_DCT = 1
- new HighbdTransform2D(HighbdIdct8, HighbdIadst8), // DCT_ADST = 2
- new HighbdTransform2D(HighbdIadst8, HighbdIadst8) // ADST_ADST = 3
- };
- public static void HighbdIht8x864Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int txType, int bd)
- {
- int i, j;
- Span<int> output = stackalloc int[8 * 8];
- Span<int> outptr = output;
- Span<int> tempIn = stackalloc int[8];
- Span<int> tempOut = stackalloc int[8];
- HighbdTransform2D ht = HighIht8[txType];
- // Inverse transform row vectors.
- for (i = 0; i < 8; ++i)
- {
- ht.Rows(input, outptr, bd);
- input = input.Slice(8);
- outptr = output.Slice(8);
- }
- // Inverse transform column vectors.
- for (i = 0; i < 8; ++i)
- {
- for (j = 0; j < 8; ++j)
- {
- tempIn[j] = output[j * 8 + i];
- }
- ht.Cols(tempIn, tempOut, bd);
- for (j = 0; j < 8; ++j)
- {
- dest[j * stride + i] = HighbdClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 5), bd);
- }
- }
- }
- private static readonly HighbdTransform2D[] HighIht16 = new HighbdTransform2D[]
- {
- new HighbdTransform2D(HighbdIdct16, HighbdIdct16), // DCT_DCT = 0
- new HighbdTransform2D(HighbdIadst16, HighbdIdct16), // ADST_DCT = 1
- new HighbdTransform2D(HighbdIdct16, HighbdIadst16), // DCT_ADST = 2
- new HighbdTransform2D(HighbdIadst16, HighbdIadst16) // ADST_ADST = 3
- };
- public static void HighbdIht16x16256Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int txType, int bd)
- {
- int i, j;
- Span<int> output = stackalloc int[16 * 16];
- Span<int> outptr = output;
- Span<int> tempIn = stackalloc int[16];
- Span<int> tempOut = stackalloc int[16];
- HighbdTransform2D ht = HighIht16[txType];
- // Rows
- for (i = 0; i < 16; ++i)
- {
- ht.Rows(input, outptr, bd);
- input = input.Slice(16);
- outptr = output.Slice(16);
- }
- // Columns
- for (i = 0; i < 16; ++i)
- {
- for (j = 0; j < 16; ++j)
- {
- tempIn[j] = output[j * 16 + i];
- }
- ht.Cols(tempIn, tempOut, bd);
- for (j = 0; j < 16; ++j)
- {
- dest[j * stride + i] = HighbdClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 6), bd);
- }
- }
- }
- // Idct
- public static void HighbdIdct4x4Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
- {
- if (eob > 1)
- {
- HighbdIdct4x416Add(input, dest, stride, bd);
- }
- else
- {
- HighbdIdct4x41Add(input, dest, stride, bd);
- }
- }
- public static void HighbdIwht4x4Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
- {
- if (eob > 1)
- {
- HighbdIwht4x416Add(input, dest, stride, bd);
- }
- else
- {
- HighbdIwht4x41Add(input, dest, stride, bd);
- }
- }
- public static void HighbdIdct8x8Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
- {
- // If dc is 1, then input[0] is the reconstructed value, do not need
- // dequantization. Also, when dc is 1, dc is counted in eobs, namely eobs >=1.
- // The calculation can be simplified if there are not many non-zero dct
- // coefficients. Use eobs to decide what to do.
- // DC only DCT coefficient
- if (eob == 1)
- {
- vpx_Highbdidct8x8_1_add_c(input, dest, stride, bd);
- }
- else if (eob <= 12)
- {
- HighbdIdct8x812Add(input, dest, stride, bd);
- }
- else
- {
- HighbdIdct8x864Add(input, dest, stride, bd);
- }
- }
- public static void HighbdIdct16x16Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
- {
- // The calculation can be simplified if there are not many non-zero dct
- // coefficients. Use eobs to separate different cases.
- // DC only DCT coefficient.
- if (eob == 1)
- {
- HighbdIdct16x161Add(input, dest, stride, bd);
- }
- else if (eob <= 10)
- {
- HighbdIdct16x1610Add(input, dest, stride, bd);
- }
- else if (eob <= 38)
- {
- HighbdIdct16x1638Add(input, dest, stride, bd);
- }
- else
- {
- HighbdIdct16x16256Add(input, dest, stride, bd);
- }
- }
- public static void HighbdIdct32x32Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
- {
- // Non-zero coeff only in upper-left 8x8
- if (eob == 1)
- {
- HighbdIdct32x321Add(input, dest, stride, bd);
- }
- else if (eob <= 34)
- {
- HighbdIdct32x3234Add(input, dest, stride, bd);
- }
- else if (eob <= 135)
- {
- HighbdIdct32x32135Add(input, dest, stride, bd);
- }
- else
- {
- HighbdIdct32x321024Add(input, dest, stride, bd);
- }
- }
- // Iht
- public static void HighbdIht4x4Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
- {
- if (txType == TxType.DctDct)
- {
- HighbdIdct4x4Add(input, dest, stride, eob, bd);
- }
- else
- {
- HighbdIht4x416Add(input, dest, stride, (int)txType, bd);
- }
- }
- public static void HighbdIht8x8Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
- {
- if (txType == TxType.DctDct)
- {
- HighbdIdct8x8Add(input, dest, stride, eob, bd);
- }
- else
- {
- HighbdIht8x864Add(input, dest, stride, (int)txType, bd);
- }
- }
- public static void HighbdIht16x16Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
- {
- if (txType == TxType.DctDct)
- {
- HighbdIdct16x16Add(input, dest, stride, eob, bd);
- }
- else
- {
- HighbdIht16x16256Add(input, dest, stride, (int)txType, bd);
- }
- }
- }
- }
|