media/libvpx/vp8/common/findnearmv.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/media/libvpx/vp8/common/findnearmv.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,193 @@
     1.4 +/*
     1.5 + *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
     1.6 + *
     1.7 + *  Use of this source code is governed by a BSD-style license
     1.8 + *  that can be found in the LICENSE file in the root of the source
     1.9 + *  tree. An additional intellectual property rights grant can be found
    1.10 + *  in the file PATENTS.  All contributing project authors may
    1.11 + *  be found in the AUTHORS file in the root of the source tree.
    1.12 + */
    1.13 +
    1.14 +
    1.15 +#include "findnearmv.h"
    1.16 +
    1.17 +const unsigned char vp8_mbsplit_offset[4][16] = {
    1.18 +    { 0,  8,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0},
    1.19 +    { 0,  2,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0},
    1.20 +    { 0,  2,  8, 10,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0},
    1.21 +    { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15}
    1.22 +};
    1.23 +
    1.24 +/* Predict motion vectors using those from already-decoded nearby blocks.
    1.25 +   Note that we only consider one 4x4 subblock from each candidate 16x16
    1.26 +   macroblock.   */
    1.27 +void vp8_find_near_mvs
    1.28 +(
    1.29 +    MACROBLOCKD *xd,
    1.30 +    const MODE_INFO *here,
    1.31 +    int_mv *nearest,
    1.32 +    int_mv *nearby,
    1.33 +    int_mv *best_mv,
    1.34 +    int cnt[4],
    1.35 +    int refframe,
    1.36 +    int *ref_frame_sign_bias
    1.37 +)
    1.38 +{
    1.39 +    const MODE_INFO *above = here - xd->mode_info_stride;
    1.40 +    const MODE_INFO *left = here - 1;
    1.41 +    const MODE_INFO *aboveleft = above - 1;
    1.42 +    int_mv            near_mvs[4];
    1.43 +    int_mv           *mv = near_mvs;
    1.44 +    int             *cntx = cnt;
    1.45 +    enum {CNT_INTRA, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV};
    1.46 +
    1.47 +    /* Zero accumulators */
    1.48 +    mv[0].as_int = mv[1].as_int = mv[2].as_int = 0;
    1.49 +    cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
    1.50 +
    1.51 +    /* Process above */
    1.52 +    if (above->mbmi.ref_frame != INTRA_FRAME)
    1.53 +    {
    1.54 +        if (above->mbmi.mv.as_int)
    1.55 +        {
    1.56 +            (++mv)->as_int = above->mbmi.mv.as_int;
    1.57 +            mv_bias(ref_frame_sign_bias[above->mbmi.ref_frame], refframe, mv, ref_frame_sign_bias);
    1.58 +            ++cntx;
    1.59 +        }
    1.60 +
    1.61 +        *cntx += 2;
    1.62 +    }
    1.63 +
    1.64 +    /* Process left */
    1.65 +    if (left->mbmi.ref_frame != INTRA_FRAME)
    1.66 +    {
    1.67 +        if (left->mbmi.mv.as_int)
    1.68 +        {
    1.69 +            int_mv this_mv;
    1.70 +
    1.71 +            this_mv.as_int = left->mbmi.mv.as_int;
    1.72 +            mv_bias(ref_frame_sign_bias[left->mbmi.ref_frame], refframe, &this_mv, ref_frame_sign_bias);
    1.73 +
    1.74 +            if (this_mv.as_int != mv->as_int)
    1.75 +            {
    1.76 +                (++mv)->as_int = this_mv.as_int;
    1.77 +                ++cntx;
    1.78 +            }
    1.79 +
    1.80 +            *cntx += 2;
    1.81 +        }
    1.82 +        else
    1.83 +            cnt[CNT_INTRA] += 2;
    1.84 +    }
    1.85 +
    1.86 +    /* Process above left */
    1.87 +    if (aboveleft->mbmi.ref_frame != INTRA_FRAME)
    1.88 +    {
    1.89 +        if (aboveleft->mbmi.mv.as_int)
    1.90 +        {
    1.91 +            int_mv this_mv;
    1.92 +
    1.93 +            this_mv.as_int = aboveleft->mbmi.mv.as_int;
    1.94 +            mv_bias(ref_frame_sign_bias[aboveleft->mbmi.ref_frame], refframe, &this_mv, ref_frame_sign_bias);
    1.95 +
    1.96 +            if (this_mv.as_int != mv->as_int)
    1.97 +            {
    1.98 +                (++mv)->as_int = this_mv.as_int;
    1.99 +                ++cntx;
   1.100 +            }
   1.101 +
   1.102 +            *cntx += 1;
   1.103 +        }
   1.104 +        else
   1.105 +            cnt[CNT_INTRA] += 1;
   1.106 +    }
   1.107 +
   1.108 +    /* If we have three distinct MV's ... */
   1.109 +    if (cnt[CNT_SPLITMV])
   1.110 +    {
   1.111 +        /* See if above-left MV can be merged with NEAREST */
   1.112 +        if (mv->as_int == near_mvs[CNT_NEAREST].as_int)
   1.113 +            cnt[CNT_NEAREST] += 1;
   1.114 +    }
   1.115 +
   1.116 +    cnt[CNT_SPLITMV] = ((above->mbmi.mode == SPLITMV)
   1.117 +                        + (left->mbmi.mode == SPLITMV)) * 2
   1.118 +                       + (aboveleft->mbmi.mode == SPLITMV);
   1.119 +
   1.120 +    /* Swap near and nearest if necessary */
   1.121 +    if (cnt[CNT_NEAR] > cnt[CNT_NEAREST])
   1.122 +    {
   1.123 +        int tmp;
   1.124 +        tmp = cnt[CNT_NEAREST];
   1.125 +        cnt[CNT_NEAREST] = cnt[CNT_NEAR];
   1.126 +        cnt[CNT_NEAR] = tmp;
   1.127 +        tmp = near_mvs[CNT_NEAREST].as_int;
   1.128 +        near_mvs[CNT_NEAREST].as_int = near_mvs[CNT_NEAR].as_int;
   1.129 +        near_mvs[CNT_NEAR].as_int = tmp;
   1.130 +    }
   1.131 +
   1.132 +    /* Use near_mvs[0] to store the "best" MV */
   1.133 +    if (cnt[CNT_NEAREST] >= cnt[CNT_INTRA])
   1.134 +        near_mvs[CNT_INTRA] = near_mvs[CNT_NEAREST];
   1.135 +
   1.136 +    /* Set up return values */
   1.137 +    best_mv->as_int = near_mvs[0].as_int;
   1.138 +    nearest->as_int = near_mvs[CNT_NEAREST].as_int;
   1.139 +    nearby->as_int = near_mvs[CNT_NEAR].as_int;
   1.140 +}
   1.141 +
   1.142 +
   1.143 +static void invert_and_clamp_mvs(int_mv *inv, int_mv *src, MACROBLOCKD *xd)
   1.144 +{
   1.145 +    inv->as_mv.row = src->as_mv.row * -1;
   1.146 +    inv->as_mv.col = src->as_mv.col * -1;
   1.147 +    vp8_clamp_mv2(inv, xd);
   1.148 +    vp8_clamp_mv2(src, xd);
   1.149 +}
   1.150 +
   1.151 +
   1.152 +int vp8_find_near_mvs_bias
   1.153 +(
   1.154 +    MACROBLOCKD *xd,
   1.155 +    const MODE_INFO *here,
   1.156 +    int_mv mode_mv_sb[2][MB_MODE_COUNT],
   1.157 +    int_mv best_mv_sb[2],
   1.158 +    int cnt[4],
   1.159 +    int refframe,
   1.160 +    int *ref_frame_sign_bias
   1.161 +)
   1.162 +{
   1.163 +    int sign_bias = ref_frame_sign_bias[refframe];
   1.164 +
   1.165 +    vp8_find_near_mvs(xd,
   1.166 +                      here,
   1.167 +                      &mode_mv_sb[sign_bias][NEARESTMV],
   1.168 +                      &mode_mv_sb[sign_bias][NEARMV],
   1.169 +                      &best_mv_sb[sign_bias],
   1.170 +                      cnt,
   1.171 +                      refframe,
   1.172 +                      ref_frame_sign_bias);
   1.173 +
   1.174 +    invert_and_clamp_mvs(&mode_mv_sb[!sign_bias][NEARESTMV],
   1.175 +                         &mode_mv_sb[sign_bias][NEARESTMV], xd);
   1.176 +    invert_and_clamp_mvs(&mode_mv_sb[!sign_bias][NEARMV],
   1.177 +                         &mode_mv_sb[sign_bias][NEARMV], xd);
   1.178 +    invert_and_clamp_mvs(&best_mv_sb[!sign_bias],
   1.179 +                         &best_mv_sb[sign_bias], xd);
   1.180 +
   1.181 +    return sign_bias;
   1.182 +}
   1.183 +
   1.184 +
   1.185 +vp8_prob *vp8_mv_ref_probs(
   1.186 +    vp8_prob p[VP8_MVREFS-1], const int near_mv_ref_ct[4]
   1.187 +)
   1.188 +{
   1.189 +    p[0] = vp8_mode_contexts [near_mv_ref_ct[0]] [0];
   1.190 +    p[1] = vp8_mode_contexts [near_mv_ref_ct[1]] [1];
   1.191 +    p[2] = vp8_mode_contexts [near_mv_ref_ct[2]] [2];
   1.192 +    p[3] = vp8_mode_contexts [near_mv_ref_ct[3]] [3];
   1.193 +    /*p[3] = vp8_mode_contexts [near_mv_ref_ct[1] + near_mv_ref_ct[2] + near_mv_ref_ct[3]] [3];*/
   1.194 +    return p;
   1.195 +}
   1.196 +

mercurial