summaryrefslogtreecommitdiffstats
path: root/third_party/aom/av1/common/txb_common.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/aom/av1/common/txb_common.h')
-rw-r--r--third_party/aom/av1/common/txb_common.h304
1 files changed, 304 insertions, 0 deletions
diff --git a/third_party/aom/av1/common/txb_common.h b/third_party/aom/av1/common/txb_common.h
new file mode 100644
index 000000000..cdd9ca26e
--- /dev/null
+++ b/third_party/aom/av1/common/txb_common.h
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2017, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+#ifndef AV1_COMMON_TXB_COMMON_H_
+#define AV1_COMMON_TXB_COMMON_H_
+extern const int16_t av1_coeff_band_4x4[16];
+
+extern const int16_t av1_coeff_band_8x8[64];
+
+extern const int16_t av1_coeff_band_16x16[256];
+
+extern const int16_t av1_coeff_band_32x32[1024];
+
+typedef struct txb_ctx {
+ int txb_skip_ctx;
+ int dc_sign_ctx;
+} TXB_CTX;
+
+#define BASE_CONTEXT_POSITION_NUM 12
+static int base_ref_offset[BASE_CONTEXT_POSITION_NUM][2] = {
+ /* clang-format off*/
+ { -2, 0 }, { -1, -1 }, { -1, 0 }, { -1, 1 }, { 0, -2 }, { 0, -1 }, { 0, 1 },
+ { 0, 2 }, { 1, -1 }, { 1, 0 }, { 1, 1 }, { 2, 0 }
+ /* clang-format on*/
+};
+
+static INLINE int get_base_ctx(const tran_low_t *tcoeffs,
+ int c, // raster order
+ const int bwl, const int level) {
+ const int row = c >> bwl;
+ const int col = c - (row << bwl);
+ const int stride = 1 << bwl;
+ const int level_minus_1 = level - 1;
+ int ctx = 0;
+ int mag = 0;
+ int idx;
+ int ctx_idx = -1;
+ tran_low_t abs_coeff;
+
+ ctx = 0;
+ for (idx = 0; idx < BASE_CONTEXT_POSITION_NUM; ++idx) {
+ int ref_row = row + base_ref_offset[idx][0];
+ int ref_col = col + base_ref_offset[idx][1];
+ int pos = (ref_row << bwl) + ref_col;
+
+ if (ref_row < 0 || ref_col < 0 || ref_row >= stride || ref_col >= stride)
+ continue;
+
+ abs_coeff = abs(tcoeffs[pos]);
+ ctx += abs_coeff > level_minus_1;
+
+ if (base_ref_offset[idx][0] >= 0 && base_ref_offset[idx][1] >= 0)
+ mag |= abs_coeff > level;
+ }
+ ctx = (ctx + 1) >> 1;
+ if (row == 0 && col == 0) {
+ ctx_idx = (ctx << 1) + mag;
+ assert(ctx_idx < 8);
+ } else if (row == 0) {
+ ctx_idx = 8 + (ctx << 1) + mag;
+ assert(ctx_idx < 18);
+ } else if (col == 0) {
+ ctx_idx = 8 + 10 + (ctx << 1) + mag;
+ assert(ctx_idx < 28);
+ } else {
+ ctx_idx = 8 + 10 + 10 + (ctx << 1) + mag;
+ assert(ctx_idx < COEFF_BASE_CONTEXTS);
+ }
+ return ctx_idx;
+}
+
+#define BR_CONTEXT_POSITION_NUM 8 // Base range coefficient context
+static int br_ref_offset[BR_CONTEXT_POSITION_NUM][2] = {
+ /* clang-format off*/
+ { -1, -1 }, { -1, 0 }, { -1, 1 }, { 0, -1 },
+ { 0, 1 }, { 1, -1 }, { 1, 0 }, { 1, 1 },
+ /* clang-format on*/
+};
+
+static int br_level_map[9] = {
+ 0, 0, 1, 1, 2, 2, 3, 3, 3,
+};
+
+static INLINE int get_level_ctx(const tran_low_t *tcoeffs,
+ const int c, // raster order
+ const int bwl) {
+ const int row = c >> bwl;
+ const int col = c - (row << bwl);
+ const int stride = 1 << bwl;
+ const int level_minus_1 = NUM_BASE_LEVELS;
+ int ctx = 0;
+ int idx;
+ tran_low_t abs_coeff;
+ int mag = 0, offset = 0;
+
+ for (idx = 0; idx < BR_CONTEXT_POSITION_NUM; ++idx) {
+ int ref_row = row + br_ref_offset[idx][0];
+ int ref_col = col + br_ref_offset[idx][1];
+ int pos = (ref_row << bwl) + ref_col;
+
+ if (ref_row < 0 || ref_col < 0 || ref_row >= stride || ref_col >= stride)
+ continue;
+
+ abs_coeff = abs(tcoeffs[pos]);
+ ctx += abs_coeff > level_minus_1;
+
+ if (br_ref_offset[idx][0] >= 0 && br_ref_offset[idx][1] >= 0)
+ mag = AOMMAX(mag, abs_coeff);
+ }
+
+ if (mag <= 1)
+ offset = 0;
+ else if (mag <= 3)
+ offset = 1;
+ else if (mag <= 6)
+ offset = 2;
+ else
+ offset = 3;
+
+ ctx = br_level_map[ctx];
+
+ ctx += offset * BR_TMP_OFFSET;
+
+ // DC: 0 - 1
+ if (row == 0 && col == 0) return ctx;
+
+ // Top row: 2 - 4
+ if (row == 0) return 2 + ctx;
+
+ // Left column: 5 - 7
+ if (col == 0) return 5 + ctx;
+
+ // others: 8 - 11
+ return 8 + ctx;
+}
+
+static int sig_ref_offset[11][2] = {
+ { -2, -1 }, { -2, 0 }, { -2, 1 }, { -1, -2 }, { -1, -1 }, { -1, 0 },
+ { -1, 1 }, { 0, -2 }, { 0, -1 }, { 1, -2 }, { 1, -1 },
+};
+
+static INLINE int get_nz_map_ctx(const tran_low_t *tcoeffs,
+ const uint8_t *txb_mask,
+ const int c, // raster order
+ const int bwl) {
+ const int row = c >> bwl;
+ const int col = c - (row << bwl);
+ int ctx = 0;
+ int idx;
+ int stride = 1 << bwl;
+
+ if (row == 0 && col == 0) return 0;
+
+ if (row == 0 && col == 1) return 1 + (tcoeffs[0] != 0);
+
+ if (row == 1 && col == 0) return 3 + (tcoeffs[0] != 0);
+
+ if (row == 1 && col == 1) {
+ int pos;
+ ctx = (tcoeffs[0] != 0);
+
+ if (txb_mask[1]) ctx += (tcoeffs[1] != 0);
+ pos = 1 << bwl;
+ if (txb_mask[pos]) ctx += (tcoeffs[pos] != 0);
+
+ ctx = (ctx + 1) >> 1;
+
+ assert(5 + ctx <= 7);
+
+ return 5 + ctx;
+ }
+
+ for (idx = 0; idx < 11; ++idx) {
+ int ref_row = row + sig_ref_offset[idx][0];
+ int ref_col = col + sig_ref_offset[idx][1];
+ int pos;
+
+ if (ref_row < 0 || ref_col < 0 || ref_row >= stride || ref_col >= stride)
+ continue;
+
+ pos = (ref_row << bwl) + ref_col;
+
+ if (txb_mask[pos]) ctx += (tcoeffs[pos] != 0);
+ }
+
+ if (row == 0) {
+ ctx = (ctx + 1) >> 1;
+
+ assert(ctx < 3);
+ return 8 + ctx;
+ }
+
+ if (col == 0) {
+ ctx = (ctx + 1) >> 1;
+
+ assert(ctx < 3);
+ return 11 + ctx;
+ }
+
+ ctx >>= 1;
+
+ assert(14 + ctx < 20);
+
+ return 14 + ctx;
+}
+
+static INLINE int get_eob_ctx(const tran_low_t *tcoeffs,
+ const int c, // raster order
+ const int bwl) {
+ (void)tcoeffs;
+ if (bwl == 2) return av1_coeff_band_4x4[c];
+ if (bwl == 3) return av1_coeff_band_8x8[c];
+ if (bwl == 4) return av1_coeff_band_16x16[c];
+ if (bwl == 5) return av1_coeff_band_32x32[c];
+
+ assert(0);
+ return 0;
+}
+
+static INLINE void set_dc_sign(int *cul_level, tran_low_t v) {
+ if (v < 0)
+ *cul_level |= 1 << COEFF_CONTEXT_BITS;
+ else if (v > 0)
+ *cul_level += 2 << COEFF_CONTEXT_BITS;
+}
+
+static INLINE int get_dc_sign_ctx(int dc_sign) {
+ int dc_sign_ctx = 0;
+ if (dc_sign < 0)
+ dc_sign_ctx = 1;
+ else if (dc_sign > 0)
+ dc_sign_ctx = 2;
+
+ return dc_sign_ctx;
+}
+
+static INLINE void get_txb_ctx(BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
+ int plane, const ENTROPY_CONTEXT *a,
+ const ENTROPY_CONTEXT *l, TXB_CTX *txb_ctx) {
+ const int tx_size_in_blocks = 1 << tx_size;
+ int ctx_offset = (plane == 0) ? 0 : 7;
+ int k;
+
+ if (plane_bsize > txsize_to_bsize[tx_size]) ctx_offset += 3;
+
+ int dc_sign = 0;
+ for (k = 0; k < tx_size_in_blocks; ++k) {
+ int sign = ((uint8_t)a[k]) >> COEFF_CONTEXT_BITS;
+ if (sign == 1)
+ --dc_sign;
+ else if (sign == 2)
+ ++dc_sign;
+ else if (sign != 0)
+ assert(0);
+
+ sign = ((uint8_t)l[k]) >> COEFF_CONTEXT_BITS;
+ if (sign == 1)
+ --dc_sign;
+ else if (sign == 2)
+ ++dc_sign;
+ else if (sign != 0)
+ assert(0);
+ }
+ txb_ctx->dc_sign_ctx = get_dc_sign_ctx(dc_sign);
+
+ if (plane == 0) {
+ int top = 0;
+ int left = 0;
+ for (k = 0; k < tx_size_in_blocks; ++k) {
+ top = AOMMAX(top, ((uint8_t)a[k] & COEFF_CONTEXT_MASK));
+ left = AOMMAX(left, ((uint8_t)l[k] & COEFF_CONTEXT_MASK));
+ }
+ top = AOMMIN(top, 255);
+ left = AOMMIN(left, 255);
+
+ if (plane_bsize == txsize_to_bsize[tx_size])
+ txb_ctx->txb_skip_ctx = 0;
+ else if (top == 0 && left == 0)
+ txb_ctx->txb_skip_ctx = 1;
+ else if (top == 0 || left == 0)
+ txb_ctx->txb_skip_ctx = 2 + (AOMMAX(top, left) > 3);
+ else if (AOMMAX(top, left) <= 3)
+ txb_ctx->txb_skip_ctx = 4;
+ else if (AOMMIN(top, left) <= 3)
+ txb_ctx->txb_skip_ctx = 5;
+ else
+ txb_ctx->txb_skip_ctx = 6;
+ } else {
+ int ctx_base = get_entropy_context(tx_size, a, l);
+ txb_ctx->txb_skip_ctx = ctx_offset + ctx_base;
+ }
+}
+
+void av1_adapt_txb_probs(AV1_COMMON *cm, unsigned int count_sat,
+ unsigned int update_factor);
+#endif // AV1_COMMON_TXB_COMMON_H_