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, int allow_hp,
     26                            int_mv *mvlist, int_mv *nearest, int_mv *near) {
     27   int i;
     28   // Make sure all the candidates are properly clamped etc
     29   for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) {
     30     lower_mv_precision(&mvlist[i].as_mv, allow_hp);
     31     clamp_mv2(&mvlist[i].as_mv, xd);
     32   }
     33   *nearest = mvlist[0];
     34   *near = mvlist[1];
     35 }
     36 
     37 void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd,
     38                                    const TileInfo *const tile,
     39                                    int_mv *dst_nearest,
     40                                    int_mv *dst_near,
     41                                    int block_idx, int ref_idx,
     42                                    int mi_row, int mi_col) {
     43   int_mv dst_list[MAX_MV_REF_CANDIDATES];
     44   int_mv mv_list[MAX_MV_REF_CANDIDATES];
     45   MODE_INFO *const mi = xd->mi_8x8[0];
     46 
     47   assert(ref_idx == 0 || ref_idx == 1);
     48   assert(MAX_MV_REF_CANDIDATES == 2);  // makes code here slightly easier
     49 
     50   vp9_find_mv_refs_idx(cm, xd, tile, mi, xd->last_mi,
     51                        mi->mbmi.ref_frame[ref_idx],
     52                        mv_list, block_idx, mi_row, mi_col);
     53 
     54   dst_list[1].as_int = 0;
     55   if (block_idx == 0) {
     56     vpx_memcpy(dst_list, mv_list, MAX_MV_REF_CANDIDATES * sizeof(int_mv));
     57   } else if (block_idx == 1 || block_idx == 2) {
     58     int dst = 0, n;
     59     b_mode_info *bmi = mi->bmi;
     60 
     61     dst_list[dst++].as_int = bmi[0].as_mv[ref_idx].as_int;
     62     for (n = 0; dst < MAX_MV_REF_CANDIDATES &&
     63                 n < MAX_MV_REF_CANDIDATES; n++)
     64       if (mv_list[n].as_int != dst_list[0].as_int)
     65         dst_list[dst++].as_int = mv_list[n].as_int;
     66   } else {
     67     int dst = 0, n;
     68     b_mode_info *bmi = mi->bmi;
     69 
     70     assert(block_idx == 3);
     71     dst_list[dst++].as_int = bmi[2].as_mv[ref_idx].as_int;
     72     if (dst_list[0].as_int != bmi[1].as_mv[ref_idx].as_int)
     73       dst_list[dst++].as_int = bmi[1].as_mv[ref_idx].as_int;
     74     if (dst < MAX_MV_REF_CANDIDATES &&
     75         dst_list[0].as_int != bmi[0].as_mv[ref_idx].as_int)
     76       dst_list[dst++].as_int = bmi[0].as_mv[ref_idx].as_int;
     77     for (n = 0; dst < MAX_MV_REF_CANDIDATES &&
     78                 n < MAX_MV_REF_CANDIDATES; n++)
     79       if (mv_list[n].as_int != dst_list[0].as_int)
     80         dst_list[dst++].as_int = mv_list[n].as_int;
     81   }
     82 
     83   dst_nearest->as_int = dst_list[0].as_int;
     84   dst_near->as_int = dst_list[1].as_int;
     85 }
     86