media/libvpx/vp8/encoder/encodemv.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/media/libvpx/vp8/encoder/encodemv.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,380 @@
     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 "vp8/common/common.h"
    1.16 +#include "encodemv.h"
    1.17 +#include "vp8/common/entropymode.h"
    1.18 +#include "vp8/common/systemdependent.h"
    1.19 +
    1.20 +#include <math.h>
    1.21 +
    1.22 +#ifdef VP8_ENTROPY_STATS
    1.23 +extern unsigned int active_section;
    1.24 +#endif
    1.25 +
    1.26 +static void encode_mvcomponent(
    1.27 +    vp8_writer *const w,
    1.28 +    const int v,
    1.29 +    const struct mv_context *mvc
    1.30 +)
    1.31 +{
    1.32 +    const vp8_prob *p = mvc->prob;
    1.33 +    const int x = v < 0 ? -v : v;
    1.34 +
    1.35 +    if (x < mvnum_short)     /* Small */
    1.36 +    {
    1.37 +        vp8_write(w, 0, p [mvpis_short]);
    1.38 +        vp8_treed_write(w, vp8_small_mvtree, p + MVPshort, x, 3);
    1.39 +
    1.40 +        if (!x)
    1.41 +            return;         /* no sign bit */
    1.42 +    }
    1.43 +    else                    /* Large */
    1.44 +    {
    1.45 +        int i = 0;
    1.46 +
    1.47 +        vp8_write(w, 1, p [mvpis_short]);
    1.48 +
    1.49 +        do
    1.50 +            vp8_write(w, (x >> i) & 1, p [MVPbits + i]);
    1.51 +
    1.52 +        while (++i < 3);
    1.53 +
    1.54 +        i = mvlong_width - 1;  /* Skip bit 3, which is sometimes implicit */
    1.55 +
    1.56 +        do
    1.57 +            vp8_write(w, (x >> i) & 1, p [MVPbits + i]);
    1.58 +
    1.59 +        while (--i > 3);
    1.60 +
    1.61 +        if (x & 0xFFF0)
    1.62 +            vp8_write(w, (x >> 3) & 1, p [MVPbits + 3]);
    1.63 +    }
    1.64 +
    1.65 +    vp8_write(w, v < 0, p [MVPsign]);
    1.66 +}
    1.67 +#if 0
    1.68 +static int max_mv_r = 0;
    1.69 +static int max_mv_c = 0;
    1.70 +#endif
    1.71 +void vp8_encode_motion_vector(vp8_writer *w, const MV *mv, const MV_CONTEXT *mvc)
    1.72 +{
    1.73 +
    1.74 +#if 0
    1.75 +    {
    1.76 +        if (abs(mv->row >> 1) > max_mv_r)
    1.77 +        {
    1.78 +            FILE *f = fopen("maxmv.stt", "a");
    1.79 +            max_mv_r = abs(mv->row >> 1);
    1.80 +            fprintf(f, "New Mv Row Max %6d\n", (mv->row >> 1));
    1.81 +
    1.82 +            if ((abs(mv->row) / 2) != max_mv_r)
    1.83 +                fprintf(f, "MV Row conversion error %6d\n", abs(mv->row) / 2);
    1.84 +
    1.85 +            fclose(f);
    1.86 +        }
    1.87 +
    1.88 +        if (abs(mv->col >> 1) > max_mv_c)
    1.89 +        {
    1.90 +            FILE *f = fopen("maxmv.stt", "a");
    1.91 +            fprintf(f, "New Mv Col Max %6d\n", (mv->col >> 1));
    1.92 +            max_mv_c = abs(mv->col >> 1);
    1.93 +            fclose(f);
    1.94 +        }
    1.95 +    }
    1.96 +#endif
    1.97 +
    1.98 +    encode_mvcomponent(w, mv->row >> 1, &mvc[0]);
    1.99 +    encode_mvcomponent(w, mv->col >> 1, &mvc[1]);
   1.100 +}
   1.101 +
   1.102 +
   1.103 +static unsigned int cost_mvcomponent(const int v, const struct mv_context *mvc)
   1.104 +{
   1.105 +    const vp8_prob *p = mvc->prob;
   1.106 +    const int x = v;
   1.107 +    unsigned int cost;
   1.108 +
   1.109 +    if (x < mvnum_short)
   1.110 +    {
   1.111 +        cost = vp8_cost_zero(p [mvpis_short])
   1.112 +               + vp8_treed_cost(vp8_small_mvtree, p + MVPshort, x, 3);
   1.113 +
   1.114 +        if (!x)
   1.115 +            return cost;
   1.116 +    }
   1.117 +    else
   1.118 +    {
   1.119 +        int i = 0;
   1.120 +        cost = vp8_cost_one(p [mvpis_short]);
   1.121 +
   1.122 +        do
   1.123 +            cost += vp8_cost_bit(p [MVPbits + i], (x >> i) & 1);
   1.124 +
   1.125 +        while (++i < 3);
   1.126 +
   1.127 +        i = mvlong_width - 1;  /* Skip bit 3, which is sometimes implicit */
   1.128 +
   1.129 +        do
   1.130 +            cost += vp8_cost_bit(p [MVPbits + i], (x >> i) & 1);
   1.131 +
   1.132 +        while (--i > 3);
   1.133 +
   1.134 +        if (x & 0xFFF0)
   1.135 +            cost += vp8_cost_bit(p [MVPbits + 3], (x >> 3) & 1);
   1.136 +    }
   1.137 +
   1.138 +    return cost;   /* + vp8_cost_bit( p [MVPsign], v < 0); */
   1.139 +}
   1.140 +
   1.141 +void vp8_build_component_cost_table(int *mvcost[2], const MV_CONTEXT *mvc, int mvc_flag[2])
   1.142 +{
   1.143 +    int i = 1;
   1.144 +    unsigned int cost0 = 0;
   1.145 +    unsigned int cost1 = 0;
   1.146 +
   1.147 +    vp8_clear_system_state();
   1.148 +
   1.149 +    i = 1;
   1.150 +
   1.151 +    if (mvc_flag[0])
   1.152 +    {
   1.153 +        mvcost [0] [0] = cost_mvcomponent(0, &mvc[0]);
   1.154 +
   1.155 +        do
   1.156 +        {
   1.157 +            cost0 = cost_mvcomponent(i, &mvc[0]);
   1.158 +
   1.159 +            mvcost [0] [i] = cost0 + vp8_cost_zero(mvc[0].prob[MVPsign]);
   1.160 +            mvcost [0] [-i] = cost0 + vp8_cost_one(mvc[0].prob[MVPsign]);
   1.161 +        }
   1.162 +        while (++i <= mv_max);
   1.163 +    }
   1.164 +
   1.165 +    i = 1;
   1.166 +
   1.167 +    if (mvc_flag[1])
   1.168 +    {
   1.169 +        mvcost [1] [0] = cost_mvcomponent(0, &mvc[1]);
   1.170 +
   1.171 +        do
   1.172 +        {
   1.173 +            cost1 = cost_mvcomponent(i, &mvc[1]);
   1.174 +
   1.175 +            mvcost [1] [i] = cost1 + vp8_cost_zero(mvc[1].prob[MVPsign]);
   1.176 +            mvcost [1] [-i] = cost1 + vp8_cost_one(mvc[1].prob[MVPsign]);
   1.177 +        }
   1.178 +        while (++i <= mv_max);
   1.179 +    }
   1.180 +}
   1.181 +
   1.182 +
   1.183 +/* Motion vector probability table update depends on benefit.
   1.184 + * Small correction allows for the fact that an update to an MV probability
   1.185 + * may have benefit in subsequent frames as well as the current one.
   1.186 + */
   1.187 +#define MV_PROB_UPDATE_CORRECTION   -1
   1.188 +
   1.189 +
   1.190 +static void calc_prob(vp8_prob *p, const unsigned int ct[2])
   1.191 +{
   1.192 +    const unsigned int tot = ct[0] + ct[1];
   1.193 +
   1.194 +    if (tot)
   1.195 +    {
   1.196 +        const vp8_prob x = ((ct[0] * 255) / tot) & -2;
   1.197 +        *p = x ? x : 1;
   1.198 +    }
   1.199 +}
   1.200 +
   1.201 +static void update(
   1.202 +    vp8_writer *const w,
   1.203 +    const unsigned int ct[2],
   1.204 +    vp8_prob *const cur_p,
   1.205 +    const vp8_prob new_p,
   1.206 +    const vp8_prob update_p,
   1.207 +    int *updated
   1.208 +)
   1.209 +{
   1.210 +    const int cur_b = vp8_cost_branch(ct, *cur_p);
   1.211 +    const int new_b = vp8_cost_branch(ct, new_p);
   1.212 +    const int cost = 7 + MV_PROB_UPDATE_CORRECTION + ((vp8_cost_one(update_p) - vp8_cost_zero(update_p) + 128) >> 8);
   1.213 +
   1.214 +    if (cur_b - new_b > cost)
   1.215 +    {
   1.216 +        *cur_p = new_p;
   1.217 +        vp8_write(w, 1, update_p);
   1.218 +        vp8_write_literal(w, new_p >> 1, 7);
   1.219 +        *updated = 1;
   1.220 +
   1.221 +    }
   1.222 +    else
   1.223 +        vp8_write(w, 0, update_p);
   1.224 +}
   1.225 +
   1.226 +static void write_component_probs(
   1.227 +    vp8_writer *const w,
   1.228 +    struct mv_context *cur_mvc,
   1.229 +    const struct mv_context *default_mvc_,
   1.230 +    const struct mv_context *update_mvc,
   1.231 +    const unsigned int events [MVvals],
   1.232 +    unsigned int rc,
   1.233 +    int *updated
   1.234 +)
   1.235 +{
   1.236 +    vp8_prob *Pcur = cur_mvc->prob;
   1.237 +    const vp8_prob *default_mvc = default_mvc_->prob;
   1.238 +    const vp8_prob *Pupdate = update_mvc->prob;
   1.239 +    unsigned int is_short_ct[2], sign_ct[2];
   1.240 +
   1.241 +    unsigned int bit_ct [mvlong_width] [2];
   1.242 +
   1.243 +    unsigned int short_ct  [mvnum_short];
   1.244 +    unsigned int short_bct [mvnum_short-1] [2];
   1.245 +
   1.246 +    vp8_prob Pnew [MVPcount];
   1.247 +
   1.248 +    (void) rc;
   1.249 +    vp8_copy_array(Pnew, default_mvc, MVPcount);
   1.250 +
   1.251 +    vp8_zero(is_short_ct)
   1.252 +    vp8_zero(sign_ct)
   1.253 +    vp8_zero(bit_ct)
   1.254 +    vp8_zero(short_ct)
   1.255 +    vp8_zero(short_bct)
   1.256 +
   1.257 +
   1.258 +    /* j=0 */
   1.259 +    {
   1.260 +        const int c = events [mv_max];
   1.261 +
   1.262 +        is_short_ct [0] += c;     /* Short vector */
   1.263 +        short_ct [0] += c;       /* Magnitude distribution */
   1.264 +    }
   1.265 +
   1.266 +    /* j: 1 ~ mv_max (1023) */
   1.267 +    {
   1.268 +        int j = 1;
   1.269 +
   1.270 +        do
   1.271 +        {
   1.272 +            const int c1 = events [mv_max + j];  /* positive */
   1.273 +            const int c2 = events [mv_max - j];  /* negative */
   1.274 +            const int c  = c1 + c2;
   1.275 +            int a = j;
   1.276 +
   1.277 +            sign_ct [0] += c1;
   1.278 +            sign_ct [1] += c2;
   1.279 +
   1.280 +            if (a < mvnum_short)
   1.281 +            {
   1.282 +                is_short_ct [0] += c;     /* Short vector */
   1.283 +                short_ct [a] += c;       /* Magnitude distribution */
   1.284 +            }
   1.285 +            else
   1.286 +            {
   1.287 +                int k = mvlong_width - 1;
   1.288 +                is_short_ct [1] += c;     /* Long vector */
   1.289 +
   1.290 +                /*  bit 3 not always encoded. */
   1.291 +                do
   1.292 +                    bit_ct [k] [(a >> k) & 1] += c;
   1.293 +
   1.294 +                while (--k >= 0);
   1.295 +            }
   1.296 +        }
   1.297 +        while (++j <= mv_max);
   1.298 +    }
   1.299 +
   1.300 +    calc_prob(Pnew + mvpis_short, is_short_ct);
   1.301 +
   1.302 +    calc_prob(Pnew + MVPsign, sign_ct);
   1.303 +
   1.304 +    {
   1.305 +        vp8_prob p [mvnum_short - 1];    /* actually only need branch ct */
   1.306 +        int j = 0;
   1.307 +
   1.308 +        vp8_tree_probs_from_distribution(
   1.309 +            8, vp8_small_mvencodings, vp8_small_mvtree,
   1.310 +            p, short_bct, short_ct,
   1.311 +            256, 1
   1.312 +        );
   1.313 +
   1.314 +        do
   1.315 +            calc_prob(Pnew + MVPshort + j, short_bct[j]);
   1.316 +
   1.317 +        while (++j < mvnum_short - 1);
   1.318 +    }
   1.319 +
   1.320 +    {
   1.321 +        int j = 0;
   1.322 +
   1.323 +        do
   1.324 +            calc_prob(Pnew + MVPbits + j, bit_ct[j]);
   1.325 +
   1.326 +        while (++j < mvlong_width);
   1.327 +    }
   1.328 +
   1.329 +    update(w, is_short_ct, Pcur + mvpis_short, Pnew[mvpis_short], *Pupdate++, updated);
   1.330 +
   1.331 +    update(w, sign_ct, Pcur + MVPsign, Pnew[MVPsign], *Pupdate++, updated);
   1.332 +
   1.333 +    {
   1.334 +        const vp8_prob *const new_p = Pnew + MVPshort;
   1.335 +        vp8_prob *const cur_p = Pcur + MVPshort;
   1.336 +
   1.337 +        int j = 0;
   1.338 +
   1.339 +        do
   1.340 +
   1.341 +            update(w, short_bct[j], cur_p + j, new_p[j], *Pupdate++, updated);
   1.342 +
   1.343 +        while (++j < mvnum_short - 1);
   1.344 +    }
   1.345 +
   1.346 +    {
   1.347 +        const vp8_prob *const new_p = Pnew + MVPbits;
   1.348 +        vp8_prob *const cur_p = Pcur + MVPbits;
   1.349 +
   1.350 +        int j = 0;
   1.351 +
   1.352 +        do
   1.353 +
   1.354 +            update(w, bit_ct[j], cur_p + j, new_p[j], *Pupdate++, updated);
   1.355 +
   1.356 +        while (++j < mvlong_width);
   1.357 +    }
   1.358 +}
   1.359 +
   1.360 +void vp8_write_mvprobs(VP8_COMP *cpi)
   1.361 +{
   1.362 +    vp8_writer *const w  = cpi->bc;
   1.363 +    MV_CONTEXT *mvc = cpi->common.fc.mvc;
   1.364 +    int flags[2] = {0, 0};
   1.365 +#ifdef VP8_ENTROPY_STATS
   1.366 +    active_section = 4;
   1.367 +#endif
   1.368 +    write_component_probs(
   1.369 +        w, &mvc[0], &vp8_default_mv_context[0], &vp8_mv_update_probs[0],
   1.370 +        cpi->mb.MVcount[0], 0, &flags[0]
   1.371 +    );
   1.372 +    write_component_probs(
   1.373 +        w, &mvc[1], &vp8_default_mv_context[1], &vp8_mv_update_probs[1],
   1.374 +        cpi->mb.MVcount[1], 1, &flags[1]
   1.375 +    );
   1.376 +
   1.377 +    if (flags[0] || flags[1])
   1.378 +        vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cpi->common.fc.mvc, flags);
   1.379 +
   1.380 +#ifdef VP8_ENTROPY_STATS
   1.381 +    active_section = 5;
   1.382 +#endif
   1.383 +}

mercurial