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 +}