summaryrefslogtreecommitdiff
path: root/vp9/encoder/vp9_rdopt.c
diff options
context:
space:
mode:
Diffstat (limited to 'vp9/encoder/vp9_rdopt.c')
-rw-r--r--vp9/encoder/vp9_rdopt.c954
1 files changed, 582 insertions, 372 deletions
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 22a2c4121..38460a5f5 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -279,6 +279,242 @@ void vp9_initialize_rd_consts(VP9_COMP *cpi, int qindex) {
}
}
+static enum BlockSize get_block_size(int bw, int bh) {
+ if (bw == 4 && bh == 4)
+ return BLOCK_4X4;
+
+ if (bw == 4 && bh == 8)
+ return BLOCK_4X8;
+
+ if (bw == 8 && bh == 4)
+ return BLOCK_8X4;
+
+ if (bw == 8 && bh == 8)
+ return BLOCK_8X8;
+
+ if (bw == 8 && bh == 16)
+ return BLOCK_8X16;
+
+ if (bw == 16 && bh == 8)
+ return BLOCK_16X8;
+
+ if (bw == 16 && bh == 16)
+ return BLOCK_16X16;
+
+ if (bw == 32 && bh == 32)
+ return BLOCK_32X32;
+
+ if (bw == 32 && bh == 16)
+ return BLOCK_32X16;
+
+ if (bw == 16 && bh == 32)
+ return BLOCK_16X32;
+
+ if (bw == 64 && bh == 32)
+ return BLOCK_64X32;
+
+ if (bw == 32 && bh == 64)
+ return BLOCK_32X64;
+
+ if (bw == 64 && bh == 64)
+ return BLOCK_64X64;
+
+ assert(0);
+ return -1;
+}
+
+static enum BlockSize get_plane_block_size(BLOCK_SIZE_TYPE bsize,
+ struct macroblockd_plane *pd) {
+ return get_block_size(plane_block_width(bsize, pd),
+ plane_block_height(bsize, pd));
+}
+
+static double linear_interpolate(double x, int ntab, int inv_step,
+ const double *tab) {
+ double y = x * inv_step;
+ int d = (int) y;
+ if (d >= ntab - 1) {
+ return tab[ntab - 1];
+ } else {
+ double a = y - d;
+ return tab[d] * (1 - a) + tab[d + 1] * a;
+ }
+}
+
+static double model_rate_norm(double x) {
+ // Normalized rate
+ // This function models the rate for a Laplacian source
+ // source with given variance when quantized with a uniform quantizer
+ // with given stepsize. The closed form expression is:
+ // Rn(x) = H(sqrt(r)) + sqrt(r)*[1 + H(r)/(1 - r)],
+ // where r = exp(-sqrt(2) * x) and x = qpstep / sqrt(variance),
+ // and H(x) is the binary entropy function.
+ static const int inv_rate_tab_step = 8;
+ static const double rate_tab[] = {
+ 64.00, 4.944, 3.949, 3.372, 2.966, 2.655, 2.403, 2.194,
+ 2.014, 1.858, 1.720, 1.596, 1.485, 1.384, 1.291, 1.206,
+ 1.127, 1.054, 0.986, 0.923, 0.863, 0.808, 0.756, 0.708,
+ 0.662, 0.619, 0.579, 0.541, 0.506, 0.473, 0.442, 0.412,
+ 0.385, 0.359, 0.335, 0.313, 0.291, 0.272, 0.253, 0.236,
+ 0.220, 0.204, 0.190, 0.177, 0.165, 0.153, 0.142, 0.132,
+ 0.123, 0.114, 0.106, 0.099, 0.091, 0.085, 0.079, 0.073,
+ 0.068, 0.063, 0.058, 0.054, 0.050, 0.047, 0.043, 0.040,
+ 0.037, 0.034, 0.032, 0.029, 0.027, 0.025, 0.023, 0.022,
+ 0.020, 0.019, 0.017, 0.016, 0.015, 0.014, 0.013, 0.012,
+ 0.011, 0.010, 0.009, 0.008, 0.008, 0.007, 0.007, 0.006,
+ 0.006, 0.005, 0.005, 0.005, 0.004, 0.004, 0.004, 0.003,
+ 0.003, 0.003, 0.003, 0.002, 0.002, 0.002, 0.002, 0.002,
+ 0.002, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001,
+ 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.000,
+ };
+ const int rate_tab_num = sizeof(rate_tab)/sizeof(rate_tab[0]);
+ assert(x >= 0.0);
+ return linear_interpolate(x, rate_tab_num, inv_rate_tab_step, rate_tab);
+}
+
+static double model_dist_norm(double x) {
+ // Normalized distortion
+ // This function models the normalized distortion for a Laplacian source
+ // source with given variance when quantized with a uniform quantizer
+ // with given stepsize. The closed form expression is:
+ // Dn(x) = 1 - 1/sqrt(2) * x / sinh(x/sqrt(2))
+ // where x = qpstep / sqrt(variance)
+ // Note the actual distortion is Dn * variance.
+ static const int inv_dist_tab_step = 8;
+ static const double dist_tab[] = {
+ 0.000, 0.001, 0.005, 0.012, 0.021, 0.032, 0.045, 0.061,
+ 0.079, 0.098, 0.119, 0.142, 0.166, 0.190, 0.216, 0.242,
+ 0.269, 0.296, 0.324, 0.351, 0.378, 0.405, 0.432, 0.458,
+ 0.484, 0.509, 0.534, 0.557, 0.580, 0.603, 0.624, 0.645,
+ 0.664, 0.683, 0.702, 0.719, 0.735, 0.751, 0.766, 0.780,
+ 0.794, 0.807, 0.819, 0.830, 0.841, 0.851, 0.861, 0.870,
+ 0.878, 0.886, 0.894, 0.901, 0.907, 0.913, 0.919, 0.925,
+ 0.930, 0.935, 0.939, 0.943, 0.947, 0.951, 0.954, 0.957,
+ 0.960, 0.963, 0.966, 0.968, 0.971, 0.973, 0.975, 0.976,
+ 0.978, 0.980, 0.981, 0.982, 0.984, 0.985, 0.986, 0.987,
+ 0.988, 0.989, 0.990, 0.990, 0.991, 0.992, 0.992, 0.993,
+ 0.993, 0.994, 0.994, 0.995, 0.995, 0.996, 0.996, 0.996,
+ 0.996, 0.997, 0.997, 0.997, 0.997, 0.998, 0.998, 0.998,
+ 0.998, 0.998, 0.998, 0.999, 0.999, 0.999, 0.999, 0.999,
+ 0.999, 0.999, 0.999, 0.999, 0.999, 0.999, 0.999, 1.000,
+ };
+ const int dist_tab_num = sizeof(dist_tab)/sizeof(dist_tab[0]);
+ assert(x >= 0.0);
+ return linear_interpolate(x, dist_tab_num, inv_dist_tab_step, dist_tab);
+}
+
+static void model_rd_from_var_lapndz(int var, int n, int 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.
+ vp9_clear_system_state();
+ if (var == 0 || n == 0) {
+ *rate = 0;
+ *dist = 0;
+ } else {
+ double D, R;
+ double s2 = (double) var / n;
+ double x = qstep / sqrt(s2);
+ D = model_dist_norm(x);
+ R = model_rate_norm(x);
+ if (R < 0) {
+ R = 0;
+ D = var;
+ }
+ *rate = (n * R * 256 + 0.5);
+ *dist = (n * D * s2 + 0.5);
+ }
+ vp9_clear_system_state();
+}
+
+static void model_rd_for_sb(VP9_COMP *cpi, BLOCK_SIZE_TYPE bsize,
+ MACROBLOCK *x, MACROBLOCKD *xd,
+ int *out_rate_sum, int64_t *out_dist_sum) {
+ // Note our transform coeffs are 8 times an orthogonal transform.
+ // Hence quantizer step is also 8 times. To get effective quantizer
+ // we need to divide by 8 before sending to modeling function.
+ int i, rate_sum = 0, dist_sum = 0;
+
+ for (i = 0; i < MAX_MB_PLANE; ++i) {
+ struct macroblock_plane *const p = &x->plane[i];
+ struct macroblockd_plane *const pd = &xd->plane[i];
+
+ // TODO(dkovalev) the same code in get_plane_block_size
+ const int bw = plane_block_width(bsize, pd);
+ const int bh = plane_block_height(bsize, pd);
+ const enum BlockSize bs = get_block_size(bw, bh);
+ unsigned int sse;
+ int rate;
+ int64_t dist;
+ (void) cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride,
+ pd->dst.buf, pd->dst.stride, &sse);
+ // sse works better than var, since there is no dc prediction used
+ model_rd_from_var_lapndz(sse, bw * bh, pd->dequant[1] >> 3, &rate, &dist);
+
+ rate_sum += rate;
+ dist_sum += dist;
+ }
+
+ *out_rate_sum = rate_sum;
+ *out_dist_sum = dist_sum << 4;
+}
+
+static void model_rd_for_sb_y_tx(VP9_COMP *cpi, BLOCK_SIZE_TYPE bsize,
+ TX_SIZE tx_size,
+ MACROBLOCK *x, MACROBLOCKD *xd,
+ int *out_rate_sum, int64_t *out_dist_sum,
+ int *out_skip) {
+ int t, j, k;
+ enum BlockSize bs;
+ struct macroblock_plane *const p = &x->plane[0];
+ struct macroblockd_plane *const pd = &xd->plane[0];
+ const int bw = plane_block_width(bsize, pd);
+ const int bh = plane_block_height(bsize, pd);
+ int rate_sum = 0;
+ int64_t dist_sum = 0;
+
+ if (tx_size == TX_4X4) {
+ bs = BLOCK_4X4;
+ t = 4;
+ } else if (tx_size == TX_8X8) {
+ bs = BLOCK_8X8;
+ t = 8;
+ } else if (tx_size == TX_16X16) {
+ bs = BLOCK_16X16;
+ t = 16;
+ } else if (tx_size == TX_32X32) {
+ bs = BLOCK_32X32;
+ t = 32;
+ } else {
+ assert(0);
+ }
+ assert(bs <= get_block_size(bw, bh));
+ *out_skip = 1;
+ for (j = 0; j < bh; j+=t) {
+ for (k = 0; k < bw; k+=t) {
+ int rate;
+ int64_t dist;
+ unsigned int sse;
+ (void) cpi->fn_ptr[bs].vf(p->src.buf + j * p->src.stride + k,
+ p->src.stride,
+ pd->dst.buf + j * pd->dst.stride + k,
+ pd->dst.stride, &sse);
+ // sse works better than var, since there is no dc prediction used
+ model_rd_from_var_lapndz(sse, t * t, pd->dequant[1] >> 3,
+ &rate, &dist);
+ rate_sum += rate;
+ dist_sum += dist;
+ *out_skip &= (rate < 1024);
+ }
+ }
+ *out_rate_sum = rate_sum;
+ *out_dist_sum = (dist_sum << 4);
+}
+
int64_t vp9_block_error_c(int16_t *coeff, int16_t *dqcoeff,
intptr_t block_size, int64_t *ssz) {
int i;
@@ -423,105 +659,6 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
return cost;
}
-static void choose_txfm_size_from_rd(VP9_COMP *cpi, MACROBLOCK *x,
- int (*r)[2], int *rate,
- int64_t *d, int64_t *distortion,
- int *s, int *skip,
- int64_t txfm_cache[NB_TXFM_MODES],
- TX_SIZE max_txfm_size) {
- VP9_COMMON *const cm = &cpi->common;
- MACROBLOCKD *const xd = &x->e_mbd;
- MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
- vp9_prob skip_prob = vp9_get_pred_prob(cm, xd, PRED_MBSKIP);
- int64_t rd[TX_SIZE_MAX_SB][2];
- int n, m;
- int s0, s1;
-
- const vp9_prob *tx_probs = vp9_get_pred_probs(cm, xd, PRED_TX_SIZE);
-
- for (n = TX_4X4; n <= max_txfm_size; n++) {
- r[n][1] = r[n][0];
- for (m = 0; m <= n - (n == max_txfm_size); m++) {
- if (m == n)
- r[n][1] += vp9_cost_zero(tx_probs[m]);
- else
- r[n][1] += vp9_cost_one(tx_probs[m]);
- }
- }
-
- assert(skip_prob > 0);
- s0 = vp9_cost_bit(skip_prob, 0);
- s1 = vp9_cost_bit(skip_prob, 1);
-
- for (n = TX_4X4; n <= max_txfm_size; n++) {
- if (s[n]) {
- rd[n][0] = rd[n][1] = RDCOST(x->rdmult, x->rddiv, s1, d[n]);
- } else {
- rd[n][0] = RDCOST(x->rdmult, x->rddiv, r[n][0] + s0, d[n]);
- rd[n][1] = RDCOST(x->rdmult, x->rddiv, r[n][1] + s0, d[n]);
- }
- }
-
- if (max_txfm_size == TX_32X32 &&
- (cm->txfm_mode == ALLOW_32X32 ||
- (cm->txfm_mode == TX_MODE_SELECT &&
- rd[TX_32X32][1] < rd[TX_16X16][1] && rd[TX_32X32][1] < rd[TX_8X8][1] &&
- rd[TX_32X32][1] < rd[TX_4X4][1]))) {
- mbmi->txfm_size = TX_32X32;
- } else if (max_txfm_size >= TX_16X16 &&
- (cm->txfm_mode == ALLOW_16X16 ||
- cm->txfm_mode == ALLOW_32X32 ||
- (cm->txfm_mode == TX_MODE_SELECT &&
- rd[TX_16X16][1] < rd[TX_8X8][1] &&
- rd[TX_16X16][1] < rd[TX_4X4][1]))) {
- mbmi->txfm_size = TX_16X16;
- } else if (cm->txfm_mode == ALLOW_8X8 ||
- cm->txfm_mode == ALLOW_16X16 ||
- cm->txfm_mode == ALLOW_32X32 ||
- (cm->txfm_mode == TX_MODE_SELECT && rd[TX_8X8][1] < rd[TX_4X4][1])) {
- mbmi->txfm_size = TX_8X8;
- } else {
- mbmi->txfm_size = TX_4X4;
- }
-
- *distortion = d[mbmi->txfm_size];
- *rate = r[mbmi->txfm_size][cm->txfm_mode == TX_MODE_SELECT];
- *skip = s[mbmi->txfm_size];
-
- txfm_cache[ONLY_4X4] = rd[TX_4X4][0];
- txfm_cache[ALLOW_8X8] = rd[TX_8X8][0];
- txfm_cache[ALLOW_16X16] = rd[MIN(max_txfm_size, TX_16X16)][0];
- txfm_cache[ALLOW_32X32] = rd[MIN(max_txfm_size, TX_32X32)][0];
- if (max_txfm_size == TX_32X32 &&
- rd[TX_32X32][1] < rd[TX_16X16][1] && rd[TX_32X32][1] < rd[TX_8X8][1] &&
- rd[TX_32X32][1] < rd[TX_4X4][1])
- txfm_cache[TX_MODE_SELECT] = rd[TX_32X32][1];
- else if (max_txfm_size >= TX_16X16 &&
- rd[TX_16X16][1] < rd[TX_8X8][1] && rd[TX_16X16][1] < rd[TX_4X4][1])
- txfm_cache[TX_MODE_SELECT] = rd[TX_16X16][1];
- else
- txfm_cache[TX_MODE_SELECT] = rd[TX_4X4][1] < rd[TX_8X8][1] ?
- rd[TX_4X4][1] : rd[TX_8X8][1];
-}
-
-static int64_t block_error_sbuv(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize,
- int shift, int64_t *sse) {
- int64_t sum = 0, this_sse;
- int plane;
-
- *sse = 0;
- for (plane = 1; plane < MAX_MB_PLANE; plane++) {
- struct macroblockd_plane *p = &x->e_mbd.plane[plane];
- const int bw = plane_block_width(bsize, p);
- const int bh = plane_block_height(bsize, p);
- sum += vp9_block_error(x->plane[plane].coeff, x->e_mbd.plane[plane].dqcoeff,
- bw * bh, &this_sse);
- *sse += this_sse;
- }
- *sse >>= shift;
- return sum >> shift;
-}
-
struct rdcost_block_args {
VP9_COMMON *cm;
MACROBLOCK *x;
@@ -568,6 +705,7 @@ static void rate_block(int plane, int block, BLOCK_SIZE_TYPE bsize,
args->bw * args->bh);
}
+
static int rdcost_plane(VP9_COMMON * const cm, MACROBLOCK *x, int plane,
BLOCK_SIZE_TYPE bsize, TX_SIZE tx_size) {
MACROBLOCKD * const xd = &x->e_mbd;
@@ -575,7 +713,7 @@ static int rdcost_plane(VP9_COMMON * const cm, MACROBLOCK *x, int plane,
const int bhl = b_height_log2(bsize) - xd->plane[plane].subsampling_y;
const int bw = 1 << bwl, bh = 1 << bhl;
struct rdcost_block_args args = { cm, x, { 0 }, { 0 }, tx_size, bw, bh,
- 0, 0, 0, 0, 0 };
+ 0, 0, 0, 0, 0 };
vpx_memcpy(&args.t_above, xd->plane[plane].above_context,
sizeof(ENTROPY_CONTEXT) * bw);
@@ -583,7 +721,6 @@ static int rdcost_plane(VP9_COMMON * const cm, MACROBLOCK *x, int plane,
sizeof(ENTROPY_CONTEXT) * bh);
foreach_transformed_block_in_plane(xd, bsize, plane, rate_block, &args);
-
return args.rate;
}
@@ -597,6 +734,49 @@ static int rdcost_uv(VP9_COMMON *const cm, MACROBLOCK *x,
return cost;
}
+static int block_error(int16_t *coeff, int16_t *dqcoeff,
+ int block_size, int shift) {
+ int i;
+ int64_t error = 0;
+
+ for (i = 0; i < block_size; i++) {
+ int this_diff = coeff[i] - dqcoeff[i];
+ error += (unsigned)this_diff * this_diff;
+ }
+ error >>= shift;
+
+ return error > INT_MAX ? INT_MAX : (int)error;
+}
+
+static int block_error_sby(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize,
+ int shift, int64_t *sse) {
+ struct macroblockd_plane *p = &x->e_mbd.plane[0];
+ const int bw = plane_block_width(bsize, p);
+ const int bh = plane_block_height(bsize, p);
+ int64_t e = vp9_block_error(x->plane[0].coeff, x->e_mbd.plane[0].dqcoeff,
+ bw * bh, sse) >> shift;
+ *sse >>= shift;
+ return e;
+}
+
+static int64_t block_error_sbuv(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize,
+ int shift, int64_t *sse) {
+ int64_t sum = 0, this_sse;
+ int plane;
+
+ *sse = 0;
+ for (plane = 1; plane < MAX_MB_PLANE; plane++) {
+ struct macroblockd_plane *p = &x->e_mbd.plane[plane];
+ const int bw = plane_block_width(bsize, p);
+ const int bh = plane_block_height(bsize, p);
+ sum += vp9_block_error(x->plane[plane].coeff, x->e_mbd.plane[plane].dqcoeff,
+ bw * bh, &this_sse);
+ *sse += this_sse;
+ }
+ *sse >>= shift;
+ return sum >> shift;
+}
+
static void block_yrd_txfm(int plane, int block, BLOCK_SIZE_TYPE bsize,
int ss_txfrm_size, void *arg) {
struct rdcost_block_args *args = arg;
@@ -635,6 +815,234 @@ static void super_block_yrd_for_txfm(VP9_COMMON *const cm, MACROBLOCK *x,
*skippable = vp9_sby_is_skippable(xd, bsize);
}
+static void choose_largest_txfm_size(VP9_COMP *cpi, MACROBLOCK *x,
+ int *rate, int64_t *distortion,
+ int *skip, int64_t *sse,
+ BLOCK_SIZE_TYPE bs) {
+ const TX_SIZE max_txfm_size = TX_32X32
+ - (bs < BLOCK_SIZE_SB32X32) - (bs < BLOCK_SIZE_MB16X16);
+ VP9_COMMON *const cm = &cpi->common;
+ MACROBLOCKD *const xd = &x->e_mbd;
+ MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
+ if (max_txfm_size == TX_32X32 &&
+ (cm->txfm_mode == ALLOW_32X32 ||
+ cm->txfm_mode == TX_MODE_SELECT)) {
+ mbmi->txfm_size = TX_32X32;
+ } else if (max_txfm_size >= TX_16X16 &&
+ (cm->txfm_mode == ALLOW_16X16 ||
+ cm->txfm_mode == ALLOW_32X32 ||
+ cm->txfm_mode == TX_MODE_SELECT)) {
+ mbmi->txfm_size = TX_16X16;
+ } else if (cm->txfm_mode != ONLY_4X4) {
+ mbmi->txfm_size = TX_8X8;
+ } else {
+ mbmi->txfm_size = TX_4X4;
+ }
+ super_block_yrd_for_txfm(cm, x, rate, distortion, skip,
+ &sse[mbmi->txfm_size], bs,
+ mbmi->txfm_size);
+ cpi->txfm_stepdown_count[0]++;
+}
+
+static void choose_txfm_size_from_rd(VP9_COMP *cpi, MACROBLOCK *x,
+ int (*r)[2], int *rate,
+ int64_t *d, int64_t *distortion,
+ int *s, int *skip,
+ int64_t txfm_cache[NB_TXFM_MODES],
+ BLOCK_SIZE_TYPE bs) {
+ const TX_SIZE max_txfm_size = TX_32X32
+ - (bs < BLOCK_SIZE_SB32X32) - (bs < BLOCK_SIZE_MB16X16);
+ VP9_COMMON *const cm = &cpi->common;
+ MACROBLOCKD *const xd = &x->e_mbd;
+ MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
+ vp9_prob skip_prob = vp9_get_pred_prob(cm, xd, PRED_MBSKIP);
+ int64_t rd[TX_SIZE_MAX_SB][2];
+ int n, m;
+ int s0, s1;
+
+ const vp9_prob *tx_probs = vp9_get_pred_probs(cm, xd, PRED_TX_SIZE);
+
+ for (n = TX_4X4; n <= max_txfm_size; n++) {
+ r[n][1] = r[n][0];
+ for (m = 0; m <= n - (n == max_txfm_size); m++) {
+ if (m == n)
+ r[n][1] += vp9_cost_zero(tx_probs[m]);
+ else
+ r[n][1] += vp9_cost_one(tx_probs[m]);
+ }
+ }
+
+ assert(skip_prob > 0);
+ s0 = vp9_cost_bit(skip_prob, 0);
+ s1 = vp9_cost_bit(skip_prob, 1);
+
+ for (n = TX_4X4; n <= max_txfm_size; n++) {
+ if (s[n]) {
+ rd[n][0] = rd[n][1] = RDCOST(x->rdmult, x->rddiv, s1, d[n]);
+ } else {
+ rd[n][0] = RDCOST(x->rdmult, x->rddiv, r[n][0] + s0, d[n]);
+ rd[n][1] = RDCOST(x->rdmult, x->rddiv, r[n][1] + s0, d[n]);
+ }
+ }
+
+ if (max_txfm_size == TX_32X32 &&
+ (cm->txfm_mode == ALLOW_32X32 ||
+ (cm->txfm_mode == TX_MODE_SELECT &&
+ rd[TX_32X32][1] < rd[TX_16X16][1] && rd[TX_32X32][1] < rd[TX_8X8][1] &&
+ rd[TX_32X32][1] < rd[TX_4X4][1]))) {
+ mbmi->txfm_size = TX_32X32;
+ } else if (max_txfm_size >= TX_16X16 &&
+ (cm->txfm_mode == ALLOW_16X16 ||
+ cm->txfm_mode == ALLOW_32X32 ||
+ (cm->txfm_mode == TX_MODE_SELECT &&
+ rd[TX_16X16][1] < rd[TX_8X8][1] &&
+ rd[TX_16X16][1] < rd[TX_4X4][1]))) {
+ mbmi->txfm_size = TX_16X16;
+ } else if (cm->txfm_mode == ALLOW_8X8 ||
+ cm->txfm_mode == ALLOW_16X16 ||
+ cm->txfm_mode == ALLOW_32X32 ||
+ (cm->txfm_mode == TX_MODE_SELECT && rd[TX_8X8][1] < rd[TX_4X4][1])) {
+ mbmi->txfm_size = TX_8X8;
+ } else {
+ mbmi->txfm_size = TX_4X4;
+ }
+
+ *distortion = d[mbmi->txfm_size];
+ *rate = r[mbmi->txfm_size][cm->txfm_mode == TX_MODE_SELECT];
+ *skip = s[mbmi->txfm_size];
+
+ txfm_cache[ONLY_4X4] = rd[TX_4X4][0];
+ txfm_cache[ALLOW_8X8] = rd[TX_8X8][0];
+ txfm_cache[ALLOW_16X16] = rd[MIN(max_txfm_size, TX_16X16)][0];
+ txfm_cache[ALLOW_32X32] = rd[MIN(max_txfm_size, TX_32X32)][0];
+ if (max_txfm_size == TX_32X32 &&
+ rd[TX_32X32][1] < rd[TX_16X16][1] && rd[TX_32X32][1] < rd[TX_8X8][1] &&
+ rd[TX_32X32][1] < rd[TX_4X4][1])
+ txfm_cache[TX_MODE_SELECT] = rd[TX_32X32][1];
+ else if (max_txfm_size >= TX_16X16 &&
+ rd[TX_16X16][1] < rd[TX_8X8][1] && rd[TX_16X16][1] < rd[TX_4X4][1])
+ txfm_cache[TX_MODE_SELECT] = rd[TX_16X16][1];
+ else
+ txfm_cache[TX_MODE_SELECT] = rd[TX_4X4][1] < rd[TX_8X8][1] ?
+ rd[TX_4X4][1] : rd[TX_8X8][1];
+
+ if (max_txfm_size == TX_32X32 &&
+ rd[TX_32X32][1] < rd[TX_16X16][1] &&
+ rd[TX_32X32][1] < rd[TX_8X8][1] &&
+ rd[TX_32X32][1] < rd[TX_4X4][1]) {
+ cpi->txfm_stepdown_count[0]++;
+ } else if (max_txfm_size >= TX_16X16 &&
+ rd[TX_16X16][1] < rd[TX_8X8][1] &&
+ rd[TX_16X16][1] < rd[TX_4X4][1]) {
+ cpi->txfm_stepdown_count[max_txfm_size - TX_16X16]++;
+ } else if (rd[TX_8X8][1] < rd[TX_4X4][1]) {
+ cpi->txfm_stepdown_count[max_txfm_size - TX_8X8]++;
+ } else {
+ cpi->txfm_stepdown_count[max_txfm_size - TX_4X4]++;
+ }
+}
+
+static void choose_txfm_size_from_modelrd(VP9_COMP *cpi, MACROBLOCK *x,
+ int (*r)[2], int *rate,
+ int64_t *d, int64_t *distortion,
+ int *s, int *skip, int64_t *sse,
+ BLOCK_SIZE_TYPE bs,
+ int *model_used) {
+ const TX_SIZE max_txfm_size = TX_32X32
+ - (bs < BLOCK_SIZE_SB32X32) - (bs < BLOCK_SIZE_MB16X16);
+ VP9_COMMON *const cm = &cpi->common;
+ MACROBLOCKD *const xd = &x->e_mbd;
+ MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
+ vp9_prob skip_prob = vp9_get_pred_prob(cm, xd, PRED_MBSKIP);
+ int64_t rd[TX_SIZE_MAX_SB][2];
+ int n, m;
+ int s0, s1;
+ double scale_rd[TX_SIZE_MAX_SB] = {1.73, 1.44, 1.20, 1.00};
+ // double scale_r[TX_SIZE_MAX_SB] = {2.82, 2.00, 1.41, 1.00};
+
+ const vp9_prob *tx_probs = vp9_get_pred_probs(cm, xd, PRED_TX_SIZE);
+
+ // for (n = TX_4X4; n <= max_txfm_size; n++)
+ // r[n][0] = (r[n][0] * scale_r[n]);
+
+ for (n = TX_4X4; n <= max_txfm_size; n++) {
+ r[n][1] = r[n][0];
+ for (m = 0; m <= n - (n == max_txfm_size); m++) {
+ if (m == n)
+ r[n][1] += vp9_cost_zero(tx_probs[m]);
+ else
+ r[n][1] += vp9_cost_one(tx_probs[m]);
+ }
+ }
+
+ assert(skip_prob > 0);
+ s0 = vp9_cost_bit(skip_prob, 0);
+ s1 = vp9_cost_bit(skip_prob, 1);
+
+ for (n = TX_4X4; n <= max_txfm_size; n++) {
+ if (s[n]) {
+ rd[n][0] = rd[n][1] = RDCOST(x->rdmult, x->rddiv, s1, d[n]);
+ } else {
+ rd[n][0] = RDCOST(x->rdmult, x->rddiv, r[n][0] + s0, d[n]);
+ rd[n][1] = RDCOST(x->rdmult, x->rddiv, r[n][1] + s0, d[n]);
+ }
+ }
+ for (n = TX_4X4; n <= max_txfm_size; n++) {
+ rd[n][0] = (scale_rd[n] * rd[n][0]);
+ rd[n][1] = (scale_rd[n] * rd[n][1]);
+ }
+
+ if (max_txfm_size == TX_32X32 &&
+ (cm->txfm_mode == ALLOW_32X32 ||
+ (cm->txfm_mode == TX_MODE_SELECT &&
+ rd[TX_32X32][1] <= rd[TX_16X16][1] &&
+ rd[TX_32X32][1] <= rd[TX_8X8][1] &&
+ rd[TX_32X32][1] <= rd[TX_4X4][1]))) {
+ mbmi->txfm_size = TX_32X32;
+ } else if (max_txfm_size >= TX_16X16 &&
+ (cm->txfm_mode == ALLOW_16X16 ||
+ cm->txfm_mode == ALLOW_32X32 ||
+ (cm->txfm_mode == TX_MODE_SELECT &&
+ rd[TX_16X16][1] <= rd[TX_8X8][1] &&
+ rd[TX_16X16][1] <= rd[TX_4X4][1]))) {
+ mbmi->txfm_size = TX_16X16;
+ } else if (cm->txfm_mode == ALLOW_8X8 ||
+ cm->txfm_mode == ALLOW_16X16 ||
+ cm->txfm_mode == ALLOW_32X32 ||
+ (cm->txfm_mode == TX_MODE_SELECT &&
+ rd[TX_8X8][1] <= rd[TX_4X4][1])) {
+ mbmi->txfm_size = TX_8X8;
+ } else {
+ mbmi->txfm_size = TX_4X4;
+ }
+
+ if (model_used[mbmi->txfm_size]) {
+ // Actually encode using the chosen mode if a model was used, but do not
+ // update the r, d costs
+ super_block_yrd_for_txfm(cm, x, rate, distortion, skip,
+ &sse[mbmi->txfm_size], bs, mbmi->txfm_size);
+ } else {
+ *distortion = d[mbmi->txfm_size];
+ *rate = r[mbmi->txfm_size][cm->txfm_mode == TX_MODE_SELECT];
+ *skip = s[mbmi->txfm_size];
+ }
+
+ if (max_txfm_size == TX_32X32 &&
+ rd[TX_32X32][1] <= rd[TX_16X16][1] &&
+ rd[TX_32X32][1] <= rd[TX_8X8][1] &&
+ rd[TX_32X32][1] <= rd[TX_4X4][1]) {
+ cpi->txfm_stepdown_count[0]++;
+ } else if (max_txfm_size >= TX_16X16 &&
+ rd[TX_16X16][1] <= rd[TX_8X8][1] &&
+ rd[TX_16X16][1] <= rd[TX_4X4][1]) {
+ cpi->txfm_stepdown_count[max_txfm_size - TX_16X16]++;
+ } else if (rd[TX_8X8][1] <= rd[TX_4X4][1]) {
+ cpi->txfm_stepdown_count[max_txfm_size - TX_8X8]++;
+ } else {
+ cpi->txfm_stepdown_count[max_txfm_size - TX_4X4]++;
+ }
+}
+
static void super_block_yrd(VP9_COMP *cpi,
MACROBLOCK *x, int *rate, int64_t *distortion,
int *skip, int64_t *psse, BLOCK_SIZE_TYPE bs,
@@ -649,38 +1057,67 @@ static void super_block_yrd(VP9_COMP *cpi,
if (mbmi->ref_frame[0] > INTRA_FRAME)
vp9_subtract_sby(x, bs);
- if (cpi->sf.use_largest_txform) {
- if (bs >= BLOCK_SIZE_SB32X32) {
- mbmi->txfm_size = TX_32X32;
- } else if (bs >= BLOCK_SIZE_MB16X16) {
- mbmi->txfm_size = TX_16X16;
- } else if (bs >= BLOCK_SIZE_SB8X8) {
- mbmi->txfm_size = TX_8X8;
- } else {
- mbmi->txfm_size = TX_4X4;
- }
+ if (cpi->sf.tx_size_search_method == USE_LARGESTALL ||
+ (cpi->sf.tx_size_search_method != USE_FULL_RD &&
+ mbmi->ref_frame[0] == INTRA_FRAME)) {
vpx_memset(txfm_cache, 0, NB_TXFM_MODES * sizeof(int64_t));
- super_block_yrd_for_txfm(cm, x, rate, distortion, skip, &sse[0], bs,
- mbmi->txfm_size);
+ choose_largest_txfm_size(cpi, x, rate, distortion, skip, sse, bs);
if (psse)
- *psse = sse[0];
+ *psse = sse[mbmi->txfm_size];
return;
}
- if (bs >= BLOCK_SIZE_SB32X32)
- super_block_yrd_for_txfm(cm, x, &r[TX_32X32][0], &d[TX_32X32], &s[TX_32X32],
- &sse[TX_32X32], bs, TX_32X32);
- if (bs >= BLOCK_SIZE_MB16X16)
- super_block_yrd_for_txfm(cm, x, &r[TX_16X16][0], &d[TX_16X16], &s[TX_16X16],
- &sse[TX_16X16], bs, TX_16X16);
- super_block_yrd_for_txfm(cm, x, &r[TX_8X8][0], &d[TX_8X8], &s[TX_8X8],
- &sse[TX_8X8], bs, TX_8X8);
- super_block_yrd_for_txfm(cm, x, &r[TX_4X4][0], &d[TX_4X4], &s[TX_4X4],
- &sse[TX_4X4], bs, TX_4X4);
-
- choose_txfm_size_from_rd(cpi, x, r, rate, d, distortion, s,
- skip, txfm_cache,
- TX_32X32 - (bs < BLOCK_SIZE_SB32X32)
- - (bs < BLOCK_SIZE_MB16X16));
+
+ if (cpi->sf.tx_size_search_method == USE_LARGESTINTRA_MODELINTER &&
+ mbmi->ref_frame[0] > INTRA_FRAME) {
+ int model_used[TX_SIZE_MAX_SB] = {1, 1, 1, 1};
+ if (bs >= BLOCK_SIZE_SB32X32) {
+ if (model_used[TX_32X32]) {
+ model_rd_for_sb_y_tx(cpi, bs, TX_32X32, x, xd,
+ &r[TX_32X32][0], &d[TX_32X32], &s[TX_32X32]);
+ } else {
+ super_block_yrd_for_txfm(cm, x, &r[TX_32X32][0], &d[TX_32X32],
+ &s[TX_32X32], &sse[TX_32X32], bs, TX_32X32);
+ }
+ }
+ if (bs >= BLOCK_SIZE_MB16X16) {
+ if (model_used[TX_16X16]) {
+ model_rd_for_sb_y_tx(cpi, bs, TX_16X16, x, xd,
+ &r[TX_16X16][0], &d[TX_16X16], &s[TX_16X16]);
+ } else {
+ super_block_yrd_for_txfm(cm, x, &r[TX_16X16][0], &d[TX_16X16],
+ &s[TX_16X16], &sse[TX_16X16], bs, TX_16X16);
+ }
+ }
+ if (model_used[TX_8X8]) {
+ model_rd_for_sb_y_tx(cpi, bs, TX_8X8, x, xd,
+ &r[TX_8X8][0], &d[TX_8X8], &s[TX_8X8]);
+ } else {
+ super_block_yrd_for_txfm(cm, x, &r[TX_8X8][0], &d[TX_8X8], &s[TX_8X8],
+ &sse[TX_8X8], bs, TX_8X8);
+ }
+ if (model_used[TX_4X4]) {
+ model_rd_for_sb_y_tx(cpi, bs, TX_4X4, x, xd,
+ &r[TX_4X4][0], &d[TX_4X4], &s[TX_4X4]);
+ } else {
+ super_block_yrd_for_txfm(cm, x, &r[TX_4X4][0], &d[TX_4X4], &s[TX_4X4],
+ &sse[TX_4X4], bs, TX_4X4);
+ }
+ choose_txfm_size_from_modelrd(cpi, x, r, rate, d, distortion, s,
+ skip, sse, bs, model_used);
+ } else {
+ if (bs >= BLOCK_SIZE_SB32X32)
+ super_block_yrd_for_txfm(cm, x, &r[TX_32X32][0], &d[TX_32X32],
+ &s[TX_32X32], &sse[TX_32X32], bs, TX_32X32);
+ if (bs >= BLOCK_SIZE_MB16X16)
+ super_block_yrd_for_txfm(cm, x, &r[TX_16X16][0], &d[TX_16X16],
+ &s[TX_16X16], &sse[TX_16X16], bs, TX_16X16);
+ super_block_yrd_for_txfm(cm, x, &r[TX_8X8][0], &d[TX_8X8], &s[TX_8X8],
+ &sse[TX_8X8], bs, TX_8X8);
+ super_block_yrd_for_txfm(cm, x, &r[TX_4X4][0], &d[TX_4X4], &s[TX_4X4],
+ &sse[TX_4X4], bs, TX_4X4);
+ choose_txfm_size_from_rd(cpi, x, r, rate, d, distortion, s,
+ skip, txfm_cache, bs);
+ }
if (psse)
*psse = sse[mbmi->txfm_size];
}
@@ -909,8 +1346,10 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
return best_rd;
}
- for (i = 0; i < NB_TXFM_MODES; i++)
- txfm_cache[i] = INT64_MAX;
+ if (cpi->sf.tx_size_search_method == USE_FULL_RD) {
+ for (i = 0; i < NB_TXFM_MODES; i++)
+ txfm_cache[i] = INT64_MAX;
+ }
/* Y Search for 32x32 intra prediction mode */
for (mode = DC_PRED; mode <= TM_PRED; mode++) {
@@ -943,11 +1382,13 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
*skippable = s;
}
- for (i = 0; i < NB_TXFM_MODES; i++) {
- int64_t adj_rd = this_rd + local_txfm_cache[i] -
- local_txfm_cache[cpi->common.txfm_mode];
- if (adj_rd < txfm_cache[i]) {
- txfm_cache[i] = adj_rd;
+ if (cpi->sf.tx_size_search_method == USE_FULL_RD) {
+ for (i = 0; i < NB_TXFM_MODES; i++) {
+ int64_t adj_rd = this_rd + local_txfm_cache[i] -
+ local_txfm_cache[cpi->common.txfm_mode];
+ if (adj_rd < txfm_cache[i]) {
+ txfm_cache[i] = adj_rd;
+ }
}
}
}
@@ -1246,50 +1687,6 @@ static INLINE int mv_check_bounds(MACROBLOCK *x, int_mv *mv) {
return r;
}
-static enum BlockSize get_block_size(int bw, int bh) {
- if (bw == 4 && bh == 4)
- return BLOCK_4X4;
-
- if (bw == 4 && bh == 8)
- return BLOCK_4X8;
-
- if (bw == 8 && bh == 4)
- return BLOCK_8X4;
-
- if (bw == 8 && bh == 8)
- return BLOCK_8X8;
-
- if (bw == 8 && bh == 16)
- return BLOCK_8X16;
-
- if (bw == 16 && bh == 8)
- return BLOCK_16X8;
-
- if (bw == 16 && bh == 16)
- return BLOCK_16X16;
-
- if (bw == 32 && bh == 32)
- return BLOCK_32X32;
-
- if (bw == 32 && bh == 16)
- return BLOCK_32X16;
-
- if (bw == 16 && bh == 32)
- return BLOCK_16X32;
-
- if (bw == 64 && bh == 32)
- return BLOCK_64X32;
-
- if (bw == 32 && bh == 64)
- return BLOCK_32X64;
-
- if (bw == 64 && bh == 64)
- return BLOCK_64X64;
-
- assert(0);
- return -1;
-}
-
static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
MB_MODE_INFO *mbmi = &x->e_mbd.mode_info_context->mbmi;
x->plane[0].src.buf =
@@ -1837,195 +2234,6 @@ static YV12_BUFFER_CONFIG *get_scaled_ref_frame(VP9_COMP *cpi, int ref_frame) {
return scaled_ref_frame;
}
-static double linear_interpolate(double x, int ntab, double step,
- const double *tab) {
- double y = x / step;
- int d = (int) y;
- double a = y - d;
- if (d >= ntab - 1)
- return tab[ntab - 1];
- else
- return tab[d] * (1 - a) + tab[d + 1] * a;
-}
-
-static double model_rate_norm(double x) {
- // Normalized rate
- // This function models the rate for a Laplacian source
- // 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.
- static const double rate_tab_step = 0.125;
- static const double rate_tab[] = {
- 256.0000, 4.944453, 3.949276, 3.371593,
- 2.965771, 2.654550, 2.403348, 2.193612,
- 2.014208, 1.857921, 1.719813, 1.596364,
- 1.484979, 1.383702, 1.291025, 1.205767,
- 1.126990, 1.053937, 0.985991, 0.922644,
- 0.863472, 0.808114, 0.756265, 0.707661,
- 0.662070, 0.619287, 0.579129, 0.541431,
- 0.506043, 0.472828, 0.441656, 0.412411,
- 0.384980, 0.359260, 0.335152, 0.312563,
- 0.291407, 0.271600, 0.253064, 0.235723,
- 0.219508, 0.204351, 0.190189, 0.176961,
- 0.164611, 0.153083, 0.142329, 0.132298,
- 0.122945, 0.114228, 0.106106, 0.098541,
- 0.091496, 0.084937, 0.078833, 0.073154,
- 0.067872, 0.062959, 0.058392, 0.054147,
- 0.050202, 0.046537, 0.043133, 0.039971,
- 0.037036, 0.034312, 0.031783, 0.029436,
- 0.027259, 0.025240, 0.023367, 0.021631,
- 0.020021, 0.018528, 0.017145, 0.015863,
- 0.014676, 0.013575, 0.012556, 0.011612,
- 0.010738, 0.009929, 0.009180, 0.008487,
- 0.007845, 0.007251, 0.006701, 0.006193,
- 0.005722, 0.005287, 0.004884, 0.004512,
- 0.004168, 0.003850, 0.003556, 0.003284,
- 0.003032, 0.002800, 0.002585, 0.002386,
- 0.002203, 0.002034, 0.001877, 0.001732,
- 0.001599, 0.001476, 0.001362, 0.001256,
- 0.001159, 0.001069, 0.000987, 0.000910,
- 0.000840, 0.000774, 0.000714, 0.000659,
- 0.000608, 0.000560, 0.000517, 0.000476,
- 0.000439, 0.000405, 0.000373, 0.000344,
- 0.000317, 0.000292, 0.000270, 0.000248,
- 0.000229, 0.000211, 0.000195, 0.000179,
- 0.000165, 0.000152, 0.000140, 0.000129,
- 0.000119, 0.000110, 0.000101, 0.000093,
- 0.000086, 0.000079, 0.000073, 0.000067,
- 0.000062, 0.000057, 0.000052, 0.000048,
- 0.000044, 0.000041, 0.000038, 0.000035,
- 0.000032, 0.000029, 0.000027, 0.000025,
- 0.000023, 0.000021, 0.000019, 0.000018,
- 0.000016, 0.000015, 0.000014, 0.000013,
- 0.000012, 0.000011, 0.000010, 0.000009,
- 0.000008, 0.000008, 0.000007, 0.000007,
- 0.000006, 0.000006, 0.000005, 0.000005,
- 0.000004, 0.000004, 0.000004, 0.000003,
- 0.000003, 0.000003, 0.000003, 0.000002,
- 0.000002, 0.000002, 0.000002, 0.000002,
- 0.000002, 0.000001, 0.000001, 0.000001,
- 0.000001, 0.000001, 0.000001, 0.000001,
- 0.000001, 0.000001, 0.000001, 0.000001,
- 0.000001, 0.000001, 0.000000, 0.000000,
- };
- const int rate_tab_num = sizeof(rate_tab)/sizeof(rate_tab[0]);
- assert(x >= 0.0);
- return linear_interpolate(x, rate_tab_num, rate_tab_step, rate_tab);
-}
-
-static double model_dist_norm(double x) {
- // Normalized distortion
- // This function models the normalized distortion for a Laplacian source
- // source with given variance when quantized with a uniform quantizer
- // with given stepsize. The closed form expression is:
- // Dn(x) = 1 - 1/sqrt(2) * x / sinh(x/sqrt(2))
- // where x = qpstep / sqrt(variance)
- // Note the actual distortion is Dn * variance.
- static const double dist_tab_step = 0.25;
- static const double dist_tab[] = {
- 0.000000, 0.005189, 0.020533, 0.045381,
- 0.078716, 0.119246, 0.165508, 0.215979,
- 0.269166, 0.323686, 0.378318, 0.432034,
- 0.484006, 0.533607, 0.580389, 0.624063,
- 0.664475, 0.701581, 0.735418, 0.766092,
- 0.793751, 0.818575, 0.840761, 0.860515,
- 0.878045, 0.893554, 0.907238, 0.919281,
- 0.929857, 0.939124, 0.947229, 0.954306,
- 0.960475, 0.965845, 0.970512, 0.974563,
- 0.978076, 0.981118, 0.983750, 0.986024,
- 0.987989, 0.989683, 0.991144, 0.992402,
- 0.993485, 0.994417, 0.995218, 0.995905,
- 0.996496, 0.997002, 0.997437, 0.997809,
- 0.998128, 0.998401, 0.998635, 0.998835,
- 0.999006, 0.999152, 0.999277, 0.999384,
- 0.999475, 0.999553, 0.999619, 0.999676,
- 0.999724, 0.999765, 0.999800, 0.999830,
- 0.999855, 0.999877, 0.999895, 0.999911,
- 0.999924, 0.999936, 0.999945, 0.999954,
- 0.999961, 0.999967, 0.999972, 0.999976,
- 0.999980, 0.999983, 0.999985, 0.999988,
- 0.999989, 0.999991, 0.999992, 0.999994,
- 0.999995, 0.999995, 0.999996, 0.999997,
- 0.999997, 0.999998, 0.999998, 0.999998,
- 0.999999, 0.999999, 0.999999, 0.999999,
- 0.999999, 0.999999, 0.999999, 1.000000,
- };
- const int dist_tab_num = sizeof(dist_tab)/sizeof(dist_tab[0]);
- assert(x >= 0.0);
- return linear_interpolate(x, dist_tab_num, dist_tab_step, dist_tab);
-}
-
-static void model_rd_from_var_lapndz(int var, int n, int 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 expression is:
- // Rn(x) = H(sqrt(r)) + sqrt(r)*[1 + H(r)/(1 - r)],
- // where r = exp(-sqrt(2) * x) and x = qpstep / sqrt(variance)
- vp9_clear_system_state();
- if (var == 0 || n == 0) {
- *rate = 0;
- *dist = 0;
- } else {
- double D, R;
- double s2 = (double) var / n;
- double x = qstep / sqrt(s2);
- // TODO(debargha): Make the modeling functions take (qstep^2 / s2)
- // as argument rather than qstep / sqrt(s2) to obviate the need for
- // the sqrt() operation.
- D = model_dist_norm(x);
- R = model_rate_norm(x);
- if (R < 0) {
- R = 0;
- D = var;
- }
- *rate = (n * R * 256 + 0.5);
- *dist = (n * D * s2 + 0.5);
- }
- vp9_clear_system_state();
-}
-
-static enum BlockSize get_plane_block_size(BLOCK_SIZE_TYPE bsize,
- struct macroblockd_plane *pd) {
- return get_block_size(plane_block_width(bsize, pd),
- plane_block_height(bsize, pd));
-}
-
-static void model_rd_for_sb(VP9_COMP *cpi, BLOCK_SIZE_TYPE bsize,
- MACROBLOCK *x, MACROBLOCKD *xd,
- int *out_rate_sum, int64_t *out_dist_sum) {
- // Note our transform coeffs are 8 times an orthogonal transform.
- // Hence quantizer step is also 8 times. To get effective quantizer
- // we need to divide by 8 before sending to modeling function.
- unsigned int sse;
- int i, rate_sum = 0;
- int64_t dist_sum = 0;
-
- for (i = 0; i < MAX_MB_PLANE; ++i) {
- struct macroblock_plane *const p = &x->plane[i];
- struct macroblockd_plane *const pd = &xd->plane[i];
-
- // TODO(dkovalev) the same code in get_plane_block_size
- const int bw = plane_block_width(bsize, pd);
- const int bh = plane_block_height(bsize, pd);
- const enum BlockSize bs = get_block_size(bw, bh);
- int rate;
- int64_t dist;
- cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride,
- pd->dst.buf, pd->dst.stride, &sse);
-
- model_rd_from_var_lapndz(sse, bw * bh, pd->dequant[1] >> 3, &rate, &dist);
-
- rate_sum += rate;
- dist_sum += dist;
- }
-
- *out_rate_sum = rate_sum;
- *out_dist_sum = dist_sum << 4;
-}
-
static INLINE int get_switchable_rate(VP9_COMMON *cm, MACROBLOCK *x) {
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
@@ -2564,7 +2772,6 @@ void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
int rate4x4_y, rate4x4_y_tokenonly;
int64_t dist4x4_y;
int64_t err4x4 = INT64_MAX;
- int i;
vpx_memset(&txfm_cache,0,sizeof(txfm_cache));
ctx->skip = 0;
@@ -2597,11 +2804,14 @@ void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
vpx_memset(ctx->txfm_rd_diff, 0, sizeof(ctx->txfm_rd_diff));
xd->mode_info_context->mbmi.txfm_size = TX_4X4;
} else {
+ int i;
*returnrate = rate_y + rate_uv +
vp9_cost_bit(vp9_get_pred_prob(cm, xd, PRED_MBSKIP), 0);
*returndist = dist_y + (dist_uv >> 2);
- for (i = 0; i < NB_TXFM_MODES; i++) {
- ctx->txfm_rd_diff[i] = txfm_cache[i] - txfm_cache[cm->txfm_mode];
+ if (cpi->sf.tx_size_search_method == USE_FULL_RD) {
+ for (i = 0; i < NB_TXFM_MODES; i++) {
+ ctx->txfm_rd_diff[i] = txfm_cache[i] - txfm_cache[cm->txfm_mode];
+ }
}
xd->mode_info_context->mbmi.txfm_size = txfm_size;
xd->mode_info_context->mbmi.mode = mode;