static void adapt_coef_probs(VP10_COMMON *cm, TX_SIZE tx_size, unsigned int count_sat, unsigned int update_factor) { const FRAME_CONTEXT *pre_fc = &cm->frame_contexts[cm->frame_context_idx]; vp10_coeff_probs_model *const probs = cm->fc->coef_probs[tx_size]; const vp10_coeff_probs_model *const pre_probs = pre_fc->coef_probs[tx_size]; vp10_coeff_count_model *counts = cm->counts.coef[tx_size]; unsigned int (*eob_counts)[REF_TYPES][COEF_BANDS][COEFF_CONTEXTS] = cm->counts.eob_branch[tx_size]; int i, j, k, l, m; for (i = 0; i < PLANE_TYPES; ++i) for (j = 0; j < REF_TYPES; ++j) for (k = 0; k < COEF_BANDS; ++k) for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) { const int n0 = counts[i][j][k][l][ZERO_TOKEN]; const int n1 = counts[i][j][k][l][ONE_TOKEN]; const int n2 = counts[i][j][k][l][TWO_TOKEN]; const int neob = counts[i][j][k][l][EOB_MODEL_TOKEN]; const unsigned int branch_ct[UNCONSTRAINED_NODES][2] = { { neob, eob_counts[i][j][k][l] - neob }, { n0, n1 + n2 }, { n1, n2 } }; for (m = 0; m < UNCONSTRAINED_NODES; ++m) probs[i][j][k][l][m] = merge_probs(pre_probs[i][j][k][l][m], branch_ct[m], count_sat, update_factor); } }
static void build_tree_distribution(VP9_COMP *cpi, TX_SIZE tx_size, vp9_coeff_stats *coef_branch_ct, vp9_coeff_probs_model *coef_probs) { vp9_coeff_count *coef_counts = cpi->td.rd_counts.coef_counts[tx_size]; unsigned int (*eob_branch_ct)[REF_TYPES][COEF_BANDS][COEFF_CONTEXTS] = cpi->common.counts.eob_branch[tx_size]; int i, j, k, l, m; for (i = 0; i < PLANE_TYPES; ++i) { for (j = 0; j < REF_TYPES; ++j) { for (k = 0; k < COEF_BANDS; ++k) { for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) { vp9_tree_probs_from_distribution(vp9_coef_tree, coef_branch_ct[i][j][k][l], coef_counts[i][j][k][l]); 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]; for (m = 0; m < UNCONSTRAINED_NODES; ++m) coef_probs[i][j][k][l][m] = get_binary_prob( coef_branch_ct[i][j][k][l][m][0], coef_branch_ct[i][j][k][l][m][1]); } } } } }
static void fill_token_costs(vp9_coeff_cost *c, vp9_coeff_probs_model (*p)[PLANE_TYPES]) { int i, j, k, l; TX_SIZE t; for (t = TX_4X4; t <= TX_32X32; ++t) for (i = 0; i < PLANE_TYPES; ++i) for (j = 0; j < REF_TYPES; ++j) for (k = 0; k < COEF_BANDS; ++k) for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) { vpx_prob probs[ENTROPY_NODES]; vp9_model_to_full_probs(p[t][i][j][k][l], probs); vp9_cost_tokens((int *)c[t][i][j][k][0][l], probs, vp9_coef_tree); vp9_cost_tokens_skip((int *)c[t][i][j][k][1][l], probs, vp9_coef_tree); assert(c[t][i][j][k][0][l][EOB_TOKEN] == c[t][i][j][k][1][l][EOB_TOKEN]); } }
static void update_coef_probs_common(vpx_writer* const bc, VP9_COMP *cpi, TX_SIZE tx_size, vp9_coeff_stats *frame_branch_ct, vp9_coeff_probs_model *new_coef_probs) { vp9_coeff_probs_model *old_coef_probs = cpi->common.fc->coef_probs[tx_size]; const vpx_prob upd = DIFF_UPDATE_PROB; const int entropy_nodes_update = UNCONSTRAINED_NODES; int i, j, k, l, t; int stepsize = cpi->sf.coeff_prob_appx_step; switch (cpi->sf.use_fast_coef_updates) { case TWO_LOOP: { /* dry run to see if there is any update at all needed */ int savings = 0; int update[2] = {0, 0}; for (i = 0; i < PLANE_TYPES; ++i) { for (j = 0; j < REF_TYPES; ++j) { for (k = 0; k < COEF_BANDS; ++k) { for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) { for (t = 0; t < entropy_nodes_update; ++t) { vpx_prob newp = new_coef_probs[i][j][k][l][t]; const vpx_prob oldp = old_coef_probs[i][j][k][l][t]; int s; int u = 0; if (t == PIVOT_NODE) s = vp9_prob_diff_update_savings_search_model( frame_branch_ct[i][j][k][l][0], oldp, &newp, upd, stepsize); else s = vp9_prob_diff_update_savings_search( frame_branch_ct[i][j][k][l][t], oldp, &newp, upd); if (s > 0 && newp != oldp) u = 1; if (u) savings += s - (int)(vp9_cost_zero(upd)); else savings -= (int)(vp9_cost_zero(upd)); update[u]++; } } } } } // printf("Update %d %d, savings %d\n", update[0], update[1], savings); /* Is coef updated at all */ if (update[1] == 0 || savings < 0) { vpx_write_bit(bc, 0); return; } vpx_write_bit(bc, 1); for (i = 0; i < PLANE_TYPES; ++i) { for (j = 0; j < REF_TYPES; ++j) { for (k = 0; k < COEF_BANDS; ++k) { for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) { // calc probs and branch cts for this frame only for (t = 0; t < entropy_nodes_update; ++t) { vpx_prob newp = new_coef_probs[i][j][k][l][t]; vpx_prob *oldp = old_coef_probs[i][j][k][l] + t; const vpx_prob upd = DIFF_UPDATE_PROB; int s; int u = 0; if (t == PIVOT_NODE) s = vp9_prob_diff_update_savings_search_model( frame_branch_ct[i][j][k][l][0], *oldp, &newp, upd, stepsize); else s = vp9_prob_diff_update_savings_search( frame_branch_ct[i][j][k][l][t], *oldp, &newp, upd); if (s > 0 && newp != *oldp) u = 1; vpx_write(bc, u, upd); if (u) { /* send/use new probability */ vp9_write_prob_diff_update(bc, newp, *oldp); *oldp = newp; } } } } } } return; } case ONE_LOOP_REDUCED: { int updates = 0; int noupdates_before_first = 0; for (i = 0; i < PLANE_TYPES; ++i) { for (j = 0; j < REF_TYPES; ++j) { for (k = 0; k < COEF_BANDS; ++k) { for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) { // calc probs and branch cts for this frame only for (t = 0; t < entropy_nodes_update; ++t) { vpx_prob newp = new_coef_probs[i][j][k][l][t]; vpx_prob *oldp = old_coef_probs[i][j][k][l] + t; int s; int u = 0; if (t == PIVOT_NODE) { s = vp9_prob_diff_update_savings_search_model( frame_branch_ct[i][j][k][l][0], *oldp, &newp, upd, stepsize); } else { s = vp9_prob_diff_update_savings_search( frame_branch_ct[i][j][k][l][t], *oldp, &newp, upd); } if (s > 0 && newp != *oldp) u = 1; updates += u; if (u == 0 && updates == 0) { noupdates_before_first++; continue; } if (u == 1 && updates == 1) { int v; // first update vpx_write_bit(bc, 1); for (v = 0; v < noupdates_before_first; ++v) vpx_write(bc, 0, upd); } vpx_write(bc, u, upd); if (u) { /* send/use new probability */ vp9_write_prob_diff_update(bc, newp, *oldp); *oldp = newp; } } } } } } if (updates == 0) { vpx_write_bit(bc, 0); // no updates } return; } default: assert(0); } }