Index skip_contexts with top/left, not min/max.
If we index the skip_contexts table with min and max, the matrix is
actually upper triangular because only the main diagonal and the entries
above the main diagonal are used (min <= max). If we index skip_contexts
with top and left instead, then the matrix is symmetric and no entries
are wasted. Also, we don't need to calculate min and max.
Background info: The code modified in this CL was added in a series of
three CLs:
- https://aomedia-review.googlesource.com/c/aom/+/39524. (This CL was
reverted because of a bug in the dc_sign_contexts table.)
- https://aomedia-review.googlesource.com/c/aom/+/39902. (Fixed the bug
in the dc_sign_contexts table.)
- https://aomedia-review.googlesource.com/c/aom/+/53423. (Edited the
comment that describes how the table was generated.)
It is not clear by reading the code review comments of these three CLs
why the skip_contexts table was not upper triagonal or symmetric.
Change-Id: Iaa0355991620f2cae2f0666b0a3901a21eb032aa
diff --git a/av1/common/txb_common.h b/av1/common/txb_common.h
index be34925..0b6ab38 100644
--- a/av1/common/txb_common.h
+++ b/av1/common/txb_common.h
@@ -386,7 +386,9 @@
if (plane_bsize == txsize_to_bsize[tx_size]) {
txb_ctx->txb_skip_ctx = 0;
} else {
- // This is the algorithm to generate table skip_contexts[min][max].
+ // This is the algorithm to generate table skip_contexts[top][left].
+ // const int max = AOMMIN(top | left, 4);
+ // const int min = AOMMIN(AOMMIN(top, left), 4);
// if (!max)
// txb_skip_ctx = 1;
// else if (!min)
@@ -398,10 +400,10 @@
// else
// txb_skip_ctx = 6;
static const uint8_t skip_contexts[5][5] = { { 1, 2, 2, 2, 3 },
- { 1, 4, 4, 4, 5 },
- { 1, 4, 4, 4, 5 },
- { 1, 4, 4, 4, 5 },
- { 1, 4, 4, 4, 6 } };
+ { 2, 4, 4, 4, 5 },
+ { 2, 4, 4, 4, 5 },
+ { 2, 4, 4, 4, 5 },
+ { 3, 5, 5, 5, 6 } };
int top = 0;
int left = 0;
@@ -410,16 +412,16 @@
top |= a[k];
} while (++k < txb_w_unit);
top &= COEFF_CONTEXT_MASK;
+ top = AOMMIN(top, 4);
k = 0;
do {
left |= l[k];
} while (++k < txb_h_unit);
left &= COEFF_CONTEXT_MASK;
- const int max = AOMMIN(top | left, 4);
- const int min = AOMMIN(AOMMIN(top, left), 4);
+ left = AOMMIN(left, 4);
- txb_ctx->txb_skip_ctx = skip_contexts[min][max];
+ txb_ctx->txb_skip_ctx = skip_contexts[top][left];
}
} else {
const int ctx_base = get_entropy_context(tx_size, a, l);