/* * Copyright (c) 2010 The WebM project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree.
*/
// The baseline rd thresholds for breaking out of the rd loop for // certain modes are assumed to be based on 8x8 blocks. // This table is used to correct for block size. // The factors here are << 2 (2 = x0.5, 32 = x8 etc). staticconst uint8_t rd_thresh_block_size_factor[BLOCK_SIZES] = {
2, 3, 3, 4, 6, 6, 8, 12, 12, 16, 24, 24, 32
};
staticvoid fill_mode_costs(VP9_COMP *cpi) { const FRAME_CONTEXT *const fc = cpi->common.fc; int i, j;
for (i = 0; i < INTRA_MODES; ++i) { for (j = 0; j < INTRA_MODES; ++j) {
vp9_cost_tokens(cpi->y_mode_costs[i][j], vp9_kf_y_mode_prob[i][j],
vp9_intra_mode_tree);
}
}
vp9_cost_tokens(cpi->mbmode_cost, fc->y_mode_prob[1], vp9_intra_mode_tree); for (i = 0; i < INTRA_MODES; ++i) {
vp9_cost_tokens(cpi->intra_uv_mode_cost[KEY_FRAME][i],
vp9_kf_uv_mode_prob[i], vp9_intra_mode_tree);
vp9_cost_tokens(cpi->intra_uv_mode_cost[INTER_FRAME][i],
fc->uv_mode_prob[i], vp9_intra_mode_tree);
}
for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) {
vp9_cost_tokens(cpi->switchable_interp_costs[i],
fc->switchable_interp_prob[i], vp9_switchable_interp_tree);
}
for (i = TX_8X8; i < TX_SIZES; ++i) { for (j = 0; j < TX_SIZE_CONTEXTS; ++j) { const vpx_prob *tx_probs = get_tx_probs(i, j, &fc->tx_probs); int k; for (k = 0; k <= i; ++k) { int cost = 0; int m; for (m = 0; m <= k - (k == i); ++m) { if (m == k)
cost += vp9_cost_zero(tx_probs[m]); else
cost += vp9_cost_one(tx_probs[m]);
}
cpi->tx_size_cost[i - 1][j][k] = cost;
}
}
}
}
staticvoid 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]);
}
}
// Values are now correlated to quantizer. staticint sad_per_bit16lut_8[QINDEX_RANGE]; staticint sad_per_bit4lut_8[QINDEX_RANGE];
staticvoid init_me_luts_bd(int *bit16lut, int *bit4lut, int range,
vpx_bit_depth_t bit_depth) { int i; // Initialize the sad lut tables using a formulaic calculation for now. // This is to make it easier to resolve the impact of experimental changes // to the quantizer tables. for (i = 0; i < range; i++) { constdouble q = vp9_convert_qindex_to_q(i, bit_depth);
bit16lut[i] = (int)(0.0418 * q + 2.4107);
bit4lut[i] = (int)(0.063 * q + 2.742);
}
}
// Note that the element below for frame type "USE_BUF_FRAME", which indicates // that the show frame flag is set, should not be used as no real frame // is encoded so we should not reach here. However, a dummy value // is inserted here to make sure the data structure has the right number // of values assigned. staticconstint rd_frame_type_factor[FRAME_UPDATE_TYPES] = { 128, 144, 128,
128, 144, 144 };
// Configure Vizier RD parameters. // Later this function will use passed in command line values. void vp9_init_rd_parameters(VP9_COMP *cpi) {
RD_CONTROL *const rdc = &cpi->rd_ctrl;
// When |use_vizier_rc_params| is 1, we expect the rd parameters have been // initialized by the pass in values. // Be careful that parameters below are only initialized to 1, if we do not // pass values to them. It is desired to take care of each parameter when // using |use_vizier_rc_params|. if (cpi->twopass.use_vizier_rc_params) return;
// Make sure this function is floating point safe.
vpx_clear_system_state();
// Returns the default rd multiplier for inter frames for a given qindex. // The function here is a first pass estimate based on data from // a previous Vizer run staticdouble def_inter_rd_multiplier(int qindex) { return 4.15 + (0.001 * (double)qindex);
}
// Returns the default rd multiplier for ARF/Golden Frames for a given qindex. // The function here is a first pass estimate based on data from // a previous Vizer run staticdouble def_arf_rd_multiplier(int qindex) { return 4.25 + (0.001 * (double)qindex);
}
// Returns the default rd multiplier for key frames for a given qindex. // The function here is a first pass estimate based on data from // a previous Vizer run staticdouble def_kf_rd_multiplier(int qindex) { return 4.35 + (0.001 * (double)qindex);
}
int vp9_compute_rd_mult_based_on_qindex(const VP9_COMP *cpi, int qindex) { const RD_CONTROL *rdc = &cpi->rd_ctrl; constint q = vp9_dc_quant(qindex, 0, cpi->common.bit_depth); // largest dc_quant is 21387, therefore rdmult should fit in int32_t int rdmult = q * q;
for (bsize = 0; bsize < BLOCK_SIZES; ++bsize) { // Threshold here seems unnecessarily harsh but fine given actual // range of values used for cpi->sf.thresh_mult[]. constint t = q * rd_thresh_block_size_factor[bsize]; constint thresh_max = INT_MAX / t;
if (bsize >= BLOCK_8X8) { for (i = 0; i < MAX_MODES; ++i)
rd->threshes[segment_id][bsize][i] = rd->thresh_mult[i] < thresh_max
? rd->thresh_mult[i] * t / 4
: INT_MAX;
} else { for (i = 0; i < MAX_REFS; ++i)
rd->threshes[segment_id][bsize][i] =
rd->thresh_mult_sub8x8[i] < thresh_max
? rd->thresh_mult_sub8x8[i] * t / 4
: INT_MAX;
}
}
}
}
void vp9_build_inter_mode_cost(VP9_COMP *cpi) { const VP9_COMMON *const cm = &cpi->common; int i; for (i = 0; i < INTER_MODE_CONTEXTS; ++i) {
vp9_cost_tokens((int *)cpi->inter_mode_cost[i], cm->fc->inter_mode_probs[i],
vp9_inter_mode_tree);
}
}
void vp9_initialize_rd_consts(VP9_COMP *cpi) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->td.mb;
MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
RD_OPT *const rd = &cpi->rd; int i;
vpx_clear_system_state();
rd->RDDIV = RDDIV_BITS; // In bits (to multiply D by 128).
rd->RDMULT = vp9_compute_rd_mult(cpi, cm->base_qindex + cm->y_dc_delta_q);
void vp9_model_rd_from_var_lapndz(unsignedint var, unsignedint n_log2, unsignedint qstep, int *rate,
int64_t *dist) { // This function models the rate and distortion for a Laplacian // source with given variance when quantized with a uniform quantizer // with given stepsize. The closed form expressions are in: // Hang and Chen, "Source Model for transform video coder and its // application - Part I: Fundamental Theory", IEEE Trans. Circ. // Sys. for Video Tech., April 1997. if (var == 0) {
*rate = 0;
*dist = 0;
} else { int d_q10, r_q10; const uint64_t xsq_q10_64 =
(((uint64_t)qstep * qstep << (n_log2 + 10)) + (var >> 1)) / var; constint xsq_q10 = (int)VPXMIN(xsq_q10_64, MAX_XSQ_Q10);
model_rd_norm(xsq_q10, &r_q10, &d_q10);
*rate = ROUND_POWER_OF_TWO(r_q10 << n_log2, 10 - VP9_PROB_COST_SHIFT);
*dist = (var * (int64_t)d_q10 + 512) >> 10;
}
}
int i; switch (tx_size) { case TX_4X4:
memcpy(t_above, above, sizeof(ENTROPY_CONTEXT) * num_4x4_w);
memcpy(t_left, left, sizeof(ENTROPY_CONTEXT) * num_4x4_h); break; case TX_8X8: for (i = 0; i < num_4x4_w; i += 2)
t_above[i] = !!*(const uint16_t *)&above[i]; for (i = 0; i < num_4x4_h; i += 2)
t_left[i] = !!*(const uint16_t *)&left[i]; break; case TX_16X16: for (i = 0; i < num_4x4_w; i += 4)
t_above[i] = !!*(const uint32_t *)&above[i]; for (i = 0; i < num_4x4_h; i += 4)
t_left[i] = !!*(const uint32_t *)&left[i]; break; default:
assert(tx_size == TX_32X32); for (i = 0; i < num_4x4_w; i += 8)
t_above[i] = !!*(const uint64_t *)&above[i]; for (i = 0; i < num_4x4_h; i += 8)
t_left[i] = !!*(const uint64_t *)&left[i]; break;
}
} #ifdefined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop #endif
void vp9_mv_pred(VP9_COMP *cpi, MACROBLOCK *x, uint8_t *ref_y_buffer, int ref_y_stride, int ref_frame, BLOCK_SIZE block_size) { int i; int zero_seen = 0; int best_index = 0; int best_sad = INT_MAX; int this_sad = INT_MAX; int max_mv = 0; int near_same_nearest;
uint8_t *src_y_ptr = x->plane[0].src.buf;
uint8_t *ref_y_ptr; constint num_mv_refs =
MAX_MV_REF_CANDIDATES + (block_size < x->max_partition_size);
ref_y_ptr = &ref_y_buffer[ref_y_stride * fp_row + fp_col]; // Find sad for current vector.
this_sad = cpi->fn_ptr[block_size].sdf(src_y_ptr, x->plane[0].src.stride,
ref_y_ptr, ref_y_stride); // Note if it is the best so far. if (this_sad < best_sad) {
best_sad = this_sad;
best_index = i;
}
}
// Note the index of the mv that worked best in the reference list.
x->mv_best_ref_index[ref_frame] = best_index;
x->max_mv_context[ref_frame] = max_mv;
x->pred_mv_sad[ref_frame] = best_sad;
}
void vp9_setup_pred_block(const MACROBLOCKD *xd, struct buf_2d dst[MAX_MB_PLANE], const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col, conststruct scale_factors *scale, conststruct scale_factors *scale_uv) { int i;
for (i = 0; i < MAX_MB_PLANE; ++i) {
setup_pred_plane(dst + i, dst[i].buf, dst[i].stride, mi_row, mi_col,
i ? scale_uv : scale, xd->plane[i].subsampling_x,
xd->plane[i].subsampling_y);
}
}
int vp9_raster_block_offset(BLOCK_SIZE plane_bsize, int raster_block, int stride) { constint bw = b_width_log2_lookup[plane_bsize]; constint y = 4 * (raster_block >> bw); constint x = 4 * (raster_block & ((1 << bw) - 1)); return y * stride + x;
}
int vp9_get_intra_cost_penalty(const VP9_COMP *const cpi, BLOCK_SIZE bsize, int qindex, int qdelta) { // Reduce the intra cost penalty for small blocks (<=16x16). int reduction_fac =
(bsize <= BLOCK_16X16) ? ((bsize <= BLOCK_8X8) ? 4 : 2) : 0;
if (cpi->noise_estimate.enabled && cpi->noise_estimate.level == kHigh) // Don't reduce intra cost penalty if estimated noise level is high.
reduction_fac = 0;
// Always use VPX_BITS_8 as input here because the penalty is applied // to rate not distortion so we want a consistent penalty for all bit // depths. If the actual bit depth were passed in here then the value // retured by vp9_dc_quant() would scale with the bit depth and we would // then need to apply inverse scaling to correct back to a bit depth // independent rate penalty. return (20 * vp9_dc_quant(qindex, qdelta, VPX_BITS_8)) >> reduction_fac;
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.