Commit 70d9f116 authored by Deb Mukherjee's avatar Deb Mukherjee
Browse files

End of orientation zero group experiment

Adds an experiment that codes an end-of-orientation symbol
for every eligible zero encountered in scan order.

This cleans out various other sub-experiments that were part
of the origiinal patch, which will be later included if found
useful.

Results are slightly positive on all sets (0.1 - 0.2% range).

Change-Id: I57765c605fefc7fb9d1b57f1b356843602abefaf
parent f82c61b8
...@@ -251,6 +251,7 @@ EXPERIMENT_LIST=" ...@@ -251,6 +251,7 @@ EXPERIMENT_LIST="
oneshotq oneshotq
sbsegment sbsegment
multiple_arf multiple_arf
code_zerogroup
" "
CONFIG_LIST=" CONFIG_LIST="
external_build external_build
......
...@@ -767,7 +767,7 @@ struct plane_block_idx { ...@@ -767,7 +767,7 @@ struct plane_block_idx {
// TODO(jkoleszar): returning a struct so it can be used in a const context, // TODO(jkoleszar): returning a struct so it can be used in a const context,
// expect to refactor this further later. // expect to refactor this further later.
static INLINE struct plane_block_idx plane_block_idx(int y_blocks, 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; const int v_offset = y_blocks * 5 / 4;
struct plane_block_idx res; struct plane_block_idx res;
...@@ -939,6 +939,9 @@ static INLINE void foreach_predicted_block_uv( ...@@ -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_ #endif // VP9_COMMON_VP9_BLOCKD_H_
...@@ -26,6 +26,10 @@ static const vp9_prob vp9_coef_update_prob[ENTROPY_NODES] = { ...@@ -26,6 +26,10 @@ static const vp9_prob vp9_coef_update_prob[ENTROPY_NODES] = {
#define NZC_UPDATE_PROB_PCAT 252 #define NZC_UPDATE_PROB_PCAT 252
#endif #endif
#if CONFIG_CODE_ZEROGROUP
#define ZPC_UPDATE_PROB 248
#endif
#if CONFIG_MODELCOEFPROB #if CONFIG_MODELCOEFPROB
#define COEF_MODEL_UPDATE_PROB 16 #define COEF_MODEL_UPDATE_PROB 16
#endif #endif
......
...@@ -995,3 +995,86 @@ static const vp9_prob default_nzc_pcat_probs[MAX_NZC_CONTEXTS] ...@@ -995,3 +995,86 @@ static const vp9_prob default_nzc_pcat_probs[MAX_NZC_CONTEXTS]
}; };
#endif // CONFIG_CODE_NONZEROCOUNT #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
...@@ -1344,10 +1344,10 @@ int vp9_get_coef_context(const int *scan, const int *neighbors, ...@@ -1344,10 +1344,10 @@ int vp9_get_coef_context(const int *scan, const int *neighbors,
int ctx; int ctx;
assert(neighbors[MAX_NEIGHBORS * c + 0] >= 0); assert(neighbors[MAX_NEIGHBORS * c + 0] >= 0);
if (neighbors[MAX_NEIGHBORS * c + 1] >= 0) { if (neighbors[MAX_NEIGHBORS * c + 1] >= 0) {
ctx = (1 + token_cache[neighbors[MAX_NEIGHBORS * c + 0]] + ctx = (1 + token_cache[scan[neighbors[MAX_NEIGHBORS * c + 0]]] +
token_cache[neighbors[MAX_NEIGHBORS * c + 1]]) >> 1; token_cache[scan[neighbors[MAX_NEIGHBORS * c + 1]]]) >> 1;
} else { } else {
ctx = token_cache[neighbors[MAX_NEIGHBORS * c + 0]]; ctx = token_cache[scan[neighbors[MAX_NEIGHBORS * c + 0]]];
} }
return vp9_pt_energy_class[ctx]; return vp9_pt_energy_class[ctx];
} }
...@@ -1447,6 +1447,16 @@ void vp9_default_coef_probs(VP9_COMMON *pc) { ...@@ -1447,6 +1447,16 @@ void vp9_default_coef_probs(VP9_COMMON *pc) {
vpx_memcpy(pc->fc.coef_probs_32x32, default_coef_probs_32x32, vpx_memcpy(pc->fc.coef_probs_32x32, default_coef_probs_32x32,
sizeof(pc->fc.coef_probs_32x32)); sizeof(pc->fc.coef_probs_32x32));
#endif #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, // Neighborhood 5-tuples for various scans and blocksizes,
...@@ -2901,3 +2911,140 @@ void vp9_adapt_nzc_probs(VP9_COMMON *cm) { ...@@ -2901,3 +2911,140 @@ void vp9_adapt_nzc_probs(VP9_COMMON *cm) {
adapt_nzc_pcat(cm, count_sat, update_factor); adapt_nzc_pcat(cm, count_sat, update_factor);
} }
#endif // CONFIG_CODE_NONZEROCOUNT #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
...@@ -250,6 +250,62 @@ extern const int vp9_basenzcvalue[NZC32X32_TOKENS]; ...@@ -250,6 +250,62 @@ extern const int vp9_basenzcvalue[NZC32X32_TOKENS];
#endif // CONFIG_CODE_NONZEROCOUNT #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" #include "vp9/common/vp9_coefupdateprobs.h"
#endif // VP9_COMMON_VP9_ENTROPY_H_ #endif // VP9_COMMON_VP9_ENTROPY_H_
...@@ -86,6 +86,12 @@ typedef struct frame_contexts { ...@@ -86,6 +86,12 @@ typedef struct frame_contexts {
vp9_prob nzc_pcat_probs[MAX_NZC_CONTEXTS] vp9_prob nzc_pcat_probs[MAX_NZC_CONTEXTS]
[NZC_TOKENS_EXTRA][NZC_BITS_EXTRA]; [NZC_TOKENS_EXTRA][NZC_BITS_EXTRA];
#endif #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 nmvc;
nmv_context pre_nmvc; nmv_context pre_nmvc;
...@@ -122,6 +128,12 @@ typedef struct frame_contexts { ...@@ -122,6 +128,12 @@ typedef struct frame_contexts {
vp9_prob pre_nzc_pcat_probs[MAX_NZC_CONTEXTS] vp9_prob pre_nzc_pcat_probs[MAX_NZC_CONTEXTS]
[NZC_TOKENS_EXTRA][NZC_BITS_EXTRA]; [NZC_TOKENS_EXTRA][NZC_BITS_EXTRA];
#endif #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_4x4[BLOCK_TYPES];
vp9_coeff_count coef_counts_8x8[BLOCK_TYPES]; vp9_coeff_count coef_counts_8x8[BLOCK_TYPES];
...@@ -142,6 +154,12 @@ typedef struct frame_contexts { ...@@ -142,6 +154,12 @@ typedef struct frame_contexts {
unsigned int nzc_pcat_counts[MAX_NZC_CONTEXTS] unsigned int nzc_pcat_counts[MAX_NZC_CONTEXTS]
[NZC_TOKENS_EXTRA][NZC_BITS_EXTRA][2]; [NZC_TOKENS_EXTRA][NZC_BITS_EXTRA][2];
#endif #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; nmv_context_counts NMVcount;
vp9_prob switchable_interp_prob[VP9_SWITCHABLE_FILTERS + 1] vp9_prob switchable_interp_prob[VP9_SWITCHABLE_FILTERS + 1]
...@@ -377,4 +395,8 @@ static int get_mb_row(const MACROBLOCKD *xd) { ...@@ -377,4 +395,8 @@ static int get_mb_row(const MACROBLOCKD *xd) {
static int get_mb_col(const MACROBLOCKD *xd) { static int get_mb_col(const MACROBLOCKD *xd) {
return ((-xd->mb_to_left_edge) >> 7); 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_ #endif // VP9_COMMON_VP9_ONYXC_INT_H_
...@@ -995,6 +995,54 @@ static void init_frame(VP9D_COMP *pbi) { ...@@ -995,6 +995,54 @@ static void init_frame(VP9D_COMP *pbi) {
xd->corrupted = 0; xd->corrupted = 0;
} }
#if CONFIG_CODE_ZEROGROUP
static void read_zpc_probs_common(VP9_COMMON *cm,
vp9_reader* bc,
TX_SIZE tx_size) {
int r, b, p, n;
vp9_zpc_probs *zpc_probs;
vp9_prob upd = ZPC_UPDATE_PROB;
if (!get_zpc_used(tx_size)) return;
if (!vp9_read_bit(bc)) return;
if (tx_size == TX_32X32) {
zpc_probs = &cm->fc.zpc_probs_32x32;
} else if (tx_size == TX_16X16) {
zpc_probs = &cm->fc.zpc_probs_16x16;
} else if (tx_size == TX_8X8) {
zpc_probs = &cm->fc.zpc_probs_8x8;
} else {
zpc_probs = &cm->fc.zpc_probs_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 *q = &(*zpc_probs)[r][b][p][n];
#if USE_ZPC_EXTRA == 0
if (n == 1) continue;
#endif
if (vp9_read(bc, upd)) {
*q = read_prob_diff_update(bc, *q);
}
}
}
}
}
}
static void read_zpc_probs(VP9_COMMON *cm,
vp9_reader* bc) {
read_zpc_probs_common(cm, bc, TX_4X4);
if (cm->txfm_mode != ONLY_4X4)
read_zpc_probs_common(cm, bc, TX_8X8);
if (cm->txfm_mode > ALLOW_8X8)
read_zpc_probs_common(cm, bc, TX_16X16);
if (cm->txfm_mode > ALLOW_16X16)
read_zpc_probs_common(cm, bc, TX_32X32);
}
#endif // CONFIG_CODE_ZEROGROUP
#if CONFIG_CODE_NONZEROCOUNT #if CONFIG_CODE_NONZEROCOUNT
static void read_nzc_probs_common(VP9_COMMON *cm, static void read_nzc_probs_common(VP9_COMMON *cm,
vp9_reader *rd, vp9_reader *rd,
...@@ -1404,6 +1452,17 @@ static void update_frame_context(VP9D_COMP *pbi) { ...@@ -1404,6 +1452,17 @@ static void update_frame_context(VP9D_COMP *pbi) {
vp9_zero(fc->nzc_counts_32x32); vp9_zero(fc->nzc_counts_32x32);
vp9_zero(fc->nzc_pcat_counts); vp9_zero(fc->nzc_pcat_counts);
#endif #endif
#if CONFIG_CODE_ZEROGROUP
vp9_copy(fc->pre_zpc_probs_4x4, fc->zpc_probs_4x4);
vp9_copy(fc->pre_zpc_probs_8x8, fc->zpc_probs_8x8);
vp9_copy(fc->pre_zpc_probs_16x16, fc->zpc_probs_16x16);
vp9_copy(fc->pre_zpc_probs_32x32, fc->zpc_probs_32x32);
vp9_zero(fc->zpc_counts_4x4);
vp9_zero(fc->zpc_counts_8x8);
vp9_zero(fc->zpc_counts_16x16);
vp9_zero(fc->zpc_counts_32x32);
#endif
} }
static void decode_tiles(VP9D_COMP *pbi, static void decode_tiles(VP9D_COMP *pbi,
...@@ -1660,6 +1719,9 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { ...@@ -1660,6 +1719,9 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
#if CONFIG_CODE_NONZEROCOUNT #if CONFIG_CODE_NONZEROCOUNT
read_nzc_probs(&pbi->common, &header_bc); read_nzc_probs(&pbi->common, &header_bc);
#endif #endif
#if CONFIG_CODE_ZEROGROUP
read_zpc_probs(&pbi->common, &header_bc);
#endif
// Initialize xd pointers. Any reference should do for xd->pre, so use 0. // Initialize xd pointers. Any reference should do for xd->pre, so use 0.
vpx_memcpy(&xd->pre, &pc->yv12_fb[pc->active_ref_idx[0]], vpx_memcpy(&xd->pre, &pc->yv12_fb[pc->active_ref_idx[0]],
...@@ -1711,6 +1773,9 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { ...@@ -1711,6 +1773,9 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
vp9_adapt_coef_probs(pc); vp9_adapt_coef_probs(pc);
#if CONFIG_CODE_NONZEROCOUNT #if CONFIG_CODE_NONZEROCOUNT
vp9_adapt_nzc_probs(pc); vp9_adapt_nzc_probs(pc);
#endif
#if CONFIG_CODE_ZEROGROUP
vp9_adapt_zpc_probs(pc);
#endif #endif
} }
......
...@@ -60,14 +60,28 @@ static const vp9_prob cat6_prob[15] = { ...@@ -60,14 +60,28 @@ static const vp9_prob cat6_prob[15] = {
DECLARE_ALIGNED(16, extern const uint8_t, vp9_norm[256]); DECLARE_ALIGNED(16, extern const uint8_t, vp9_norm[256]);
#if CONFIG_CODE_ZEROGROUP
#define ZEROGROUP_ADVANCE() \
do { \
token_cache[scan[c]] = ZERO_TOKEN; \
is_last_zero[o] = 1; \
c++; \
} while (0)
#define INCREMENT_COUNT(token) \
do { \
coef_counts[type][ref][get_coef_band(scan, txfm_size, c)] \
[pt][token]++; \
token_cache[scan[c]] = token; \
is_last_zero[o] = (token == ZERO_TOKEN); \
} while (0)
#else
#define INCREMENT_COUNT(token) \ #define INCREMENT_COUNT(token) \
do { \ do { \
coef_counts[type][ref][get_coef_band(scan, txfm_size, c)] \ coef_counts[type][ref][get_coef_band(scan, txfm_size, c)] \
[pt][token]++; \ [pt][token]++; \
token_cache[c] = token; \ token_cache[scan[c]] = token; \
pt = vp9_get_coef_context(scan, nb, pad, token_cache, \
c + 1, default_eob); \