/* * 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. */ #include <assert.h>#include <stdio.h>#include <math.h>#include <limits.h>#include <assert.h>#include "vpx_config.h"#include "vp8_rtcd.h"#include "./vpx_dsp_rtcd.h"#include "encodeframe.h"#include "tokenize.h"#include "treewriter.h"#include "onyx_int.h"#include "modecosts.h"#include "encodeintra.h"#include "pickinter.h"#include "vp8/common/common.h"#include "vp8/common/entropymode.h"#include "vp8/common/reconinter.h"#include "vp8/common/reconintra.h"#include "vp8/common/reconintra4x4.h"#include "vp8/common/findnearmv.h"#include "vp8/common/quant_common.h"#include "encodemb.h"#include "vp8/encoder/quantize.h"#include "vpx_dsp/variance.h"#include "vpx_ports/system_state.h"#include "mcomp.h"#include "rdopt.h"#include "vpx_mem/vpx_mem.h"#include "vp8/common/systemdependent.h"#if CONFIG_TEMPORAL_DENOISING#include "denoising.h"#endifextern void vp8_update_zbin_extra(VP8_COMP *cpi, MACROBLOCK *x); #define MAXF(a, b) (((a) > (b)) ? (a) : (b)) typedef struct rate_distortion_struct { int rate2; int rate_y; int rate_uv; int distortion2; int distortion_uv;} RATE_DISTORTION; typedef struct best_mode_struct { int yrd; int rd; int intra_rd; MB_MODE_INFO mbmode; union b_mode_info bmodes[16]; PARTITION_INFO partition;} BEST_MODE; static const int auto_speed_thresh[17] = { 1000, 200, 150, 130, 150, 125, 120, 115, 115, 115, 115, 115, 115, 115, 115, 115, 105 }; const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES] = { ZEROMV, DC_PRED, NEARESTMV, NEARMV, ZEROMV, NEARESTMV, ZEROMV, NEARESTMV, NEARMV, NEARMV, V_PRED, H_PRED, TM_PRED, NEWMV, NEWMV, NEWMV, SPLITMV, SPLITMV, SPLITMV, B_PRED,}; /* This table determines the search order in reference frame priority order, * which may not necessarily match INTRA,LAST,GOLDEN,ARF */const int vp8_ref_frame_order[MAX_MODES] = { 1, 0, 1, 1, 2, 2, 3, 3, 2, 3, 0, 0, 0, 1, 2, 3, 1, 2, 3, 0,}; static void fill_token_costs( int c[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS], const vp8_prob p[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS] [ENTROPY_NODES]) { int i, j, k; for (i = 0; i < BLOCK_TYPES; ++i) { for (j = 0; j < COEF_BANDS; ++j) { for (k = 0; k < PREV_COEF_CONTEXTS; ++k) { /* check for pt=0 and band > 1 if block type 0 * and 0 if blocktype 1 */ if (k == 0 && j > (i == 0)) { vp8_cost_tokens2(c[i][j][k], p[i][j][k], vp8_coef_tree, 2); } else { vp8_cost_tokens(c[i][j][k], p[i][j][k], vp8_coef_tree); } } } }} static const int rd_iifactor[32] = { 4, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* values are now correlated to quantizer */static const int sad_per_bit16lut[QINDEX_RANGE] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14};static const int sad_per_bit4lut[QINDEX_RANGE] = { 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 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, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20,}; void vp8cx_initialize_me_consts(VP8_COMP *cpi, int QIndex) { cpi->mb.sadperbit16 = sad_per_bit16lut[QIndex]; cpi->mb.sadperbit4 = sad_per_bit4lut[QIndex];} void vp8_initialize_rd_consts(VP8_COMP *cpi, MACROBLOCK *x, int Qvalue) { int q; int i; double capped_q = (Qvalue < 160) ? (double)Qvalue : 160.0; double rdconst = 2.80; vpx_clear_system_state(); /* Further tests required to see if optimum is different * for key frames, golden frames and arf frames. */ cpi->RDMULT = (int)(rdconst * (capped_q * capped_q)); /* Extend rate multiplier along side quantizer zbin increases */ if (cpi->mb.zbin_over_quant > 0) { double oq_factor; double modq; /* Experimental code using the same basic equation as used for Q above * The units of cpi->mb.zbin_over_quant are 1/128 of Q bin size */ oq_factor = 1.0 + ((double)0.0015625 * cpi->mb.zbin_over_quant); modq = (int)((double)capped_q * oq_factor); cpi->RDMULT = (int)(rdconst * (modq * modq)); } if (cpi->pass == 2 && (cpi->common.frame_type != KEY_FRAME)) { if (cpi->twopass.next_iiratio > 31) { cpi->RDMULT += (cpi->RDMULT * rd_iifactor[31]) >> 4; } else { cpi->RDMULT += (cpi->RDMULT * rd_iifactor[cpi->twopass.next_iiratio]) >> 4; } } cpi->mb.errorperbit = (cpi->RDMULT / 110); cpi->mb.errorperbit += (cpi->mb.errorperbit == 0); vp8_set_speed_features(cpi); for (i = 0; i < MAX_MODES; ++i) { x->mode_test_hit_counts[i] = 0; } q = (int)pow(Qvalue, 1.25); if (q < 8) q = 8; if (cpi->RDMULT > 1000) { cpi->RDDIV = 1; cpi->RDMULT /= 100; for (i = 0; i < MAX_MODES; ++i) { if (cpi->sf.thresh_mult[i] < INT_MAX) { x->rd_threshes[i] = cpi->sf.thresh_mult[i] * q / 100; } else { x->rd_threshes[i] = INT_MAX; } cpi->rd_baseline_thresh[i] = x->rd_threshes[i]; } } else { cpi->RDDIV = 100; for (i = 0; i < MAX_MODES; ++i) { if (cpi->sf.thresh_mult[i] < (INT_MAX / q)) { x->rd_threshes[i] = cpi->sf.thresh_mult[i] * q; } else { x->rd_threshes[i] = INT_MAX; } cpi->rd_baseline_thresh[i] = x->rd_threshes[i]; } } { /* build token cost array for the type of frame we have now */ FRAME_CONTEXT *l = &cpi->lfc_n; if (cpi->common.refresh_alt_ref_frame) { l = &cpi->lfc_a; } else if (cpi->common.refresh_golden_frame) { l = &cpi->lfc_g; } fill_token_costs(cpi->mb.token_costs, (const vp8_prob(*)[8][3][11])l->coef_probs); /* fill_token_costs( cpi->mb.token_costs, (const vp8_prob( *)[8][3][11]) cpi->common.fc.coef_probs); */ /* TODO make these mode costs depend on last,alt or gold too. (jbb) */ vp8_init_mode_costs(cpi); }} void vp8_auto_select_speed(VP8_COMP *cpi) { int milliseconds_for_compress = (int)(1000000 / cpi->framerate); milliseconds_for_compress = milliseconds_for_compress * (16 - cpi->oxcf.cpu_used) / 16; #if 0 if (0) { FILE *f; f = fopen("speed.stt", "a"); fprintf(f, " %8ld %10ld %10ld %10ld\n", cpi->common.current_video_frame, cpi->Speed, milliseconds_for_compress, cpi->avg_pick_mode_time); fclose(f); } #endif if (cpi->avg_pick_mode_time < milliseconds_for_compress && (cpi->avg_encode_time - cpi->avg_pick_mode_time) < milliseconds_for_compress) { if (cpi->avg_pick_mode_time == 0) { cpi->Speed = 4; } else { if (milliseconds_for_compress * 100 < cpi->avg_encode_time * 95) { cpi->Speed += 2; cpi->avg_pick_mode_time = 0; cpi->avg_encode_time = 0; if (cpi->Speed > 16) { cpi->Speed = 16; } } if (milliseconds_for_compress * 100 > cpi->avg_encode_time * auto_speed_thresh[cpi->Speed]) { cpi->Speed -= 1; cpi->avg_pick_mode_time = 0; cpi->avg_encode_time = 0; /* In real-time mode, cpi->speed is in [4, 16]. */ if (cpi->Speed < 4) { cpi->Speed = 4; } } } } else { cpi->Speed += 4; if (cpi->Speed > 16) cpi->Speed = 16; cpi->avg_pick_mode_time = 0; cpi->avg_encode_time = 0; }} int vp8_block_error_c(short *coeff, short *dqcoeff) { int i; int error = 0; for (i = 0; i < 16; ++i) { int this_diff = coeff[i] - dqcoeff[i]; error += this_diff * this_diff; } return error;} int vp8_mbblock_error_c(MACROBLOCK *mb, int dc) { BLOCK *be; BLOCKD *bd; int i, j; int berror, error = 0; for (i = 0; i < 16; ++i) { be = &mb->block[i]; bd = &mb->e_mbd.block[i]; berror = 0; for (j = dc; j < 16; ++j) { int this_diff = be->coeff[j] - bd->dqcoeff[j]; berror += this_diff * this_diff; } error += berror; } return error;} int vp8_mbuverror_c(MACROBLOCK *mb) { BLOCK *be; BLOCKD *bd; int i; int error = 0; for (i = 16; i < 24; ++i) { be = &mb->block[i]; bd = &mb->e_mbd.block[i]; error += vp8_block_error_c(be->coeff, bd->dqcoeff); } return error;} int VP8_UVSSE(MACROBLOCK *x) { unsigned char *uptr, *vptr; unsigned char *upred_ptr = (*(x->block[16].base_src) + x->block[16].src); unsigned char *vpred_ptr = (*(x->block[20].base_src) + x->block[20].src); int uv_stride = x->block[16].src_stride; unsigned int sse1 = 0; unsigned int sse2 = 0; int mv_row = x->e_mbd.mode_info_context->mbmi.mv.as_mv.row; int mv_col = x->e_mbd.mode_info_context->mbmi.mv.as_mv.col; int offset; int pre_stride = x->e_mbd.pre.uv_stride; if (mv_row < 0) { mv_row -= 1; } else { mv_row += 1; } if (mv_col < 0) { mv_col -= 1; } else { mv_col += 1; } mv_row /= 2; mv_col /= 2; offset = (mv_row >> 3) * pre_stride + (mv_col >> 3); uptr = x->e_mbd.pre.u_buffer + offset; vptr = x->e_mbd.pre.v_buffer + offset; if ((mv_row | mv_col) & 7) { vpx_sub_pixel_variance8x8(uptr, pre_stride, mv_col & 7, mv_row & 7, upred_ptr, uv_stride, &sse2); vpx_sub_pixel_variance8x8(vptr, pre_stride, mv_col & 7, mv_row & 7, vpred_ptr, uv_stride, &sse1); sse2 += sse1; } else { vpx_variance8x8(uptr, pre_stride, upred_ptr, uv_stride, &sse2); vpx_variance8x8(vptr, pre_stride, vpred_ptr, uv_stride, &sse1); sse2 += sse1; } return sse2;} static int cost_coeffs(MACROBLOCK *mb, BLOCKD *b, int type, ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l) { int c = !type; /* start at coef 0, unless Y with Y2 */ int eob = (int)(*b->eob); int pt; /* surrounding block/prev coef predictor */ int cost = 0; short *qcoeff_ptr = b->qcoeff; VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); assert(eob <= 16); for (; c < eob; ++c) { const int v = qcoeff_ptr[vp8_default_zig_zag1d[c]]; const int t = vp8_dct_value_tokens_ptr[v].Token; cost += mb->token_costs[type][vp8_coef_bands[c]][pt][t]; cost += vp8_dct_value_cost_ptr[v]; pt = vp8_prev_token_class[t]; } if (c < 16) { cost += mb->token_costs[type][vp8_coef_bands[c]][pt][DCT_EOB_TOKEN]; } pt = (c != !type); /* is eob first coefficient; */ *a = *l = pt; return cost;} static int vp8_rdcost_mby(MACROBLOCK *mb) { int cost = 0; int b; MACROBLOCKD *x = &mb->e_mbd; ENTROPY_CONTEXT_PLANES t_above, t_left; ENTROPY_CONTEXT *ta; ENTROPY_CONTEXT *tl; memcpy(&t_above, mb->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES)); memcpy(&t_left, mb->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES)); ta = (ENTROPY_CONTEXT *)&t_above; tl = (ENTROPY_CONTEXT *)&t_left; for (b = 0; b < 16; ++b) { cost += cost_coeffs(mb, x->block + b, PLANE_TYPE_Y_NO_DC, ta + vp8_block2above[b], tl + vp8_block2left[b]); } cost += cost_coeffs(mb, x->block + 24, PLANE_TYPE_Y2, ta + vp8_block2above[24], tl + vp8_block2left[24]); return cost;} static void macro_block_yrd(MACROBLOCK *mb, int *Rate, int *Distortion) { int b; MACROBLOCKD *const x = &mb->e_mbd; BLOCK *const mb_y2 = mb->block + 24; BLOCKD *const x_y2 = x->block + 24; short *Y2DCPtr = mb_y2->src_diff; BLOCK *beptr; int d; vp8_subtract_mby(mb->src_diff, *(mb->block[0].base_src), mb->block[0].src_stride, mb->e_mbd.predictor, 16); /* Fdct and building the 2nd order block */ for (beptr = mb->block; beptr < mb->block + 16; beptr += 2) { mb->short_fdct8x4(beptr->src_diff, beptr->coeff, 32); *Y2DCPtr++ = beptr->coeff[0]; *Y2DCPtr++ = beptr->coeff[16]; } /* 2nd order fdct */ mb->short_walsh4x4(mb_y2->src_diff, mb_y2->coeff, 8); /* Quantization */ for (b = 0; b < 16; ++b) { mb->quantize_b(&mb->block[b], &mb->e_mbd.block[b]); } /* DC predication and Quantization of 2nd Order block */ mb->quantize_b(mb_y2, x_y2); Lines 1–500 of 2394. Load more
/* * 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. */ #include <assert.h> #include <stdio.h> #include <math.h> #include <limits.h> #include <assert.h> #include "vpx_config.h" #include "vp8_rtcd.h" #include "./vpx_dsp_rtcd.h" #include "encodeframe.h" #include "tokenize.h" #include "treewriter.h" #include "onyx_int.h" #include "modecosts.h" #include "encodeintra.h" #include "pickinter.h" #include "vp8/common/common.h" #include "vp8/common/entropymode.h" #include "vp8/common/reconinter.h" #include "vp8/common/reconintra.h" #include "vp8/common/reconintra4x4.h" #include "vp8/common/findnearmv.h" #include "vp8/common/quant_common.h" #include "encodemb.h" #include "vp8/encoder/quantize.h" #include "vpx_dsp/variance.h" #include "vpx_ports/system_state.h" #include "mcomp.h" #include "rdopt.h" #include "vpx_mem/vpx_mem.h" #include "vp8/common/systemdependent.h" #if CONFIG_TEMPORAL_DENOISING #include "denoising.h" #endif extern void vp8_update_zbin_extra(VP8_COMP *cpi, MACROBLOCK *x); #define MAXF(a, b) (((a) > (b)) ? (a) : (b)) typedef struct rate_distortion_struct { int rate2; int rate_y; int rate_uv; int distortion2; int distortion_uv; } RATE_DISTORTION; typedef struct best_mode_struct { int yrd; int rd; int intra_rd; MB_MODE_INFO mbmode; union b_mode_info bmodes[16]; PARTITION_INFO partition; } BEST_MODE; static const int auto_speed_thresh[17] = { 1000, 200, 150, 130, 150, 125, 120, 115, 115, 115, 115, 115, 115, 115, 115, 115, 105 }; const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES] = { ZEROMV, DC_PRED, NEARESTMV, NEARMV, ZEROMV, NEARESTMV, ZEROMV, NEARESTMV, NEARMV, NEARMV, V_PRED, H_PRED, TM_PRED, NEWMV, NEWMV, NEWMV, SPLITMV, SPLITMV, SPLITMV, B_PRED, }; /* This table determines the search order in reference frame priority order, * which may not necessarily match INTRA,LAST,GOLDEN,ARF */ const int vp8_ref_frame_order[MAX_MODES] = { 1, 0, 1, 1, 2, 2, 3, 3, 2, 3, 0, 0, 0, 1, 2, 3, 1, 2, 3, 0, }; static void fill_token_costs( int c[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS], const vp8_prob p[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS] [ENTROPY_NODES]) { int i, j, k; for (i = 0; i < BLOCK_TYPES; ++i) { for (j = 0; j < COEF_BANDS; ++j) { for (k = 0; k < PREV_COEF_CONTEXTS; ++k) { /* check for pt=0 and band > 1 if block type 0 * and 0 if blocktype 1 */ if (k == 0 && j > (i == 0)) { vp8_cost_tokens2(c[i][j][k], p[i][j][k], vp8_coef_tree, 2); } else { vp8_cost_tokens(c[i][j][k], p[i][j][k], vp8_coef_tree); } } } } } static const int rd_iifactor[32] = { 4, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* values are now correlated to quantizer */ static const int sad_per_bit16lut[QINDEX_RANGE] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14 }; static const int sad_per_bit4lut[QINDEX_RANGE] = { 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 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, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, }; void vp8cx_initialize_me_consts(VP8_COMP *cpi, int QIndex) { cpi->mb.sadperbit16 = sad_per_bit16lut[QIndex]; cpi->mb.sadperbit4 = sad_per_bit4lut[QIndex]; } void vp8_initialize_rd_consts(VP8_COMP *cpi, MACROBLOCK *x, int Qvalue) { int q; int i; double capped_q = (Qvalue < 160) ? (double)Qvalue : 160.0; double rdconst = 2.80; vpx_clear_system_state(); /* Further tests required to see if optimum is different * for key frames, golden frames and arf frames. */ cpi->RDMULT = (int)(rdconst * (capped_q * capped_q)); /* Extend rate multiplier along side quantizer zbin increases */ if (cpi->mb.zbin_over_quant > 0) { double oq_factor; double modq; /* Experimental code using the same basic equation as used for Q above * The units of cpi->mb.zbin_over_quant are 1/128 of Q bin size */ oq_factor = 1.0 + ((double)0.0015625 * cpi->mb.zbin_over_quant); modq = (int)((double)capped_q * oq_factor); cpi->RDMULT = (int)(rdconst * (modq * modq)); } if (cpi->pass == 2 && (cpi->common.frame_type != KEY_FRAME)) { if (cpi->twopass.next_iiratio > 31) { cpi->RDMULT += (cpi->RDMULT * rd_iifactor[31]) >> 4; } else { cpi->RDMULT += (cpi->RDMULT * rd_iifactor[cpi->twopass.next_iiratio]) >> 4; } } cpi->mb.errorperbit = (cpi->RDMULT / 110); cpi->mb.errorperbit += (cpi->mb.errorperbit == 0); vp8_set_speed_features(cpi); for (i = 0; i < MAX_MODES; ++i) { x->mode_test_hit_counts[i] = 0; } q = (int)pow(Qvalue, 1.25); if (q < 8) q = 8; if (cpi->RDMULT > 1000) { cpi->RDDIV = 1; cpi->RDMULT /= 100; for (i = 0; i < MAX_MODES; ++i) { if (cpi->sf.thresh_mult[i] < INT_MAX) { x->rd_threshes[i] = cpi->sf.thresh_mult[i] * q / 100; } else { x->rd_threshes[i] = INT_MAX; } cpi->rd_baseline_thresh[i] = x->rd_threshes[i]; } } else { cpi->RDDIV = 100; for (i = 0; i < MAX_MODES; ++i) { if (cpi->sf.thresh_mult[i] < (INT_MAX / q)) { x->rd_threshes[i] = cpi->sf.thresh_mult[i] * q; } else { x->rd_threshes[i] = INT_MAX; } cpi->rd_baseline_thresh[i] = x->rd_threshes[i]; } } { /* build token cost array for the type of frame we have now */ FRAME_CONTEXT *l = &cpi->lfc_n; if (cpi->common.refresh_alt_ref_frame) { l = &cpi->lfc_a; } else if (cpi->common.refresh_golden_frame) { l = &cpi->lfc_g; } fill_token_costs(cpi->mb.token_costs, (const vp8_prob(*)[8][3][11])l->coef_probs); /* fill_token_costs( cpi->mb.token_costs, (const vp8_prob( *)[8][3][11]) cpi->common.fc.coef_probs); */ /* TODO make these mode costs depend on last,alt or gold too. (jbb) */ vp8_init_mode_costs(cpi); } } void vp8_auto_select_speed(VP8_COMP *cpi) { int milliseconds_for_compress = (int)(1000000 / cpi->framerate); milliseconds_for_compress = milliseconds_for_compress * (16 - cpi->oxcf.cpu_used) / 16; #if 0 if (0) { FILE *f; f = fopen("speed.stt", "a"); fprintf(f, " %8ld %10ld %10ld %10ld\n", cpi->common.current_video_frame, cpi->Speed, milliseconds_for_compress, cpi->avg_pick_mode_time); fclose(f); } #endif if (cpi->avg_pick_mode_time < milliseconds_for_compress && (cpi->avg_encode_time - cpi->avg_pick_mode_time) < milliseconds_for_compress) { if (cpi->avg_pick_mode_time == 0) { cpi->Speed = 4; } else { if (milliseconds_for_compress * 100 < cpi->avg_encode_time * 95) { cpi->Speed += 2; cpi->avg_pick_mode_time = 0; cpi->avg_encode_time = 0; if (cpi->Speed > 16) { cpi->Speed = 16; } } if (milliseconds_for_compress * 100 > cpi->avg_encode_time * auto_speed_thresh[cpi->Speed]) { cpi->Speed -= 1; cpi->avg_pick_mode_time = 0; cpi->avg_encode_time = 0; /* In real-time mode, cpi->speed is in [4, 16]. */ if (cpi->Speed < 4) { cpi->Speed = 4; } } } } else { cpi->Speed += 4; if (cpi->Speed > 16) cpi->Speed = 16; cpi->avg_pick_mode_time = 0; cpi->avg_encode_time = 0; } } int vp8_block_error_c(short *coeff, short *dqcoeff) { int i; int error = 0; for (i = 0; i < 16; ++i) { int this_diff = coeff[i] - dqcoeff[i]; error += this_diff * this_diff; } return error; } int vp8_mbblock_error_c(MACROBLOCK *mb, int dc) { BLOCK *be; BLOCKD *bd; int i, j; int berror, error = 0; for (i = 0; i < 16; ++i) { be = &mb->block[i]; bd = &mb->e_mbd.block[i]; berror = 0; for (j = dc; j < 16; ++j) { int this_diff = be->coeff[j] - bd->dqcoeff[j]; berror += this_diff * this_diff; } error += berror; } return error; } int vp8_mbuverror_c(MACROBLOCK *mb) { BLOCK *be; BLOCKD *bd; int i; int error = 0; for (i = 16; i < 24; ++i) { be = &mb->block[i]; bd = &mb->e_mbd.block[i]; error += vp8_block_error_c(be->coeff, bd->dqcoeff); } return error; } int VP8_UVSSE(MACROBLOCK *x) { unsigned char *uptr, *vptr; unsigned char *upred_ptr = (*(x->block[16].base_src) + x->block[16].src); unsigned char *vpred_ptr = (*(x->block[20].base_src) + x->block[20].src); int uv_stride = x->block[16].src_stride; unsigned int sse1 = 0; unsigned int sse2 = 0; int mv_row = x->e_mbd.mode_info_context->mbmi.mv.as_mv.row; int mv_col = x->e_mbd.mode_info_context->mbmi.mv.as_mv.col; int offset; int pre_stride = x->e_mbd.pre.uv_stride; if (mv_row < 0) { mv_row -= 1; } else { mv_row += 1; } if (mv_col < 0) { mv_col -= 1; } else { mv_col += 1; } mv_row /= 2; mv_col /= 2; offset = (mv_row >> 3) * pre_stride + (mv_col >> 3); uptr = x->e_mbd.pre.u_buffer + offset; vptr = x->e_mbd.pre.v_buffer + offset; if ((mv_row | mv_col) & 7) { vpx_sub_pixel_variance8x8(uptr, pre_stride, mv_col & 7, mv_row & 7, upred_ptr, uv_stride, &sse2); vpx_sub_pixel_variance8x8(vptr, pre_stride, mv_col & 7, mv_row & 7, vpred_ptr, uv_stride, &sse1); sse2 += sse1; } else { vpx_variance8x8(uptr, pre_stride, upred_ptr, uv_stride, &sse2); vpx_variance8x8(vptr, pre_stride, vpred_ptr, uv_stride, &sse1); sse2 += sse1; } return sse2; } static int cost_coeffs(MACROBLOCK *mb, BLOCKD *b, int type, ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l) { int c = !type; /* start at coef 0, unless Y with Y2 */ int eob = (int)(*b->eob); int pt; /* surrounding block/prev coef predictor */ int cost = 0; short *qcoeff_ptr = b->qcoeff; VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); assert(eob <= 16); for (; c < eob; ++c) { const int v = qcoeff_ptr[vp8_default_zig_zag1d[c]]; const int t = vp8_dct_value_tokens_ptr[v].Token; cost += mb->token_costs[type][vp8_coef_bands[c]][pt][t]; cost += vp8_dct_value_cost_ptr[v]; pt = vp8_prev_token_class[t]; } if (c < 16) { cost += mb->token_costs[type][vp8_coef_bands[c]][pt][DCT_EOB_TOKEN]; } pt = (c != !type); /* is eob first coefficient; */ *a = *l = pt; return cost; } static int vp8_rdcost_mby(MACROBLOCK *mb) { int cost = 0; int b; MACROBLOCKD *x = &mb->e_mbd; ENTROPY_CONTEXT_PLANES t_above, t_left; ENTROPY_CONTEXT *ta; ENTROPY_CONTEXT *tl; memcpy(&t_above, mb->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES)); memcpy(&t_left, mb->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES)); ta = (ENTROPY_CONTEXT *)&t_above; tl = (ENTROPY_CONTEXT *)&t_left; for (b = 0; b < 16; ++b) { cost += cost_coeffs(mb, x->block + b, PLANE_TYPE_Y_NO_DC, ta + vp8_block2above[b], tl + vp8_block2left[b]); } cost += cost_coeffs(mb, x->block + 24, PLANE_TYPE_Y2, ta + vp8_block2above[24], tl + vp8_block2left[24]); return cost; } static void macro_block_yrd(MACROBLOCK *mb, int *Rate, int *Distortion) { int b; MACROBLOCKD *const x = &mb->e_mbd; BLOCK *const mb_y2 = mb->block + 24; BLOCKD *const x_y2 = x->block + 24; short *Y2DCPtr = mb_y2->src_diff; BLOCK *beptr; int d; vp8_subtract_mby(mb->src_diff, *(mb->block[0].base_src), mb->block[0].src_stride, mb->e_mbd.predictor, 16); /* Fdct and building the 2nd order block */ for (beptr = mb->block; beptr < mb->block + 16; beptr += 2) { mb->short_fdct8x4(beptr->src_diff, beptr->coeff, 32); *Y2DCPtr++ = beptr->coeff[0]; *Y2DCPtr++ = beptr->coeff[16]; } /* 2nd order fdct */ mb->short_walsh4x4(mb_y2->src_diff, mb_y2->coeff, 8); /* Quantization */ for (b = 0; b < 16; ++b) { mb->quantize_b(&mb->block[b], &mb->e_mbd.block[b]); } /* DC predication and Quantization of 2nd Order block */ mb->quantize_b(mb_y2, x_y2);