]> granicus.if.org Git - libvpx/blob - vp9/encoder/vp9_pickmode.c
6115f5a0f1dd9e83effb9c65d48bacb64c1c62c5
[libvpx] / vp9 / encoder / vp9_pickmode.c
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_encoder.h"
26 #include "vp9/encoder/vp9_pickmode.h"
27 #include "vp9/encoder/vp9_ratectrl.h"
28 #include "vp9/encoder/vp9_rd.h"
29
30 static int mv_refs_rt(const VP9_COMMON *cm, const MACROBLOCKD *xd,
31                        const TileInfo *const tile,
32                        MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
33                        int_mv *mv_ref_list,
34                        int mi_row, int mi_col) {
35   const int *ref_sign_bias = cm->ref_frame_sign_bias;
36   int i, refmv_count = 0;
37
38   const POSITION *const mv_ref_search = mv_ref_blocks[mi->mbmi.sb_type];
39
40   int different_ref_found = 0;
41   int context_counter = 0;
42   int const_motion = 0;
43
44   // Blank the reference vector list
45   vpx_memset(mv_ref_list, 0, sizeof(*mv_ref_list) * MAX_MV_REF_CANDIDATES);
46
47   // The nearest 2 blocks are treated differently
48   // if the size < 8x8 we get the mv from the bmi substructure,
49   // and we also need to keep a mode count.
50   for (i = 0; i < 2; ++i) {
51     const POSITION *const mv_ref = &mv_ref_search[i];
52     if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) {
53       const MODE_INFO *const candidate_mi = xd->mi[mv_ref->col + mv_ref->row *
54                                                    xd->mi_stride];
55       const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
56       // Keep counts for entropy encoding.
57       context_counter += mode_2_counter[candidate->mode];
58       different_ref_found = 1;
59
60       if (candidate->ref_frame[0] == ref_frame)
61         ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 0, mv_ref->col, -1));
62     }
63   }
64
65   const_motion = 1;
66
67   // Check the rest of the neighbors in much the same way
68   // as before except we don't need to keep track of sub blocks or
69   // mode counts.
70   for (; i < MVREF_NEIGHBOURS && !refmv_count; ++i) {
71     const POSITION *const mv_ref = &mv_ref_search[i];
72     if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) {
73       const MB_MODE_INFO *const candidate = &xd->mi[mv_ref->col + mv_ref->row *
74                                                     xd->mi_stride]->mbmi;
75       different_ref_found = 1;
76
77       if (candidate->ref_frame[0] == ref_frame)
78         ADD_MV_REF_LIST(candidate->mv[0]);
79     }
80   }
81
82   // Since we couldn't find 2 mvs from the same reference frame
83   // go back through the neighbors and find motion vectors from
84   // different reference frames.
85   if (different_ref_found && !refmv_count) {
86     for (i = 0; i < MVREF_NEIGHBOURS; ++i) {
87       const POSITION *mv_ref = &mv_ref_search[i];
88       if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) {
89         const MB_MODE_INFO *const candidate = &xd->mi[mv_ref->col + mv_ref->row
90                                               * xd->mi_stride]->mbmi;
91
92         // If the candidate is INTRA we don't want to consider its mv.
93         IF_DIFF_REF_FRAME_ADD_MV(candidate);
94       }
95     }
96   }
97
98  Done:
99
100   mi->mbmi.mode_context[ref_frame] = counter_to_context[context_counter];
101
102   // Clamp vectors
103   for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i)
104     clamp_mv_ref(&mv_ref_list[i].as_mv, xd);
105
106   return const_motion;
107 }
108
109 static int combined_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
110                                   BLOCK_SIZE bsize, int mi_row, int mi_col,
111                                   int_mv *tmp_mv, int *rate_mv,
112                                   int64_t best_rd_sofar) {
113   MACROBLOCKD *xd = &x->e_mbd;
114   MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
115   struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0, 0}};
116   const int step_param = cpi->sf.mv.fullpel_search_step_param;
117   const int sadpb = x->sadperbit16;
118   MV mvp_full;
119   const int ref = mbmi->ref_frame[0];
120   const MV ref_mv = mbmi->ref_mvs[ref][0].as_mv;
121   int dis;
122   int rate_mode;
123   const int tmp_col_min = x->mv_col_min;
124   const int tmp_col_max = x->mv_col_max;
125   const int tmp_row_min = x->mv_row_min;
126   const int tmp_row_max = x->mv_row_max;
127   int rv = 0;
128   const YV12_BUFFER_CONFIG *scaled_ref_frame = vp9_get_scaled_ref_frame(cpi,
129                                                                         ref);
130   if (cpi->common.show_frame &&
131       (x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[LAST_FRAME])
132     return rv;
133
134   if (scaled_ref_frame) {
135     int i;
136     // Swap out the reference frame for a version that's been scaled to
137     // match the resolution of the current frame, allowing the existing
138     // motion search code to be used without additional modifications.
139     for (i = 0; i < MAX_MB_PLANE; i++)
140       backup_yv12[i] = xd->plane[i].pre[0];
141     vp9_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
142   }
143   vp9_set_mv_search_range(x, &ref_mv);
144
145   assert(x->mv_best_ref_index[ref] <= 2);
146   if (x->mv_best_ref_index[ref] < 2)
147     mvp_full = mbmi->ref_mvs[ref][x->mv_best_ref_index[ref]].as_mv;
148   else
149     mvp_full = x->pred_mv[ref];
150
151   mvp_full.col >>= 3;
152   mvp_full.row >>= 3;
153
154   vp9_full_pixel_search(cpi, x, bsize, &mvp_full, step_param, sadpb, &ref_mv,
155                         &tmp_mv->as_mv, INT_MAX, 0);
156
157   x->mv_col_min = tmp_col_min;
158   x->mv_col_max = tmp_col_max;
159   x->mv_row_min = tmp_row_min;
160   x->mv_row_max = tmp_row_max;
161
162   // calculate the bit cost on motion vector
163   mvp_full.row = tmp_mv->as_mv.row * 8;
164   mvp_full.col = tmp_mv->as_mv.col * 8;
165
166   *rate_mv = vp9_mv_bit_cost(&mvp_full, &ref_mv,
167                              x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
168
169   rate_mode = cpi->inter_mode_cost[mbmi->mode_context[ref]]
170                                   [INTER_OFFSET(NEWMV)];
171   rv = !(RDCOST(x->rdmult, x->rddiv, (*rate_mv + rate_mode), 0) >
172          best_rd_sofar);
173
174   if (rv) {
175     cpi->find_fractional_mv_step(x, &tmp_mv->as_mv, &ref_mv,
176                                  cpi->common.allow_high_precision_mv,
177                                  x->errorperbit,
178                                  &cpi->fn_ptr[bsize],
179                                  cpi->sf.mv.subpel_force_stop,
180                                  cpi->sf.mv.subpel_iters_per_step,
181                                  x->nmvjointcost, x->mvcost,
182                                  &dis, &x->pred_sse[ref], NULL, 0, 0);
183     x->pred_mv[ref] = tmp_mv->as_mv;
184   }
185
186   if (scaled_ref_frame) {
187     int i;
188     for (i = 0; i < MAX_MB_PLANE; i++)
189       xd->plane[i].pre[0] = backup_yv12[i];
190   }
191   return rv;
192 }
193
194
195 static void model_rd_for_sb_y(VP9_COMP *cpi, BLOCK_SIZE bsize,
196                               MACROBLOCK *x, MACROBLOCKD *xd,
197                               int *out_rate_sum, int64_t *out_dist_sum,
198                               unsigned int *var_y, unsigned int *sse_y) {
199   // Note our transform coeffs are 8 times an orthogonal transform.
200   // Hence quantizer step is also 8 times. To get effective quantizer
201   // we need to divide by 8 before sending to modeling function.
202   unsigned int sse;
203   int rate;
204   int64_t dist;
205   struct macroblock_plane *const p = &x->plane[0];
206   struct macroblockd_plane *const pd = &xd->plane[0];
207   const uint32_t dc_quant = pd->dequant[0];
208   const uint32_t ac_quant = pd->dequant[1];
209   unsigned int var = cpi->fn_ptr[bsize].vf(p->src.buf, p->src.stride,
210                                            pd->dst.buf, pd->dst.stride, &sse);
211   *var_y = var;
212   *sse_y = sse;
213
214   if (sse < dc_quant * dc_quant >> 6)
215     x->skip_txfm[0] = 1;
216   else if (var < ac_quant * ac_quant >> 6)
217     x->skip_txfm[0] = 2;
218   else
219     x->skip_txfm[0] = 0;
220
221   if (cpi->common.tx_mode == TX_MODE_SELECT) {
222     if (sse > (var << 2))
223       xd->mi[0]->mbmi.tx_size = MIN(max_txsize_lookup[bsize],
224                           tx_mode_to_biggest_tx_size[cpi->common.tx_mode]);
225     else
226       xd->mi[0]->mbmi.tx_size = TX_8X8;
227   } else {
228     xd->mi[0]->mbmi.tx_size = MIN(max_txsize_lookup[bsize],
229                          tx_mode_to_biggest_tx_size[cpi->common.tx_mode]);
230   }
231
232   vp9_model_rd_from_var_lapndz(sse - var, 1 << num_pels_log2_lookup[bsize],
233                                dc_quant >> 3, &rate, &dist);
234   *out_rate_sum = rate >> 1;
235   *out_dist_sum = dist << 3;
236
237   vp9_model_rd_from_var_lapndz(var, 1 << num_pels_log2_lookup[bsize],
238                                ac_quant >> 3, &rate, &dist);
239   *out_rate_sum += rate;
240   *out_dist_sum += dist << 4;
241 }
242
243 static int get_pred_buffer(PRED_BUFFER *p, int len) {
244   int i;
245
246   for (i = 0; i < len; i++) {
247     if (!p[i].in_use) {
248       p[i].in_use = 1;
249       return i;
250     }
251   }
252   return -1;
253 }
254
255 static void free_pred_buffer(PRED_BUFFER *p) {
256   p->in_use = 0;
257 }
258
259 static void encode_breakout_test(VP9_COMP *cpi, MACROBLOCK *x,
260                                  BLOCK_SIZE bsize, int mi_row, int mi_col,
261                                  MV_REFERENCE_FRAME ref_frame,
262                                  PREDICTION_MODE this_mode,
263                                  unsigned int var_y, unsigned int sse_y,
264                                  struct buf_2d yv12_mb[][MAX_MB_PLANE],
265                                  int *rate, int64_t *dist) {
266   MACROBLOCKD *xd = &x->e_mbd;
267   MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
268
269   const BLOCK_SIZE uv_size = get_plane_block_size(bsize, &xd->plane[1]);
270   unsigned int var = var_y, sse = sse_y;
271   // Skipping threshold for ac.
272   unsigned int thresh_ac;
273   // Skipping threshold for dc.
274   unsigned int thresh_dc;
275   if (x->encode_breakout > 0) {
276     // Set a maximum for threshold to avoid big PSNR loss in low bit rate
277     // case. Use extreme low threshold for static frames to limit
278     // skipping.
279     const unsigned int max_thresh = 36000;
280     // The encode_breakout input
281     const unsigned int min_thresh =
282         MIN(((unsigned int)x->encode_breakout << 4), max_thresh);
283
284     // Calculate threshold according to dequant value.
285     thresh_ac = (xd->plane[0].dequant[1] * xd->plane[0].dequant[1]) / 9;
286     thresh_ac = clamp(thresh_ac, min_thresh, max_thresh);
287
288     // Adjust ac threshold according to partition size.
289     thresh_ac >>=
290         8 - (b_width_log2(bsize) + b_height_log2(bsize));
291
292     thresh_dc = (xd->plane[0].dequant[0] * xd->plane[0].dequant[0] >> 6);
293   } else {
294     thresh_ac = 0;
295     thresh_dc = 0;
296   }
297
298   // Y skipping condition checking for ac and dc.
299   if (var <= thresh_ac && (sse - var) <= thresh_dc) {
300     unsigned int sse_u, sse_v;
301     unsigned int var_u, var_v;
302
303     // Skip UV prediction unless breakout is zero (lossless) to save
304     // computation with low impact on the result
305     if (x->encode_breakout == 0) {
306       xd->plane[1].pre[0] = yv12_mb[ref_frame][1];
307       xd->plane[2].pre[0] = yv12_mb[ref_frame][2];
308       vp9_build_inter_predictors_sbuv(xd, mi_row, mi_col, bsize);
309     }
310
311     var_u = cpi->fn_ptr[uv_size].vf(x->plane[1].src.buf,
312                                     x->plane[1].src.stride,
313                                     xd->plane[1].dst.buf,
314                                     xd->plane[1].dst.stride, &sse_u);
315
316     // U skipping condition checking
317     if ((var_u * 4 <= thresh_ac) && (sse_u - var_u <= thresh_dc)) {
318       var_v = cpi->fn_ptr[uv_size].vf(x->plane[2].src.buf,
319                                       x->plane[2].src.stride,
320                                       xd->plane[2].dst.buf,
321                                       xd->plane[2].dst.stride, &sse_v);
322
323       // V skipping condition checking
324       if ((var_v * 4 <= thresh_ac) && (sse_v - var_v <= thresh_dc)) {
325         x->skip = 1;
326
327         // The cost of skip bit needs to be added.
328         *rate = cpi->inter_mode_cost[mbmi->mode_context[ref_frame]]
329                                      [INTER_OFFSET(this_mode)];
330
331         // More on this part of rate
332         // rate += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1);
333
334         // Scaling factor for SSE from spatial domain to frequency
335         // domain is 16. Adjust distortion accordingly.
336         // TODO(yunqingwang): In this function, only y-plane dist is
337         // calculated.
338         *dist = (sse << 4);  // + ((sse_u + sse_v) << 4);
339
340         // *disable_skip = 1;
341       }
342     }
343   }
344 }
345
346 static const THR_MODES mode_idx[MAX_REF_FRAMES - 1][4] = {
347   {THR_NEARESTMV, THR_NEARMV, THR_ZEROMV, THR_NEWMV},
348   {THR_NEARESTG, THR_NEARG, THR_ZEROG, THR_NEWG},
349   {THR_NEARESTA, THR_NEARA, THR_ZEROA, THR_NEWA},
350 };
351
352 // TODO(jingning) placeholder for inter-frame non-RD mode decision.
353 // this needs various further optimizations. to be continued..
354 int64_t vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
355                             const TileInfo *const tile,
356                             int mi_row, int mi_col,
357                             int *returnrate,
358                             int64_t *returndistortion,
359                             BLOCK_SIZE bsize,
360                             PICK_MODE_CONTEXT *ctx) {
361   MACROBLOCKD *xd = &x->e_mbd;
362   MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
363   struct macroblock_plane *const p = &x->plane[0];
364   struct macroblockd_plane *const pd = &xd->plane[0];
365   PREDICTION_MODE this_mode, best_mode = ZEROMV;
366   MV_REFERENCE_FRAME ref_frame, best_ref_frame = LAST_FRAME;
367   TX_SIZE best_tx_size = MIN(max_txsize_lookup[bsize],
368                              tx_mode_to_biggest_tx_size[cpi->common.tx_mode]);
369   INTERP_FILTER best_pred_filter = EIGHTTAP;
370   int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
371   struct buf_2d yv12_mb[4][MAX_MB_PLANE];
372   static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
373                                     VP9_ALT_FLAG };
374   int64_t best_rd = INT64_MAX;
375   int64_t this_rd = INT64_MAX;
376   int skip_txfm = 0;
377   int rate = INT_MAX;
378   int64_t dist = INT64_MAX;
379   // var_y and sse_y are saved to be used in skipping checking
380   unsigned int var_y = UINT_MAX;
381   unsigned int sse_y = UINT_MAX;
382
383   VP9_COMMON *cm = &cpi->common;
384   int intra_cost_penalty = 20 * vp9_dc_quant(cm->base_qindex, cm->y_dc_delta_q);
385
386   const int64_t inter_mode_thresh = RDCOST(x->rdmult, x->rddiv,
387                                            intra_cost_penalty, 0);
388   const int64_t intra_mode_cost = 50;
389
390   unsigned char segment_id = mbmi->segment_id;
391   const int *const rd_threshes = cpi->rd.threshes[segment_id][bsize];
392   const int *const rd_thresh_freq_fact = cpi->rd.thresh_freq_fact[bsize];
393   // Mode index conversion form THR_MODES to PREDICTION_MODE for a ref frame.
394   INTERP_FILTER filter_ref = cm->interp_filter;
395   int bsl = mi_width_log2(bsize);
396   const int pred_filter_search = cm->interp_filter == SWITCHABLE ?
397       (((mi_row + mi_col) >> bsl) +
398        get_chessboard_index(cm->current_video_frame)) & 0x1 : 0;
399   int const_motion[MAX_REF_FRAMES] = { 0 };
400   int bh = num_4x4_blocks_high_lookup[bsize] << 2;
401   int bw = num_4x4_blocks_wide_lookup[bsize] << 2;
402   int pixels_in_block = bh * bw;
403   // For speed 6, the result of interp filter is reused later in actual encoding
404   // process.
405   // tmp[3] points to dst buffer, and the other 3 point to allocated buffers.
406   PRED_BUFFER tmp[4];
407   DECLARE_ALIGNED_ARRAY(16, uint8_t, pred_buf, 3 * 64 * 64);
408   struct buf_2d orig_dst = pd->dst;
409   PRED_BUFFER *best_pred = NULL;
410   PRED_BUFFER *this_mode_pred = NULL;
411   int i;
412
413   // CTX is used by the temporal denoiser which is currently being developed.
414   // TODO(jbb): when temporal denoiser is finished and in the default build
415   // remove the following line;
416   (void) ctx;
417   if (cpi->sf.reuse_inter_pred_sby) {
418     for (i = 0; i < 3; i++) {
419       tmp[i].data = &pred_buf[pixels_in_block * i];
420       tmp[i].stride = bw;
421       tmp[i].in_use = 0;
422     }
423     tmp[3].data = pd->dst.buf;
424     tmp[3].stride = pd->dst.stride;
425     tmp[3].in_use = 0;
426   }
427
428   x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
429   x->skip = 0;
430
431   // initialize mode decisions
432   *returnrate = INT_MAX;
433   *returndistortion = INT64_MAX;
434   vpx_memset(mbmi, 0, sizeof(MB_MODE_INFO));
435   mbmi->sb_type = bsize;
436   mbmi->ref_frame[0] = NONE;
437   mbmi->ref_frame[1] = NONE;
438   mbmi->tx_size = MIN(max_txsize_lookup[bsize],
439                       tx_mode_to_biggest_tx_size[cm->tx_mode]);
440   mbmi->interp_filter = cm->interp_filter == SWITCHABLE ?
441                         EIGHTTAP : cm->interp_filter;
442   mbmi->segment_id = segment_id;
443
444   for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
445     x->pred_mv_sad[ref_frame] = INT_MAX;
446     frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
447     frame_mv[ZEROMV][ref_frame].as_int = 0;
448
449     if (xd->up_available)
450       filter_ref = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
451     else if (xd->left_available)
452       filter_ref = xd->mi[-1]->mbmi.interp_filter;
453
454     if (cpi->ref_frame_flags & flag_list[ref_frame]) {
455       const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
456       int_mv *const candidates = mbmi->ref_mvs[ref_frame];
457       const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
458       vp9_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col,
459                            sf, sf);
460
461       if (!cm->error_resilient_mode)
462         vp9_find_mv_refs(cm, xd, tile, xd->mi[0], ref_frame,
463                          candidates, mi_row, mi_col);
464       else
465         const_motion[ref_frame] = mv_refs_rt(cm, xd, tile, xd->mi[0],
466                                              ref_frame, candidates,
467                                              mi_row, mi_col);
468
469       vp9_find_best_ref_mvs(xd, cm->allow_high_precision_mv, candidates,
470                             &frame_mv[NEARESTMV][ref_frame],
471                             &frame_mv[NEARMV][ref_frame]);
472
473       if (!vp9_is_scaled(sf) && bsize >= BLOCK_8X8)
474         vp9_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride,
475                     ref_frame, bsize);
476     } else {
477       continue;
478     }
479
480     // Select prediction reference frames.
481     xd->plane[0].pre[0] = yv12_mb[ref_frame][0];
482
483     clamp_mv2(&frame_mv[NEARESTMV][ref_frame].as_mv, xd);
484     clamp_mv2(&frame_mv[NEARMV][ref_frame].as_mv, xd);
485
486     mbmi->ref_frame[0] = ref_frame;
487
488     for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
489       int rate_mv = 0;
490       int mode_rd_thresh;
491
492       if (const_motion[ref_frame] &&
493           (this_mode == NEARMV || this_mode == ZEROMV))
494         continue;
495
496       if (!(cpi->sf.inter_mode_mask[bsize] & (1 << this_mode)))
497         continue;
498
499       mode_rd_thresh =  rd_threshes[mode_idx[ref_frame - LAST_FRAME]
500                                             [this_mode - NEARESTMV]];
501       if (rd_less_than_thresh(best_rd, mode_rd_thresh,
502                               rd_thresh_freq_fact[this_mode]))
503         continue;
504
505       if (this_mode == NEWMV) {
506         if (this_rd < (int64_t)(1 << num_pels_log2_lookup[bsize]))
507           continue;
508         if (!combined_motion_search(cpi, x, bsize, mi_row, mi_col,
509                                     &frame_mv[NEWMV][ref_frame],
510                                     &rate_mv, best_rd))
511           continue;
512       }
513
514       if (this_mode != NEARESTMV &&
515           frame_mv[this_mode][ref_frame].as_int ==
516               frame_mv[NEARESTMV][ref_frame].as_int)
517           continue;
518
519       mbmi->mode = this_mode;
520       mbmi->mv[0].as_int = frame_mv[this_mode][ref_frame].as_int;
521
522       // Search for the best prediction filter type, when the resulting
523       // motion vector is at sub-pixel accuracy level for luma component, i.e.,
524       // the last three bits are all zeros.
525       if (cpi->sf.reuse_inter_pred_sby) {
526         if (this_mode == NEARESTMV) {
527           this_mode_pred = &tmp[3];
528         } else {
529           this_mode_pred = &tmp[get_pred_buffer(tmp, 3)];
530           pd->dst.buf = this_mode_pred->data;
531           pd->dst.stride = bw;
532         }
533       }
534
535       if ((this_mode == NEWMV || filter_ref == SWITCHABLE) &&
536           pred_filter_search &&
537           ((mbmi->mv[0].as_mv.row & 0x07) != 0 ||
538            (mbmi->mv[0].as_mv.col & 0x07) != 0)) {
539         int pf_rate[3];
540         int64_t pf_dist[3];
541         unsigned int pf_var[3];
542         unsigned int pf_sse[3];
543         TX_SIZE pf_tx_size[3];
544         int64_t best_cost = INT64_MAX;
545         INTERP_FILTER best_filter = SWITCHABLE, filter;
546         PRED_BUFFER *current_pred = this_mode_pred;
547
548         for (filter = EIGHTTAP; filter <= EIGHTTAP_SHARP; ++filter) {
549           int64_t cost;
550           mbmi->interp_filter = filter;
551           vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
552           model_rd_for_sb_y(cpi, bsize, x, xd, &pf_rate[filter],
553                             &pf_dist[filter], &pf_var[filter], &pf_sse[filter]);
554           cost = RDCOST(x->rdmult, x->rddiv,
555                         vp9_get_switchable_rate(cpi) + pf_rate[filter],
556                         pf_dist[filter]);
557           pf_tx_size[filter] = mbmi->tx_size;
558           if (cost < best_cost) {
559             best_filter = filter;
560             best_cost = cost;
561             skip_txfm = x->skip_txfm[0];
562
563             if (cpi->sf.reuse_inter_pred_sby) {
564               if (this_mode_pred != current_pred) {
565                 free_pred_buffer(this_mode_pred);
566                 this_mode_pred = current_pred;
567               }
568
569               if (filter < EIGHTTAP_SHARP) {
570                 current_pred = &tmp[get_pred_buffer(tmp, 3)];
571                 pd->dst.buf = current_pred->data;
572                 pd->dst.stride = bw;
573               }
574             }
575           }
576         }
577
578         if (cpi->sf.reuse_inter_pred_sby && this_mode_pred != current_pred)
579           free_pred_buffer(current_pred);
580
581         mbmi->interp_filter = best_filter;
582         mbmi->tx_size = pf_tx_size[mbmi->interp_filter];
583         rate = pf_rate[mbmi->interp_filter];
584         dist = pf_dist[mbmi->interp_filter];
585         var_y = pf_var[mbmi->interp_filter];
586         sse_y = pf_sse[mbmi->interp_filter];
587         x->skip_txfm[0] = skip_txfm;
588       } else {
589         mbmi->interp_filter = (filter_ref == SWITCHABLE) ? EIGHTTAP: filter_ref;
590         vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
591         model_rd_for_sb_y(cpi, bsize, x, xd, &rate, &dist, &var_y, &sse_y);
592       }
593
594       rate += rate_mv;
595       rate += cpi->inter_mode_cost[mbmi->mode_context[ref_frame]]
596                                 [INTER_OFFSET(this_mode)];
597       this_rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
598
599       // Skipping checking: test to see if this block can be reconstructed by
600       // prediction only.
601       if (cpi->allow_encode_breakout) {
602         encode_breakout_test(cpi, x, bsize, mi_row, mi_col, ref_frame,
603                              this_mode, var_y, sse_y, yv12_mb, &rate, &dist);
604         if (x->skip) {
605           rate += rate_mv;
606           this_rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
607         }
608       }
609
610 #if CONFIG_VP9_TEMPORAL_DENOISING
611       if (cpi->oxcf.noise_sensitivity > 0) {
612         vp9_denoiser_update_frame_stats(&cpi->denoiser, mbmi, sse_y,
613                                         this_mode, ctx);
614       }
615 #endif
616
617       if (this_rd < best_rd || x->skip) {
618         best_rd = this_rd;
619         *returnrate = rate;
620         *returndistortion = dist;
621         best_mode = this_mode;
622         best_pred_filter = mbmi->interp_filter;
623         best_tx_size = mbmi->tx_size;
624         best_ref_frame = ref_frame;
625         skip_txfm = x->skip_txfm[0];
626
627         if (cpi->sf.reuse_inter_pred_sby) {
628           if (best_pred != NULL)
629             free_pred_buffer(best_pred);
630
631           best_pred = this_mode_pred;
632         }
633       } else {
634         if (cpi->sf.reuse_inter_pred_sby)
635           free_pred_buffer(this_mode_pred);
636       }
637
638       if (x->skip)
639         break;
640     }
641     // If the current reference frame is valid and we found a usable mode,
642     // we are done.
643     if (best_rd < INT64_MAX)
644       break;
645   }
646
647   // If best prediction is not in dst buf, then copy the prediction block from
648   // temp buf to dst buf.
649   if (cpi->sf.reuse_inter_pred_sby && best_pred->data != orig_dst.buf) {
650     uint8_t *copy_from, *copy_to;
651
652     pd->dst = orig_dst;
653     copy_to = pd->dst.buf;
654
655     copy_from = best_pred->data;
656
657     vp9_convolve_copy(copy_from, bw, copy_to, pd->dst.stride, NULL, 0, NULL, 0,
658                       bw, bh);
659   }
660
661   mbmi->mode          = best_mode;
662   mbmi->interp_filter = best_pred_filter;
663   mbmi->tx_size       = best_tx_size;
664   mbmi->ref_frame[0]  = best_ref_frame;
665   mbmi->mv[0].as_int  = frame_mv[best_mode][best_ref_frame].as_int;
666   xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
667   x->skip_txfm[0] = skip_txfm;
668
669   // Perform intra prediction search, if the best SAD is above a certain
670   // threshold.
671   if (!x->skip && best_rd > inter_mode_thresh &&
672       bsize <= cpi->sf.max_intra_bsize) {
673     int i, j;
674     const int width  = num_4x4_blocks_wide_lookup[bsize];
675     const int height = num_4x4_blocks_high_lookup[bsize];
676
677     int rate2 = 0;
678     int64_t dist2 = 0;
679     const int dst_stride = cpi->sf.reuse_inter_pred_sby ? bw : pd->dst.stride;
680     const int src_stride = p->src.stride;
681     int block_idx = 0;
682
683     TX_SIZE tmp_tx_size = MIN(max_txsize_lookup[bsize],
684                               tx_mode_to_biggest_tx_size[cpi->common.tx_mode]);
685     const BLOCK_SIZE bsize_tx = txsize_to_bsize[tmp_tx_size];
686     const int step = 1 << tmp_tx_size;
687
688     if (cpi->sf.reuse_inter_pred_sby) {
689       pd->dst.buf = tmp[0].data;
690       pd->dst.stride = bw;
691     }
692
693     for (this_mode = DC_PRED; this_mode <= DC_PRED; ++this_mode) {
694       uint8_t *const src_buf_base = p->src.buf;
695       uint8_t *const dst_buf_base = pd->dst.buf;
696       for (j = 0; j < height; j += step) {
697         for (i = 0; i < width; i += step) {
698           p->src.buf = &src_buf_base[4 * (j * src_stride + i)];
699           pd->dst.buf = &dst_buf_base[4 * (j * dst_stride + i)];
700           // Use source buffer as an approximation for the fully reconstructed
701           // buffer
702           vp9_predict_intra_block(xd, block_idx, b_width_log2(bsize),
703                                   tmp_tx_size, this_mode,
704                                   p->src.buf, src_stride,
705                                   pd->dst.buf, dst_stride,
706                                   i, j, 0);
707           model_rd_for_sb_y(cpi, bsize_tx, x, xd, &rate, &dist, &var_y, &sse_y);
708           rate2 += rate;
709           dist2 += dist;
710           ++block_idx;
711         }
712       }
713       p->src.buf = src_buf_base;
714       pd->dst.buf = dst_buf_base;
715
716       rate = rate2;
717       dist = dist2;
718
719       rate += cpi->mbmode_cost[this_mode];
720       rate += intra_cost_penalty;
721       this_rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
722
723       if (cpi->sf.reuse_inter_pred_sby)
724         pd->dst = orig_dst;
725
726       if (this_rd + intra_mode_cost < best_rd) {
727         best_rd = this_rd;
728         *returnrate = rate;
729         *returndistortion = dist;
730         mbmi->mode = this_mode;
731         mbmi->tx_size = tmp_tx_size;
732         mbmi->ref_frame[0] = INTRA_FRAME;
733         mbmi->uv_mode = this_mode;
734         mbmi->mv[0].as_int = INVALID_MV;
735       } else {
736         x->skip_txfm[0] = skip_txfm;
737       }
738     }
739   }
740
741   return INT64_MAX;
742 }