motion_search_facade.c (44474B)
1 /* 2 * Copyright (c) 2020, Alliance for Open Media. All rights reserved. 3 * 4 * This source code is subject to the terms of the BSD 2 Clause License and 5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License 6 * was not distributed with this source code in the LICENSE file, you can 7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open 8 * Media Patent License 1.0 was not distributed with this source code in the 9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent. 10 */ 11 12 #include "av1/common/reconinter.h" 13 14 #include "av1/encoder/encodemv.h" 15 #include "av1/encoder/encoder.h" 16 #include "av1/encoder/interp_search.h" 17 #include "av1/encoder/mcomp.h" 18 #include "av1/encoder/motion_search_facade.h" 19 #include "av1/encoder/partition_strategy.h" 20 #include "av1/encoder/reconinter_enc.h" 21 #include "av1/encoder/tpl_model.h" 22 #include "av1/encoder/tx_search.h" 23 24 #define RIGHT_SHIFT_MV(x) (((x) + 3 + ((x) >= 0)) >> 3) 25 26 typedef struct { 27 int_mv fmv; 28 int weight; 29 } cand_mv_t; 30 31 static int compare_weight(const void *a, const void *b) { 32 const int diff = ((cand_mv_t *)a)->weight - ((cand_mv_t *)b)->weight; 33 if (diff < 0) 34 return 1; 35 else if (diff > 0) 36 return -1; 37 return 0; 38 } 39 40 // Allow more mesh searches for screen content type on the ARF. 41 static int use_fine_search_interval(const AV1_COMP *const cpi) { 42 return cpi->is_screen_content_type && 43 cpi->ppi->gf_group.update_type[cpi->gf_frame_index] == ARF_UPDATE && 44 cpi->oxcf.speed <= 2; 45 } 46 47 // Iterate through the tpl and collect the mvs to be used as candidates 48 static inline void get_mv_candidate_from_tpl(const AV1_COMP *const cpi, 49 const MACROBLOCK *x, 50 BLOCK_SIZE bsize, int ref, 51 cand_mv_t *cand, int *cand_count, 52 int *total_cand_weight) { 53 const SuperBlockEnc *sb_enc = &x->sb_enc; 54 if (!sb_enc->tpl_data_count) { 55 return; 56 } 57 58 const AV1_COMMON *cm = &cpi->common; 59 const MACROBLOCKD *xd = &x->e_mbd; 60 const int mi_row = xd->mi_row; 61 const int mi_col = xd->mi_col; 62 63 const BLOCK_SIZE tpl_bsize = 64 convert_length_to_bsize(cpi->ppi->tpl_data.tpl_bsize_1d); 65 const int tplw = mi_size_wide[tpl_bsize]; 66 const int tplh = mi_size_high[tpl_bsize]; 67 const int nw = mi_size_wide[bsize] / tplw; 68 const int nh = mi_size_high[bsize] / tplh; 69 70 if (nw >= 1 && nh >= 1) { 71 const int of_h = mi_row % mi_size_high[cm->seq_params->sb_size]; 72 const int of_w = mi_col % mi_size_wide[cm->seq_params->sb_size]; 73 const int start = of_h / tplh * sb_enc->tpl_stride + of_w / tplw; 74 int valid = 1; 75 76 // Assign large weight to start_mv, so it is always tested. 77 cand[0].weight = nw * nh; 78 79 for (int k = 0; k < nh; k++) { 80 for (int l = 0; l < nw; l++) { 81 const int_mv mv = 82 sb_enc 83 ->tpl_mv[start + k * sb_enc->tpl_stride + l][ref - LAST_FRAME]; 84 if (mv.as_int == INVALID_MV) { 85 valid = 0; 86 break; 87 } 88 89 const FULLPEL_MV fmv = { GET_MV_RAWPEL(mv.as_mv.row), 90 GET_MV_RAWPEL(mv.as_mv.col) }; 91 int unique = 1; 92 for (int m = 0; m < *cand_count; m++) { 93 if (RIGHT_SHIFT_MV(fmv.row) == 94 RIGHT_SHIFT_MV(cand[m].fmv.as_fullmv.row) && 95 RIGHT_SHIFT_MV(fmv.col) == 96 RIGHT_SHIFT_MV(cand[m].fmv.as_fullmv.col)) { 97 unique = 0; 98 cand[m].weight++; 99 break; 100 } 101 } 102 103 if (unique) { 104 cand[*cand_count].fmv.as_fullmv = fmv; 105 cand[*cand_count].weight = 1; 106 (*cand_count)++; 107 } 108 } 109 if (!valid) break; 110 } 111 112 if (valid) { 113 *total_cand_weight = 2 * nh * nw; 114 if (*cand_count > 2) 115 qsort(cand, *cand_count, sizeof(cand[0]), &compare_weight); 116 } 117 } 118 } 119 120 void av1_single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x, 121 BLOCK_SIZE bsize, int ref_idx, int *rate_mv, 122 int search_range, inter_mode_info *mode_info, 123 int_mv *best_mv, 124 struct HandleInterModeArgs *const args) { 125 MACROBLOCKD *xd = &x->e_mbd; 126 const AV1_COMMON *cm = &cpi->common; 127 const MotionVectorSearchParams *mv_search_params = &cpi->mv_search_params; 128 const int num_planes = av1_num_planes(cm); 129 MB_MODE_INFO *mbmi = xd->mi[0]; 130 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } }; 131 int bestsme = INT_MAX; 132 const int ref = mbmi->ref_frame[ref_idx]; 133 const YV12_BUFFER_CONFIG *scaled_ref_frame = 134 av1_get_scaled_ref_frame(cpi, ref); 135 const int mi_row = xd->mi_row; 136 const int mi_col = xd->mi_col; 137 const MvCosts *mv_costs = x->mv_costs; 138 139 if (scaled_ref_frame) { 140 // Swap out the reference frame for a version that's been scaled to 141 // match the resolution of the current frame, allowing the existing 142 // full-pixel motion search code to be used without additional 143 // modifications. 144 for (int i = 0; i < num_planes; i++) { 145 backup_yv12[i] = xd->plane[i].pre[ref_idx]; 146 } 147 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL, 148 num_planes); 149 } 150 151 // Work out the size of the first step in the mv step search. 152 // 0 here is maximum length first step. 1 is AOMMAX >> 1 etc. 153 int step_param; 154 if (cpi->sf.mv_sf.auto_mv_step_size && cm->show_frame) { 155 // Take the weighted average of the step_params based on the last frame's 156 // max mv magnitude and that based on the best ref mvs of the current 157 // block for the given reference. 158 step_param = (av1_init_search_range(x->max_mv_context[ref]) + 159 mv_search_params->mv_step_param) / 160 2; 161 } else { 162 step_param = mv_search_params->mv_step_param; 163 } 164 165 const MV ref_mv = av1_get_ref_mv(x, ref_idx).as_mv; 166 FULLPEL_MV start_mv; 167 if (mbmi->motion_mode != SIMPLE_TRANSLATION) 168 start_mv = get_fullmv_from_mv(&mbmi->mv[0].as_mv); 169 else 170 start_mv = get_fullmv_from_mv(&ref_mv); 171 172 // cand stores start_mv and all possible MVs in a SB. 173 cand_mv_t cand[MAX_TPL_BLK_IN_SB * MAX_TPL_BLK_IN_SB + 1]; 174 av1_zero(cand); 175 cand[0].fmv.as_fullmv = start_mv; 176 int cnt = 1; 177 int total_weight = 0; 178 179 if (!cpi->sf.mv_sf.full_pixel_search_level && 180 mbmi->motion_mode == SIMPLE_TRANSLATION) { 181 get_mv_candidate_from_tpl(cpi, x, bsize, ref, cand, &cnt, &total_weight); 182 } 183 184 const int cand_cnt = AOMMIN(2, cnt); 185 // TODO(any): Test the speed feature for OBMC_CAUSAL mode. 186 if (cpi->sf.mv_sf.skip_fullpel_search_using_startmv && 187 mbmi->motion_mode == SIMPLE_TRANSLATION) { 188 const int stack_size = args->start_mv_cnt; 189 for (int cand_idx = 0; cand_idx < cand_cnt; cand_idx++) { 190 int_mv *fmv_cand = &cand[cand_idx].fmv; 191 int skip_cand_mv = 0; 192 193 // Check difference between mvs in the stack and candidate mv. 194 for (int stack_idx = 0; stack_idx < stack_size; stack_idx++) { 195 const uint8_t this_ref_mv_idx = args->ref_mv_idx_stack[stack_idx]; 196 const FULLPEL_MV *fmv_stack = &args->start_mv_stack[stack_idx]; 197 const int this_newmv_valid = 198 args->single_newmv_valid[this_ref_mv_idx][ref]; 199 const int row_diff = abs(fmv_stack->row - fmv_cand->as_fullmv.row); 200 const int col_diff = abs(fmv_stack->col - fmv_cand->as_fullmv.col); 201 202 if (!this_newmv_valid) continue; 203 204 if (cpi->sf.mv_sf.skip_fullpel_search_using_startmv >= 2) { 205 // Prunes the current start_mv candidate, if the absolute mv 206 // difference of both row and column are <= 1. 207 if (row_diff <= 1 && col_diff <= 1) { 208 skip_cand_mv = 1; 209 break; 210 } 211 } else if (cpi->sf.mv_sf.skip_fullpel_search_using_startmv >= 1) { 212 // Prunes the current start_mv candidate, if the sum of the absolute 213 // mv difference of row and column is <= 1. 214 if (row_diff + col_diff <= 1) { 215 skip_cand_mv = 1; 216 break; 217 } 218 } 219 } 220 if (skip_cand_mv) { 221 // Ensure atleast one full-pel motion search is not pruned. 222 assert(mbmi->ref_mv_idx != 0); 223 // Mark the candidate mv as invalid so that motion search gets skipped. 224 cand[cand_idx].fmv.as_int = INVALID_MV; 225 } else { 226 // Store start_mv candidate and corresponding ref_mv_idx of full-pel 227 // search in the mv stack (except last ref_mv_idx). 228 if (mbmi->ref_mv_idx != MAX_REF_MV_SEARCH - 1) { 229 assert(args->start_mv_cnt < (MAX_REF_MV_SEARCH - 1) * 2); 230 args->start_mv_stack[args->start_mv_cnt] = fmv_cand->as_fullmv; 231 args->ref_mv_idx_stack[args->start_mv_cnt] = mbmi->ref_mv_idx; 232 args->start_mv_cnt++; 233 } 234 } 235 } 236 } 237 238 // Hot fix for asan complaints when resize mode is on. When resize mode is on, 239 // the stride of the reference frame can be different from indicated by 240 // MotionVectorSearchParams::search_site_cfg. When this happens, we need to 241 // readjust the stride. 242 const MV_SPEED_FEATURES *mv_sf = &cpi->sf.mv_sf; 243 const SEARCH_METHODS search_method = 244 av1_get_default_mv_search_method(x, mv_sf, bsize); 245 const search_site_config *src_search_site_cfg = 246 av1_get_search_site_config(cpi, x, search_method); 247 248 // Further reduce the search range. 249 if (search_range < INT_MAX) { 250 const search_site_config *search_site_cfg = 251 &src_search_site_cfg[search_method_lookup[search_method]]; 252 // Max step_param is search_site_cfg->num_search_steps. 253 if (search_range < 1) { 254 step_param = search_site_cfg->num_search_steps; 255 } else { 256 while (search_site_cfg->radius[search_site_cfg->num_search_steps - 257 step_param - 1] > (search_range << 1) && 258 search_site_cfg->num_search_steps - step_param - 1 > 0) 259 step_param++; 260 } 261 } 262 263 int cost_list[5]; 264 FULLPEL_MV_STATS best_mv_stats; 265 int_mv second_best_mv; 266 best_mv->as_int = second_best_mv.as_int = INVALID_MV; 267 268 // Allow more mesh searches for screen content type on the ARF. 269 const int fine_search_interval = use_fine_search_interval(cpi); 270 FULLPEL_MOTION_SEARCH_PARAMS full_ms_params; 271 272 switch (mbmi->motion_mode) { 273 case SIMPLE_TRANSLATION: { 274 // Perform a search with the top 2 candidates 275 int sum_weight = 0; 276 for (int m = 0; m < cand_cnt; m++) { 277 int_mv smv = cand[m].fmv; 278 FULLPEL_MV this_best_mv, this_second_best_mv; 279 FULLPEL_MV_STATS this_mv_stats; 280 281 if (smv.as_int == INVALID_MV) continue; 282 283 av1_make_default_fullpel_ms_params( 284 &full_ms_params, cpi, x, bsize, &ref_mv, smv.as_fullmv, 285 src_search_site_cfg, search_method, fine_search_interval); 286 287 const int thissme = 288 av1_full_pixel_search(smv.as_fullmv, &full_ms_params, step_param, 289 cond_cost_list(cpi, cost_list), &this_best_mv, 290 &this_mv_stats, &this_second_best_mv); 291 292 if (thissme < bestsme) { 293 bestsme = thissme; 294 best_mv->as_fullmv = this_best_mv; 295 best_mv_stats = this_mv_stats; 296 second_best_mv.as_fullmv = this_second_best_mv; 297 } 298 299 sum_weight += cand[m].weight; 300 if (4 * sum_weight > 3 * total_weight) break; 301 } 302 } break; 303 case OBMC_CAUSAL: 304 av1_make_default_fullpel_ms_params(&full_ms_params, cpi, x, bsize, 305 &ref_mv, start_mv, src_search_site_cfg, 306 search_method, fine_search_interval); 307 308 bestsme = av1_obmc_full_pixel_search(start_mv, &full_ms_params, 309 step_param, &best_mv->as_fullmv); 310 break; 311 default: assert(0 && "Invalid motion mode!\n"); 312 } 313 if (best_mv->as_int == INVALID_MV) return; 314 315 if (scaled_ref_frame) { 316 // Swap back the original buffers for subpel motion search. 317 for (int i = 0; i < num_planes; i++) { 318 xd->plane[i].pre[ref_idx] = backup_yv12[i]; 319 } 320 } 321 322 // Terminate search with the current ref_idx based on fullpel mv, rate cost, 323 // and other know cost. 324 if (cpi->sf.inter_sf.skip_newmv_in_drl >= 2 && 325 mbmi->motion_mode == SIMPLE_TRANSLATION && 326 best_mv->as_int != INVALID_MV) { 327 int_mv this_mv; 328 this_mv.as_mv = get_mv_from_fullmv(&best_mv->as_fullmv); 329 const int ref_mv_idx = mbmi->ref_mv_idx; 330 const int this_mv_rate = 331 av1_mv_bit_cost(&this_mv.as_mv, &ref_mv, mv_costs->nmv_joint_cost, 332 mv_costs->mv_cost_stack, MV_COST_WEIGHT); 333 mode_info[ref_mv_idx].full_search_mv.as_int = this_mv.as_int; 334 mode_info[ref_mv_idx].full_mv_rate = this_mv_rate; 335 mode_info[ref_mv_idx].full_mv_bestsme = bestsme; 336 337 for (int prev_ref_idx = 0; prev_ref_idx < ref_mv_idx; ++prev_ref_idx) { 338 // Check if the motion search result same as previous results 339 if (this_mv.as_int == mode_info[prev_ref_idx].full_search_mv.as_int) { 340 // Compare the rate cost 341 const int prev_rate_cost = mode_info[prev_ref_idx].full_mv_rate + 342 mode_info[prev_ref_idx].drl_cost; 343 const int this_rate_cost = 344 this_mv_rate + mode_info[ref_mv_idx].drl_cost; 345 346 if (prev_rate_cost <= this_rate_cost) { 347 // If the current rate_cost is worse than the previous rate_cost, then 348 // we terminate the search. Since av1_single_motion_search is only 349 // called by handle_new_mv in SIMPLE_TRANSLATION mode, we set the 350 // best_mv to INVALID mv to signal that we wish to terminate search 351 // for the current mode. 352 best_mv->as_int = INVALID_MV; 353 return; 354 } 355 } 356 357 // Terminate the evaluation of current ref_mv_idx based on bestsme and 358 // drl_cost. 359 const int psme = mode_info[prev_ref_idx].full_mv_bestsme; 360 if (psme == INT_MAX) continue; 361 const int thr = 362 cpi->sf.inter_sf.skip_newmv_in_drl == 3 ? (psme + (psme >> 2)) : psme; 363 if (cpi->sf.inter_sf.skip_newmv_in_drl >= 3 && 364 mode_info[ref_mv_idx].full_mv_bestsme > thr && 365 mode_info[prev_ref_idx].drl_cost < mode_info[ref_mv_idx].drl_cost) { 366 best_mv->as_int = INVALID_MV; 367 return; 368 } 369 } 370 } 371 372 if (cpi->common.features.cur_frame_force_integer_mv) { 373 convert_fullmv_to_mv(best_mv); 374 } 375 376 const int use_fractional_mv = 377 bestsme < INT_MAX && cpi->common.features.cur_frame_force_integer_mv == 0; 378 int best_mv_rate = 0; 379 int mv_rate_calculated = 0; 380 if (use_fractional_mv) { 381 int_mv fractional_ms_list[3]; 382 av1_set_fractional_mv(fractional_ms_list); 383 int dis; /* TODO: use dis in distortion calculation later. */ 384 385 SUBPEL_MOTION_SEARCH_PARAMS ms_params; 386 av1_make_default_subpel_ms_params(&ms_params, cpi, x, bsize, &ref_mv, 387 cost_list); 388 MV subpel_start_mv = get_mv_from_fullmv(&best_mv->as_fullmv); 389 assert(av1_is_subpelmv_in_range(&ms_params.mv_limits, subpel_start_mv)); 390 391 switch (mbmi->motion_mode) { 392 case SIMPLE_TRANSLATION: 393 if (mv_sf->use_accurate_subpel_search) { 394 const int try_second = second_best_mv.as_int != INVALID_MV && 395 second_best_mv.as_int != best_mv->as_int && 396 (mv_sf->disable_second_mv <= 1); 397 const int best_mv_var = mv_search_params->find_fractional_mv_step( 398 xd, cm, &ms_params, subpel_start_mv, &best_mv_stats, 399 &best_mv->as_mv, &dis, &x->pred_sse[ref], fractional_ms_list); 400 401 if (try_second) { 402 struct macroblockd_plane *p = xd->plane; 403 const BUFFER_SET orig_dst = { 404 { p[0].dst.buf, p[1].dst.buf, p[2].dst.buf }, 405 { p[0].dst.stride, p[1].dst.stride, p[2].dst.stride }, 406 }; 407 int64_t rd = INT64_MAX; 408 if (!mv_sf->disable_second_mv) { 409 // Calculate actual rd cost. 410 mbmi->mv[0].as_mv = best_mv->as_mv; 411 av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, &orig_dst, 412 bsize, 0, 0); 413 av1_subtract_plane(x, bsize, 0); 414 RD_STATS this_rd_stats; 415 av1_init_rd_stats(&this_rd_stats); 416 av1_estimate_txfm_yrd(cpi, x, &this_rd_stats, INT64_MAX, bsize, 417 max_txsize_rect_lookup[bsize]); 418 int this_mv_rate = av1_mv_bit_cost( 419 &best_mv->as_mv, &ref_mv, mv_costs->nmv_joint_cost, 420 mv_costs->mv_cost_stack, MV_COST_WEIGHT); 421 rd = RDCOST(x->rdmult, this_mv_rate + this_rd_stats.rate, 422 this_rd_stats.dist); 423 } 424 425 MV this_best_mv; 426 subpel_start_mv = get_mv_from_fullmv(&second_best_mv.as_fullmv); 427 if (av1_is_subpelmv_in_range(&ms_params.mv_limits, 428 subpel_start_mv)) { 429 unsigned int sse; 430 const int this_var = mv_search_params->find_fractional_mv_step( 431 xd, cm, &ms_params, subpel_start_mv, NULL, &this_best_mv, 432 &dis, &sse, fractional_ms_list); 433 434 if (!mv_sf->disable_second_mv) { 435 // If cpi->sf.mv_sf.disable_second_mv is 0, use actual rd cost 436 // to choose the better MV. 437 mbmi->mv[0].as_mv = this_best_mv; 438 av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, &orig_dst, 439 bsize, 0, 0); 440 av1_subtract_plane(x, bsize, 0); 441 RD_STATS tmp_rd_stats; 442 av1_init_rd_stats(&tmp_rd_stats); 443 av1_estimate_txfm_yrd(cpi, x, &tmp_rd_stats, INT64_MAX, bsize, 444 max_txsize_rect_lookup[bsize]); 445 int tmp_mv_rate = av1_mv_bit_cost( 446 &this_best_mv, &ref_mv, mv_costs->nmv_joint_cost, 447 mv_costs->mv_cost_stack, MV_COST_WEIGHT); 448 int64_t tmp_rd = 449 RDCOST(x->rdmult, tmp_rd_stats.rate + tmp_mv_rate, 450 tmp_rd_stats.dist); 451 if (tmp_rd < rd) { 452 best_mv->as_mv = this_best_mv; 453 x->pred_sse[ref] = sse; 454 } 455 } else { 456 // If cpi->sf.mv_sf.disable_second_mv = 1, use var to decide the 457 // best MV. 458 if (this_var < best_mv_var) { 459 best_mv->as_mv = this_best_mv; 460 x->pred_sse[ref] = sse; 461 } 462 } 463 } 464 } 465 } else { 466 mv_search_params->find_fractional_mv_step( 467 xd, cm, &ms_params, subpel_start_mv, &best_mv_stats, 468 &best_mv->as_mv, &dis, &x->pred_sse[ref], NULL); 469 } 470 break; 471 case OBMC_CAUSAL: 472 av1_find_best_obmc_sub_pixel_tree_up( 473 xd, cm, &ms_params, subpel_start_mv, NULL, &best_mv->as_mv, &dis, 474 &x->pred_sse[ref], NULL); 475 break; 476 default: assert(0 && "Invalid motion mode!\n"); 477 } 478 479 // Terminate search with the current ref_idx based on subpel mv and rate 480 // cost. 481 if (cpi->sf.inter_sf.skip_newmv_in_drl >= 1 && args != NULL && 482 mbmi->motion_mode == SIMPLE_TRANSLATION && 483 best_mv->as_int != INVALID_MV) { 484 const int ref_mv_idx = mbmi->ref_mv_idx; 485 best_mv_rate = 486 av1_mv_bit_cost(&best_mv->as_mv, &ref_mv, mv_costs->nmv_joint_cost, 487 mv_costs->mv_cost_stack, MV_COST_WEIGHT); 488 mv_rate_calculated = 1; 489 490 for (int prev_ref_idx = 0; prev_ref_idx < ref_mv_idx; ++prev_ref_idx) { 491 if (!args->single_newmv_valid[prev_ref_idx][ref]) continue; 492 // Check if the motion vectors are the same. 493 if (best_mv->as_int == args->single_newmv[prev_ref_idx][ref].as_int) { 494 // Skip this evaluation if the previous one is skipped. 495 if (mode_info[prev_ref_idx].skip) { 496 mode_info[ref_mv_idx].skip = 1; 497 break; 498 } 499 // Compare the rate cost that we current know. 500 const int prev_rate_cost = 501 args->single_newmv_rate[prev_ref_idx][ref] + 502 mode_info[prev_ref_idx].drl_cost; 503 const int this_rate_cost = 504 best_mv_rate + mode_info[ref_mv_idx].drl_cost; 505 506 if (prev_rate_cost <= this_rate_cost) { 507 // If the current rate_cost is worse than the previous rate_cost, 508 // then we terminate the search for this ref_mv_idx. 509 mode_info[ref_mv_idx].skip = 1; 510 break; 511 } 512 } 513 } 514 } 515 } 516 517 if (mv_rate_calculated) { 518 *rate_mv = best_mv_rate; 519 } else { 520 *rate_mv = 521 av1_mv_bit_cost(&best_mv->as_mv, &ref_mv, mv_costs->nmv_joint_cost, 522 mv_costs->mv_cost_stack, MV_COST_WEIGHT); 523 } 524 } 525 526 int av1_joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x, 527 BLOCK_SIZE bsize, int_mv *cur_mv, 528 const uint8_t *mask, int mask_stride, int *rate_mv, 529 int allow_second_mv, int joint_me_num_refine_iter) { 530 const AV1_COMMON *const cm = &cpi->common; 531 const int num_planes = av1_num_planes(cm); 532 const int pw = block_size_wide[bsize]; 533 const int ph = block_size_high[bsize]; 534 const int plane = 0; 535 MACROBLOCKD *xd = &x->e_mbd; 536 MB_MODE_INFO *mbmi = xd->mi[0]; 537 // This function should only ever be called for compound modes 538 assert(has_second_ref(mbmi)); 539 const int_mv init_mv[2] = { cur_mv[0], cur_mv[1] }; 540 const int refs[2] = { mbmi->ref_frame[0], mbmi->ref_frame[1] }; 541 const MvCosts *mv_costs = x->mv_costs; 542 int_mv ref_mv[2]; 543 int ite, ref; 544 545 // Get the prediction block from the 'other' reference frame. 546 const int_interpfilters interp_filters = 547 av1_broadcast_interp_filter(EIGHTTAP_REGULAR); 548 549 InterPredParams inter_pred_params; 550 const int mi_row = xd->mi_row; 551 const int mi_col = xd->mi_col; 552 553 // Do joint motion search in compound mode to get more accurate mv. 554 struct buf_2d backup_yv12[2][MAX_MB_PLANE]; 555 int last_besterr[2] = { INT_MAX, INT_MAX }; 556 const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = { 557 av1_get_scaled_ref_frame(cpi, refs[0]), 558 av1_get_scaled_ref_frame(cpi, refs[1]) 559 }; 560 561 // Prediction buffer from second frame. 562 DECLARE_ALIGNED(16, uint8_t, second_pred16[MAX_SB_SQUARE * sizeof(uint16_t)]); 563 uint8_t *second_pred = get_buf_by_bd(xd, second_pred16); 564 565 int_mv best_mv, second_best_mv; 566 567 // Allow joint search multiple times iteratively for each reference frame 568 // and break out of the search loop if it couldn't find a better mv. 569 for (ite = 0; ite < (2 * joint_me_num_refine_iter); ite++) { 570 struct buf_2d ref_yv12[2]; 571 int bestsme = INT_MAX; 572 int id = ite % 2; // Even iterations search in the first reference frame, 573 // odd iterations search in the second. The predictor 574 // found for the 'other' reference frame is factored in. 575 if (ite >= 2 && cur_mv[!id].as_int == init_mv[!id].as_int) { 576 if (cur_mv[id].as_int == init_mv[id].as_int) { 577 break; 578 } else { 579 int_mv cur_int_mv, init_int_mv; 580 cur_int_mv.as_mv.col = cur_mv[id].as_mv.col >> 3; 581 cur_int_mv.as_mv.row = cur_mv[id].as_mv.row >> 3; 582 init_int_mv.as_mv.row = init_mv[id].as_mv.row >> 3; 583 init_int_mv.as_mv.col = init_mv[id].as_mv.col >> 3; 584 if (cur_int_mv.as_int == init_int_mv.as_int) { 585 break; 586 } 587 } 588 } 589 for (ref = 0; ref < 2; ++ref) { 590 ref_mv[ref] = av1_get_ref_mv(x, ref); 591 // Swap out the reference frame for a version that's been scaled to 592 // match the resolution of the current frame, allowing the existing 593 // motion search code to be used without additional modifications. 594 if (scaled_ref_frame[ref]) { 595 int i; 596 for (i = 0; i < num_planes; i++) 597 backup_yv12[ref][i] = xd->plane[i].pre[ref]; 598 av1_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col, 599 NULL, num_planes); 600 } 601 } 602 603 assert(IMPLIES(scaled_ref_frame[0] != NULL, 604 cm->width == scaled_ref_frame[0]->y_crop_width && 605 cm->height == scaled_ref_frame[0]->y_crop_height)); 606 assert(IMPLIES(scaled_ref_frame[1] != NULL, 607 cm->width == scaled_ref_frame[1]->y_crop_width && 608 cm->height == scaled_ref_frame[1]->y_crop_height)); 609 610 // Initialize based on (possibly scaled) prediction buffers. 611 ref_yv12[0] = xd->plane[plane].pre[0]; 612 ref_yv12[1] = xd->plane[plane].pre[1]; 613 614 av1_init_inter_params(&inter_pred_params, pw, ph, mi_row * MI_SIZE, 615 mi_col * MI_SIZE, 0, 0, xd->bd, is_cur_buf_hbd(xd), 0, 616 &cm->sf_identity, &ref_yv12[!id], interp_filters); 617 inter_pred_params.conv_params = get_conv_params(0, 0, xd->bd); 618 619 // Since we have scaled the reference frames to match the size of the 620 // current frame we must use a unit scaling factor during mode selection. 621 av1_enc_build_one_inter_predictor(second_pred, pw, &cur_mv[!id].as_mv, 622 &inter_pred_params); 623 624 // Do full-pixel compound motion search on the current reference frame. 625 if (id) xd->plane[plane].pre[0] = ref_yv12[id]; 626 627 // Make motion search params 628 FULLPEL_MOTION_SEARCH_PARAMS full_ms_params; 629 FULLPEL_MV_STATS best_mv_stats; 630 const MV_SPEED_FEATURES *mv_sf = &cpi->sf.mv_sf; 631 const SEARCH_METHODS search_method = 632 av1_get_default_mv_search_method(x, mv_sf, bsize); 633 const search_site_config *src_search_sites = 634 av1_get_search_site_config(cpi, x, search_method); 635 // Use the mv result from the single mode as mv predictor. 636 const FULLPEL_MV start_fullmv = get_fullmv_from_mv(&cur_mv[id].as_mv); 637 av1_make_default_fullpel_ms_params(&full_ms_params, cpi, x, bsize, 638 &ref_mv[id].as_mv, start_fullmv, 639 src_search_sites, search_method, 640 /*fine_search_interval=*/0); 641 642 av1_set_ms_compound_refs(&full_ms_params.ms_buffers, second_pred, mask, 643 mask_stride, id); 644 645 // Small-range full-pixel motion search. 646 if (!mv_sf->disable_extensive_joint_motion_search && 647 mbmi->interinter_comp.type != COMPOUND_WEDGE) { 648 bestsme = av1_full_pixel_search(start_fullmv, &full_ms_params, 5, NULL, 649 &best_mv.as_fullmv, &best_mv_stats, 650 &second_best_mv.as_fullmv); 651 } else { 652 bestsme = av1_refining_search_8p_c(&full_ms_params, start_fullmv, 653 &best_mv.as_fullmv); 654 second_best_mv = best_mv; 655 } 656 657 const int try_second = second_best_mv.as_int != INVALID_MV && 658 second_best_mv.as_int != best_mv.as_int && 659 allow_second_mv; 660 661 // Restore the pointer to the first (possibly scaled) prediction buffer. 662 if (id) xd->plane[plane].pre[0] = ref_yv12[0]; 663 664 for (ref = 0; ref < 2; ++ref) { 665 if (scaled_ref_frame[ref]) { 666 // Swap back the original buffers for subpel motion search. 667 for (int i = 0; i < num_planes; i++) { 668 xd->plane[i].pre[ref] = backup_yv12[ref][i]; 669 } 670 // Re-initialize based on unscaled prediction buffers. 671 ref_yv12[ref] = xd->plane[plane].pre[ref]; 672 } 673 } 674 675 // Do sub-pixel compound motion search on the current reference frame. 676 if (id) xd->plane[plane].pre[0] = ref_yv12[id]; 677 678 if (cpi->common.features.cur_frame_force_integer_mv) { 679 convert_fullmv_to_mv(&best_mv); 680 } 681 if (bestsme < INT_MAX && 682 cpi->common.features.cur_frame_force_integer_mv == 0) { 683 int dis; /* TODO: use dis in distortion calculation later. */ 684 unsigned int sse; 685 SUBPEL_MOTION_SEARCH_PARAMS ms_params; 686 av1_make_default_subpel_ms_params(&ms_params, cpi, x, bsize, 687 &ref_mv[id].as_mv, NULL); 688 av1_set_ms_compound_refs(&ms_params.var_params.ms_buffers, second_pred, 689 mask, mask_stride, id); 690 ms_params.forced_stop = EIGHTH_PEL; 691 MV start_mv = get_mv_from_fullmv(&best_mv.as_fullmv); 692 assert(av1_is_subpelmv_in_range(&ms_params.mv_limits, start_mv)); 693 bestsme = cpi->mv_search_params.find_fractional_mv_step( 694 xd, cm, &ms_params, start_mv, NULL, &best_mv.as_mv, &dis, &sse, NULL); 695 696 if (try_second) { 697 MV this_best_mv; 698 MV subpel_start_mv = get_mv_from_fullmv(&second_best_mv.as_fullmv); 699 if (av1_is_subpelmv_in_range(&ms_params.mv_limits, subpel_start_mv)) { 700 const int thissme = cpi->mv_search_params.find_fractional_mv_step( 701 xd, cm, &ms_params, subpel_start_mv, NULL, &this_best_mv, &dis, 702 &sse, NULL); 703 if (thissme < bestsme) { 704 best_mv.as_mv = this_best_mv; 705 bestsme = thissme; 706 } 707 } 708 } 709 } 710 711 // Restore the pointer to the first prediction buffer. 712 if (id) xd->plane[plane].pre[0] = ref_yv12[0]; 713 if (bestsme < last_besterr[id]) { 714 cur_mv[id] = best_mv; 715 last_besterr[id] = bestsme; 716 } else { 717 break; 718 } 719 } 720 721 *rate_mv = 0; 722 723 for (ref = 0; ref < 2; ++ref) { 724 const int_mv curr_ref_mv = av1_get_ref_mv(x, ref); 725 *rate_mv += av1_mv_bit_cost(&cur_mv[ref].as_mv, &curr_ref_mv.as_mv, 726 mv_costs->nmv_joint_cost, 727 mv_costs->mv_cost_stack, MV_COST_WEIGHT); 728 } 729 730 return AOMMIN(last_besterr[0], last_besterr[1]); 731 } 732 733 // Search for the best mv for one component of a compound, 734 // given that the other component is fixed. 735 int av1_compound_single_motion_search(const AV1_COMP *cpi, MACROBLOCK *x, 736 BLOCK_SIZE bsize, MV *this_mv, 737 const uint8_t *second_pred, 738 const uint8_t *mask, int mask_stride, 739 int *rate_mv, int ref_idx) { 740 const AV1_COMMON *const cm = &cpi->common; 741 const int num_planes = av1_num_planes(cm); 742 MACROBLOCKD *xd = &x->e_mbd; 743 MB_MODE_INFO *mbmi = xd->mi[0]; 744 const int ref = mbmi->ref_frame[ref_idx]; 745 const int_mv ref_mv = av1_get_ref_mv(x, ref_idx); 746 struct macroblockd_plane *const pd = &xd->plane[0]; 747 const MvCosts *mv_costs = x->mv_costs; 748 749 struct buf_2d backup_yv12[MAX_MB_PLANE]; 750 const YV12_BUFFER_CONFIG *const scaled_ref_frame = 751 av1_get_scaled_ref_frame(cpi, ref); 752 753 // Check that this is either an interinter or an interintra block 754 assert(has_second_ref(mbmi) || (ref_idx == 0 && is_interintra_mode(mbmi))); 755 756 // Store the first prediction buffer. 757 struct buf_2d orig_yv12; 758 if (ref_idx) { 759 orig_yv12 = pd->pre[0]; 760 pd->pre[0] = pd->pre[ref_idx]; 761 } 762 763 if (scaled_ref_frame) { 764 // Swap out the reference frame for a version that's been scaled to 765 // match the resolution of the current frame, allowing the existing 766 // full-pixel motion search code to be used without additional 767 // modifications. 768 for (int i = 0; i < num_planes; i++) { 769 backup_yv12[i] = xd->plane[i].pre[ref_idx]; 770 } 771 const int mi_row = xd->mi_row; 772 const int mi_col = xd->mi_col; 773 // The index below needs to be 0 instead of ref_idx since we assume the 774 // 0th slot to be used for subsequent searches. Note that the ref_idx 775 // reference buffer has been copied to the 0th slot in the code above. 776 // Now we need to swap the reference frame for the 0th slot. 777 av1_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL, 778 num_planes); 779 } 780 781 int bestsme = INT_MAX; 782 int_mv best_mv; 783 784 // Make motion search params 785 FULLPEL_MOTION_SEARCH_PARAMS full_ms_params; 786 FULLPEL_MV_STATS best_mv_stats; 787 const SEARCH_METHODS search_method = 788 av1_get_default_mv_search_method(x, &cpi->sf.mv_sf, bsize); 789 const search_site_config *src_search_sites = 790 av1_get_search_site_config(cpi, x, search_method); 791 // Use the mv result from the single mode as mv predictor. 792 const FULLPEL_MV start_fullmv = get_fullmv_from_mv(this_mv); 793 av1_make_default_fullpel_ms_params(&full_ms_params, cpi, x, bsize, 794 &ref_mv.as_mv, start_fullmv, 795 src_search_sites, search_method, 796 /*fine_search_interval=*/0); 797 798 av1_set_ms_compound_refs(&full_ms_params.ms_buffers, second_pred, mask, 799 mask_stride, ref_idx); 800 801 // Small-range full-pixel motion search. 802 bestsme = av1_full_pixel_search(start_fullmv, &full_ms_params, 5, NULL, 803 &best_mv.as_fullmv, &best_mv_stats, NULL); 804 805 if (scaled_ref_frame) { 806 // Swap back the original buffers for subpel motion search for the 0th slot. 807 for (int i = 0; i < num_planes; i++) { 808 xd->plane[i].pre[0] = backup_yv12[i]; 809 } 810 } 811 812 if (cpi->common.features.cur_frame_force_integer_mv) { 813 convert_fullmv_to_mv(&best_mv); 814 } 815 const int use_fractional_mv = 816 bestsme < INT_MAX && cpi->common.features.cur_frame_force_integer_mv == 0; 817 if (use_fractional_mv) { 818 int dis; /* TODO: use dis in distortion calculation later. */ 819 unsigned int sse; 820 SUBPEL_MOTION_SEARCH_PARAMS ms_params; 821 av1_make_default_subpel_ms_params(&ms_params, cpi, x, bsize, &ref_mv.as_mv, 822 NULL); 823 av1_set_ms_compound_refs(&ms_params.var_params.ms_buffers, second_pred, 824 mask, mask_stride, ref_idx); 825 ms_params.forced_stop = EIGHTH_PEL; 826 MV start_mv = get_mv_from_fullmv(&best_mv.as_fullmv); 827 assert(av1_is_subpelmv_in_range(&ms_params.mv_limits, start_mv)); 828 bestsme = cpi->mv_search_params.find_fractional_mv_step( 829 xd, cm, &ms_params, start_mv, &best_mv_stats, &best_mv.as_mv, &dis, 830 &sse, NULL); 831 } 832 833 // Restore the pointer to the first unscaled prediction buffer. 834 if (ref_idx) pd->pre[0] = orig_yv12; 835 836 if (bestsme < INT_MAX) *this_mv = best_mv.as_mv; 837 838 *rate_mv = 0; 839 840 *rate_mv += av1_mv_bit_cost(this_mv, &ref_mv.as_mv, mv_costs->nmv_joint_cost, 841 mv_costs->mv_cost_stack, MV_COST_WEIGHT); 842 return bestsme; 843 } 844 845 static inline void build_second_inter_pred(const AV1_COMP *cpi, MACROBLOCK *x, 846 BLOCK_SIZE bsize, const MV *other_mv, 847 int ref_idx, uint8_t *second_pred) { 848 const AV1_COMMON *const cm = &cpi->common; 849 const int pw = block_size_wide[bsize]; 850 const int ph = block_size_high[bsize]; 851 MACROBLOCKD *xd = &x->e_mbd; 852 MB_MODE_INFO *mbmi = xd->mi[0]; 853 struct macroblockd_plane *const pd = &xd->plane[0]; 854 const int mi_row = xd->mi_row; 855 const int mi_col = xd->mi_col; 856 const int p_col = ((mi_col * MI_SIZE) >> pd->subsampling_x); 857 const int p_row = ((mi_row * MI_SIZE) >> pd->subsampling_y); 858 859 // This function should only ever be called for compound modes 860 assert(has_second_ref(mbmi)); 861 862 const int plane = 0; 863 struct buf_2d ref_yv12 = xd->plane[plane].pre[!ref_idx]; 864 865 struct scale_factors sf; 866 av1_setup_scale_factors_for_frame(&sf, ref_yv12.width, ref_yv12.height, 867 cm->width, cm->height); 868 869 InterPredParams inter_pred_params; 870 871 av1_init_inter_params(&inter_pred_params, pw, ph, p_row, p_col, 872 pd->subsampling_x, pd->subsampling_y, xd->bd, 873 is_cur_buf_hbd(xd), 0, &sf, &ref_yv12, 874 mbmi->interp_filters); 875 inter_pred_params.conv_params = get_conv_params(0, plane, xd->bd); 876 877 // Get the prediction block from the 'other' reference frame. 878 av1_enc_build_one_inter_predictor(second_pred, pw, other_mv, 879 &inter_pred_params); 880 } 881 882 // Wrapper for av1_compound_single_motion_search, for the common case 883 // where the second prediction is also an inter mode. 884 static int compound_single_motion_search_interinter( 885 const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int_mv *cur_mv, 886 const uint8_t *mask, int mask_stride, int *rate_mv, int ref_idx) { 887 MACROBLOCKD *xd = &x->e_mbd; 888 // This function should only ever be called for compound modes 889 assert(has_second_ref(xd->mi[0])); 890 891 // Prediction buffer from second frame. 892 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[MAX_SB_SQUARE]); 893 uint8_t *second_pred; 894 if (is_cur_buf_hbd(xd)) 895 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16); 896 else 897 second_pred = (uint8_t *)second_pred_alloc_16; 898 899 MV *this_mv = &cur_mv[ref_idx].as_mv; 900 const MV *other_mv = &cur_mv[!ref_idx].as_mv; 901 build_second_inter_pred(cpi, x, bsize, other_mv, ref_idx, second_pred); 902 return av1_compound_single_motion_search(cpi, x, bsize, this_mv, second_pred, 903 mask, mask_stride, rate_mv, ref_idx); 904 } 905 906 static inline void do_masked_motion_search_indexed( 907 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv, 908 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE bsize, 909 int_mv *tmp_mv, int *rate_mv, int which) { 910 // NOTE: which values: 0 - 0 only, 1 - 1 only, 2 - both 911 MACROBLOCKD *xd = &x->e_mbd; 912 MB_MODE_INFO *mbmi = xd->mi[0]; 913 BLOCK_SIZE sb_type = mbmi->bsize; 914 const uint8_t *mask; 915 const int mask_stride = block_size_wide[bsize]; 916 917 mask = av1_get_compound_type_mask(comp_data, sb_type); 918 919 tmp_mv[0].as_int = cur_mv[0].as_int; 920 tmp_mv[1].as_int = cur_mv[1].as_int; 921 if (which == 0 || which == 1) { 922 compound_single_motion_search_interinter(cpi, x, bsize, tmp_mv, mask, 923 mask_stride, rate_mv, which); 924 } else if (which == 2) { 925 const int joint_me_num_refine_iter = 926 cpi->sf.inter_sf.enable_fast_compound_mode_search == 2 927 ? REDUCED_JOINT_ME_REFINE_ITER 928 : NUM_JOINT_ME_REFINE_ITER; 929 av1_joint_motion_search(cpi, x, bsize, tmp_mv, mask, mask_stride, rate_mv, 930 !cpi->sf.mv_sf.disable_second_mv, 931 joint_me_num_refine_iter); 932 } 933 } 934 935 int av1_interinter_compound_motion_search(const AV1_COMP *const cpi, 936 MACROBLOCK *x, 937 const int_mv *const cur_mv, 938 const BLOCK_SIZE bsize, 939 const PREDICTION_MODE this_mode) { 940 MACROBLOCKD *const xd = &x->e_mbd; 941 MB_MODE_INFO *const mbmi = xd->mi[0]; 942 int_mv tmp_mv[2]; 943 int tmp_rate_mv = 0; 944 // TODO(jingning): The average compound mode has proper SAD and variance 945 // functions implemented, and is triggerd by setting the mask pointer as 946 // Null. Need to further implement those for frame distance weighted mode. 947 mbmi->interinter_comp.seg_mask = 948 mbmi->interinter_comp.type == COMPOUND_AVERAGE ? NULL : xd->seg_mask; 949 const INTERINTER_COMPOUND_DATA *compound_data = &mbmi->interinter_comp; 950 951 if (this_mode == NEW_NEWMV) { 952 do_masked_motion_search_indexed(cpi, x, cur_mv, compound_data, bsize, 953 tmp_mv, &tmp_rate_mv, 2); 954 mbmi->mv[0].as_int = tmp_mv[0].as_int; 955 mbmi->mv[1].as_int = tmp_mv[1].as_int; 956 } else if (this_mode >= NEAREST_NEWMV && this_mode <= NEW_NEARMV) { 957 // which = 1 if this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV 958 // which = 0 if this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV 959 int which = (NEWMV == compound_ref1_mode(this_mode)); 960 do_masked_motion_search_indexed(cpi, x, cur_mv, compound_data, bsize, 961 tmp_mv, &tmp_rate_mv, which); 962 mbmi->mv[which].as_int = tmp_mv[which].as_int; 963 } 964 return tmp_rate_mv; 965 } 966 967 int_mv av1_simple_motion_search_sse_var(AV1_COMP *const cpi, MACROBLOCK *x, 968 int mi_row, int mi_col, 969 BLOCK_SIZE bsize, int ref, 970 FULLPEL_MV start_mv, int num_planes, 971 int use_subpixel, unsigned int *sse, 972 unsigned int *var) { 973 assert(num_planes == 1 && 974 "Currently simple_motion_search only supports luma plane"); 975 assert(!frame_is_intra_only(&cpi->common) && 976 "Simple motion search only enabled for non-key frames"); 977 AV1_COMMON *const cm = &cpi->common; 978 MACROBLOCKD *xd = &x->e_mbd; 979 980 set_offsets_for_motion_search(cpi, x, mi_row, mi_col, bsize); 981 982 MB_MODE_INFO *mbmi = xd->mi[0]; 983 mbmi->bsize = bsize; 984 mbmi->ref_frame[0] = ref; 985 mbmi->ref_frame[1] = NONE_FRAME; 986 mbmi->motion_mode = SIMPLE_TRANSLATION; 987 mbmi->interp_filters = av1_broadcast_interp_filter(EIGHTTAP_REGULAR); 988 989 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_yv12_buf(cm, ref); 990 const YV12_BUFFER_CONFIG *scaled_ref_frame = 991 av1_get_scaled_ref_frame(cpi, ref); 992 struct buf_2d backup_yv12; 993 // ref_mv is used to calculate the cost of the motion vector 994 const MV ref_mv = kZeroMv; 995 const int step_param = 996 AOMMIN(cpi->mv_search_params.mv_step_param + 997 cpi->sf.part_sf.simple_motion_search_reduce_search_steps, 998 MAX_MVSEARCH_STEPS - 2); 999 int cost_list[5]; 1000 const int ref_idx = 0; 1001 int bestsme; 1002 int_mv best_mv; 1003 FULLPEL_MV_STATS best_mv_stats; 1004 1005 av1_setup_pre_planes(xd, ref_idx, yv12, mi_row, mi_col, 1006 get_ref_scale_factors(cm, ref), num_planes); 1007 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]); 1008 if (scaled_ref_frame) { 1009 backup_yv12 = xd->plane[AOM_PLANE_Y].pre[ref_idx]; 1010 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL, 1011 num_planes); 1012 } 1013 1014 // Allow more mesh searches for screen content type on the ARF. 1015 const int fine_search_interval = use_fine_search_interval(cpi); 1016 FULLPEL_MOTION_SEARCH_PARAMS full_ms_params; 1017 const MV_SPEED_FEATURES *mv_sf = &cpi->sf.mv_sf; 1018 const SEARCH_METHODS search_method = 1019 av1_get_default_mv_search_method(x, mv_sf, bsize); 1020 const search_site_config *src_search_sites = 1021 av1_get_search_site_config(cpi, x, search_method); 1022 av1_make_default_fullpel_ms_params(&full_ms_params, cpi, x, bsize, &ref_mv, 1023 start_mv, src_search_sites, search_method, 1024 fine_search_interval); 1025 1026 bestsme = av1_full_pixel_search(start_mv, &full_ms_params, step_param, 1027 cond_cost_list(cpi, cost_list), 1028 &best_mv.as_fullmv, &best_mv_stats, NULL); 1029 1030 const int use_subpel_search = 1031 bestsme < INT_MAX && !cpi->common.features.cur_frame_force_integer_mv && 1032 use_subpixel && 1033 (cpi->sf.mv_sf.simple_motion_subpel_force_stop != FULL_PEL); 1034 if (scaled_ref_frame) { 1035 xd->plane[AOM_PLANE_Y].pre[ref_idx] = backup_yv12; 1036 } 1037 if (use_subpel_search) { 1038 int not_used = 0; 1039 1040 SUBPEL_MOTION_SEARCH_PARAMS ms_params; 1041 av1_make_default_subpel_ms_params(&ms_params, cpi, x, bsize, &ref_mv, 1042 cost_list); 1043 // TODO(yunqing): integrate this into av1_make_default_subpel_ms_params(). 1044 ms_params.forced_stop = mv_sf->simple_motion_subpel_force_stop; 1045 1046 MV subpel_start_mv = get_mv_from_fullmv(&best_mv.as_fullmv); 1047 assert(av1_is_subpelmv_in_range(&ms_params.mv_limits, subpel_start_mv)); 1048 1049 cpi->mv_search_params.find_fractional_mv_step( 1050 xd, cm, &ms_params, subpel_start_mv, &best_mv_stats, &best_mv.as_mv, 1051 ¬_used, &x->pred_sse[ref], NULL); 1052 1053 mbmi->mv[0] = best_mv; 1054 1055 // Get a copy of the prediction output 1056 av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, NULL, bsize, 1057 AOM_PLANE_Y, AOM_PLANE_Y); 1058 *var = cpi->ppi->fn_ptr[bsize].vf( 1059 x->plane[0].src.buf, x->plane[0].src.stride, xd->plane[0].dst.buf, 1060 xd->plane[0].dst.stride, sse); 1061 } else { 1062 // Manually convert from units of pixel to 1/8-pixels if we are not doing 1063 // subpel search 1064 convert_fullmv_to_mv(&best_mv); 1065 *var = best_mv_stats.distortion; 1066 *sse = best_mv_stats.sse; 1067 } 1068 1069 return best_mv; 1070 }