summaryrefslogtreecommitdiff
path: root/vp9/common
diff options
context:
space:
mode:
authorDeb Mukherjee <debargha@google.com>2013-04-22 10:33:12 -0700
committerGerrit Code Review <gerrit@gerrit.golo.chromium.org>2013-04-22 10:33:12 -0700
commit6ce718eb180467c3e18ee648403699ed762cc187 (patch)
treeae0daa2ed3db08570b0bf696586fd71a43c1a016 /vp9/common
parent6d5ac8f2e1ad259b66928e854904c2c2e6656084 (diff)
parent70d9f116fd90f130ec7798b16c2083c9e3853050 (diff)
downloadlibvpx-6ce718eb180467c3e18ee648403699ed762cc187.tar
libvpx-6ce718eb180467c3e18ee648403699ed762cc187.tar.gz
libvpx-6ce718eb180467c3e18ee648403699ed762cc187.tar.bz2
libvpx-6ce718eb180467c3e18ee648403699ed762cc187.zip
Merge "End of orientation zero group experiment" into experimental
Diffstat (limited to 'vp9/common')
-rw-r--r--vp9/common/vp9_blockd.h9
-rw-r--r--vp9/common/vp9_coefupdateprobs.h4
-rw-r--r--vp9/common/vp9_default_coef_probs.h83
-rw-r--r--vp9/common/vp9_entropy.c153
-rw-r--r--vp9/common/vp9_entropy.h56
-rw-r--r--vp9/common/vp9_onyxc_int.h22
6 files changed, 321 insertions, 6 deletions
diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h
index aa48958b0..b1915d18a 100644
--- a/vp9/common/vp9_blockd.h
+++ b/vp9/common/vp9_blockd.h
@@ -767,7 +767,7 @@ struct plane_block_idx {
// TODO(jkoleszar): returning a struct so it can be used in a const context,
// expect to refactor this further later.
static INLINE struct plane_block_idx plane_block_idx(int y_blocks,
- int b_idx) {
+ int b_idx) {
const int v_offset = y_blocks * 5 / 4;
struct plane_block_idx res;
@@ -939,6 +939,9 @@ static INLINE void foreach_predicted_block_uv(
}
}
-
-
+#if CONFIG_CODE_ZEROGROUP
+static int get_zpc_used(TX_SIZE tx_size) {
+ return (tx_size >= TX_16X16);
+}
+#endif
#endif // VP9_COMMON_VP9_BLOCKD_H_
diff --git a/vp9/common/vp9_coefupdateprobs.h b/vp9/common/vp9_coefupdateprobs.h
index b4d892df9..a13f9b290 100644
--- a/vp9/common/vp9_coefupdateprobs.h
+++ b/vp9/common/vp9_coefupdateprobs.h
@@ -26,6 +26,10 @@ static const vp9_prob vp9_coef_update_prob[ENTROPY_NODES] = {
#define NZC_UPDATE_PROB_PCAT 252
#endif
+#if CONFIG_CODE_ZEROGROUP
+#define ZPC_UPDATE_PROB 248
+#endif
+
#if CONFIG_MODELCOEFPROB
#define COEF_MODEL_UPDATE_PROB 16
#endif
diff --git a/vp9/common/vp9_default_coef_probs.h b/vp9/common/vp9_default_coef_probs.h
index 5a781fb0a..9e105bd5c 100644
--- a/vp9/common/vp9_default_coef_probs.h
+++ b/vp9/common/vp9_default_coef_probs.h
@@ -995,3 +995,86 @@ static const vp9_prob default_nzc_pcat_probs[MAX_NZC_CONTEXTS]
};
#endif // CONFIG_CODE_NONZEROCOUNT
+
+#if CONFIG_CODE_ZEROGROUP
+
+// There are two probs: the first is the prob(0) of the isolated zero bit,
+// the second is the prob(0) of the end of orientation symbol [if 0 that
+// indicates a zerotree root].
+static const vp9_zpc_probs default_zpc_probs_4x4 = {
+ { /* Intra */
+ { /* Coeff Band 0 */
+ { 1, }, { 1, }, { 1, },
+ }, { /* Coeff Band 1 */
+ { 1, }, { 1, }, { 1, },
+ }, { /* Coeff Band 2 */
+ { 1, }, { 1, }, { 1, },
+ }
+ }, { /* Inter */
+ { /* Coeff Band 0 */
+ { 1, }, { 1, }, { 1, },
+ }, { /* Coeff Band 1 */
+ { 1, }, { 1, }, { 1, },
+ }, { /* Coeff Band 2 */
+ { 1, }, { 1, }, { 1, },
+ }
+ }
+};
+static const vp9_zpc_probs default_zpc_probs_8x8 = {
+ { /* Intra */
+ { /* ZPC Band 0 */
+ { 4, }, { 2, }, { 1, },
+ }, { /* ZPC Band 1 */
+ { 4, }, { 2, }, { 1, },
+ }, { /* ZPC Band 2 */
+ { 4, }, { 2, }, { 1, },
+ }
+ }, { /* Inter */
+ { /* ZPC Band 0 */
+ { 4, }, { 2, }, { 1, },
+ }, { /* ZPC Band 1 */
+ { 4, }, { 2, }, { 1, },
+ }, { /* ZPC Band 2 */
+ { 4, }, { 2, }, { 1, },
+ }
+ }
+};
+static const vp9_zpc_probs default_zpc_probs_16x16 = {
+ { /* Intra */
+ { /* ZPC Band 0 */
+ { 57, }, { 30, }, { 13, },
+ }, { /* ZPC Band 1 */
+ { 46, }, { 23, }, { 4, },
+ }, { /* ZPC Band 1 */
+ { 36, }, { 11, }, { 2, },
+ },
+ }, { /* Inter */
+ { /* ZPC Band 0 */
+ { 45, }, { 21 }, { 10, },
+ }, { /* ZPC Band 1 */
+ { 24, }, { 14, }, { 3, },
+ }, { /* ZPC Band 2 */
+ { 16, }, { 6, }, { 1, },
+ },
+ },
+};
+static const vp9_zpc_probs default_zpc_probs_32x32 = {
+ { /* Intra */
+ { /* ZPC Band 0 */
+ { 132, }, { 60, }, { 19, },
+ }, { /* ZPC Band 1 */
+ { 64, }, { 32, }, { 8, },
+ }, { /* ZPC Band 2 */
+ { 25, }, { 11, }, { 1, },
+ },
+ }, { /* Inter */
+ { /* ZPC Band 0 */
+ { 134, }, { 39, }, { 25, },
+ }, { /* ZPC Band 1 */
+ { 64, }, { 24, }, { 12, },
+ }, { /* ZPC Band 2 */
+ { 21, }, { 10, }, { 1, },
+ },
+ },
+};
+#endif // CONFIG_CODE_ZEROGROUP
diff --git a/vp9/common/vp9_entropy.c b/vp9/common/vp9_entropy.c
index 5b3ddfbc2..cfd6a3cd1 100644
--- a/vp9/common/vp9_entropy.c
+++ b/vp9/common/vp9_entropy.c
@@ -1344,10 +1344,10 @@ int vp9_get_coef_context(const int *scan, const int *neighbors,
int ctx;
assert(neighbors[MAX_NEIGHBORS * c + 0] >= 0);
if (neighbors[MAX_NEIGHBORS * c + 1] >= 0) {
- ctx = (1 + token_cache[neighbors[MAX_NEIGHBORS * c + 0]] +
- token_cache[neighbors[MAX_NEIGHBORS * c + 1]]) >> 1;
+ ctx = (1 + token_cache[scan[neighbors[MAX_NEIGHBORS * c + 0]]] +
+ token_cache[scan[neighbors[MAX_NEIGHBORS * c + 1]]]) >> 1;
} else {
- ctx = token_cache[neighbors[MAX_NEIGHBORS * c + 0]];
+ ctx = token_cache[scan[neighbors[MAX_NEIGHBORS * c + 0]]];
}
return vp9_pt_energy_class[ctx];
}
@@ -1447,6 +1447,16 @@ void vp9_default_coef_probs(VP9_COMMON *pc) {
vpx_memcpy(pc->fc.coef_probs_32x32, default_coef_probs_32x32,
sizeof(pc->fc.coef_probs_32x32));
#endif
+#if CONFIG_CODE_ZEROGROUP
+ vpx_memcpy(pc->fc.zpc_probs_4x4, default_zpc_probs_4x4,
+ sizeof(pc->fc.zpc_probs_4x4));
+ vpx_memcpy(pc->fc.zpc_probs_8x8, default_zpc_probs_8x8,
+ sizeof(pc->fc.zpc_probs_8x8));
+ vpx_memcpy(pc->fc.zpc_probs_16x16, default_zpc_probs_16x16,
+ sizeof(pc->fc.zpc_probs_16x16));
+ vpx_memcpy(pc->fc.zpc_probs_32x32, default_zpc_probs_32x32,
+ sizeof(pc->fc.zpc_probs_32x32));
+#endif
}
// Neighborhood 5-tuples for various scans and blocksizes,
@@ -2901,3 +2911,140 @@ void vp9_adapt_nzc_probs(VP9_COMMON *cm) {
adapt_nzc_pcat(cm, count_sat, update_factor);
}
#endif // CONFIG_CODE_NONZEROCOUNT
+
+#if CONFIG_CODE_ZEROGROUP
+OrientationType vp9_get_orientation(int rc, TX_SIZE tx_size) {
+ int i = rc >> (tx_size + 2);
+ int j = rc & ((4 << tx_size) - 1);
+ if (i > 2 * j)
+ return VERTICAL;
+ else if (j > 2 * i)
+ return HORIZONTAL;
+ else
+ return DIAGONAL;
+ /*
+ if (i == 0 && j == 0) return DIAGONAL;
+ while (i > 1 || j > 1) {
+ i >>= 1;
+ j >>= 1;
+ }
+ if (i == 0 && j == 1)
+ return HORIZONTAL; // horizontal
+ else if (i == 1 && j == 1)
+ return DIAGONAL; // diagonal
+ else if (i == 1 && j == 0)
+ return VERTICAL; // vertical
+ assert(0);
+ */
+}
+
+int vp9_use_eoo(int c, int seg_eob, const int *scan,
+ TX_SIZE tx_size, int *is_last_zero, int *is_eoo) {
+ // NOTE: returning 0 from this function will turn off eoo symbols
+ // For instance we can experiment with turning eoo off for smaller blocks
+ // and/or lower bands
+ int o = vp9_get_orientation(scan[c], tx_size);
+ int band = get_coef_band(scan, tx_size, c);
+ int use_eoo = (!is_last_zero[o] &&
+ !is_eoo[o] &&
+ band <= ZPC_EOO_BAND_UPPER &&
+ band >= ZPC_EOO_BAND_LOWER &&
+ get_zpc_used(tx_size) &&
+ seg_eob - c > (ZPC_USEEOO_THRESH << tx_size) &&
+ is_eoo[0] + is_eoo[1] + is_eoo[2] < 2);
+ return use_eoo;
+}
+
+int vp9_is_eoo(int c, int eob, const int *scan, TX_SIZE tx_size,
+ const int16_t *qcoeff_ptr, int *last_nz_pos) {
+ int rc = scan[c];
+ int o = vp9_get_orientation(rc, tx_size);
+ int eoo = c > last_nz_pos[o];
+ return eoo;
+}
+
+static void adapt_zpc_probs_common(VP9_COMMON *cm,
+ TX_SIZE tx_size,
+ int count_sat,
+ int update_factor) {
+ int r, b, p, n;
+ int count, factor;
+ vp9_zpc_probs *zpc_probs;
+ vp9_zpc_probs *pre_zpc_probs;
+ vp9_zpc_count *zpc_counts;
+ if (!get_zpc_used(tx_size)) return;
+ if (tx_size == TX_32X32) {
+ zpc_probs = &cm->fc.zpc_probs_32x32;
+ pre_zpc_probs = &cm->fc.pre_zpc_probs_32x32;
+ zpc_counts = &cm->fc.zpc_counts_32x32;
+ } else if (tx_size == TX_16X16) {
+ zpc_probs = &cm->fc.zpc_probs_16x16;
+ pre_zpc_probs = &cm->fc.pre_zpc_probs_16x16;
+ zpc_counts = &cm->fc.zpc_counts_16x16;
+ } else if (tx_size == TX_8X8) {
+ zpc_probs = &cm->fc.zpc_probs_8x8;
+ pre_zpc_probs = &cm->fc.pre_zpc_probs_8x8;
+ zpc_counts = &cm->fc.zpc_counts_8x8;
+ } else {
+ zpc_probs = &cm->fc.zpc_probs_4x4;
+ pre_zpc_probs = &cm->fc.pre_zpc_probs_4x4;
+ zpc_counts = &cm->fc.zpc_counts_4x4;
+ }
+ for (r = 0; r < REF_TYPES; ++r) {
+ for (b = 0; b < ZPC_BANDS; ++b) {
+ for (p = 0; p < ZPC_PTOKS; ++p) {
+ for (n = 0; n < ZPC_NODES; ++n) {
+ vp9_prob prob = get_binary_prob((*zpc_counts)[r][b][p][n][0],
+ (*zpc_counts)[r][b][p][n][1]);
+ count = (*zpc_counts)[r][b][p][n][0] + (*zpc_counts)[r][b][p][n][1];
+ count = count > count_sat ? count_sat : count;
+ factor = (update_factor * count / count_sat);
+ (*zpc_probs)[r][b][p][n] = weighted_prob(
+ (*pre_zpc_probs)[r][b][p][n], prob, factor);
+ }
+ }
+ }
+ }
+}
+
+// #define ZPC_COUNT_TESTING
+void vp9_adapt_zpc_probs(VP9_COMMON *cm) {
+ int count_sat;
+ int update_factor; /* denominator 256 */
+#ifdef NZC_COUNT_TESTING
+ int r, b, p, n;
+ printf("\n");
+ for (r = 0; r < REF_TYPES; ++r) {
+ printf("{");
+ for (b = 0; b < ZPC_BANDS; ++b) {
+ printf(" {");
+ for (p = 0; p < ZPC_PTOKS; ++p) {
+ printf(" {");
+ for (n = 0; n < ZPC_NODES; ++n) {
+ printf(" %d,", cm->fc.zpc_counts_16x16[r][b][p][n]);
+ }
+ printf("},\n");
+ }
+ printf(" },\n");
+ }
+ printf("},\n");
+ }
+#endif
+
+ if (cm->frame_type == KEY_FRAME) {
+ update_factor = COEF_MAX_UPDATE_FACTOR_KEY;
+ count_sat = COEF_COUNT_SAT_KEY;
+ } else if (cm->last_frame_type == KEY_FRAME) {
+ update_factor = COEF_MAX_UPDATE_FACTOR_AFTER_KEY; /* adapt quickly */
+ count_sat = COEF_COUNT_SAT_AFTER_KEY;
+ } else {
+ update_factor = COEF_MAX_UPDATE_FACTOR;
+ count_sat = COEF_COUNT_SAT;
+ }
+
+ adapt_zpc_probs_common(cm, TX_4X4, count_sat, update_factor);
+ adapt_zpc_probs_common(cm, TX_8X8, count_sat, update_factor);
+ adapt_zpc_probs_common(cm, TX_16X16, count_sat, update_factor);
+ adapt_zpc_probs_common(cm, TX_32X32, count_sat, update_factor);
+}
+#endif // CONFIG_CODE_ZEROGROUP
diff --git a/vp9/common/vp9_entropy.h b/vp9/common/vp9_entropy.h
index 3cae94649..6b24ffc94 100644
--- a/vp9/common/vp9_entropy.h
+++ b/vp9/common/vp9_entropy.h
@@ -250,6 +250,62 @@ extern const int vp9_basenzcvalue[NZC32X32_TOKENS];
#endif // CONFIG_CODE_NONZEROCOUNT
+#if CONFIG_CODE_ZEROGROUP
+
+#define ZPC_STATS
+
+typedef enum {
+ HORIZONTAL = 0,
+ DIAGONAL,
+ VERTICAL,
+} OrientationType;
+
+/* Note EOB should become part of this symbol eventually,
+ * but holding off on this for now because that is a major
+ * change in the rest of the codebase */
+
+#define ZPC_ISOLATED (MAX_ENTROPY_TOKENS + 0) /* Isolated zero */
+
+/* ZPC_EOORIENT: All remaining coefficients in the same orientation are 0.
+ * In other words all remaining coeffs in the current subband, and all
+ * children of the current subband are zero. Subbands are defined by
+ * dyadic partitioning in the coeff domain */
+#define ZPC_EOORIENT (MAX_ENTROPY_TOKENS + 1) /* End of Orientation */
+
+/* Band limits over which the eoo bit is sent */
+#define ZPC_EOO_BAND_LOWER 0
+#define ZPC_EOO_BAND_UPPER 5
+
+#define USE_ZPC_EOORIENT 1 /* 0: not used */
+ /* 1: used */
+#define ZPC_NODES 1
+
+#define UNKNOWN_TOKEN 255 /* Not signalled, encoder only */
+
+#define ZPC_BANDS 3 /* context bands for izr */
+#define ZPC_PTOKS 3 /* context pt for zpcs */
+
+#define coef_to_zpc_band(b) ((b) >> 1)
+#define coef_to_zpc_ptok(p) ((p) > 2 ? 2 : (p))
+
+typedef vp9_prob vp9_zpc_probs[REF_TYPES][ZPC_BANDS]
+ [ZPC_PTOKS][ZPC_NODES];
+typedef unsigned int vp9_zpc_count[REF_TYPES][ZPC_BANDS]
+ [ZPC_PTOKS][ZPC_NODES][2];
+
+OrientationType vp9_get_orientation(int rc, TX_SIZE tx_size);
+int vp9_use_eoo(int c, int eob, const int *scan, TX_SIZE tx_size,
+ int *is_last_zero, int *is_eoo);
+int vp9_is_eoo(int c, int eob, const int *scan, TX_SIZE tx_size,
+ const int16_t *qcoeff_ptr, int *last_nz_pos);
+
+#define ZPC_USEEOO_THRESH 4
+#define ZPC_ZEROSSAVED_EOO 7 /* encoder only */
+
+void vp9_adapt_zpc_probs(struct VP9Common *cm);
+
+#endif // CONFIG_CODE_ZEROGROUP
+
#include "vp9/common/vp9_coefupdateprobs.h"
#endif // VP9_COMMON_VP9_ENTROPY_H_
diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h
index 13ec8657f..eb2a2c682 100644
--- a/vp9/common/vp9_onyxc_int.h
+++ b/vp9/common/vp9_onyxc_int.h
@@ -86,6 +86,12 @@ typedef struct frame_contexts {
vp9_prob nzc_pcat_probs[MAX_NZC_CONTEXTS]
[NZC_TOKENS_EXTRA][NZC_BITS_EXTRA];
#endif
+#if CONFIG_CODE_ZEROGROUP
+ vp9_zpc_probs zpc_probs_4x4;
+ vp9_zpc_probs zpc_probs_8x8;
+ vp9_zpc_probs zpc_probs_16x16;
+ vp9_zpc_probs zpc_probs_32x32;
+#endif
nmv_context nmvc;
nmv_context pre_nmvc;
@@ -122,6 +128,12 @@ typedef struct frame_contexts {
vp9_prob pre_nzc_pcat_probs[MAX_NZC_CONTEXTS]
[NZC_TOKENS_EXTRA][NZC_BITS_EXTRA];
#endif
+#if CONFIG_CODE_ZEROGROUP
+ vp9_zpc_probs pre_zpc_probs_4x4;
+ vp9_zpc_probs pre_zpc_probs_8x8;
+ vp9_zpc_probs pre_zpc_probs_16x16;
+ vp9_zpc_probs pre_zpc_probs_32x32;
+#endif
vp9_coeff_count coef_counts_4x4[BLOCK_TYPES];
vp9_coeff_count coef_counts_8x8[BLOCK_TYPES];
@@ -142,6 +154,12 @@ typedef struct frame_contexts {
unsigned int nzc_pcat_counts[MAX_NZC_CONTEXTS]
[NZC_TOKENS_EXTRA][NZC_BITS_EXTRA][2];
#endif
+#if CONFIG_CODE_ZEROGROUP
+ vp9_zpc_count zpc_counts_4x4;
+ vp9_zpc_count zpc_counts_8x8;
+ vp9_zpc_count zpc_counts_16x16;
+ vp9_zpc_count zpc_counts_32x32;
+#endif
nmv_context_counts NMVcount;
vp9_prob switchable_interp_prob[VP9_SWITCHABLE_FILTERS + 1]
@@ -377,4 +395,8 @@ static int get_mb_row(const MACROBLOCKD *xd) {
static int get_mb_col(const MACROBLOCKD *xd) {
return ((-xd->mb_to_left_edge) >> 7);
}
+
+static int get_token_alloc(int mb_rows, int mb_cols) {
+ return mb_rows * mb_cols * (24 * 16 + 4);
+}
#endif // VP9_COMMON_VP9_ONYXC_INT_H_