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 "findnearmv.h"
     12 
     13 const unsigned char vp8_mbsplit_offset[4][16] = {
     14   { 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
     15   { 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
     16   { 0, 2, 8, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
     17   { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }
     18 };
     19 
     20 /* Predict motion vectors using those from already-decoded nearby blocks.
     21    Note that we only consider one 4x4 subblock from each candidate 16x16
     22    macroblock.   */
     23 void vp8_find_near_mvs(MACROBLOCKD *xd, const MODE_INFO *here, int_mv *nearest,
     24                        int_mv *nearby, int_mv *best_mv, int cnt[4],
     25                        int refframe, int *ref_frame_sign_bias) {
     26   const MODE_INFO *above = here - xd->mode_info_stride;
     27   const MODE_INFO *left = here - 1;
     28   const MODE_INFO *aboveleft = above - 1;
     29   int_mv near_mvs[4];
     30   int_mv *mv = near_mvs;
     31   int *cntx = cnt;
     32   enum { CNT_INTRA, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV };
     33 
     34   /* Zero accumulators */
     35   mv[0].as_int = mv[1].as_int = mv[2].as_int = 0;
     36   cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
     37 
     38   /* Process above */
     39   if (above->mbmi.ref_frame != INTRA_FRAME) {
     40     if (above->mbmi.mv.as_int) {
     41       (++mv)->as_int = above->mbmi.mv.as_int;
     42       mv_bias(ref_frame_sign_bias[above->mbmi.ref_frame], refframe, mv,
     43               ref_frame_sign_bias);
     44       ++cntx;
     45     }
     46 
     47     *cntx += 2;
     48   }
     49 
     50   /* Process left */
     51   if (left->mbmi.ref_frame != INTRA_FRAME) {
     52     if (left->mbmi.mv.as_int) {
     53       int_mv this_mv;
     54 
     55       this_mv.as_int = left->mbmi.mv.as_int;
     56       mv_bias(ref_frame_sign_bias[left->mbmi.ref_frame], refframe, &this_mv,
     57               ref_frame_sign_bias);
     58 
     59       if (this_mv.as_int != mv->as_int) {
     60         (++mv)->as_int = this_mv.as_int;
     61         ++cntx;
     62       }
     63 
     64       *cntx += 2;
     65     } else {
     66       cnt[CNT_INTRA] += 2;
     67     }
     68   }
     69 
     70   /* Process above left */
     71   if (aboveleft->mbmi.ref_frame != INTRA_FRAME) {
     72     if (aboveleft->mbmi.mv.as_int) {
     73       int_mv this_mv;
     74 
     75       this_mv.as_int = aboveleft->mbmi.mv.as_int;
     76       mv_bias(ref_frame_sign_bias[aboveleft->mbmi.ref_frame], refframe,
     77               &this_mv, ref_frame_sign_bias);
     78 
     79       if (this_mv.as_int != mv->as_int) {
     80         (++mv)->as_int = this_mv.as_int;
     81         ++cntx;
     82       }
     83 
     84       *cntx += 1;
     85     } else {
     86       cnt[CNT_INTRA] += 1;
     87     }
     88   }
     89 
     90   /* If we have three distinct MV's ... */
     91   if (cnt[CNT_SPLITMV]) {
     92     /* See if above-left MV can be merged with NEAREST */
     93     if (mv->as_int == near_mvs[CNT_NEAREST].as_int) cnt[CNT_NEAREST] += 1;
     94   }
     95 
     96   cnt[CNT_SPLITMV] =
     97       ((above->mbmi.mode == SPLITMV) + (left->mbmi.mode == SPLITMV)) * 2 +
     98       (aboveleft->mbmi.mode == SPLITMV);
     99 
    100   /* Swap near and nearest if necessary */
    101   if (cnt[CNT_NEAR] > cnt[CNT_NEAREST]) {
    102     int tmp;
    103     tmp = cnt[CNT_NEAREST];
    104     cnt[CNT_NEAREST] = cnt[CNT_NEAR];
    105     cnt[CNT_NEAR] = tmp;
    106     tmp = near_mvs[CNT_NEAREST].as_int;
    107     near_mvs[CNT_NEAREST].as_int = near_mvs[CNT_NEAR].as_int;
    108     near_mvs[CNT_NEAR].as_int = tmp;
    109   }
    110 
    111   /* Use near_mvs[0] to store the "best" MV */
    112   if (cnt[CNT_NEAREST] >= cnt[CNT_INTRA]) {
    113     near_mvs[CNT_INTRA] = near_mvs[CNT_NEAREST];
    114   }
    115 
    116   /* Set up return values */
    117   best_mv->as_int = near_mvs[0].as_int;
    118   nearest->as_int = near_mvs[CNT_NEAREST].as_int;
    119   nearby->as_int = near_mvs[CNT_NEAR].as_int;
    120 }
    121 
    122 static void invert_and_clamp_mvs(int_mv *inv, int_mv *src, MACROBLOCKD *xd) {
    123   inv->as_mv.row = src->as_mv.row * -1;
    124   inv->as_mv.col = src->as_mv.col * -1;
    125   vp8_clamp_mv2(inv, xd);
    126   vp8_clamp_mv2(src, xd);
    127 }
    128 
    129 int vp8_find_near_mvs_bias(MACROBLOCKD *xd, const MODE_INFO *here,
    130                            int_mv mode_mv_sb[2][MB_MODE_COUNT],
    131                            int_mv best_mv_sb[2], int cnt[4], int refframe,
    132                            int *ref_frame_sign_bias) {
    133   int sign_bias = ref_frame_sign_bias[refframe];
    134 
    135   vp8_find_near_mvs(xd, here, &mode_mv_sb[sign_bias][NEARESTMV],
    136                     &mode_mv_sb[sign_bias][NEARMV], &best_mv_sb[sign_bias], cnt,
    137                     refframe, ref_frame_sign_bias);
    138 
    139   invert_and_clamp_mvs(&mode_mv_sb[!sign_bias][NEARESTMV],
    140                        &mode_mv_sb[sign_bias][NEARESTMV], xd);
    141   invert_and_clamp_mvs(&mode_mv_sb[!sign_bias][NEARMV],
    142                        &mode_mv_sb[sign_bias][NEARMV], xd);
    143   invert_and_clamp_mvs(&best_mv_sb[!sign_bias], &best_mv_sb[sign_bias], xd);
    144 
    145   return sign_bias;
    146 }
    147 
    148 vp8_prob *vp8_mv_ref_probs(vp8_prob p[VP8_MVREFS - 1],
    149                            const int near_mv_ref_ct[4]) {
    150   p[0] = vp8_mode_contexts[near_mv_ref_ct[0]][0];
    151   p[1] = vp8_mode_contexts[near_mv_ref_ct[1]][1];
    152   p[2] = vp8_mode_contexts[near_mv_ref_ct[2]][2];
    153   p[3] = vp8_mode_contexts[near_mv_ref_ct[3]][3];
    154   /* p[3] = vp8_mode_contexts[near_mv_ref_ct[1] + near_mv_ref_ct[2] +
    155                            near_mv_ref_ct[3]][3]; */
    156   return p;
    157 }
    158