1 /*
2 * Copyright (c) 2014 The WebM project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include <assert.h>
12 #include <limits.h>
13 #include <math.h>
14 #include <stdio.h>
15
16 #include "./vp9_rtcd.h"
17
18 #include "vpx_mem/vpx_mem.h"
19
20 #include "vp9/common/vp9_common.h"
21 #include "vp9/common/vp9_mvref_common.h"
22 #include "vp9/common/vp9_reconinter.h"
23 #include "vp9/common/vp9_reconintra.h"
24
25 #include "vp9/encoder/vp9_onyx_int.h"
26 #include "vp9/encoder/vp9_ratectrl.h"
27 #include "vp9/encoder/vp9_rdopt.h"
28
full_pixel_motion_search(VP9_COMP * cpi,MACROBLOCK * x,const TileInfo * const tile,BLOCK_SIZE bsize,int mi_row,int mi_col,int_mv * tmp_mv)29 static void full_pixel_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
30 const TileInfo *const tile,
31 BLOCK_SIZE bsize, int mi_row, int mi_col,
32 int_mv *tmp_mv) {
33 MACROBLOCKD *xd = &x->e_mbd;
34 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
35 struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}};
36 int step_param;
37 int sadpb = x->sadperbit16;
38 MV mvp_full;
39 int ref = mbmi->ref_frame[0];
40 const MV ref_mv = mbmi->ref_mvs[ref][0].as_mv;
41 int i;
42
43 int tmp_col_min = x->mv_col_min;
44 int tmp_col_max = x->mv_col_max;
45 int tmp_row_min = x->mv_row_min;
46 int tmp_row_max = x->mv_row_max;
47
48 const YV12_BUFFER_CONFIG *scaled_ref_frame = vp9_get_scaled_ref_frame(cpi,
49 ref);
50 if (scaled_ref_frame) {
51 int i;
52 // Swap out the reference frame for a version that's been scaled to
53 // match the resolution of the current frame, allowing the existing
54 // motion search code to be used without additional modifications.
55 for (i = 0; i < MAX_MB_PLANE; i++)
56 backup_yv12[i] = xd->plane[i].pre[0];
57
58 vp9_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
59 }
60
61 vp9_set_mv_search_range(x, &ref_mv);
62
63 // TODO(jingning) exploiting adaptive motion search control in non-RD
64 // mode decision too.
65 step_param = 6;
66
67 for (i = LAST_FRAME; i <= LAST_FRAME && cpi->common.show_frame; ++i) {
68 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
69 tmp_mv->as_int = INVALID_MV;
70
71 if (scaled_ref_frame) {
72 int i;
73 for (i = 0; i < MAX_MB_PLANE; i++)
74 xd->plane[i].pre[0] = backup_yv12[i];
75 }
76 return;
77 }
78 }
79 assert(x->mv_best_ref_index[ref] <= 2);
80 if (x->mv_best_ref_index[ref] < 2)
81 mvp_full = mbmi->ref_mvs[ref][x->mv_best_ref_index[ref]].as_mv;
82 else
83 mvp_full = x->pred_mv[ref].as_mv;
84
85 mvp_full.col >>= 3;
86 mvp_full.row >>= 3;
87
88 if (cpi->sf.search_method == FAST_DIAMOND) {
89 // NOTE: this returns SAD
90 vp9_fast_dia_search(x, &mvp_full, step_param, sadpb, 0,
91 &cpi->fn_ptr[bsize], 1,
92 &ref_mv, &tmp_mv->as_mv);
93 } else if (cpi->sf.search_method == FAST_HEX) {
94 // NOTE: this returns SAD
95 vp9_fast_hex_search(x, &mvp_full, step_param, sadpb, 0,
96 &cpi->fn_ptr[bsize], 1,
97 &ref_mv, &tmp_mv->as_mv);
98 } else if (cpi->sf.search_method == HEX) {
99 // NOTE: this returns SAD
100 vp9_hex_search(x, &mvp_full, step_param, sadpb, 1,
101 &cpi->fn_ptr[bsize], 1,
102 &ref_mv, &tmp_mv->as_mv);
103 } else if (cpi->sf.search_method == SQUARE) {
104 // NOTE: this returns SAD
105 vp9_square_search(x, &mvp_full, step_param, sadpb, 1,
106 &cpi->fn_ptr[bsize], 1,
107 &ref_mv, &tmp_mv->as_mv);
108 } else if (cpi->sf.search_method == BIGDIA) {
109 // NOTE: this returns SAD
110 vp9_bigdia_search(x, &mvp_full, step_param, sadpb, 1,
111 &cpi->fn_ptr[bsize], 1,
112 &ref_mv, &tmp_mv->as_mv);
113 } else {
114 int further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
115 // NOTE: this returns variance
116 vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
117 sadpb, further_steps, 1,
118 &cpi->fn_ptr[bsize],
119 &ref_mv, &tmp_mv->as_mv);
120 }
121 x->mv_col_min = tmp_col_min;
122 x->mv_col_max = tmp_col_max;
123 x->mv_row_min = tmp_row_min;
124 x->mv_row_max = tmp_row_max;
125
126 if (scaled_ref_frame) {
127 int i;
128 for (i = 0; i < MAX_MB_PLANE; i++)
129 xd->plane[i].pre[0] = backup_yv12[i];
130 }
131 }
132
sub_pixel_motion_search(VP9_COMP * cpi,MACROBLOCK * x,const TileInfo * const tile,BLOCK_SIZE bsize,int mi_row,int mi_col,MV * tmp_mv,int * rate_mv)133 static void sub_pixel_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
134 const TileInfo *const tile,
135 BLOCK_SIZE bsize, int mi_row, int mi_col,
136 MV *tmp_mv, int *rate_mv) {
137 MACROBLOCKD *xd = &x->e_mbd;
138 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
139 struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}};
140 int ref = mbmi->ref_frame[0];
141 MV ref_mv = mbmi->ref_mvs[ref][0].as_mv;
142 int dis;
143
144 const YV12_BUFFER_CONFIG *scaled_ref_frame = vp9_get_scaled_ref_frame(cpi,
145 ref);
146 if (scaled_ref_frame) {
147 int i;
148 // Swap out the reference frame for a version that's been scaled to
149 // match the resolution of the current frame, allowing the existing
150 // motion search code to be used without additional modifications.
151 for (i = 0; i < MAX_MB_PLANE; i++)
152 backup_yv12[i] = xd->plane[i].pre[0];
153
154 vp9_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
155 }
156
157 cpi->find_fractional_mv_step(x, tmp_mv, &ref_mv,
158 cpi->common.allow_high_precision_mv,
159 x->errorperbit,
160 &cpi->fn_ptr[bsize],
161 cpi->sf.subpel_force_stop,
162 cpi->sf.subpel_iters_per_step,
163 x->nmvjointcost, x->mvcost,
164 &dis, &x->pred_sse[ref]);
165
166 // calculate the bit cost on motion vector
167 *rate_mv = vp9_mv_bit_cost(tmp_mv, &ref_mv,
168 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
169
170 if (scaled_ref_frame) {
171 int i;
172 for (i = 0; i < MAX_MB_PLANE; i++)
173 xd->plane[i].pre[0] = backup_yv12[i];
174 }
175
176 x->pred_mv[ref].as_mv = *tmp_mv;
177 }
178
model_rd_for_sb_y(VP9_COMP * cpi,BLOCK_SIZE bsize,MACROBLOCK * x,MACROBLOCKD * xd,int * out_rate_sum,int64_t * out_dist_sum)179 static void model_rd_for_sb_y(VP9_COMP *cpi, BLOCK_SIZE bsize,
180 MACROBLOCK *x, MACROBLOCKD *xd,
181 int *out_rate_sum, int64_t *out_dist_sum) {
182 // Note our transform coeffs are 8 times an orthogonal transform.
183 // Hence quantizer step is also 8 times. To get effective quantizer
184 // we need to divide by 8 before sending to modeling function.
185 unsigned int sse;
186 int rate;
187 int64_t dist;
188
189 struct macroblock_plane *const p = &x->plane[0];
190 struct macroblockd_plane *const pd = &xd->plane[0];
191
192 int var = cpi->fn_ptr[bsize].vf(p->src.buf, p->src.stride,
193 pd->dst.buf, pd->dst.stride, &sse);
194
195 vp9_model_rd_from_var_lapndz(sse + var, 1 << num_pels_log2_lookup[bsize],
196 pd->dequant[1] >> 3, &rate, &dist);
197 *out_rate_sum = rate;
198 *out_dist_sum = dist << 3;
199 }
200
201 // TODO(jingning) placeholder for inter-frame non-RD mode decision.
202 // this needs various further optimizations. to be continued..
vp9_pick_inter_mode(VP9_COMP * cpi,MACROBLOCK * x,const TileInfo * const tile,int mi_row,int mi_col,int * returnrate,int64_t * returndistortion,BLOCK_SIZE bsize)203 int64_t vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
204 const TileInfo *const tile,
205 int mi_row, int mi_col,
206 int *returnrate,
207 int64_t *returndistortion,
208 BLOCK_SIZE bsize) {
209 MACROBLOCKD *xd = &x->e_mbd;
210 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
211 struct macroblock_plane *const p = &x->plane[0];
212 struct macroblockd_plane *const pd = &xd->plane[0];
213 MB_PREDICTION_MODE this_mode, best_mode = ZEROMV;
214 MV_REFERENCE_FRAME ref_frame, best_ref_frame = LAST_FRAME;
215 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
216 struct buf_2d yv12_mb[4][MAX_MB_PLANE];
217 static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
218 VP9_ALT_FLAG };
219 int64_t best_rd = INT64_MAX;
220 int64_t this_rd = INT64_MAX;
221
222 int rate = INT_MAX;
223 int64_t dist = INT64_MAX;
224
225 VP9_COMMON *cm = &cpi->common;
226 int intra_cost_penalty = 20 * vp9_dc_quant(cm->base_qindex, cm->y_dc_delta_q);
227
228 const int64_t inter_mode_thresh = RDCOST(x->rdmult, x->rddiv,
229 intra_cost_penalty, 0);
230 const int64_t intra_mode_cost = 50;
231
232 unsigned char segment_id = mbmi->segment_id;
233 const int *const rd_threshes = cpi->rd_threshes[segment_id][bsize];
234 const int *const rd_thresh_freq_fact = cpi->rd_thresh_freq_fact[bsize];
235 // Mode index conversion form THR_MODES to MB_PREDICTION_MODE for a ref frame.
236 int mode_idx[MB_MODE_COUNT] = {0};
237
238 x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
239
240 x->skip = 0;
241 if (!x->in_active_map)
242 x->skip = 1;
243 // initialize mode decisions
244 *returnrate = INT_MAX;
245 *returndistortion = INT64_MAX;
246 vpx_memset(mbmi, 0, sizeof(MB_MODE_INFO));
247 mbmi->sb_type = bsize;
248 mbmi->ref_frame[0] = NONE;
249 mbmi->ref_frame[1] = NONE;
250 mbmi->tx_size = MIN(max_txsize_lookup[bsize],
251 tx_mode_to_biggest_tx_size[cpi->common.tx_mode]);
252 mbmi->interp_filter = cpi->common.interp_filter == SWITCHABLE ?
253 EIGHTTAP : cpi->common.interp_filter;
254 mbmi->skip = 0;
255 mbmi->segment_id = segment_id;
256
257 for (ref_frame = LAST_FRAME; ref_frame <= LAST_FRAME ; ++ref_frame) {
258 x->pred_mv_sad[ref_frame] = INT_MAX;
259 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
260 vp9_setup_buffer_inter(cpi, x, tile,
261 ref_frame, bsize, mi_row, mi_col,
262 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
263 }
264 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
265 frame_mv[ZEROMV][ref_frame].as_int = 0;
266 }
267
268 for (ref_frame = LAST_FRAME; ref_frame <= LAST_FRAME ; ++ref_frame) {
269 if (!(cpi->ref_frame_flags & flag_list[ref_frame]))
270 continue;
271
272 // Select prediction reference frames.
273 xd->plane[0].pre[0] = yv12_mb[ref_frame][0];
274
275 clamp_mv2(&frame_mv[NEARESTMV][ref_frame].as_mv, xd);
276 clamp_mv2(&frame_mv[NEARMV][ref_frame].as_mv, xd);
277
278 mbmi->ref_frame[0] = ref_frame;
279
280 // Set conversion index for LAST_FRAME.
281 if (ref_frame == LAST_FRAME) {
282 mode_idx[NEARESTMV] = THR_NEARESTMV; // LAST_FRAME, NEARESTMV
283 mode_idx[NEARMV] = THR_NEARMV; // LAST_FRAME, NEARMV
284 mode_idx[ZEROMV] = THR_ZEROMV; // LAST_FRAME, ZEROMV
285 mode_idx[NEWMV] = THR_NEWMV; // LAST_FRAME, NEWMV
286 }
287
288 for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
289 int rate_mv = 0;
290
291 if (cpi->sf.disable_inter_mode_mask[bsize] &
292 (1 << INTER_OFFSET(this_mode)))
293 continue;
294
295 if (best_rd < ((int64_t)rd_threshes[mode_idx[this_mode]] *
296 rd_thresh_freq_fact[this_mode] >> 5) ||
297 rd_threshes[mode_idx[this_mode]] == INT_MAX)
298 continue;
299
300 if (this_mode == NEWMV) {
301 if (this_rd < (int64_t)(1 << num_pels_log2_lookup[bsize]))
302 continue;
303
304 full_pixel_motion_search(cpi, x, tile, bsize, mi_row, mi_col,
305 &frame_mv[NEWMV][ref_frame]);
306
307 if (frame_mv[NEWMV][ref_frame].as_int == INVALID_MV)
308 continue;
309
310 sub_pixel_motion_search(cpi, x, tile, bsize, mi_row, mi_col,
311 &frame_mv[NEWMV][ref_frame].as_mv, &rate_mv);
312 }
313
314 if (this_mode != NEARESTMV)
315 if (frame_mv[this_mode][ref_frame].as_int ==
316 frame_mv[NEARESTMV][ref_frame].as_int)
317 continue;
318
319 mbmi->mode = this_mode;
320 mbmi->mv[0].as_int = frame_mv[this_mode][ref_frame].as_int;
321 vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
322
323 model_rd_for_sb_y(cpi, bsize, x, xd, &rate, &dist);
324 rate += rate_mv;
325 rate += x->inter_mode_cost[mbmi->mode_context[ref_frame]]
326 [INTER_OFFSET(this_mode)];
327 this_rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
328
329 if (this_rd < best_rd) {
330 best_rd = this_rd;
331 *returnrate = rate;
332 *returndistortion = dist;
333 best_mode = this_mode;
334 best_ref_frame = ref_frame;
335 }
336 }
337 }
338
339 mbmi->mode = best_mode;
340 mbmi->ref_frame[0] = best_ref_frame;
341 mbmi->mv[0].as_int = frame_mv[best_mode][best_ref_frame].as_int;
342 xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
343
344 // Perform intra prediction search, if the best SAD is above a certain
345 // threshold.
346 if (best_rd > inter_mode_thresh) {
347 for (this_mode = DC_PRED; this_mode <= DC_PRED; ++this_mode) {
348 vp9_predict_intra_block(xd, 0, b_width_log2(bsize),
349 mbmi->tx_size, this_mode,
350 &p->src.buf[0], p->src.stride,
351 &pd->dst.buf[0], pd->dst.stride, 0, 0, 0);
352
353 model_rd_for_sb_y(cpi, bsize, x, xd, &rate, &dist);
354 rate += x->mbmode_cost[this_mode];
355 rate += intra_cost_penalty;
356 this_rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
357
358 if (this_rd + intra_mode_cost < best_rd) {
359 best_rd = this_rd;
360 *returnrate = rate;
361 *returndistortion = dist;
362 mbmi->mode = this_mode;
363 mbmi->ref_frame[0] = INTRA_FRAME;
364 mbmi->uv_mode = this_mode;
365 mbmi->mv[0].as_int = INVALID_MV;
366 }
367 }
368 }
369
370 return INT64_MAX;
371 }
372