Home | History | Annotate | Download | only in common
      1 /*
      2  *  Copyright (c) 2010 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 "vp9/common/vp9_findnearmv.h"
     12 #include "vp9/common/vp9_mvref_common.h"
     13 
     14 static void lower_mv_precision(MV *mv, int allow_hp) {
     15   const int use_hp = allow_hp && vp9_use_mv_hp(mv);
     16   if (!use_hp) {
     17     if (mv->row & 1)
     18       mv->row += (mv->row > 0 ? -1 : 1);
     19     if (mv->col & 1)
     20       mv->col += (mv->col > 0 ? -1 : 1);
     21   }
     22 }
     23 
     24 
     25 void vp9_find_best_ref_mvs(MACROBLOCKD *xd,
     26                            int_mv *mvlist,
     27                            int_mv *nearest,
     28                            int_mv *near) {
     29   int i;
     30   // Make sure all the candidates are properly clamped etc
     31   for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) {
     32     lower_mv_precision(&mvlist[i].as_mv, xd->allow_high_precision_mv);
     33     clamp_mv2(&mvlist[i].as_mv, xd);
     34   }
     35   *nearest = mvlist[0];
     36   *near = mvlist[1];
     37 }
     38 
     39 void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd,
     40                                    int_mv *dst_nearest,
     41                                    int_mv *dst_near,
     42                                    int block_idx, int ref_idx,
     43                                    int mi_row, int mi_col) {
     44   int_mv dst_list[MAX_MV_REF_CANDIDATES];
     45   int_mv mv_list[MAX_MV_REF_CANDIDATES];
     46   MODE_INFO *const mi = xd->this_mi;
     47 
     48   assert(ref_idx == 0 || ref_idx == 1);
     49   assert(MAX_MV_REF_CANDIDATES == 2);  // makes code here slightly easier
     50 
     51   vp9_find_mv_refs_idx(cm, xd, mi, xd->last_mi,
     52                        mi->mbmi.ref_frame[ref_idx],
     53                        mv_list, block_idx, mi_row, mi_col);
     54 
     55   dst_list[1].as_int = 0;
     56   if (block_idx == 0) {
     57     memcpy(dst_list, mv_list, MAX_MV_REF_CANDIDATES * sizeof(int_mv));
     58   } else if (block_idx == 1 || block_idx == 2) {
     59     int dst = 0, n;
     60     union b_mode_info *bmi = mi->bmi;
     61 
     62     dst_list[dst++].as_int = bmi[0].as_mv[ref_idx].as_int;
     63     for (n = 0; dst < MAX_MV_REF_CANDIDATES &&
     64                 n < MAX_MV_REF_CANDIDATES; n++)
     65       if (mv_list[n].as_int != dst_list[0].as_int)
     66         dst_list[dst++].as_int = mv_list[n].as_int;
     67   } else {
     68     int dst = 0, n;
     69     union b_mode_info *bmi = mi->bmi;
     70 
     71     assert(block_idx == 3);
     72     dst_list[dst++].as_int = bmi[2].as_mv[ref_idx].as_int;
     73     if (dst_list[0].as_int != bmi[1].as_mv[ref_idx].as_int)
     74       dst_list[dst++].as_int = bmi[1].as_mv[ref_idx].as_int;
     75     if (dst < MAX_MV_REF_CANDIDATES &&
     76         dst_list[0].as_int != bmi[0].as_mv[ref_idx].as_int)
     77       dst_list[dst++].as_int = bmi[0].as_mv[ref_idx].as_int;
     78     for (n = 0; dst < MAX_MV_REF_CANDIDATES &&
     79                 n < MAX_MV_REF_CANDIDATES; n++)
     80       if (mv_list[n].as_int != dst_list[0].as_int)
     81         dst_list[dst++].as_int = mv_list[n].as_int;
     82   }
     83 
     84   dst_nearest->as_int = dst_list[0].as_int;
     85   dst_near->as_int = dst_list[1].as_int;
     86 }
     87