New previous coef context experiment
Adds an experiment to derive the previous context of a coefficient not just from the previous coefficient in the scan order but from a combination of several neighboring coefficients previously encountered in scan order. A precomputed table of neighbors for each location for each scan type and block size is used. Currently 5 neighbors are used. Results are about 0.2% positive using a strategy where the max coef magnitude from the 5 neigbors is used to derive the context. Change-Id: Ie708b54d8e1898af742846ce2d1e2b0d89fd4ad5
This commit is contained in:
parent
de52948665
commit
08f0c7cc9c
1
configure
vendored
1
configure
vendored
@ -250,6 +250,7 @@ EXPERIMENT_LIST="
|
||||
tx32x32
|
||||
dwt32x32hybrid
|
||||
cnvcontext
|
||||
newcoefcontext
|
||||
"
|
||||
CONFIG_LIST="
|
||||
external_build
|
||||
|
@ -220,4 +220,8 @@ void vp9_initialize_common() {
|
||||
vp9_entropy_mode_init();
|
||||
|
||||
vp9_entropy_mv_init();
|
||||
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
vp9_init_neighbors();
|
||||
#endif
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ DECLARE_ALIGNED(16, const int, vp9_col_scan_4x4[16]) = {
|
||||
2, 6, 10, 14,
|
||||
3, 7, 11, 15
|
||||
};
|
||||
|
||||
DECLARE_ALIGNED(16, const int, vp9_row_scan_4x4[16]) = {
|
||||
0, 1, 2, 3,
|
||||
4, 5, 6, 7,
|
||||
@ -69,16 +70,16 @@ DECLARE_ALIGNED(16, const int, vp9_row_scan_4x4[16]) = {
|
||||
12, 13, 14, 15
|
||||
};
|
||||
|
||||
|
||||
DECLARE_ALIGNED(64, const int, vp9_coef_bands_8x8[64]) = { 0, 1, 2, 3, 5, 4, 4, 5,
|
||||
5, 3, 6, 3, 5, 4, 6, 6,
|
||||
6, 5, 5, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7
|
||||
};
|
||||
5, 3, 6, 3, 5, 4, 6, 6,
|
||||
6, 5, 5, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7
|
||||
};
|
||||
|
||||
DECLARE_ALIGNED(64, const int, vp9_default_zig_zag1d_8x8[64]) = {
|
||||
0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
|
||||
12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
|
||||
@ -118,17 +119,17 @@ DECLARE_ALIGNED(16, const int, vp9_default_zig_zag1d_16x16[256]) = {
|
||||
25, 10, 11, 26, 41, 56, 71, 86,
|
||||
101, 116, 131, 146, 161, 176, 192, 177,
|
||||
162, 147, 132, 117, 102, 87, 72, 57,
|
||||
42, 27, 12, 13, 28, 43, 58, 73,
|
||||
42, 27, 12, 13, 28, 43, 58, 73,
|
||||
88, 103, 118, 133, 148, 163, 178, 193,
|
||||
208, 224, 209, 194, 179, 164, 149, 134,
|
||||
119, 104, 89, 74, 59, 44, 29, 14,
|
||||
15, 30, 45, 60, 75, 90, 105, 120,
|
||||
15, 30, 45, 60, 75, 90, 105, 120,
|
||||
135, 150, 165, 180, 195, 210, 225, 240,
|
||||
241, 226, 211, 196, 181, 166, 151, 136,
|
||||
121, 106, 91, 76, 61, 46, 31, 47,
|
||||
62, 77, 92, 107, 122, 137, 152, 167,
|
||||
62, 77, 92, 107, 122, 137, 152, 167,
|
||||
182, 197, 212, 227, 242, 243, 228, 213,
|
||||
198, 183, 168, 153, 138, 123, 108, 93,
|
||||
198, 183, 168, 153, 138, 123, 108, 93,
|
||||
78, 63, 79, 94, 109, 124, 139, 154,
|
||||
169, 184, 199, 214, 229, 244, 245, 230,
|
||||
215, 200, 185, 170, 155, 140, 125, 110,
|
||||
@ -530,6 +531,152 @@ vp9_extra_bit_struct vp9_extra_bits[12] = {
|
||||
|
||||
#include "vp9/common/vp9_default_coef_probs.h"
|
||||
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
|
||||
// Neighborhood 5-tuples for various scans and blocksizes,
|
||||
// in {top, left, topleft, topright, bottomleft} order
|
||||
// for each position in raster scan order.
|
||||
// -1 indicates the neighbor does not exist.
|
||||
DECLARE_ALIGNED(16, int,
|
||||
vp9_default_zig_zag1d_4x4_neighbors[16 * MAX_NEIGHBORS]);
|
||||
DECLARE_ALIGNED(16, int,
|
||||
vp9_col_scan_4x4_neighbors[16 * MAX_NEIGHBORS]);
|
||||
DECLARE_ALIGNED(16, int,
|
||||
vp9_row_scan_4x4_neighbors[16 * MAX_NEIGHBORS]);
|
||||
DECLARE_ALIGNED(16, int,
|
||||
vp9_default_zig_zag1d_8x8_neighbors[64 * MAX_NEIGHBORS]);
|
||||
DECLARE_ALIGNED(16, int,
|
||||
vp9_default_zig_zag1d_16x16_neighbors[256 * MAX_NEIGHBORS]);
|
||||
#if CONFIG_TX32X32 && CONFIG_SUPERBLOCKS
|
||||
DECLARE_ALIGNED(16, int,
|
||||
vp9_default_zig_zag1d_32x32_neighbors[1024 * MAX_NEIGHBORS]);
|
||||
#endif
|
||||
|
||||
static int find_in_scan(const int *scan, int l, int m) {
|
||||
int i, l2 = l * l;
|
||||
for (i = 0; i < l2; ++i) {
|
||||
if (scan[i] == m)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void init_scan_neighbors(const int *scan, int l, int *neighbors) {
|
||||
int l2 = l * l;
|
||||
int m, n, i, j, k;
|
||||
for (n = 0; n < l2; ++n) {
|
||||
int locn = find_in_scan(scan, l, n);
|
||||
int z = -1;
|
||||
i = n / l;
|
||||
j = n % l;
|
||||
for (k = 0; k < MAX_NEIGHBORS; ++k)
|
||||
neighbors[MAX_NEIGHBORS * n + k] = -1;
|
||||
if (i - 1 >= 0) {
|
||||
m = (i - 1) * l + j;
|
||||
if (find_in_scan(scan, l, m) < locn) {
|
||||
neighbors[MAX_NEIGHBORS * n] = m;
|
||||
if (m == 0) z = 0;
|
||||
}
|
||||
}
|
||||
if (j - 1 >= 0) {
|
||||
m = i * l + j - 1;
|
||||
if (find_in_scan(scan, l, m) < locn) {
|
||||
neighbors[MAX_NEIGHBORS * n + 1] = m;
|
||||
if (m == 0) z = 1;
|
||||
}
|
||||
}
|
||||
if (i - 1 >= 0 && j - 1 >= 0) {
|
||||
m = (i - 1) * l + j - 1;
|
||||
if (find_in_scan(scan, l, m) < locn) {
|
||||
neighbors[MAX_NEIGHBORS * n + 2] = m;
|
||||
if (m == 0) z = 2;
|
||||
}
|
||||
}
|
||||
if (i - 1 >= 0 && j + 1 < l) {
|
||||
m = (i - 1) * l + j + 1;
|
||||
if (find_in_scan(scan, l, m) < locn) {
|
||||
neighbors[MAX_NEIGHBORS * n + 3] = m;
|
||||
if (m == 0) z = 3;
|
||||
}
|
||||
}
|
||||
if (i + 1 < l && j - 1 >= 0) {
|
||||
m = (i + 1) * l + j - 1;
|
||||
if (find_in_scan(scan, l, m) < locn) {
|
||||
neighbors[MAX_NEIGHBORS * n + 4] = m;
|
||||
if (m == 0) z = 4;
|
||||
}
|
||||
}
|
||||
if (z != -1) { // zero exists
|
||||
int v = 0;
|
||||
for (k = 0; k < MAX_NEIGHBORS; ++k)
|
||||
v += (neighbors[MAX_NEIGHBORS * n + k] > 0);
|
||||
if (v) {
|
||||
neighbors[MAX_NEIGHBORS * n + z] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vp9_init_neighbors() {
|
||||
init_scan_neighbors(vp9_default_zig_zag1d_4x4, 4,
|
||||
vp9_default_zig_zag1d_4x4_neighbors);
|
||||
init_scan_neighbors(vp9_row_scan_4x4, 4,
|
||||
vp9_row_scan_4x4_neighbors);
|
||||
init_scan_neighbors(vp9_col_scan_4x4, 4,
|
||||
vp9_col_scan_4x4_neighbors);
|
||||
init_scan_neighbors(vp9_default_zig_zag1d_8x8, 8,
|
||||
vp9_default_zig_zag1d_8x8_neighbors);
|
||||
init_scan_neighbors(vp9_default_zig_zag1d_16x16, 16,
|
||||
vp9_default_zig_zag1d_16x16_neighbors);
|
||||
#if CONFIG_TX32X32 && CONFIG_SUPERBLOCKS
|
||||
init_scan_neighbors(vp9_default_zig_zag1d_32x32, 32,
|
||||
vp9_default_zig_zag1d_32x32_neighbors);
|
||||
#endif
|
||||
}
|
||||
|
||||
const int *vp9_get_coef_neighbors_handle(const int *scan) {
|
||||
if (scan == vp9_default_zig_zag1d_4x4) {
|
||||
return vp9_default_zig_zag1d_4x4_neighbors;
|
||||
} else if (scan == vp9_row_scan_4x4) {
|
||||
return vp9_row_scan_4x4_neighbors;
|
||||
} else if (scan == vp9_col_scan_4x4) {
|
||||
return vp9_col_scan_4x4_neighbors;
|
||||
} else if (scan == vp9_default_zig_zag1d_8x8) {
|
||||
return vp9_default_zig_zag1d_8x8_neighbors;
|
||||
} else if (scan == vp9_default_zig_zag1d_16x16) {
|
||||
return vp9_default_zig_zag1d_16x16_neighbors;
|
||||
#if CONFIG_TX32X32 && CONFIG_SUPERBLOCKS
|
||||
} else if (scan == vp9_default_zig_zag1d_32x32) {
|
||||
return vp9_default_zig_zag1d_32x32_neighbors;
|
||||
#endif
|
||||
}
|
||||
return vp9_default_zig_zag1d_4x4_neighbors;
|
||||
}
|
||||
|
||||
int vp9_get_coef_neighbor_context(const short int *qcoeff_ptr, int nodc,
|
||||
const int *neigbor_handle, int rc) {
|
||||
static int neighbors_used = MAX_NEIGHBORS; // maximum is MAX_NEIGHBORS
|
||||
const int *nb = neigbor_handle + rc * MAX_NEIGHBORS;
|
||||
int i, v, val = 0, n = 0;
|
||||
for (i = 0; i < neighbors_used; ++i) {
|
||||
if (nb[i] == -1 || (nb[i] == 0 && nodc)) {
|
||||
continue;
|
||||
}
|
||||
v = abs(qcoeff_ptr[nb[i]]);
|
||||
val = (v > val ? v : val);
|
||||
n++;
|
||||
}
|
||||
if (n == 0)
|
||||
return 0;
|
||||
else if (val <= 1)
|
||||
return val;
|
||||
else if (val < 4)
|
||||
return 2;
|
||||
else
|
||||
return 3;
|
||||
}
|
||||
#endif /* CONFIG_NEWCOEFCONTEXT */
|
||||
|
||||
void vp9_default_coef_probs(VP9_COMMON *pc) {
|
||||
vpx_memcpy(pc->fc.coef_probs_4x4, default_coef_probs_4x4,
|
||||
sizeof(pc->fc.coef_probs_4x4));
|
||||
@ -546,7 +693,6 @@ void vp9_default_coef_probs(VP9_COMMON *pc) {
|
||||
vpx_memcpy(pc->fc.hybrid_coef_probs_16x16,
|
||||
default_hybrid_coef_probs_16x16,
|
||||
sizeof(pc->fc.hybrid_coef_probs_16x16));
|
||||
|
||||
#if CONFIG_TX32X32 && CONFIG_SUPERBLOCKS
|
||||
vpx_memcpy(pc->fc.coef_probs_32x32, default_coef_probs_32x32,
|
||||
sizeof(pc->fc.coef_probs_32x32));
|
||||
|
@ -98,7 +98,7 @@ extern DECLARE_ALIGNED(16, const int, vp9_coef_bands_32x32[1024]);
|
||||
distinct bands). */
|
||||
|
||||
/*# define DC_TOKEN_CONTEXTS 3*/ /* 00, 0!0, !0!0 */
|
||||
#define PREV_COEF_CONTEXTS 4
|
||||
#define PREV_COEF_CONTEXTS 4
|
||||
|
||||
typedef unsigned int vp9_coeff_count[COEF_BANDS][PREV_COEF_CONTEXTS]
|
||||
[MAX_ENTROPY_TOKENS];
|
||||
@ -127,13 +127,36 @@ extern DECLARE_ALIGNED(16, const int, vp9_default_zig_zag1d_32x32[1024]);
|
||||
#endif
|
||||
|
||||
void vp9_coef_tree_initialize(void);
|
||||
|
||||
void vp9_adapt_coef_probs(struct VP9Common *);
|
||||
|
||||
static void vp9_reset_mb_tokens_context(MACROBLOCKD* const xd) {
|
||||
/* Clear entropy contexts */
|
||||
vpx_memset(xd->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
|
||||
vpx_memset(xd->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
|
||||
vpx_memset(xd->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
|
||||
vpx_memset(xd->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
|
||||
}
|
||||
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
|
||||
#define MAX_NEIGHBORS 5
|
||||
#define NEWCOEFCONTEXT_BAND_COND(b) ((b) >= 1)
|
||||
void vp9_init_neighbors(void);
|
||||
|
||||
const int *vp9_get_coef_neighbors_handle(const int *scan);
|
||||
int vp9_get_coef_neighbor_context(const short int *qcoeff_ptr, int nodc,
|
||||
const int *neigbor_handle, int rc);
|
||||
extern DECLARE_ALIGNED(16, int, vp9_default_zig_zag1d_4x4_neighbors[
|
||||
16 * MAX_NEIGHBORS]);
|
||||
extern DECLARE_ALIGNED(16, int, vp9_row_scan_4x4_neighbors[
|
||||
16 * MAX_NEIGHBORS]);
|
||||
extern DECLARE_ALIGNED(16, int, vp9_col_scan_4x4_neighbors[
|
||||
16 * MAX_NEIGHBORS]);
|
||||
extern DECLARE_ALIGNED(16, int, vp9_default_zig_zag1d_8x8_neighbors[
|
||||
64 * MAX_NEIGHBORS]);
|
||||
extern DECLARE_ALIGNED(16, int, vp9_default_zig_zag1d_16x16_neighbors[
|
||||
256 * MAX_NEIGHBORS]);
|
||||
#if CONFIG_SUPERBLOCKS && CONFIG_TX32X32
|
||||
extern DECLARE_ALIGNED(16, int, vp9_default_zig_zag1d_32x32_neighbors[
|
||||
1024 * MAX_NEIGHBORS]);
|
||||
#endif
|
||||
#endif // CONFIG_NEWCOEFCONTEXT
|
||||
#endif // VP9_COMMON_VP9_ENTROPY_H_
|
||||
|
@ -63,11 +63,24 @@ static int get_signed(BOOL_DECODER *br, int value_to_sign) {
|
||||
return decode_bool(br, 128) ? -value_to_sign : value_to_sign;
|
||||
}
|
||||
|
||||
#define INCREMENT_COUNT(token) \
|
||||
do { \
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
#define PT pn
|
||||
#define INCREMENT_COUNT(token) \
|
||||
do { \
|
||||
coef_counts[type][coef_bands[c]][pn][token]++; \
|
||||
pn = pt = vp9_prev_token_class[token]; \
|
||||
if (c < seg_eob - 1 && NEWCOEFCONTEXT_BAND_COND(coef_bands[c + 1])) \
|
||||
pn = vp9_get_coef_neighbor_context( \
|
||||
qcoeff_ptr, nodc, neighbors, scan[c + 1]); \
|
||||
} while (0)
|
||||
#else
|
||||
#define PT pt
|
||||
#define INCREMENT_COUNT(token) \
|
||||
do { \
|
||||
coef_counts[type][coef_bands[c]][pt][token]++; \
|
||||
pt = vp9_prev_token_class[token]; \
|
||||
} while (0)
|
||||
#endif /* CONFIG_NEWCOEFCONTEXT */
|
||||
|
||||
#define WRITE_COEF_CONTINUE(val, token) \
|
||||
{ \
|
||||
@ -92,7 +105,12 @@ static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
|
||||
const int *const scan, TX_SIZE txfm_size,
|
||||
const int *coef_bands) {
|
||||
FRAME_CONTEXT *const fc = &dx->common.fc;
|
||||
int pt, c = (type == PLANE_TYPE_Y_NO_DC);
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
const int *neighbors;
|
||||
int pn;
|
||||
#endif
|
||||
int nodc = (type == PLANE_TYPE_Y_NO_DC);
|
||||
int pt, c = nodc;
|
||||
vp9_coeff_probs *coef_probs;
|
||||
vp9_prob *prob;
|
||||
vp9_coeff_count *coef_counts;
|
||||
@ -135,11 +153,15 @@ static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
|
||||
}
|
||||
|
||||
VP9_COMBINEENTROPYCONTEXTS(pt, *a, *l);
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
pn = pt;
|
||||
neighbors = vp9_get_coef_neighbors_handle(scan);
|
||||
#endif
|
||||
while (1) {
|
||||
int val;
|
||||
const uint8_t *cat6 = cat6_prob;
|
||||
if (c >= seg_eob) break;
|
||||
prob = coef_probs[type][coef_bands[c]][pt];
|
||||
prob = coef_probs[type][coef_bands[c]][PT];
|
||||
if (!vp9_read(br, prob[EOB_CONTEXT_NODE]))
|
||||
break;
|
||||
SKIP_START:
|
||||
@ -147,7 +169,7 @@ SKIP_START:
|
||||
if (!vp9_read(br, prob[ZERO_CONTEXT_NODE])) {
|
||||
INCREMENT_COUNT(ZERO_TOKEN);
|
||||
++c;
|
||||
prob = coef_probs[type][coef_bands[c]][pt];
|
||||
prob = coef_probs[type][coef_bands[c]][PT];
|
||||
goto SKIP_START;
|
||||
}
|
||||
// ONE_CONTEXT_NODE_0_
|
||||
@ -211,7 +233,7 @@ SKIP_START:
|
||||
}
|
||||
|
||||
if (c < seg_eob)
|
||||
coef_counts[type][coef_bands[c]][pt][DCT_EOB_TOKEN]++;
|
||||
coef_counts[type][coef_bands[c]][PT][DCT_EOB_TOKEN]++;
|
||||
|
||||
a[0] = l[0] = (c > !type);
|
||||
|
||||
|
@ -380,6 +380,9 @@ static void optimize_b(MACROBLOCK *mb, int i, PLANE_TYPE type,
|
||||
int err_mult = plane_rd_mult[type];
|
||||
int default_eob;
|
||||
int const *scan, *bands;
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
const int *neighbors;
|
||||
#endif
|
||||
|
||||
switch (tx_size) {
|
||||
default:
|
||||
@ -421,6 +424,9 @@ static void optimize_b(MACROBLOCK *mb, int i, PLANE_TYPE type,
|
||||
default_eob = 256;
|
||||
break;
|
||||
}
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
neighbors = vp9_get_coef_neighbors_handle(scan);
|
||||
#endif
|
||||
|
||||
/* Now set up a Viterbi trellis to evaluate alternative roundings. */
|
||||
rdmult = mb->rdmult * err_mult;
|
||||
@ -454,6 +460,11 @@ static void optimize_b(MACROBLOCK *mb, int i, PLANE_TYPE type,
|
||||
if (next < default_eob) {
|
||||
band = bands[i + 1];
|
||||
pt = vp9_prev_token_class[t0];
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
if (NEWCOEFCONTEXT_BAND_COND(band))
|
||||
pt = vp9_get_coef_neighbor_context(
|
||||
qcoeff_ptr, i0, neighbors, scan[i + 1]);
|
||||
#endif
|
||||
rate0 +=
|
||||
mb->token_costs[tx_size][type][band][pt][tokens[next][0].token];
|
||||
rate1 +=
|
||||
@ -501,12 +512,34 @@ static void optimize_b(MACROBLOCK *mb, int i, PLANE_TYPE type,
|
||||
if (next < default_eob) {
|
||||
band = bands[i + 1];
|
||||
if (t0 != DCT_EOB_TOKEN) {
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
int tmp = qcoeff_ptr[scan[i]];
|
||||
qcoeff_ptr[scan[i]] = x;
|
||||
if (NEWCOEFCONTEXT_BAND_COND(band))
|
||||
pt = vp9_get_coef_neighbor_context(
|
||||
qcoeff_ptr, i0, neighbors, scan[i + 1]);
|
||||
else
|
||||
pt = vp9_prev_token_class[t0];
|
||||
qcoeff_ptr[scan[i]] = tmp;
|
||||
#else
|
||||
pt = vp9_prev_token_class[t0];
|
||||
#endif
|
||||
rate0 += mb->token_costs[tx_size][type][band][pt][
|
||||
tokens[next][0].token];
|
||||
}
|
||||
if (t1 != DCT_EOB_TOKEN) {
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
int tmp = qcoeff_ptr[scan[i]];
|
||||
qcoeff_ptr[scan[i]] = x;
|
||||
if (NEWCOEFCONTEXT_BAND_COND(band))
|
||||
pt = vp9_get_coef_neighbor_context(
|
||||
qcoeff_ptr, i0, neighbors, scan[i + 1]);
|
||||
else
|
||||
pt = vp9_prev_token_class[t1];
|
||||
qcoeff_ptr[scan[i]] = tmp;
|
||||
#else
|
||||
pt = vp9_prev_token_class[t1];
|
||||
#endif
|
||||
rate1 += mb->token_costs[tx_size][type][band][pt][
|
||||
tokens[next][1].token];
|
||||
}
|
||||
|
@ -513,29 +513,48 @@ int vp9_uvsse(MACROBLOCK *x) {
|
||||
|
||||
}
|
||||
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
#define PT pn
|
||||
#else
|
||||
#define PT pt
|
||||
#endif
|
||||
|
||||
static int cost_coeffs_2x2(MACROBLOCK *mb,
|
||||
BLOCKD *b, PLANE_TYPE type,
|
||||
ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l) {
|
||||
int c = (type == PLANE_TYPE_Y_NO_DC); /* start at coef 0, unless Y with Y2 */
|
||||
int nodc = (type == PLANE_TYPE_Y_NO_DC);
|
||||
int c = nodc; /* start at coef 0, unless Y with Y2 */
|
||||
int eob = b->eob;
|
||||
int pt; /* surrounding block/prev coef predictor */
|
||||
int cost = 0;
|
||||
int16_t *qcoeff_ptr = b->qcoeff;
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
const int *neighbors = vp9_default_zig_zag1d_4x4_neighbors;
|
||||
int pn;
|
||||
#endif
|
||||
|
||||
VP9_COMBINEENTROPYCONTEXTS(pt, *a, *l);
|
||||
assert(eob <= 4);
|
||||
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
pn = pt;
|
||||
#endif
|
||||
for (; c < eob; c++) {
|
||||
int v = qcoeff_ptr[vp9_default_zig_zag1d_4x4[c]];
|
||||
int t = vp9_dct_value_tokens_ptr[v].Token;
|
||||
cost += mb->token_costs[TX_8X8][type][vp9_coef_bands_4x4[c]][pt][t];
|
||||
cost += vp9_dct_value_cost_ptr[v];
|
||||
pt = vp9_prev_token_class[t];
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
if (c < 4 - 1)
|
||||
pn = vp9_get_coef_neighbor_context(
|
||||
qcoeff_ptr, nodc, neighbors, vp9_default_zig_zag1d_4x4[c + 1]);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (c < 4)
|
||||
cost += mb->token_costs[TX_8X8][type][vp9_coef_bands_4x4[c]]
|
||||
[pt] [DCT_EOB_TOKEN];
|
||||
[PT][DCT_EOB_TOKEN];
|
||||
// is eob first coefficient;
|
||||
pt = (c > !type);
|
||||
*a = *l = pt;
|
||||
@ -546,7 +565,8 @@ static int cost_coeffs(MACROBLOCK *mb, BLOCKD *b, PLANE_TYPE type,
|
||||
ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l,
|
||||
TX_SIZE tx_size) {
|
||||
const int eob = b->eob;
|
||||
int c = (type == PLANE_TYPE_Y_NO_DC); /* start at coef 0, unless Y with Y2 */
|
||||
int nodc = (type == PLANE_TYPE_Y_NO_DC);
|
||||
int c = nodc; /* start at coef 0, unless Y with Y2 */
|
||||
int cost = 0, default_eob, seg_eob;
|
||||
int pt; /* surrounding block/prev coef predictor */
|
||||
int const *scan, *band;
|
||||
@ -555,6 +575,10 @@ static int cost_coeffs(MACROBLOCK *mb, BLOCKD *b, PLANE_TYPE type,
|
||||
MB_MODE_INFO *mbmi = &mb->e_mbd.mode_info_context->mbmi;
|
||||
TX_TYPE tx_type = DCT_DCT;
|
||||
int segment_id = mbmi->segment_id;
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
const int *neighbors;
|
||||
int pn;
|
||||
#endif
|
||||
scan = vp9_default_zig_zag1d_4x4;
|
||||
band = vp9_coef_bands_4x4;
|
||||
default_eob = 16;
|
||||
@ -628,17 +652,28 @@ static int cost_coeffs(MACROBLOCK *mb, BLOCKD *b, PLANE_TYPE type,
|
||||
|
||||
VP9_COMBINEENTROPYCONTEXTS(pt, *a, *l);
|
||||
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
neighbors = vp9_get_coef_neighbors_handle(scan);
|
||||
pn = pt;
|
||||
#endif
|
||||
if (tx_type != DCT_DCT) {
|
||||
for (; c < eob; c++) {
|
||||
int v = qcoeff_ptr[scan[c]];
|
||||
int t = vp9_dct_value_tokens_ptr[v].Token;
|
||||
cost += mb->hybrid_token_costs[tx_size][type][band[c]][pt][t];
|
||||
cost += mb->hybrid_token_costs[tx_size][type][band[c]][PT][t];
|
||||
cost += vp9_dct_value_cost_ptr[v];
|
||||
pt = vp9_prev_token_class[t];
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
if (c < seg_eob - 1 && NEWCOEFCONTEXT_BAND_COND(band[c + 1]))
|
||||
pn = vp9_get_coef_neighbor_context(
|
||||
qcoeff_ptr, nodc, neighbors, scan[c + 1]);
|
||||
else
|
||||
pn = pt;
|
||||
#endif
|
||||
}
|
||||
if (c < seg_eob)
|
||||
cost += mb->hybrid_token_costs[tx_size][type][band[c]]
|
||||
[pt][DCT_EOB_TOKEN];
|
||||
[PT][DCT_EOB_TOKEN];
|
||||
} else {
|
||||
for (; c < eob; c++) {
|
||||
int v = qcoeff_ptr[scan[c]];
|
||||
@ -646,10 +681,17 @@ static int cost_coeffs(MACROBLOCK *mb, BLOCKD *b, PLANE_TYPE type,
|
||||
cost += mb->token_costs[tx_size][type][band[c]][pt][t];
|
||||
cost += vp9_dct_value_cost_ptr[v];
|
||||
pt = vp9_prev_token_class[t];
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
if (c < seg_eob - 1 && NEWCOEFCONTEXT_BAND_COND(band[c + 1]))
|
||||
pn = vp9_get_coef_neighbor_context(
|
||||
qcoeff_ptr, nodc, neighbors, scan[c + 1]);
|
||||
else
|
||||
pn = pt;
|
||||
#endif
|
||||
}
|
||||
if (c < seg_eob)
|
||||
cost += mb->token_costs[tx_size][type][band[c]]
|
||||
[pt][DCT_EOB_TOKEN];
|
||||
[PT][DCT_EOB_TOKEN];
|
||||
}
|
||||
|
||||
// is eob first coefficient;
|
||||
|
@ -103,6 +103,13 @@ static void fill_value_tokens() {
|
||||
vp9_dct_value_tokens_ptr = dct_value_tokens + DCT_MAX_VALUE;
|
||||
vp9_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE;
|
||||
}
|
||||
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
#define PT pn
|
||||
#else
|
||||
#define PT pt
|
||||
#endif
|
||||
|
||||
static void tokenize_b(VP9_COMP *cpi,
|
||||
MACROBLOCKD *xd,
|
||||
const int ib,
|
||||
@ -123,6 +130,10 @@ static void tokenize_b(VP9_COMP *cpi,
|
||||
vp9_coeff_probs *probs;
|
||||
const TX_TYPE tx_type = (type == PLANE_TYPE_Y_WITH_DC) ?
|
||||
get_tx_type(xd, b) : DCT_DCT;
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
const int *neighbors;
|
||||
int pn;
|
||||
#endif
|
||||
|
||||
ENTROPY_CONTEXT *const a = (ENTROPY_CONTEXT *)xd->above_context +
|
||||
vp9_block2above[tx_size][ib];
|
||||
@ -229,6 +240,10 @@ static void tokenize_b(VP9_COMP *cpi,
|
||||
}
|
||||
|
||||
VP9_COMBINEENTROPYCONTEXTS(pt, a_ec, l_ec);
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
neighbors = vp9_get_coef_neighbors_handle(scan);
|
||||
pn = pt;
|
||||
#endif
|
||||
|
||||
if (vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB))
|
||||
seg_eob = vp9_get_segdata(xd, segment_id, SEG_LVL_EOB);
|
||||
@ -249,14 +264,21 @@ static void tokenize_b(VP9_COMP *cpi,
|
||||
}
|
||||
|
||||
t->Token = token;
|
||||
t->context_tree = probs[type][band][pt];
|
||||
t->context_tree = probs[type][band][PT];
|
||||
t->skip_eob_node = (pt == 0) && ((band > 0 && type != PLANE_TYPE_Y_NO_DC) ||
|
||||
(band > 1 && type == PLANE_TYPE_Y_NO_DC));
|
||||
assert(vp9_coef_encodings[t->Token].Len - t->skip_eob_node > 0);
|
||||
if (!dry_run) {
|
||||
++counts[type][band][pt][token];
|
||||
++counts[type][band][PT][token];
|
||||
}
|
||||
pt = vp9_prev_token_class[token];
|
||||
#if CONFIG_NEWCOEFCONTEXT
|
||||
if (c < seg_eob - 1 && NEWCOEFCONTEXT_BAND_COND(bands[c + 1]))
|
||||
pn = vp9_get_coef_neighbor_context(
|
||||
qcoeff_ptr, (type == PLANE_TYPE_Y_NO_DC), neighbors, scan[c + 1]);
|
||||
else
|
||||
pn = pt;
|
||||
#endif
|
||||
++t;
|
||||
} while (c < eob && ++c < seg_eob);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user