2394 lines · 74.4 KB · C
RawDownload
/* *  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.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t