#include "vp10/encoder/encodemb.h"
#include "vp10/encoder/encodemv.h"
#include "vp10/encoder/encoder.h"
+#include "vp10/encoder/hybrid_fwd_txfm.h"
#include "vp10/encoder/mcomp.h"
- #include "vp10/encoder/palette.h"
#include "vp10/encoder/quantize.h"
#include "vp10/encoder/ratectrl.h"
#include "vp10/encoder/rd.h"
*distortion = total_distortion;
mic->mbmi.mode = mic->bmi[3].as_mode;
- return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion);
+ return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion);
+}
+
+#if CONFIG_EXT_INTRA
+// Return 1 if an ext intra mode is selected; return 0 otherwise.
+static int rd_pick_ext_intra_sby(VP10_COMP *cpi, MACROBLOCK *x,
+ int *rate, int *rate_tokenonly,
+ int64_t *distortion, int *skippable,
+ BLOCK_SIZE bsize, int mode_cost,
+ int64_t *best_rd) {
+ MACROBLOCKD *const xd = &x->e_mbd;
+ MODE_INFO *const mic = xd->mi[0];
+ MB_MODE_INFO *mbmi = &mic->mbmi;
+ int this_rate, this_rate_tokenonly, s;
+ int ext_intra_selected_flag = 0;
+ int64_t this_distortion, this_rd;
+ EXT_INTRA_MODE mode;
+ TX_SIZE best_tx_size = TX_4X4;
+ EXT_INTRA_MODE_INFO ext_intra_mode_info;
+#if CONFIG_EXT_TX
+ TX_TYPE best_tx_type;
+#endif // CONFIG_EXT_TX
+
+ vp10_zero(ext_intra_mode_info);
+ mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 1;
+ mbmi->mode = DC_PRED;
+
+ for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
+ mbmi->ext_intra_mode_info.ext_intra_mode[0] = mode;
+ super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
+ &s, NULL, bsize, *best_rd);
+ if (this_rate_tokenonly == INT_MAX)
+ continue;
+
+ this_rate = this_rate_tokenonly +
+ vp10_cost_bit(cpi->common.fc->ext_intra_probs[0], 1) +
+ write_uniform_cost(FILTER_INTRA_MODES, mode) + mode_cost;
+ this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
+
+ if (this_rd < *best_rd) {
+ *best_rd = this_rd;
+ best_tx_size = mic->mbmi.tx_size;
+ ext_intra_mode_info = mbmi->ext_intra_mode_info;
+#if CONFIG_EXT_TX
+ best_tx_type = mic->mbmi.tx_type;
+#endif // CONFIG_EXT_TX
+ *rate = this_rate;
+ *rate_tokenonly = this_rate_tokenonly;
+ *distortion = this_distortion;
+ *skippable = s;
+ ext_intra_selected_flag = 1;
+ }
+ }
+
+ if (ext_intra_selected_flag) {
+ mbmi->mode = DC_PRED;
+ mbmi->tx_size = best_tx_size;
+ mbmi->ext_intra_mode_info.use_ext_intra_mode[0] =
+ ext_intra_mode_info.use_ext_intra_mode[0];
+ mbmi->ext_intra_mode_info.ext_intra_mode[0] =
+ ext_intra_mode_info.ext_intra_mode[0];
+#if CONFIG_EXT_TX
+ mbmi->tx_type = best_tx_type;
+#endif // CONFIG_EXT_TX
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int64_t rd_pick_intra_angle_sby(VP10_COMP *cpi, MACROBLOCK *x,
+ int *rate, int *rate_tokenonly,
+ int64_t *distortion, int *skippable,
+ BLOCK_SIZE bsize, int rate_overhead,
+ int64_t best_rd) {
+ MACROBLOCKD *const xd = &x->e_mbd;
+ MODE_INFO *const mic = xd->mi[0];
+ MB_MODE_INFO *mbmi = &mic->mbmi;
+ int this_rate, this_rate_tokenonly, s;
+ int angle_delta, best_angle_delta = 0;
+ const double rd_adjust = 1.2;
+ int64_t this_distortion, this_rd, sse_dummy;
+ TX_SIZE best_tx_size = mic->mbmi.tx_size;
+#if CONFIG_EXT_TX
+ TX_TYPE best_tx_type = mbmi->tx_type;
+#endif // CONFIG_EXT_TX
+
+ if (ANGLE_FAST_SEARCH) {
+ int deltas_level1[3] = {0, -2, 2};
+ int deltas_level2[3][2] = {
+ {-1, 1}, {-3, -1}, {1, 3},
+ };
+ const int level1 = 3, level2 = 2;
+ int i, j, best_i = -1;
+
+ for (i = 0; i < level1; ++i) {
+ mic->mbmi.angle_delta[0] = deltas_level1[i];
+ super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
+ &s, NULL, bsize,
+ (i == 0 && best_rd < INT64_MAX) ? best_rd * rd_adjust :
+ best_rd);
+ if (this_rate_tokenonly == INT_MAX) {
+ if (i == 0)
+ break;
+ else
+ continue;
+ }
+ this_rate = this_rate_tokenonly + rate_overhead;
+ this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
+ if (i == 0 && best_rd < INT64_MAX && this_rd > best_rd * rd_adjust)
+ break;
+ if (this_rd < best_rd) {
+ best_i = i;
+ best_rd = this_rd;
+ best_angle_delta = mbmi->angle_delta[0];
+ best_tx_size = mbmi->tx_size;
+#if CONFIG_EXT_TX
+ best_tx_type = mbmi->tx_type;
+#endif // CONFIG_EXT_TX
+ *rate = this_rate;
+ *rate_tokenonly = this_rate_tokenonly;
+ *distortion = this_distortion;
+ *skippable = s;
+ }
+ }
+
+ if (best_i >= 0) {
+ for (j = 0; j < level2; ++j) {
+ mic->mbmi.angle_delta[0] = deltas_level2[best_i][j];
+ super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
+ &s, NULL, bsize, best_rd);
+ if (this_rate_tokenonly == INT_MAX)
+ continue;
+ this_rate = this_rate_tokenonly + rate_overhead;
+ this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
+ if (this_rd < best_rd) {
+ best_rd = this_rd;
+ best_angle_delta = mbmi->angle_delta[0];
+ best_tx_size = mbmi->tx_size;
+#if CONFIG_EXT_TX
+ best_tx_type = mbmi->tx_type;
+#endif // CONFIG_EXT_TX
+ *rate = this_rate;
+ *rate_tokenonly = this_rate_tokenonly;
+ *distortion = this_distortion;
+ *skippable = s;
+ }
+ }
+ }
+ } else {
+ for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS;
+ ++angle_delta) {
+ mic->mbmi.angle_delta[0] = angle_delta;
+
+ super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
+ &s, NULL, bsize, best_rd);
+ if (this_rate_tokenonly == INT_MAX)
+ continue;
+
+ this_rate = this_rate_tokenonly + rate_overhead;
+ this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
+
+ if (this_rd < best_rd) {
+ best_rd = this_rd;
+ best_angle_delta = mbmi->angle_delta[0];
+ best_tx_size = mbmi->tx_size;
+#if CONFIG_EXT_TX
+ best_tx_type = mbmi->tx_type;
+#endif // CONFIG_EXT_TX
+ *rate = this_rate;
+ *rate_tokenonly = this_rate_tokenonly;
+ *distortion = this_distortion;
+ *skippable = s;
+ }
+ }
+ }
+
+ mbmi->tx_size = best_tx_size;
+ mbmi->angle_delta[0] = best_angle_delta;
+#if CONFIG_EXT_TX
+ mbmi->tx_type = best_tx_type;
+#endif // CONFIG_EXT_TX
+
+ if (*rate_tokenonly < INT_MAX) {
+ txfm_rd_in_plane(x,
+#if CONFIG_VAR_TX
+ cpi,
+#endif
+ &this_rate_tokenonly, &this_distortion, &s,
+ &sse_dummy, INT64_MAX, 0, bsize, mbmi->tx_size,
+ cpi->sf.use_fast_coef_costing);
+ }
+
+ return best_rd;
+}
+
+static inline int get_angle_index(double angle) {
+ const double step = 22.5, base = 45;
+ return (int)round((angle - base) / step);
+}
+
+static void angle_estimation(const uint8_t *src, int src_stride,
+ int rows, int cols, double *hist) {
+ int r, c, i, index;
+ const double pi = 3.1415;
+ double angle, dx, dy;
+ double temp, divisor = 0;
+
+ for (i = 0; i < DIRECTIONAL_MODES; ++i)
+ hist[i] = 0;
+
+ src += src_stride;
+ for (r = 1; r < rows; ++r) {
+ for (c = 1; c < cols; ++c) {
+ dx = src[c] - src[c - 1];
+ dy = src[c] - src[c - src_stride];
+ temp = dx * dx + dy * dy;
+ if (dy == 0)
+ angle = 90;
+ else
+ angle = (atan((double)dx / (double)dy)) * 180 / pi;
+ assert(angle >= -90 && angle <= 90);
+ index = get_angle_index(angle + 180);
+ if (index < DIRECTIONAL_MODES) {
+ hist[index] += temp;
+ divisor += temp;
+ }
+ if (angle > 0) {
+ index = get_angle_index(angle);
+ if (index >= 0) {
+ hist[index] += temp;
+ divisor += temp;
+ }
+ }
+ }
+ src += src_stride;
+ }
+
+ if (divisor < 1)
+ divisor = 1;
+ for (i = 0; i < DIRECTIONAL_MODES; ++i)
+ hist[i] /= divisor;
+}
+
+#if CONFIG_VP9_HIGHBITDEPTH
+static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
+ int rows, int cols, double *hist) {
+ int r, c, i, index;
+ const double pi = 3.1415;
+ double angle, dx, dy;
+ double temp, divisor = 0;
+ uint16_t *src = CONVERT_TO_SHORTPTR(src8);
+
+ for (i = 0; i < DIRECTIONAL_MODES; ++i)
+ hist[i] = 0;
+
+ src += src_stride;
+ for (r = 1; r < rows; ++r) {
+ for (c = 1; c < cols; ++c) {
+ dx = src[c] - src[c - 1];
+ dy = src[c] - src[c - src_stride];
+ temp = dx * dx + dy * dy;
+ if (dy == 0)
+ angle = 90;
+ else
+ angle = (atan((double)dx / (double)dy)) * 180 / pi;
+ assert(angle >= -90 && angle <= 90);
+ index = get_angle_index(angle + 180);
+ if (index < DIRECTIONAL_MODES) {
+ hist[index] += temp;
+ divisor += temp;
+ }
+ if (angle > 0) {
+ index = get_angle_index(angle);
+ if (index >= 0) {
+ hist[index] += temp;
+ divisor += temp;
+ }
+ }
+ }
+ src += src_stride;
+ }
+
+ if (divisor < 1)
+ divisor = 1;
+ for (i = 0; i < DIRECTIONAL_MODES; ++i)
+ hist[i] /= divisor;
+}
+#endif // CONFIG_VP9_HIGHBITDEPTH
+#endif // CONFIG_EXT_INTRA
+
+// This function is used only for intra_only frames
+static int64_t rd_pick_intra_sby_mode(VP10_COMP *cpi, MACROBLOCK *x,
+ int *rate, int *rate_tokenonly,
+ int64_t *distortion, int *skippable,
+ BLOCK_SIZE bsize,
+ int64_t best_rd) {
+ PREDICTION_MODE mode;
+ PREDICTION_MODE mode_selected = DC_PRED;
+ MACROBLOCKD *const xd = &x->e_mbd;
+ MODE_INFO *const mic = xd->mi[0];
+ int this_rate, this_rate_tokenonly, s;
+ int64_t this_distortion, this_rd;
+ TX_SIZE best_tx = TX_4X4;
+#if CONFIG_EXT_INTRA
+ EXT_INTRA_MODE_INFO ext_intra_mode_info;
+ int is_directional_mode, rate_overhead, best_angle_delta = 0;
+ uint8_t directional_mode_skip_mask[INTRA_MODES];
+ const int src_stride = x->plane[0].src.stride;
+ const uint8_t *src = x->plane[0].src.buf;
+ double hist[DIRECTIONAL_MODES];
++ int rows = 4 * num_4x4_blocks_high_lookup[bsize];
++ int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
+#endif // CONFIG_EXT_INTRA
+#if CONFIG_EXT_TX
+ TX_TYPE best_tx_type = DCT_DCT;
+#endif // CONFIG_EXT_TX
+ int *bmode_costs;
- PALETTE_MODE_INFO palette_mode_info;
- uint8_t *best_palette_color_map = cpi->common.allow_screen_content_tools ?
- x->palette_buffer->best_palette_color_map : NULL;
- const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
- const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
- int palette_ctx = 0;
+ const MODE_INFO *above_mi = xd->above_mi;
+ const MODE_INFO *left_mi = xd->left_mi;
+ const PREDICTION_MODE A = vp10_above_block_mode(mic, above_mi, 0);
+ const PREDICTION_MODE L = vp10_left_block_mode(mic, left_mi, 0);
+ bmode_costs = cpi->y_mode_costs[A][L];
+
+#if CONFIG_EXT_INTRA
+ ext_intra_mode_info.use_ext_intra_mode[0] = 0;
+ mic->mbmi.ext_intra_mode_info.use_ext_intra_mode[0] = 0;
+ mic->mbmi.angle_delta[0] = 0;
+ memset(directional_mode_skip_mask, 0,
+ sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
+#if CONFIG_VP9_HIGHBITDEPTH
+ if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
+ highbd_angle_estimation(src, src_stride, rows, cols, hist);
+ else
+#endif
+ angle_estimation(src, src_stride, rows, cols, hist);
+
+ for (mode = 0; mode < INTRA_MODES; ++mode) {
+ if (mode != DC_PRED && mode != TM_PRED) {
+ int index = get_angle_index((double)mode_to_angle_map[mode]);
+ double score, weight = 1.0;
+ score = hist[index];
+ if (index > 0) {
+ score += hist[index - 1] * 0.5;
+ weight += 0.5;
+ }
+ if (index < DIRECTIONAL_MODES - 1) {
+ score += hist[index + 1] * 0.5;
+ weight += 0.5;
+ }
+ score /= weight;
+ if (score < ANGLE_SKIP_THRESH)
+ directional_mode_skip_mask[mode] = 1;
+ }
+ }
+#endif // CONFIG_EXT_INTRA
+ memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
- palette_mode_info.palette_size[0] = 0;
- mic->mbmi.palette_mode_info.palette_size[0] = 0;
- if (above_mi)
- palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
- if (left_mi)
- palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
+
+ /* Y Search for intra prediction mode */
+ for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
+ mic->mbmi.mode = mode;
+#if CONFIG_EXT_INTRA
+ is_directional_mode = (mode != DC_PRED && mode != TM_PRED);
+ if (is_directional_mode && directional_mode_skip_mask[mode])
+ continue;
+ if (is_directional_mode) {
+ rate_overhead = bmode_costs[mode] +
+ write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0);
+ this_rate_tokenonly = INT_MAX;
+ this_rd =
+ rd_pick_intra_angle_sby(cpi, x, &this_rate, &this_rate_tokenonly,
+ &this_distortion, &s, bsize, rate_overhead,
+ best_rd);
+ } else {
+ mic->mbmi.angle_delta[0] = 0;
+ super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
+ &s, NULL, bsize, best_rd);
+ }
+#endif // CONFIG_EXT_INTRA
+ super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
+ &s, NULL, bsize, best_rd);
+
+ if (this_rate_tokenonly == INT_MAX)
+ continue;
+
+ this_rate = this_rate_tokenonly + bmode_costs[mode];
- if (cpi->common.allow_screen_content_tools && mode == DC_PRED)
- this_rate +=
- vp10_cost_bit(vp10_default_palette_y_mode_prob[bsize - BLOCK_8X8]
- [palette_ctx], 0);
+#if CONFIG_EXT_INTRA
+ if (mode == DC_PRED && ALLOW_FILTER_INTRA_MODES)
+ this_rate += vp10_cost_bit(cpi->common.fc->ext_intra_probs[0], 0);
+ if (is_directional_mode)
+ this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
+ MAX_ANGLE_DELTAS +
+ mic->mbmi.angle_delta[0]);
+#endif // CONFIG_EXT_INTRA
+ this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
+
+ if (this_rd < best_rd) {
+ mode_selected = mode;
+ best_rd = this_rd;
+ best_tx = mic->mbmi.tx_size;
+#if CONFIG_EXT_INTRA
+ best_angle_delta = mic->mbmi.angle_delta[0];
+#endif // CONFIG_EXT_INTRA
+#if CONFIG_EXT_TX
+ best_tx_type = mic->mbmi.tx_type;
+#endif // CONFIG_EXT_TX
+ *rate = this_rate;
+ *rate_tokenonly = this_rate_tokenonly;
+ *distortion = this_distortion;
+ *skippable = s;
+ }
+ }
+
- if (cpi->common.allow_screen_content_tools)
- rd_pick_palette_intra_sby(cpi, x, bsize, palette_ctx, bmode_costs[DC_PRED],
- &palette_mode_info, best_palette_color_map,
- &best_tx, &mode_selected, &best_rd);
-
+#if CONFIG_EXT_INTRA
- if (!palette_mode_info.palette_size[0] > 0 && ALLOW_FILTER_INTRA_MODES) {
- if (rd_pick_ext_intra_sby(cpi, x, rate, rate_tokenonly, distortion,
- skippable, bsize, bmode_costs[DC_PRED],
- &best_rd)) {
- mode_selected = mic->mbmi.mode;
- best_tx = mic->mbmi.tx_size;
- ext_intra_mode_info = mic->mbmi.ext_intra_mode_info;
++ if (rd_pick_ext_intra_sby(cpi, x, rate, rate_tokenonly, distortion,
++ skippable, bsize, bmode_costs[DC_PRED],
++ &best_rd)) {
++ mode_selected = mic->mbmi.mode;
++ best_tx = mic->mbmi.tx_size;
++ ext_intra_mode_info = mic->mbmi.ext_intra_mode_info;
+#if CONFIG_EXT_TX
- best_tx_type = mic->mbmi.tx_type;
++ best_tx_type = mic->mbmi.tx_type;
+#endif // CONFIG_EXT_TX
- }
+ }
+
+ mic->mbmi.ext_intra_mode_info.use_ext_intra_mode[0] =
+ ext_intra_mode_info.use_ext_intra_mode[0];
+ if (ext_intra_mode_info.use_ext_intra_mode[0]) {
+ mic->mbmi.ext_intra_mode_info.ext_intra_mode[0] =
+ ext_intra_mode_info.ext_intra_mode[0];
+ }
+#endif // CONFIG_EXT_INTRA
+
+ mic->mbmi.mode = mode_selected;
+ mic->mbmi.tx_size = best_tx;
+#if CONFIG_EXT_INTRA
+ mic->mbmi.angle_delta[0] = best_angle_delta;
+#endif // CONFIG_EXT_INTRA
+#if CONFIG_EXT_TX
+ mic->mbmi.tx_type = best_tx_type;
+#endif // CONFIG_EXT_TX
- mic->mbmi.palette_mode_info.palette_size[0] =
- palette_mode_info.palette_size[0];
- if (palette_mode_info.palette_size[0] > 0) {
- memcpy(mic->mbmi.palette_mode_info.palette_colors,
- palette_mode_info.palette_colors,
- PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
- memcpy(xd->plane[0].color_index_map, best_palette_color_map,
- rows * cols * sizeof(best_palette_color_map[0]));
- }
+
+ return best_rd;
+}
+
+#if CONFIG_VAR_TX
+static void tx_block_rd_b(const VP10_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
+ int blk_row, int blk_col, int plane, int block,
+ int plane_bsize, int coeff_ctx,
+ int *rate, int64_t *dist, int64_t *bsse, int *skip) {
+ MACROBLOCKD *xd = &x->e_mbd;
+ const struct macroblock_plane *const p = &x->plane[plane];
+ struct macroblockd_plane *const pd = &xd->plane[plane];
+#if CONFIG_VP9_HIGHBITDEPTH
+ const int ss_txfrm_size = tx_size << 1;
+ int64_t this_sse;
+ int shift = tx_size == TX_32X32 ? 0 : 2;
+ tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
+#endif
+ unsigned int tmp_sse = 0;
+ tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
+ PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
+ TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
+ const scan_order *const scan_order =
+ get_scan(tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
+
+ BLOCK_SIZE txm_bsize = txsize_to_bsize[tx_size];
+ int bh = 4 * num_4x4_blocks_wide_lookup[txm_bsize];
+ int src_stride = p->src.stride;
+ uint8_t *src = &p->src.buf[4 * blk_row * src_stride + 4 * blk_col];
+ uint8_t *dst = &pd->dst.buf[4 * blk_row * pd->dst.stride + 4 * blk_col];
+ DECLARE_ALIGNED(16, uint8_t, rec_buffer[32 * 32]);
+
+ int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
+ int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
+
+ if (xd->mb_to_bottom_edge < 0)
+ max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
+ if (xd->mb_to_right_edge < 0)
+ max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
+
+ vp10_xform_quant(x, plane, block, blk_row, blk_col, plane_bsize, tx_size);
+
+ vpx_convolve_copy(dst, pd->dst.stride, rec_buffer, 32,
+ NULL, 0, NULL, 0, bh, bh);
+
+ if (blk_row + (bh >> 2) > max_blocks_high ||
+ blk_col + (bh >> 2) > max_blocks_wide) {
+ int idx, idy;
+ unsigned int this_sse;
+ int blocks_height = VPXMIN(bh >> 2, max_blocks_high - blk_row);
+ int blocks_width = VPXMIN(bh >> 2, max_blocks_wide - blk_col);
+ for (idy = 0; idy < blocks_height; idy += 2) {
+ for (idx = 0; idx < blocks_width; idx += 2) {
+ cpi->fn_ptr[BLOCK_8X8].vf(src + 4 * idy * src_stride + 4 * idx,
+ src_stride,
+ rec_buffer + 4 * idy * 32 + 4 * idx,
+ 32, &this_sse);
+ tmp_sse += this_sse;
+ }
+ }
+ } else {
+ cpi->fn_ptr[txm_bsize].vf(src, src_stride, rec_buffer, 32, &tmp_sse);
+ }
+
+#if CONFIG_VP9_HIGHBITDEPTH
+ *dist += vp10_highbd_block_error(coeff, dqcoeff, 16 << ss_txfrm_size,
+ &this_sse, xd->bd) >> shift;
+ *bsse += this_sse >> shift;
+#else
+ *bsse += (int64_t)tmp_sse * 16;
+
+ if (p->eobs[block] > 0) {
+ switch (tx_size) {
+ case TX_32X32:
+ vp10_inv_txfm_add_32x32(dqcoeff, rec_buffer, 32, p->eobs[block],
+ tx_type);
+ break;
+ case TX_16X16:
+ vp10_inv_txfm_add_16x16(dqcoeff, rec_buffer, 32, p->eobs[block],
+ tx_type);
+ break;
+ case TX_8X8:
+ vp10_inv_txfm_add_8x8(dqcoeff, rec_buffer, 32, p->eobs[block],
+ tx_type);
+ break;
+ case TX_4X4:
+ vp10_inv_txfm_add_4x4(dqcoeff, rec_buffer, 32, p->eobs[block],
+ tx_type,
+ xd->lossless[xd->mi[0]->mbmi.segment_id]);
+ break;
+ default:
+ assert(0 && "Invalid transform size");
+ break;
+ }
+
+ if ((bh >> 2) + blk_col > max_blocks_wide ||
+ (bh >> 2) + blk_row > max_blocks_high) {
+ int idx, idy;
+ unsigned int this_sse;
+ int blocks_height = VPXMIN(bh >> 2, max_blocks_high - blk_row);
+ int blocks_width = VPXMIN(bh >> 2, max_blocks_wide - blk_col);
+ tmp_sse = 0;
+ for (idy = 0; idy < blocks_height; idy += 2) {
+ for (idx = 0; idx < blocks_width; idx += 2) {
+ cpi->fn_ptr[BLOCK_8X8].vf(src + 4 * idy * src_stride + 4 * idx,
+ src_stride,
+ rec_buffer + 4 * idy * 32 + 4 * idx,
+ 32, &this_sse);
+ tmp_sse += this_sse;
+ }
+ }
+ } else {
+ cpi->fn_ptr[txm_bsize].vf(src, src_stride,
+ rec_buffer, 32, &tmp_sse);
+ }
+ }
+ *dist += (int64_t)tmp_sse * 16;
+#endif // CONFIG_VP9_HIGHBITDEPTH
+
+ *rate += cost_coeffs(x, plane, block, coeff_ctx, tx_size,
+ scan_order->scan, scan_order->neighbors, 0);
+ *skip &= (p->eobs[block] == 0);
+}
+
+static void select_tx_block(const VP10_COMP *cpi, MACROBLOCK *x,
+ int blk_row, int blk_col, int plane, int block,
+ TX_SIZE tx_size, BLOCK_SIZE plane_bsize,
+ ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
+ TXFM_CONTEXT *tx_above, TXFM_CONTEXT *tx_left,
+ int *rate, int64_t *dist,
+ int64_t *bsse, int *skip,
+ int64_t ref_best_rd, int *is_cost_valid) {
+ MACROBLOCKD *const xd = &x->e_mbd;
+ MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
+ struct macroblock_plane *const p = &x->plane[plane];
+ struct macroblockd_plane *const pd = &xd->plane[plane];
+ int tx_idx = (blk_row >> (1 - pd->subsampling_y)) * 8 +
+ (blk_col >> (1 - pd->subsampling_x));
+ int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
+ int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
+ int64_t this_rd = INT64_MAX;
+ ENTROPY_CONTEXT *pta = ta + blk_col;
+ ENTROPY_CONTEXT *ptl = tl + blk_row;
+ ENTROPY_CONTEXT stxa = 0, stxl = 0;
+ int coeff_ctx, i;
+ int ctx = txfm_partition_context(tx_above + (blk_col >> 1),
+ tx_left + (blk_row >> 1), tx_size);
+
+ int64_t sum_dist = 0, sum_bsse = 0;
+ int64_t sum_rd = INT64_MAX;
+ int sum_rate = vp10_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 1);
+ int all_skip = 1;
+ int tmp_eob = 0;
+ int zero_blk_rate;
+
+ if (ref_best_rd < 0) {
+ *is_cost_valid = 0;
+ return;
+ }
+
+ switch (tx_size) {
+ case TX_4X4:
+ stxa = pta[0];
+ stxl = ptl[0];
+ break;
+ case TX_8X8:
+ stxa = !!*(const uint16_t *)&pta[0];
+ stxl = !!*(const uint16_t *)&ptl[0];
+ break;
+ case TX_16X16:
+ stxa = !!*(const uint32_t *)&pta[0];
+ stxl = !!*(const uint32_t *)&ptl[0];
+ break;
+ case TX_32X32:
+ stxa = !!*(const uint64_t *)&pta[0];
+ stxl = !!*(const uint64_t *)&ptl[0];
+ break;
+ default:
+ assert(0 && "Invalid transform size.");
+ break;
+ }
+ coeff_ctx = combine_entropy_contexts(stxa, stxl);
+
+ if (xd->mb_to_bottom_edge < 0)
+ max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
+ if (xd->mb_to_right_edge < 0)
+ max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
+
+ *rate = 0;
+ *dist = 0;
+ *bsse = 0;
+ *skip = 1;
+
+ if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
+ return;
+
+ zero_blk_rate =
+ x->token_costs[tx_size][pd->plane_type][1][0][0][coeff_ctx][EOB_TOKEN];
+
+ if (cpi->common.tx_mode == TX_MODE_SELECT || tx_size == TX_4X4) {
+ mbmi->inter_tx_size[tx_idx] = tx_size;
+ tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
+ plane_bsize, coeff_ctx, rate, dist, bsse, skip);
+
+ if ((RDCOST(x->rdmult, x->rddiv, *rate, *dist) >=
+ RDCOST(x->rdmult, x->rddiv, zero_blk_rate, *bsse) || *skip == 1) &&
+ !xd->lossless[mbmi->segment_id]) {
+ *rate = zero_blk_rate;
+ *dist = *bsse;
+ *skip = 1;
+ x->blk_skip[plane][blk_row * max_blocks_wide + blk_col] = 1;
+ p->eobs[block] = 0;
+ } else {
+ x->blk_skip[plane][blk_row * max_blocks_wide + blk_col] = 0;
+ *skip = 0;
+ }
+
+ if (tx_size > TX_4X4)
+ *rate += vp10_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 0);
+ this_rd = RDCOST(x->rdmult, x->rddiv, *rate, *dist);
+ tmp_eob = p->eobs[block];
+ }
+
+ if (tx_size > TX_4X4) {
+ BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
+ int bsl = b_height_log2_lookup[bsize];
+ int sub_step = 1 << (2 * (tx_size - 1));
+ int i;
+ int this_rate;
+ int64_t this_dist;
+ int64_t this_bsse;
+ int this_skip;
+ int this_cost_valid = 1;
+ int64_t tmp_rd = 0;
+
+ --bsl;
+ for (i = 0; i < 4 && this_cost_valid; ++i) {
+ int offsetr = (i >> 1) << bsl;
+ int offsetc = (i & 0x01) << bsl;
+ select_tx_block(cpi, x, blk_row + offsetr, blk_col + offsetc,
+ plane, block + i * sub_step, tx_size - 1,
+ plane_bsize, ta, tl, tx_above, tx_left,
+ &this_rate, &this_dist,
+ &this_bsse, &this_skip,
+ ref_best_rd - tmp_rd, &this_cost_valid);
+ sum_rate += this_rate;
+ sum_dist += this_dist;
+ sum_bsse += this_bsse;
+ all_skip &= this_skip;
+ tmp_rd += RDCOST(x->rdmult, x->rddiv, this_rate, this_dist);
+ if (this_rd < tmp_rd)
+ break;
+ }
+ if (this_cost_valid)
+ sum_rd = tmp_rd;
+ }
+
+ if (this_rd < sum_rd) {
+ int idx, idy;
+ for (i = 0; i < (1 << tx_size); ++i)
+ pta[i] = ptl[i] = !(tmp_eob == 0);
+ txfm_partition_update(tx_above + (blk_col >> 1),
+ tx_left + (blk_row >> 1), tx_size);
+ mbmi->inter_tx_size[tx_idx] = tx_size;
+
+ for (idy = 0; idy < (1 << tx_size) / 2; ++idy)
+ for (idx = 0; idx < (1 << tx_size) / 2; ++idx)
+ mbmi->inter_tx_size[tx_idx + (idy << 3) + idx] = tx_size;
+ mbmi->tx_size = tx_size;
+ if (this_rd == INT64_MAX)
+ *is_cost_valid = 0;
+ x->blk_skip[plane][blk_row * max_blocks_wide + blk_col] = *skip;
+ } else {
+ *rate = sum_rate;
+ *dist = sum_dist;
+ *bsse = sum_bsse;
+ *skip = all_skip;
+ if (sum_rd == INT64_MAX)
+ *is_cost_valid = 0;
+ }
+}
+
+static void inter_block_yrd(const VP10_COMP *cpi, MACROBLOCK *x,
+ int *rate, int64_t *distortion, int *skippable,
+ int64_t *sse, BLOCK_SIZE bsize,
+ int64_t ref_best_rd) {
+ MACROBLOCKD *const xd = &x->e_mbd;
+ int is_cost_valid = 1;
+ int64_t this_rd = 0;
+
+ if (ref_best_rd < 0)
+ is_cost_valid = 0;
+
+ *rate = 0;
+ *distortion = 0;
+ *sse = 0;
+ *skippable = 1;
+
+ if (is_cost_valid) {
+ const struct macroblockd_plane *const pd = &xd->plane[0];
+ const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
+ const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
+ const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
+ BLOCK_SIZE txb_size = txsize_to_bsize[max_txsize_lookup[plane_bsize]];
+ int bh = num_4x4_blocks_wide_lookup[txb_size];
+ int idx, idy;
+ int block = 0;
+ int step = 1 << (max_txsize_lookup[plane_bsize] * 2);
+ ENTROPY_CONTEXT ctxa[16], ctxl[16];
+ TXFM_CONTEXT tx_above[8], tx_left[8];
+
+ int pnrate = 0, pnskip = 1;
+ int64_t pndist = 0, pnsse = 0;
+
+ vp10_get_entropy_contexts(bsize, TX_4X4, pd, ctxa, ctxl);
+ memcpy(tx_above, xd->above_txfm_context,
+ sizeof(TXFM_CONTEXT) * (mi_width >> 1));
+ memcpy(tx_left, xd->left_txfm_context,
+ sizeof(TXFM_CONTEXT) * (mi_height >> 1));
+
+ for (idy = 0; idy < mi_height; idy += bh) {
+ for (idx = 0; idx < mi_width; idx += bh) {
+ select_tx_block(cpi, x, idy, idx, 0, block,
+ max_txsize_lookup[plane_bsize], plane_bsize,
+ ctxa, ctxl, tx_above, tx_left,
+ &pnrate, &pndist, &pnsse, &pnskip,
+ ref_best_rd - this_rd, &is_cost_valid);
+ *rate += pnrate;
+ *distortion += pndist;
+ *sse += pnsse;
+ *skippable &= pnskip;
+ this_rd += VPXMIN(RDCOST(x->rdmult, x->rddiv, pnrate, pndist),
+ RDCOST(x->rdmult, x->rddiv, 0, pnsse));
+ block += step;
+ }
+ }
+ }
+
+ this_rd = VPXMIN(RDCOST(x->rdmult, x->rddiv, *rate, *distortion),
+ RDCOST(x->rdmult, x->rddiv, 0, *sse));
+ if (this_rd > ref_best_rd)
+ is_cost_valid = 0;
+
+ if (!is_cost_valid) {
+ // reset cost value
+ *rate = INT_MAX;
+ *distortion = INT64_MAX;
+ *sse = INT64_MAX;
+ *skippable = 0;
+ }
+}
+
+#if CONFIG_EXT_TX
+static void select_tx_type_yrd(const VP10_COMP *cpi, MACROBLOCK *x,
+ int *rate, int64_t *distortion, int *skippable,
+ int64_t *sse, BLOCK_SIZE bsize,
+ int64_t ref_best_rd) {
+ const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
+ const VP10_COMMON *const cm = &cpi->common;
+ MACROBLOCKD *const xd = &x->e_mbd;
+ MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
+ int64_t rd = INT64_MAX;
+ int64_t best_rd = INT64_MAX;
+ TX_TYPE tx_type, best_tx_type = DCT_DCT;
+ int ext_tx_set;
+ const int is_inter = is_inter_block(mbmi);
+ vpx_prob skip_prob = vp10_get_skip_prob(cm, xd);
+ int s0 = vp10_cost_bit(skip_prob, 0);
+ int s1 = vp10_cost_bit(skip_prob, 1);
+ TX_SIZE best_tx_size[64];
+ TX_SIZE best_tx = TX_SIZES;
+ uint8_t best_blk_skip[256];
+ const int n4 = 1 << (num_pels_log2_lookup[bsize] - 4);
+ int idx, idy;
+
+ *distortion = INT64_MAX;
+ *rate = INT_MAX;
+ *skippable = 0;
+ *sse = INT64_MAX;
+
+ ext_tx_set = get_ext_tx_set(max_tx_size, bsize, is_inter);
+
+ for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
+ int this_rate = 0;
+ int this_skip = 1;
+ int64_t this_dist = 0;
+ int64_t this_sse = 0;
+
+ if (is_inter) {
+ if (!ext_tx_used_inter[ext_tx_set][tx_type])
+ continue;
+ } else {
+ if (!ALLOW_INTRA_EXT_TX && bsize >= BLOCK_8X8) {
+ if (tx_type != intra_mode_to_tx_type_lookup[mbmi->mode])
+ continue;
+ }
+ if (!ext_tx_used_intra[ext_tx_set][tx_type])
+ continue;
+ }
+
+ mbmi->tx_type = tx_type;
+
+ if (ext_tx_set == 1 &&
+ mbmi->tx_type >= DST_ADST && mbmi->tx_type < IDTX &&
+ best_tx_type == DCT_DCT) {
+ tx_type = IDTX - 1;
+ break;
+ }
+
+ inter_block_yrd(cpi, x, &this_rate, &this_dist, &this_skip, &this_sse,
+ bsize, ref_best_rd);
+
+ if (get_ext_tx_types(max_tx_size, bsize, is_inter) > 1 &&
+ !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
+ this_rate != INT_MAX) {
+ if (is_inter) {
+ if (ext_tx_set > 0)
+ this_rate += cpi->inter_tx_type_costs[ext_tx_set]
+ [max_tx_size][mbmi->tx_type];
+ } else {
+ if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
+ this_rate += cpi->intra_tx_type_costs[ext_tx_set][max_tx_size]
+ [mbmi->mode][mbmi->tx_type];
+ }
+ }
+
+ if (this_rate == INT_MAX)
+ continue;
+
+ if (this_skip)
+ rd = RDCOST(x->rdmult, x->rddiv, s1, this_sse);
+ else
+ rd = RDCOST(x->rdmult, x->rddiv, this_rate + s0, this_dist);
+
+ if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] && !this_skip)
+ rd = VPXMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, this_sse));
+
+ if (rd <
+ (is_inter && best_tx_type == DCT_DCT ? ext_tx_th : 1) *
+ best_rd) {
+ best_rd = rd;
+ *distortion = this_dist;
+ *rate = this_rate;
+ *skippable = this_skip;
+ *sse = this_sse;
+ best_tx_type = mbmi->tx_type;
+ best_tx = mbmi->tx_size;
+ memcpy(best_blk_skip, x->blk_skip[0], sizeof(best_blk_skip[0]) * n4);
+ for (idy = 0; idy < xd->n8_h; ++idy)
+ for (idx = 0; idx < xd->n8_w; ++idx)
+ best_tx_size[idy * 8 + idx] = mbmi->inter_tx_size[idy * 8 + idx];
+ }
+ }
+
+ mbmi->tx_type = best_tx_type;
+ for (idy = 0; idy < xd->n8_h; ++idy)
+ for (idx = 0; idx < xd->n8_w; ++idx)
+ mbmi->inter_tx_size[idy * 8 + idx] = best_tx_size[idy * 8 + idx];
+ mbmi->tx_size = best_tx;
+ memcpy(x->blk_skip[0], best_blk_skip, sizeof(best_blk_skip[0]) * n4);
+}
+#endif
+
+static void tx_block_rd(const VP10_COMP *cpi, MACROBLOCK *x,
+ int blk_row, int blk_col, int plane, int block,
+ TX_SIZE tx_size, BLOCK_SIZE plane_bsize,
+ ENTROPY_CONTEXT *above_ctx, ENTROPY_CONTEXT *left_ctx,
+ int *rate, int64_t *dist, int64_t *bsse, int *skip) {
+ MACROBLOCKD *const xd = &x->e_mbd;
+ MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
+ struct macroblock_plane *const p = &x->plane[plane];
+ struct macroblockd_plane *const pd = &xd->plane[plane];
+ BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
+ int tx_idx = (blk_row >> (1 - pd->subsampling_y)) * 8 +
+ (blk_col >> (1 - pd->subsampling_x));
+ TX_SIZE plane_tx_size = plane ?
+ get_uv_tx_size_impl(mbmi->inter_tx_size[tx_idx], bsize,
+ 0, 0) :
+ mbmi->inter_tx_size[tx_idx];
+
+ int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
+ int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
+
+ if (xd->mb_to_bottom_edge < 0)
+ max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
+ if (xd->mb_to_right_edge < 0)
+ max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
+
+ if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
+ return;
+
+ if (tx_size == plane_tx_size) {
+ int coeff_ctx, i;
+ ENTROPY_CONTEXT *ta = above_ctx + blk_col;
+ ENTROPY_CONTEXT *tl = left_ctx + blk_row;
+ switch (tx_size) {
+ case TX_4X4:
+ break;
+ case TX_8X8:
+ ta[0] = !!*(const uint16_t *)&ta[0];
+ tl[0] = !!*(const uint16_t *)&tl[0];
+ break;
+ case TX_16X16:
+ ta[0] = !!*(const uint32_t *)&ta[0];
+ tl[0] = !!*(const uint32_t *)&tl[0];
+ break;
+ case TX_32X32:
+ ta[0] = !!*(const uint64_t *)&ta[0];
+ tl[0] = !!*(const uint64_t *)&tl[0];
+ break;
+ default:
+ assert(0 && "Invalid transform size.");
+ break;
+ }
+ coeff_ctx = combine_entropy_contexts(ta[0], tl[0]);
+ tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
+ plane_bsize, coeff_ctx, rate, dist, bsse, skip);
+ for (i = 0; i < (1 << tx_size); ++i) {
+ ta[i] = !(p->eobs[block] == 0);
+ tl[i] = !(p->eobs[block] == 0);
+ }
+ } else {
+ int bsl = b_width_log2_lookup[bsize];
+ int step = 1 << (2 * (tx_size - 1));
+ int i;
+
+ assert(bsl > 0);
+ --bsl;
+
+ for (i = 0; i < 4; ++i) {
+ int offsetr = (i >> 1) << bsl;
+ int offsetc = (i & 0x01) << bsl;
+ tx_block_rd(cpi, x, blk_row + offsetr, blk_col + offsetc, plane,
+ block + i * step, tx_size - 1, plane_bsize,
+ above_ctx, left_ctx, rate, dist, bsse, skip);
+ }
+ }
}
-// This function is used only for intra_only frames
-static int64_t rd_pick_intra_sby_mode(VP10_COMP *cpi, MACROBLOCK *x,
- int *rate, int *rate_tokenonly,
- int64_t *distortion, int *skippable,
- BLOCK_SIZE bsize,
- int64_t best_rd) {
- PREDICTION_MODE mode;
- PREDICTION_MODE mode_selected = DC_PRED;
+// Return value 0: early termination triggered, no valid rd cost available;
+// 1: rd cost values are valid.
+static int inter_block_uvrd(const VP10_COMP *cpi, MACROBLOCK *x,
+ int *rate, int64_t *distortion, int *skippable,
+ int64_t *sse, BLOCK_SIZE bsize,
+ int64_t ref_best_rd) {
MACROBLOCKD *const xd = &x->e_mbd;
- MODE_INFO *const mic = xd->mi[0];
- int this_rate, this_rate_tokenonly, s;
- int64_t this_distortion, this_rd;
- TX_SIZE best_tx = TX_4X4;
- int *bmode_costs;
- const MODE_INFO *above_mi = xd->above_mi;
- const MODE_INFO *left_mi = xd->left_mi;
- const PREDICTION_MODE A = vp10_above_block_mode(mic, above_mi, 0);
- const PREDICTION_MODE L = vp10_left_block_mode(mic, left_mi, 0);
- bmode_costs = cpi->y_mode_costs[A][L];
+ MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
+ int plane;
+ int is_cost_valid = 1;
+ int64_t this_rd;
- memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
+ if (ref_best_rd < 0)
+ is_cost_valid = 0;
- /* Y Search for intra prediction mode */
- for (mode = DC_PRED; mode <= TM_PRED; mode++) {
- mic->mbmi.mode = mode;
+ if (is_inter_block(mbmi) && is_cost_valid) {
+ int plane;
+ for (plane = 1; plane < MAX_MB_PLANE; ++plane)
+ vp10_subtract_plane(x, bsize, plane);
+ }
- super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
- &s, NULL, bsize, best_rd);
+ *rate = 0;
+ *distortion = 0;
+ *sse = 0;
+ *skippable = 1;
- if (this_rate_tokenonly == INT_MAX)
- continue;
+ for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
+ const struct macroblockd_plane *const pd = &xd->plane[plane];
+ const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
+ const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
+ const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
+ BLOCK_SIZE txb_size = txsize_to_bsize[max_txsize_lookup[plane_bsize]];
+ int bh = num_4x4_blocks_wide_lookup[txb_size];
+ int idx, idy;
+ int block = 0;
+ int step = 1 << (max_txsize_lookup[plane_bsize] * 2);
+ int pnrate = 0, pnskip = 1;
+ int64_t pndist = 0, pnsse = 0;
+ ENTROPY_CONTEXT ta[16], tl[16];
+
+ vp10_get_entropy_contexts(bsize, TX_4X4, pd, ta, tl);
+
+ for (idy = 0; idy < mi_height; idy += bh) {
+ for (idx = 0; idx < mi_width; idx += bh) {
+ tx_block_rd(cpi, x, idy, idx, plane, block,
+ max_txsize_lookup[plane_bsize], plane_bsize, ta, tl,
+ &pnrate, &pndist, &pnsse, &pnskip);
+ block += step;
+ }
+ }
- this_rate = this_rate_tokenonly + bmode_costs[mode];
- this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
+ if (pnrate == INT_MAX) {
+ is_cost_valid = 0;
+ break;
+ }
- if (this_rd < best_rd) {
- mode_selected = mode;
- best_rd = this_rd;
- best_tx = mic->mbmi.tx_size;
- *rate = this_rate;
- *rate_tokenonly = this_rate_tokenonly;
- *distortion = this_distortion;
- *skippable = s;
+ *rate += pnrate;
+ *distortion += pndist;
+ *sse += pnsse;
+ *skippable &= pnskip;
+
+ this_rd = VPXMIN(RDCOST(x->rdmult, x->rddiv, *rate, *distortion),
+ RDCOST(x->rdmult, x->rddiv, 0, *sse));
+
+ if (this_rd > ref_best_rd) {
+ is_cost_valid = 0;
+ break;
}
}
int64_t best_rd = INT64_MAX, this_rd;
int this_rate_tokenonly, this_rate, s;
int64_t this_distortion, this_sse;
+#if CONFIG_EXT_INTRA
+ int is_directional_mode, rate_overhead, best_angle_delta = 0;
+ EXT_INTRA_MODE_INFO ext_intra_mode_info;
+ ext_intra_mode_info.use_ext_intra_mode[1] = 0;
+ mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
+#endif // CONFIG_EXT_INTRA
memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
- xd->mi[0]->mbmi.palette_mode_info.palette_size[1] = 0;
for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
if (!(cpi->sf.intra_uv_mode_mask[max_tx_size] & (1 << mode)))
continue;
assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
- mbmi->palette_mode_info.palette_size[0] = 0;
- mbmi->palette_mode_info.palette_size[1] = 0;
+#if CONFIG_EXT_INTRA
+ mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
+ mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
+#endif // CONFIG_EXT_INTRA
mbmi->mode = ZEROMV;
mbmi->uv_mode = DC_PRED;
mbmi->ref_frame[0] = LAST_FRAME;