Merge "Use above/left (instead of previous in scan-order) as token context." into experimental
This commit is contained in:
commit
c6efbbcfe4
File diff suppressed because it is too large
Load Diff
@ -1886,25 +1886,25 @@ vp9_extra_bit_struct vp9_extra_bits[12] = {
|
||||
// within the current block.
|
||||
//
|
||||
// For now it just returns the previously used context.
|
||||
int vp9_get_coef_context(int * recent_energy, int token) {
|
||||
// int token_energy;
|
||||
// int av_energy;
|
||||
|
||||
/*token_energy = ((token != DCT_EOB_TOKEN) ? token : 0);
|
||||
if (!token_energy) {
|
||||
if (!(*recent_energy)) {
|
||||
av_energy = 0;
|
||||
} else {
|
||||
av_energy = 1;
|
||||
}
|
||||
#define MAX_NEIGHBORS 2
|
||||
int vp9_get_coef_context(const int *scan, const int *neighbors,
|
||||
int nb_pad, uint8_t *token_cache, int c, int l) {
|
||||
int eob = l;
|
||||
assert(nb_pad == MAX_NEIGHBORS);
|
||||
if (c == eob - 1) {
|
||||
return 0;
|
||||
} else {
|
||||
av_energy = ((token_energy + *recent_energy + 1) >> 1) + 1;
|
||||
if (av_energy > DCT_VAL_CATEGORY6)
|
||||
av_energy = DCT_VAL_CATEGORY6;
|
||||
int ctx;
|
||||
c++;
|
||||
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;
|
||||
} else {
|
||||
ctx = token_cache[neighbors[MAX_NEIGHBORS * c + 0]];
|
||||
}
|
||||
return vp9_pt_energy_class[ctx];
|
||||
}
|
||||
*recent_energy = token_energy;*/
|
||||
|
||||
return vp9_pt_energy_class[token];
|
||||
};
|
||||
|
||||
void vp9_default_coef_probs(VP9_COMMON *pc) {
|
||||
@ -2063,7 +2063,119 @@ void vp9_adjust_default_coef_probs(VP9_COMMON *cm) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// 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]);
|
||||
DECLARE_ALIGNED(16, int,
|
||||
vp9_default_zig_zag1d_32x32_neighbors[1024 * MAX_NEIGHBORS]);
|
||||
|
||||
static int find_in_scan(const int *scan, int l, int idx) {
|
||||
int n, l2 = l * l;
|
||||
for (n = 0; n < l2; n++) {
|
||||
int rc = scan[n];
|
||||
if (rc == idx)
|
||||
return n;
|
||||
}
|
||||
assert(0);
|
||||
return -1;
|
||||
}
|
||||
static void init_scan_neighbors(const int *scan, int l, int *neighbors,
|
||||
int max_neighbors) {
|
||||
int l2 = l * l;
|
||||
int n, i, j;
|
||||
|
||||
for (n = 0; n < l2; n++) {
|
||||
int rc = scan[n];
|
||||
assert(max_neighbors == MAX_NEIGHBORS);
|
||||
i = rc / l;
|
||||
j = rc % l;
|
||||
if (i > 0 && j > 0) {
|
||||
// col/row scan is used for adst/dct, and generally means that
|
||||
// energy decreases to zero much faster in the dimension in
|
||||
// which ADST is used compared to the direction in which DCT
|
||||
// is used. Likewise, we find much higher correlation between
|
||||
// coefficients within the direction in which DCT is used.
|
||||
// Therefore, if we use ADST/DCT, prefer the DCT neighbor coeff
|
||||
// as a context. If ADST or DCT is used in both directions, we
|
||||
// use the combination of the two as a context.
|
||||
int a = find_in_scan(scan, l, (i - 1) * l + j);
|
||||
int b = find_in_scan(scan, l, i * l + j - 1);
|
||||
if (scan == vp9_col_scan_4x4 || scan == vp9_row_scan_4x4) {
|
||||
neighbors[max_neighbors * n + 0] = MAX(a, b);
|
||||
neighbors[max_neighbors * n + 1] = -1;
|
||||
} else {
|
||||
neighbors[max_neighbors * n + 0] = a;
|
||||
neighbors[max_neighbors * n + 1] = b;
|
||||
}
|
||||
} else if (i > 0) {
|
||||
neighbors[max_neighbors * n + 0] = find_in_scan(scan, l, (i - 1) * l + j);
|
||||
neighbors[max_neighbors * n + 1] = -1;
|
||||
} else if (j > 0) {
|
||||
neighbors[max_neighbors * n + 0] =
|
||||
find_in_scan(scan, l, i * l + j - 1);
|
||||
neighbors[max_neighbors * n + 1] = -1;
|
||||
} else {
|
||||
assert(n == 0);
|
||||
// dc predictor doesn't use previous tokens
|
||||
neighbors[max_neighbors * n + 0] = -1;
|
||||
}
|
||||
assert(neighbors[max_neighbors * n + 0] < n);
|
||||
}
|
||||
}
|
||||
|
||||
void vp9_init_neighbors() {
|
||||
init_scan_neighbors(vp9_default_zig_zag1d_4x4, 4,
|
||||
vp9_default_zig_zag1d_4x4_neighbors, MAX_NEIGHBORS);
|
||||
init_scan_neighbors(vp9_row_scan_4x4, 4,
|
||||
vp9_row_scan_4x4_neighbors, MAX_NEIGHBORS);
|
||||
init_scan_neighbors(vp9_col_scan_4x4, 4,
|
||||
vp9_col_scan_4x4_neighbors, MAX_NEIGHBORS);
|
||||
init_scan_neighbors(vp9_default_zig_zag1d_8x8, 8,
|
||||
vp9_default_zig_zag1d_8x8_neighbors, MAX_NEIGHBORS);
|
||||
init_scan_neighbors(vp9_default_zig_zag1d_16x16, 16,
|
||||
vp9_default_zig_zag1d_16x16_neighbors, MAX_NEIGHBORS);
|
||||
init_scan_neighbors(vp9_default_zig_zag1d_32x32, 32,
|
||||
vp9_default_zig_zag1d_32x32_neighbors, MAX_NEIGHBORS);
|
||||
}
|
||||
|
||||
const int *vp9_get_coef_neighbors_handle(const int *scan, int *pad) {
|
||||
if (scan == vp9_default_zig_zag1d_4x4) {
|
||||
*pad = MAX_NEIGHBORS;
|
||||
return vp9_default_zig_zag1d_4x4_neighbors;
|
||||
} else if (scan == vp9_row_scan_4x4) {
|
||||
*pad = MAX_NEIGHBORS;
|
||||
return vp9_row_scan_4x4_neighbors;
|
||||
} else if (scan == vp9_col_scan_4x4) {
|
||||
*pad = MAX_NEIGHBORS;
|
||||
return vp9_col_scan_4x4_neighbors;
|
||||
} else if (scan == vp9_default_zig_zag1d_8x8) {
|
||||
*pad = MAX_NEIGHBORS;
|
||||
return vp9_default_zig_zag1d_8x8_neighbors;
|
||||
} else if (scan == vp9_default_zig_zag1d_16x16) {
|
||||
*pad = MAX_NEIGHBORS;
|
||||
return vp9_default_zig_zag1d_16x16_neighbors;
|
||||
} else if (scan == vp9_default_zig_zag1d_32x32) {
|
||||
*pad = MAX_NEIGHBORS;
|
||||
return vp9_default_zig_zag1d_32x32_neighbors;
|
||||
} else {
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void vp9_coef_tree_initialize() {
|
||||
vp9_init_neighbors();
|
||||
init_bit_trees();
|
||||
vp9_tokens_from_tree(vp9_coef_encodings, vp9_coef_tree);
|
||||
#if CONFIG_CODE_NONZEROCOUNT
|
||||
@ -3170,6 +3282,9 @@ void vp9_update_nzc_counts(VP9_COMMON *cm,
|
||||
static void adapt_coef_probs(vp9_coeff_probs *dst_coef_probs,
|
||||
vp9_coeff_probs *pre_coef_probs,
|
||||
int block_types, vp9_coeff_count *coef_counts,
|
||||
unsigned int (*eob_branch_count)[REF_TYPES]
|
||||
[COEF_BANDS]
|
||||
[PREV_COEF_CONTEXTS],
|
||||
int count_sat, int update_factor) {
|
||||
int t, i, j, k, l, count;
|
||||
unsigned int branch_ct[ENTROPY_NODES][2];
|
||||
@ -3190,6 +3305,8 @@ static void adapt_coef_probs(vp9_coeff_probs *dst_coef_probs,
|
||||
vp9_tree_probs_from_distribution(vp9_coef_tree,
|
||||
coef_probs, branch_ct,
|
||||
coef_counts[i][j][k][l], 0);
|
||||
branch_ct[0][1] = eob_branch_count[i][j][k][l] - branch_ct[0][0];
|
||||
coef_probs[0] = get_binary_prob(branch_ct[0][0], branch_ct[0][1]);
|
||||
for (t = 0; t < entropy_nodes_adapt; ++t) {
|
||||
count = branch_ct[t][0] + branch_ct[t][1];
|
||||
count = count > count_sat ? count_sat : count;
|
||||
@ -3224,15 +3341,19 @@ void vp9_adapt_coef_probs(VP9_COMMON *cm) {
|
||||
|
||||
adapt_coef_probs(cm->fc.coef_probs_4x4, cm->fc.pre_coef_probs_4x4,
|
||||
BLOCK_TYPES, cm->fc.coef_counts_4x4,
|
||||
cm->fc.eob_branch_counts[TX_4X4],
|
||||
count_sat, update_factor);
|
||||
adapt_coef_probs(cm->fc.coef_probs_8x8, cm->fc.pre_coef_probs_8x8,
|
||||
BLOCK_TYPES, cm->fc.coef_counts_8x8,
|
||||
cm->fc.eob_branch_counts[TX_8X8],
|
||||
count_sat, update_factor);
|
||||
adapt_coef_probs(cm->fc.coef_probs_16x16, cm->fc.pre_coef_probs_16x16,
|
||||
BLOCK_TYPES, cm->fc.coef_counts_16x16,
|
||||
cm->fc.eob_branch_counts[TX_16X16],
|
||||
count_sat, update_factor);
|
||||
adapt_coef_probs(cm->fc.coef_probs_32x32, cm->fc.pre_coef_probs_32x32,
|
||||
BLOCK_TYPES, cm->fc.coef_counts_32x32,
|
||||
cm->fc.eob_branch_counts[TX_32X32],
|
||||
count_sat, update_factor);
|
||||
}
|
||||
|
||||
|
@ -139,7 +139,9 @@ static int get_coef_band(TX_SIZE tx_size, int coef_index) {
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
extern int vp9_get_coef_context(int * recent_energy, int token);
|
||||
extern int vp9_get_coef_context(const int *scan, const int *neighbors,
|
||||
int nb_pad, uint8_t *token_cache, int c, int l);
|
||||
const int *vp9_get_coef_neighbors_handle(const int *scan, int *pad);
|
||||
|
||||
#if CONFIG_MODELCOEFPROB
|
||||
#define COEFPROB_BITS 8
|
||||
|
@ -114,6 +114,9 @@ typedef struct frame_contexts {
|
||||
vp9_coeff_count coef_counts_8x8[BLOCK_TYPES];
|
||||
vp9_coeff_count coef_counts_16x16[BLOCK_TYPES];
|
||||
vp9_coeff_count coef_counts_32x32[BLOCK_TYPES];
|
||||
unsigned int eob_branch_counts[TX_SIZE_MAX_SB][BLOCK_TYPES][REF_TYPES]
|
||||
[COEF_BANDS][PREV_COEF_CONTEXTS];
|
||||
|
||||
#if CONFIG_CODE_NONZEROCOUNT
|
||||
unsigned int nzc_counts_4x4[MAX_NZC_CONTEXTS][REF_TYPES][BLOCK_TYPES]
|
||||
[NZC4X4_TOKENS];
|
||||
|
@ -1729,6 +1729,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
|
||||
vp9_zero(pbi->common.fc.coef_counts_8x8);
|
||||
vp9_zero(pbi->common.fc.coef_counts_16x16);
|
||||
vp9_zero(pbi->common.fc.coef_counts_32x32);
|
||||
vp9_zero(pbi->common.fc.eob_branch_counts);
|
||||
vp9_zero(pbi->common.fc.ymode_counts);
|
||||
vp9_zero(pbi->common.fc.sb_ymode_counts);
|
||||
vp9_zero(pbi->common.fc.uv_mode_counts);
|
||||
|
@ -66,7 +66,8 @@ static int get_signed(BOOL_DECODER *br, int value_to_sign) {
|
||||
#define INCREMENT_COUNT(token) \
|
||||
do { \
|
||||
coef_counts[type][ref][get_coef_band(txfm_size, c)][pt][token]++; \
|
||||
pt = vp9_get_coef_context(&recent_energy, token); \
|
||||
token_cache[c] = token; \
|
||||
pt = vp9_get_coef_context(scan, nb, pad, token_cache, c, default_eob); \
|
||||
} while (0)
|
||||
|
||||
#if CONFIG_CODE_NONZEROCOUNT
|
||||
@ -103,8 +104,7 @@ static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
|
||||
int aidx, lidx;
|
||||
ENTROPY_CONTEXT above_ec, left_ec;
|
||||
FRAME_CONTEXT *const fc = &dx->common.fc;
|
||||
int recent_energy = 0;
|
||||
int pt, c = 0;
|
||||
int pt, c = 0, pad, default_eob;
|
||||
vp9_coeff_probs *coef_probs;
|
||||
vp9_prob *prob;
|
||||
vp9_coeff_count *coef_counts;
|
||||
@ -113,7 +113,8 @@ static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
|
||||
uint16_t nzc = 0;
|
||||
uint16_t nzc_expected = xd->mode_info_context->mbmi.nzcs[block_idx];
|
||||
#endif
|
||||
const int *scan;
|
||||
const int *scan, *nb;
|
||||
uint8_t token_cache[1024];
|
||||
|
||||
if (xd->mode_info_context->mbmi.sb_type == BLOCK_SIZE_SB64X64) {
|
||||
aidx = vp9_block2above_sb64[txfm_size][block_idx];
|
||||
@ -145,6 +146,7 @@ static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
|
||||
left_ec = L0[lidx] != 0;
|
||||
coef_probs = fc->coef_probs_4x4;
|
||||
coef_counts = fc->coef_counts_4x4;
|
||||
default_eob = 16;
|
||||
break;
|
||||
}
|
||||
case TX_8X8:
|
||||
@ -153,6 +155,7 @@ static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
|
||||
coef_counts = fc->coef_counts_8x8;
|
||||
above_ec = (A0[aidx] + A0[aidx + 1]) != 0;
|
||||
left_ec = (L0[lidx] + L0[lidx + 1]) != 0;
|
||||
default_eob = 64;
|
||||
break;
|
||||
case TX_16X16:
|
||||
scan = vp9_default_zig_zag1d_16x16;
|
||||
@ -167,6 +170,7 @@ static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
|
||||
above_ec = (A0[aidx] + A0[aidx + 1] + A0[aidx + 2] + A0[aidx + 3]) != 0;
|
||||
left_ec = (L0[lidx] + L0[lidx + 1] + L0[lidx + 2] + L0[lidx + 3]) != 0;
|
||||
}
|
||||
default_eob = 256;
|
||||
break;
|
||||
case TX_32X32:
|
||||
scan = vp9_default_zig_zag1d_32x32;
|
||||
@ -191,10 +195,13 @@ static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
|
||||
left_ec = (L0[lidx] + L0[lidx + 1] + L0[lidx + 2] + L0[lidx + 3] +
|
||||
L1[lidx] + L1[lidx + 1] + L1[lidx + 2] + L1[lidx + 3]) != 0;
|
||||
}
|
||||
default_eob = 1024;
|
||||
break;
|
||||
}
|
||||
|
||||
VP9_COMBINEENTROPYCONTEXTS(pt, above_ec, left_ec);
|
||||
nb = vp9_get_coef_neighbors_handle(scan, &pad);
|
||||
|
||||
while (1) {
|
||||
int val;
|
||||
const uint8_t *cat6 = cat6_prob;
|
||||
@ -207,6 +214,8 @@ static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
|
||||
#endif
|
||||
prob = coef_probs[type][ref][get_coef_band(txfm_size, c)][pt];
|
||||
#if CONFIG_CODE_NONZEROCOUNT == 0
|
||||
fc->eob_branch_counts[txfm_size][type][ref]
|
||||
[get_coef_band(txfm_size, c)][pt]++;
|
||||
if (!vp9_read(br, prob[EOB_CONTEXT_NODE]))
|
||||
break;
|
||||
#endif
|
||||
|
@ -1758,6 +1758,9 @@ static void print_prob_tree(vp9_coeff_probs *coef_probs, int block_types) {
|
||||
|
||||
static void build_tree_distribution(vp9_coeff_probs *coef_probs,
|
||||
vp9_coeff_count *coef_counts,
|
||||
unsigned int (*eob_branch_ct)[REF_TYPES]
|
||||
[COEF_BANDS]
|
||||
[PREV_COEF_CONTEXTS],
|
||||
#ifdef ENTROPY_STATS
|
||||
VP9_COMP *cpi,
|
||||
vp9_coeff_accum *context_counters,
|
||||
@ -1779,10 +1782,18 @@ static void build_tree_distribution(vp9_coeff_probs *coef_probs,
|
||||
coef_probs[i][j][k][l],
|
||||
coef_branch_ct[i][j][k][l],
|
||||
coef_counts[i][j][k][l], 0);
|
||||
coef_branch_ct[i][j][k][l][0][1] = eob_branch_ct[i][j][k][l] -
|
||||
coef_branch_ct[i][j][k][l][0][0];
|
||||
coef_probs[i][j][k][l][0] =
|
||||
get_binary_prob(coef_branch_ct[i][j][k][l][0][0],
|
||||
coef_branch_ct[i][j][k][l][0][1]);
|
||||
#ifdef ENTROPY_STATS
|
||||
if (!cpi->dummy_packing)
|
||||
for (t = 0; t < MAX_ENTROPY_TOKENS; ++t)
|
||||
context_counters[i][j][k][l][t] += coef_counts[i][j][k][l][t];
|
||||
if (!cpi->dummy_packing) {
|
||||
for (t = 0; t < MAX_ENTROPY_TOKENS; ++t)
|
||||
context_counters[i][j][k][l][t] += coef_counts[i][j][k][l][t];
|
||||
context_counters[i][j][k][l][MAX_ENTROPY_TOKENS] +=
|
||||
eob_branch_ct[i][j][k][l];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -1793,24 +1804,28 @@ static void build_tree_distribution(vp9_coeff_probs *coef_probs,
|
||||
static void build_coeff_contexts(VP9_COMP *cpi) {
|
||||
build_tree_distribution(cpi->frame_coef_probs_4x4,
|
||||
cpi->coef_counts_4x4,
|
||||
cpi->common.fc.eob_branch_counts[TX_4X4],
|
||||
#ifdef ENTROPY_STATS
|
||||
cpi, context_counters_4x4,
|
||||
#endif
|
||||
cpi->frame_branch_ct_4x4, BLOCK_TYPES);
|
||||
build_tree_distribution(cpi->frame_coef_probs_8x8,
|
||||
cpi->coef_counts_8x8,
|
||||
cpi->common.fc.eob_branch_counts[TX_8X8],
|
||||
#ifdef ENTROPY_STATS
|
||||
cpi, context_counters_8x8,
|
||||
#endif
|
||||
cpi->frame_branch_ct_8x8, BLOCK_TYPES);
|
||||
build_tree_distribution(cpi->frame_coef_probs_16x16,
|
||||
cpi->coef_counts_16x16,
|
||||
cpi->common.fc.eob_branch_counts[TX_16X16],
|
||||
#ifdef ENTROPY_STATS
|
||||
cpi, context_counters_16x16,
|
||||
#endif
|
||||
cpi->frame_branch_ct_16x16, BLOCK_TYPES);
|
||||
build_tree_distribution(cpi->frame_coef_probs_32x32,
|
||||
cpi->coef_counts_32x32,
|
||||
cpi->common.fc.eob_branch_counts[TX_32X32],
|
||||
#ifdef ENTROPY_STATS
|
||||
cpi, context_counters_32x32,
|
||||
#endif
|
||||
|
@ -1276,6 +1276,7 @@ static void encode_frame_internal(VP9_COMP *cpi) {
|
||||
vp9_zero(cpi->coef_counts_8x8);
|
||||
vp9_zero(cpi->coef_counts_16x16);
|
||||
vp9_zero(cpi->coef_counts_32x32);
|
||||
vp9_zero(cm->fc.eob_branch_counts);
|
||||
#if CONFIG_CODE_NONZEROCOUNT
|
||||
vp9_zero(cm->fc.nzc_counts_4x4);
|
||||
vp9_zero(cm->fc.nzc_counts_8x8);
|
||||
|
@ -528,9 +528,16 @@ static const int plane_rd_mult[4] = {
|
||||
|
||||
// This function is a place holder for now but may ultimately need
|
||||
// to scan previous tokens to work out the correct context.
|
||||
static int trellis_get_coeff_context(int token) {
|
||||
int recent_energy = 0;
|
||||
return vp9_get_coef_context(&recent_energy, token);
|
||||
static int trellis_get_coeff_context(const int *scan,
|
||||
const int *nb,
|
||||
int idx, int token,
|
||||
uint8_t *token_cache,
|
||||
int pad, int l) {
|
||||
int bak = token_cache[idx], pt;
|
||||
token_cache[idx] = token;
|
||||
pt = vp9_get_coef_context(scan, nb, pad, token_cache, idx + 1, l);
|
||||
token_cache[idx] = bak;
|
||||
return pt;
|
||||
}
|
||||
|
||||
static void optimize_b(VP9_COMMON *const cm,
|
||||
@ -552,9 +559,10 @@ static void optimize_b(VP9_COMMON *const cm,
|
||||
int rate0, rate1, error0, error1, t0, t1;
|
||||
int best, band, pt;
|
||||
int err_mult = plane_rd_mult[type];
|
||||
int default_eob;
|
||||
int const *scan;
|
||||
int default_eob, pad;
|
||||
int const *scan, *nb;
|
||||
const int mul = 1 + (tx_size == TX_32X32);
|
||||
uint8_t token_cache[1024];
|
||||
#if CONFIG_CODE_NONZEROCOUNT
|
||||
// TODO(debargha): the dynamic programming approach used in this function
|
||||
// is not compatible with the true rate cost when nzcs are used. Note
|
||||
@ -631,6 +639,10 @@ static void optimize_b(VP9_COMMON *const cm,
|
||||
tokens[eob][0].qc = 0;
|
||||
*(tokens[eob] + 1) = *(tokens[eob] + 0);
|
||||
next = eob;
|
||||
for (i = 0; i < eob; i++)
|
||||
token_cache[i] = vp9_dct_value_tokens_ptr[qcoeff_ptr[scan[i]]].Token;
|
||||
nb = vp9_get_coef_neighbors_handle(scan, &pad);
|
||||
|
||||
for (i = eob; i-- > i0;) {
|
||||
int base_bits, d2, dx;
|
||||
#if CONFIG_CODE_NONZEROCOUNT
|
||||
@ -651,7 +663,8 @@ static void optimize_b(VP9_COMMON *const cm,
|
||||
/* Consider both possible successor states. */
|
||||
if (next < default_eob) {
|
||||
band = get_coef_band(tx_size, i + 1);
|
||||
pt = trellis_get_coeff_context(t0);
|
||||
pt = trellis_get_coeff_context(scan, nb, i, t0, token_cache,
|
||||
pad, default_eob);
|
||||
rate0 +=
|
||||
mb->token_costs[tx_size][type][ref][band][pt][tokens[next][0].token];
|
||||
rate1 +=
|
||||
@ -710,12 +723,14 @@ static void optimize_b(VP9_COMMON *const cm,
|
||||
if (next < default_eob) {
|
||||
band = get_coef_band(tx_size, i + 1);
|
||||
if (t0 != DCT_EOB_TOKEN) {
|
||||
pt = trellis_get_coeff_context(t0);
|
||||
pt = trellis_get_coeff_context(scan, nb, i, t0, token_cache,
|
||||
pad, default_eob);
|
||||
rate0 += mb->token_costs[tx_size][type][ref][band][pt][
|
||||
tokens[next][0].token];
|
||||
}
|
||||
if (t1 != DCT_EOB_TOKEN) {
|
||||
pt = trellis_get_coeff_context(t1);
|
||||
pt = trellis_get_coeff_context(scan, nb, i, t1, token_cache,
|
||||
pad, default_eob);
|
||||
rate1 += mb->token_costs[tx_size][type][ref][band][pt][
|
||||
tokens[next][1].token];
|
||||
}
|
||||
|
@ -156,21 +156,9 @@ static void fill_token_costs(vp9_coeff_count *c,
|
||||
for (j = 0; j < REF_TYPES; j++)
|
||||
for (k = 0; k < COEF_BANDS; k++)
|
||||
for (l = 0; l < PREV_COEF_CONTEXTS; l++) {
|
||||
#if CONFIG_CODE_NONZEROCOUNT
|
||||
// All costs are without the EOB node
|
||||
vp9_cost_tokens_skip((int *)(c[i][j][k][l]),
|
||||
p[i][j][k][l],
|
||||
vp9_coef_tree);
|
||||
#else
|
||||
if (l == 0 && k > 0)
|
||||
vp9_cost_tokens_skip((int *)(c[i][j][k][l]),
|
||||
p[i][j][k][l],
|
||||
vp9_coef_tree);
|
||||
else
|
||||
vp9_cost_tokens((int *)(c[i][j][k][l]),
|
||||
p[i][j][k][l],
|
||||
vp9_coef_tree);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -448,8 +436,8 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
|
||||
int pt;
|
||||
const int eob = xd->eobs[ib];
|
||||
int c = 0;
|
||||
int cost = 0;
|
||||
const int *scan;
|
||||
int cost = 0, pad;
|
||||
const int *scan, *nb;
|
||||
const int16_t *qcoeff_ptr = xd->qcoeff + ib * 16;
|
||||
const int ref = mbmi->ref_frame != INTRA_FRAME;
|
||||
unsigned int (*token_costs)[PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS] =
|
||||
@ -464,9 +452,12 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
|
||||
int nzc_context = vp9_get_nzc_context(cm, xd, ib);
|
||||
unsigned int *nzc_cost;
|
||||
#else
|
||||
int seg_eob;
|
||||
const int segment_id = xd->mode_info_context->mbmi.segment_id;
|
||||
vp9_prob (*coef_probs)[REF_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS]
|
||||
[ENTROPY_NODES];
|
||||
#endif
|
||||
int seg_eob, default_eob;
|
||||
uint8_t token_cache[1024];
|
||||
|
||||
// Check for consistency of tx_size with mode info
|
||||
if (type == PLANE_TYPE_Y_WITH_DC) {
|
||||
@ -485,8 +476,9 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
|
||||
#if CONFIG_CODE_NONZEROCOUNT
|
||||
nzc_cost = mb->nzc_costs_4x4[nzc_context][ref][type];
|
||||
#else
|
||||
seg_eob = 16;
|
||||
coef_probs = cm->fc.coef_probs_4x4;
|
||||
#endif
|
||||
seg_eob = 16;
|
||||
if (tx_type == ADST_DCT) {
|
||||
scan = vp9_row_scan_4x4;
|
||||
} else if (tx_type == DCT_ADST) {
|
||||
@ -503,16 +495,18 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
|
||||
#if CONFIG_CODE_NONZEROCOUNT
|
||||
nzc_cost = mb->nzc_costs_8x8[nzc_context][ref][type];
|
||||
#else
|
||||
seg_eob = 64;
|
||||
coef_probs = cm->fc.coef_probs_8x8;
|
||||
#endif
|
||||
seg_eob = 64;
|
||||
break;
|
||||
case TX_16X16:
|
||||
scan = vp9_default_zig_zag1d_16x16;
|
||||
#if CONFIG_CODE_NONZEROCOUNT
|
||||
nzc_cost = mb->nzc_costs_16x16[nzc_context][ref][type];
|
||||
#else
|
||||
seg_eob = 256;
|
||||
coef_probs = cm->fc.coef_probs_16x16;
|
||||
#endif
|
||||
seg_eob = 256;
|
||||
if (type == PLANE_TYPE_UV) {
|
||||
a_ec = (a[0] + a[1] + a1[0] + a1[1]) != 0;
|
||||
l_ec = (l[0] + l[1] + l1[0] + l1[1]) != 0;
|
||||
@ -526,8 +520,9 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
|
||||
#if CONFIG_CODE_NONZEROCOUNT
|
||||
nzc_cost = mb->nzc_costs_32x32[nzc_context][ref][type];
|
||||
#else
|
||||
seg_eob = 1024;
|
||||
coef_probs = cm->fc.coef_probs_32x32;
|
||||
#endif
|
||||
seg_eob = 1024;
|
||||
if (type == PLANE_TYPE_UV) {
|
||||
ENTROPY_CONTEXT *a2, *a3, *l2, *l3;
|
||||
a2 = a1 + sizeof(ENTROPY_CONTEXT_PLANES) / sizeof(ENTROPY_CONTEXT);
|
||||
@ -551,6 +546,8 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
|
||||
}
|
||||
|
||||
VP9_COMBINEENTROPYCONTEXTS(pt, a_ec, l_ec);
|
||||
nb = vp9_get_coef_neighbors_handle(scan, &pad);
|
||||
default_eob = seg_eob;
|
||||
|
||||
#if CONFIG_CODE_NONZEROCOUNT == 0
|
||||
if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))
|
||||
@ -558,7 +555,6 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
|
||||
#endif
|
||||
|
||||
{
|
||||
int recent_energy = 0;
|
||||
#if CONFIG_CODE_NONZEROCOUNT
|
||||
int nzc = 0;
|
||||
#endif
|
||||
@ -568,9 +564,16 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
|
||||
#if CONFIG_CODE_NONZEROCOUNT
|
||||
nzc += (v != 0);
|
||||
#endif
|
||||
token_cache[c] = t;
|
||||
cost += token_costs[get_coef_band(tx_size, c)][pt][t];
|
||||
cost += vp9_dct_value_cost_ptr[v];
|
||||
pt = vp9_get_coef_context(&recent_energy, t);
|
||||
#if !CONFIG_CODE_NONZEROCOUNT
|
||||
if (!c || token_cache[c - 1])
|
||||
cost += vp9_cost_bit(coef_probs[type][ref]
|
||||
[get_coef_band(tx_size, c)]
|
||||
[pt][0], 1);
|
||||
#endif
|
||||
pt = vp9_get_coef_context(scan, nb, pad, token_cache, c, default_eob);
|
||||
}
|
||||
#if CONFIG_CODE_NONZEROCOUNT
|
||||
cost += nzc_cost[nzc];
|
||||
|
@ -109,6 +109,8 @@ static void fill_value_tokens() {
|
||||
vp9_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE;
|
||||
}
|
||||
|
||||
extern const int *vp9_get_coef_neighbors_handle(const int *scan, int *pad);
|
||||
|
||||
static void tokenize_b(VP9_COMP *cpi,
|
||||
MACROBLOCKD *xd,
|
||||
const int ib,
|
||||
@ -119,18 +121,18 @@ static void tokenize_b(VP9_COMP *cpi,
|
||||
MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
|
||||
int pt; /* near block/prev token context index */
|
||||
int c = 0;
|
||||
int recent_energy = 0;
|
||||
const int eob = xd->eobs[ib]; /* one beyond last nonzero coeff */
|
||||
TOKENEXTRA *t = *tp; /* store tokens starting here */
|
||||
int16_t *qcoeff_ptr = xd->qcoeff + 16 * ib;
|
||||
int seg_eob;
|
||||
int seg_eob, default_eob, pad;
|
||||
const int segment_id = mbmi->segment_id;
|
||||
const BLOCK_SIZE_TYPE sb_type = mbmi->sb_type;
|
||||
const int *scan;
|
||||
const int *scan, *nb;
|
||||
vp9_coeff_count *counts;
|
||||
vp9_coeff_probs *probs;
|
||||
const int ref = mbmi->ref_frame != INTRA_FRAME;
|
||||
ENTROPY_CONTEXT *a, *l, *a1, *l1, *a2, *l2, *a3, *l3, a_ec, l_ec;
|
||||
uint8_t token_cache[1024];
|
||||
#if CONFIG_CODE_NONZEROCOUNT
|
||||
int zerosleft, nzc = 0;
|
||||
if (eob == 0)
|
||||
@ -220,6 +222,8 @@ static void tokenize_b(VP9_COMP *cpi,
|
||||
}
|
||||
|
||||
VP9_COMBINEENTROPYCONTEXTS(pt, a_ec, l_ec);
|
||||
nb = vp9_get_coef_neighbors_handle(scan, &pad);
|
||||
default_eob = seg_eob;
|
||||
|
||||
if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))
|
||||
seg_eob = 0;
|
||||
@ -252,17 +256,20 @@ static void tokenize_b(VP9_COMP *cpi,
|
||||
// Skip zero node if there are no zeros left
|
||||
t->skip_eob_node = 1 + (zerosleft == 0);
|
||||
#else
|
||||
t->skip_eob_node = (pt == 0) && (band > 0);
|
||||
t->skip_eob_node = (c > 0) && (token_cache[c - 1] == 0);
|
||||
#endif
|
||||
assert(vp9_coef_encodings[t->Token].Len - t->skip_eob_node > 0);
|
||||
if (!dry_run) {
|
||||
++counts[type][ref][band][pt][token];
|
||||
if (!t->skip_eob_node)
|
||||
++cpi->common.fc.eob_branch_counts[tx_size][type][ref][band][pt];
|
||||
}
|
||||
#if CONFIG_CODE_NONZEROCOUNT
|
||||
nzc += (v != 0);
|
||||
#endif
|
||||
token_cache[c] = token;
|
||||
|
||||
pt = vp9_get_coef_context(&recent_energy, token);
|
||||
pt = vp9_get_coef_context(scan, nb, pad, token_cache, c, default_eob);
|
||||
++t;
|
||||
} while (c < eob && ++c < seg_eob);
|
||||
#if CONFIG_CODE_NONZEROCOUNT
|
||||
@ -833,7 +840,7 @@ static void print_counter(FILE *f, vp9_coeff_accum *context_counters,
|
||||
|
||||
assert(x == (int64_t) y); /* no overflow handling yet */
|
||||
fprintf(f, "%s %d", Comma(t), y);
|
||||
} while (++t < MAX_ENTROPY_TOKENS);
|
||||
} while (++t < 1 + MAX_ENTROPY_TOKENS);
|
||||
fprintf(f, "}");
|
||||
} while (++pt < PREV_COEF_CONTEXTS);
|
||||
fprintf(f, "\n }");
|
||||
@ -867,13 +874,17 @@ static void print_probs(FILE *f, vp9_coeff_accum *context_counters,
|
||||
pt = 0;
|
||||
do {
|
||||
unsigned int branch_ct[ENTROPY_NODES][2];
|
||||
unsigned int coef_counts[MAX_ENTROPY_TOKENS];
|
||||
unsigned int coef_counts[MAX_ENTROPY_TOKENS + 1];
|
||||
vp9_prob coef_probs[ENTROPY_NODES];
|
||||
|
||||
for (t = 0; t < MAX_ENTROPY_TOKENS; ++t)
|
||||
if (pt >= 3 && band == 0)
|
||||
break;
|
||||
for (t = 0; t < MAX_ENTROPY_TOKENS + 1; ++t)
|
||||
coef_counts[t] = context_counters[type][ref][band][pt][t];
|
||||
vp9_tree_probs_from_distribution(vp9_coef_tree, coef_probs,
|
||||
branch_ct, coef_counts, 0);
|
||||
branch_ct[0][1] = coef_counts[MAX_ENTROPY_TOKENS] - branch_ct[0][0];
|
||||
coef_probs[0] = get_binary_prob(branch_ct[0][0], branch_ct[0][1]);
|
||||
fprintf(f, "%s\n {", Comma(pt));
|
||||
|
||||
t = 0;
|
||||
@ -1025,7 +1036,7 @@ static void stuff_b(VP9_COMP *cpi,
|
||||
|
||||
#if CONFIG_CODE_NONZEROCOUNT == 0
|
||||
VP9_COMBINEENTROPYCONTEXTS(pt, a_ec, l_ec);
|
||||
band = get_coef_band(tx_size, 0);
|
||||
band = 0;
|
||||
t->Token = DCT_EOB_TOKEN;
|
||||
t->context_tree = probs[type][ref][band][pt];
|
||||
t->skip_eob_node = 0;
|
||||
|
@ -29,7 +29,7 @@ typedef struct {
|
||||
} TOKENEXTRA;
|
||||
|
||||
typedef int64_t vp9_coeff_accum[REF_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS]
|
||||
[MAX_ENTROPY_TOKENS];
|
||||
[MAX_ENTROPY_TOKENS + 1];
|
||||
|
||||
int vp9_mby_is_skippable_4x4(MACROBLOCKD *xd);
|
||||
int vp9_mbuv_is_skippable_4x4(MACROBLOCKD *xd);
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
|
||||
#include "vp9/encoder/vp9_treewriter.h"
|
||||
#include "vp9/common/vp9_common.h"
|
||||
|
||||
static void cost(
|
||||
int *const C,
|
||||
@ -35,6 +36,7 @@ void vp9_cost_tokens(int *c, const vp9_prob *p, vp9_tree t) {
|
||||
}
|
||||
|
||||
void vp9_cost_tokens_skip(int *c, const vp9_prob *p, vp9_tree t) {
|
||||
c[0] = 0;
|
||||
assert(t[1] > 0 && t[0] <= 0);
|
||||
c[-t[0]] = vp9_cost_bit(p[0], 0);
|
||||
cost(c, t, p, 2, 0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user