1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libvpx/vp9/encoder/vp9_encodemv.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,332 @@ 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 +#include <math.h> 1.15 + 1.16 +#include "vp9/common/vp9_common.h" 1.17 +#include "vp9/common/vp9_entropymode.h" 1.18 +#include "vp9/common/vp9_systemdependent.h" 1.19 +#include "vp9/encoder/vp9_encodemv.h" 1.20 + 1.21 + 1.22 +#ifdef ENTROPY_STATS 1.23 +extern unsigned int active_section; 1.24 +#endif 1.25 + 1.26 +static void encode_mv_component(vp9_writer* w, int comp, 1.27 + const nmv_component* mvcomp, int usehp) { 1.28 + int offset; 1.29 + const int sign = comp < 0; 1.30 + const int mag = sign ? -comp : comp; 1.31 + const int mv_class = vp9_get_mv_class(mag - 1, &offset); 1.32 + const int d = offset >> 3; // int mv data 1.33 + const int fr = (offset >> 1) & 3; // fractional mv data 1.34 + const int hp = offset & 1; // high precision mv data 1.35 + 1.36 + assert(comp != 0); 1.37 + 1.38 + // Sign 1.39 + vp9_write(w, sign, mvcomp->sign); 1.40 + 1.41 + // Class 1.42 + write_token(w, vp9_mv_class_tree, mvcomp->classes, 1.43 + &vp9_mv_class_encodings[mv_class]); 1.44 + 1.45 + // Integer bits 1.46 + if (mv_class == MV_CLASS_0) { 1.47 + write_token(w, vp9_mv_class0_tree, mvcomp->class0, 1.48 + &vp9_mv_class0_encodings[d]); 1.49 + } else { 1.50 + int i; 1.51 + const int n = mv_class + CLASS0_BITS - 1; // number of bits 1.52 + for (i = 0; i < n; ++i) 1.53 + vp9_write(w, (d >> i) & 1, mvcomp->bits[i]); 1.54 + } 1.55 + 1.56 + // Fractional bits 1.57 + write_token(w, vp9_mv_fp_tree, 1.58 + mv_class == MV_CLASS_0 ? mvcomp->class0_fp[d] : mvcomp->fp, 1.59 + &vp9_mv_fp_encodings[fr]); 1.60 + 1.61 + // High precision bit 1.62 + if (usehp) 1.63 + vp9_write(w, hp, 1.64 + mv_class == MV_CLASS_0 ? mvcomp->class0_hp : mvcomp->hp); 1.65 +} 1.66 + 1.67 + 1.68 +static void build_nmv_component_cost_table(int *mvcost, 1.69 + const nmv_component* const mvcomp, 1.70 + int usehp) { 1.71 + int i, v; 1.72 + int sign_cost[2], class_cost[MV_CLASSES], class0_cost[CLASS0_SIZE]; 1.73 + int bits_cost[MV_OFFSET_BITS][2]; 1.74 + int class0_fp_cost[CLASS0_SIZE][4], fp_cost[4]; 1.75 + int class0_hp_cost[2], hp_cost[2]; 1.76 + 1.77 + sign_cost[0] = vp9_cost_zero(mvcomp->sign); 1.78 + sign_cost[1] = vp9_cost_one(mvcomp->sign); 1.79 + vp9_cost_tokens(class_cost, mvcomp->classes, vp9_mv_class_tree); 1.80 + vp9_cost_tokens(class0_cost, mvcomp->class0, vp9_mv_class0_tree); 1.81 + for (i = 0; i < MV_OFFSET_BITS; ++i) { 1.82 + bits_cost[i][0] = vp9_cost_zero(mvcomp->bits[i]); 1.83 + bits_cost[i][1] = vp9_cost_one(mvcomp->bits[i]); 1.84 + } 1.85 + 1.86 + for (i = 0; i < CLASS0_SIZE; ++i) 1.87 + vp9_cost_tokens(class0_fp_cost[i], mvcomp->class0_fp[i], vp9_mv_fp_tree); 1.88 + vp9_cost_tokens(fp_cost, mvcomp->fp, vp9_mv_fp_tree); 1.89 + 1.90 + if (usehp) { 1.91 + class0_hp_cost[0] = vp9_cost_zero(mvcomp->class0_hp); 1.92 + class0_hp_cost[1] = vp9_cost_one(mvcomp->class0_hp); 1.93 + hp_cost[0] = vp9_cost_zero(mvcomp->hp); 1.94 + hp_cost[1] = vp9_cost_one(mvcomp->hp); 1.95 + } 1.96 + mvcost[0] = 0; 1.97 + for (v = 1; v <= MV_MAX; ++v) { 1.98 + int z, c, o, d, e, f, cost = 0; 1.99 + z = v - 1; 1.100 + c = vp9_get_mv_class(z, &o); 1.101 + cost += class_cost[c]; 1.102 + d = (o >> 3); /* int mv data */ 1.103 + f = (o >> 1) & 3; /* fractional pel mv data */ 1.104 + e = (o & 1); /* high precision mv data */ 1.105 + if (c == MV_CLASS_0) { 1.106 + cost += class0_cost[d]; 1.107 + } else { 1.108 + int i, b; 1.109 + b = c + CLASS0_BITS - 1; /* number of bits */ 1.110 + for (i = 0; i < b; ++i) 1.111 + cost += bits_cost[i][((d >> i) & 1)]; 1.112 + } 1.113 + if (c == MV_CLASS_0) { 1.114 + cost += class0_fp_cost[d][f]; 1.115 + } else { 1.116 + cost += fp_cost[f]; 1.117 + } 1.118 + if (usehp) { 1.119 + if (c == MV_CLASS_0) { 1.120 + cost += class0_hp_cost[e]; 1.121 + } else { 1.122 + cost += hp_cost[e]; 1.123 + } 1.124 + } 1.125 + mvcost[v] = cost + sign_cost[0]; 1.126 + mvcost[-v] = cost + sign_cost[1]; 1.127 + } 1.128 +} 1.129 + 1.130 +static int update_mv(vp9_writer *w, const unsigned int ct[2], vp9_prob *cur_p, 1.131 + vp9_prob upd_p) { 1.132 + const vp9_prob new_p = get_binary_prob(ct[0], ct[1]); 1.133 + vp9_prob mod_p = new_p | 1; 1.134 + const int cur_b = cost_branch256(ct, *cur_p); 1.135 + const int mod_b = cost_branch256(ct, mod_p); 1.136 + const int cost = 7 * 256 + (vp9_cost_one(upd_p) - vp9_cost_zero(upd_p)); 1.137 + if (cur_b - mod_b > cost) { 1.138 + *cur_p = mod_p; 1.139 + vp9_write(w, 1, upd_p); 1.140 + vp9_write_literal(w, mod_p >> 1, 7); 1.141 + return 1; 1.142 + } else { 1.143 + vp9_write(w, 0, upd_p); 1.144 + return 0; 1.145 + } 1.146 +} 1.147 + 1.148 +static void counts_to_nmv_context( 1.149 + nmv_context_counts *nmv_count, 1.150 + int usehp, 1.151 + unsigned int (*branch_ct_joint)[2], 1.152 + unsigned int (*branch_ct_sign)[2], 1.153 + unsigned int (*branch_ct_classes)[MV_CLASSES - 1][2], 1.154 + unsigned int (*branch_ct_class0)[CLASS0_SIZE - 1][2], 1.155 + unsigned int (*branch_ct_bits)[MV_OFFSET_BITS][2], 1.156 + unsigned int (*branch_ct_class0_fp)[CLASS0_SIZE][4 - 1][2], 1.157 + unsigned int (*branch_ct_fp)[4 - 1][2], 1.158 + unsigned int (*branch_ct_class0_hp)[2], 1.159 + unsigned int (*branch_ct_hp)[2]) { 1.160 + int i, j, k; 1.161 + vp9_tree_probs_from_distribution(vp9_mv_joint_tree, branch_ct_joint, 1.162 + nmv_count->joints); 1.163 + for (i = 0; i < 2; ++i) { 1.164 + const uint32_t s0 = nmv_count->comps[i].sign[0]; 1.165 + const uint32_t s1 = nmv_count->comps[i].sign[1]; 1.166 + 1.167 + branch_ct_sign[i][0] = s0; 1.168 + branch_ct_sign[i][1] = s1; 1.169 + vp9_tree_probs_from_distribution(vp9_mv_class_tree, 1.170 + branch_ct_classes[i], 1.171 + nmv_count->comps[i].classes); 1.172 + vp9_tree_probs_from_distribution(vp9_mv_class0_tree, 1.173 + branch_ct_class0[i], 1.174 + nmv_count->comps[i].class0); 1.175 + for (j = 0; j < MV_OFFSET_BITS; ++j) { 1.176 + const uint32_t b0 = nmv_count->comps[i].bits[j][0]; 1.177 + const uint32_t b1 = nmv_count->comps[i].bits[j][1]; 1.178 + 1.179 + branch_ct_bits[i][j][0] = b0; 1.180 + branch_ct_bits[i][j][1] = b1; 1.181 + } 1.182 + } 1.183 + for (i = 0; i < 2; ++i) { 1.184 + for (k = 0; k < CLASS0_SIZE; ++k) { 1.185 + vp9_tree_probs_from_distribution(vp9_mv_fp_tree, 1.186 + branch_ct_class0_fp[i][k], 1.187 + nmv_count->comps[i].class0_fp[k]); 1.188 + } 1.189 + vp9_tree_probs_from_distribution(vp9_mv_fp_tree, 1.190 + branch_ct_fp[i], 1.191 + nmv_count->comps[i].fp); 1.192 + } 1.193 + if (usehp) { 1.194 + for (i = 0; i < 2; ++i) { 1.195 + const uint32_t c0_hp0 = nmv_count->comps[i].class0_hp[0]; 1.196 + const uint32_t c0_hp1 = nmv_count->comps[i].class0_hp[1]; 1.197 + const uint32_t hp0 = nmv_count->comps[i].hp[0]; 1.198 + const uint32_t hp1 = nmv_count->comps[i].hp[1]; 1.199 + 1.200 + branch_ct_class0_hp[i][0] = c0_hp0; 1.201 + branch_ct_class0_hp[i][1] = c0_hp1; 1.202 + 1.203 + branch_ct_hp[i][0] = hp0; 1.204 + branch_ct_hp[i][1] = hp1; 1.205 + } 1.206 + } 1.207 +} 1.208 + 1.209 +void vp9_write_nmv_probs(VP9_COMP* const cpi, int usehp, vp9_writer* const bc) { 1.210 + int i, j; 1.211 + unsigned int branch_ct_joint[MV_JOINTS - 1][2]; 1.212 + unsigned int branch_ct_sign[2][2]; 1.213 + unsigned int branch_ct_classes[2][MV_CLASSES - 1][2]; 1.214 + unsigned int branch_ct_class0[2][CLASS0_SIZE - 1][2]; 1.215 + unsigned int branch_ct_bits[2][MV_OFFSET_BITS][2]; 1.216 + unsigned int branch_ct_class0_fp[2][CLASS0_SIZE][4 - 1][2]; 1.217 + unsigned int branch_ct_fp[2][4 - 1][2]; 1.218 + unsigned int branch_ct_class0_hp[2][2]; 1.219 + unsigned int branch_ct_hp[2][2]; 1.220 + nmv_context *mvc = &cpi->common.fc.nmvc; 1.221 + 1.222 + counts_to_nmv_context(&cpi->NMVcount, usehp, 1.223 + branch_ct_joint, branch_ct_sign, branch_ct_classes, 1.224 + branch_ct_class0, branch_ct_bits, 1.225 + branch_ct_class0_fp, branch_ct_fp, 1.226 + branch_ct_class0_hp, branch_ct_hp); 1.227 + 1.228 + for (j = 0; j < MV_JOINTS - 1; ++j) 1.229 + update_mv(bc, branch_ct_joint[j], &mvc->joints[j], NMV_UPDATE_PROB); 1.230 + 1.231 + for (i = 0; i < 2; ++i) { 1.232 + update_mv(bc, branch_ct_sign[i], &mvc->comps[i].sign, NMV_UPDATE_PROB); 1.233 + for (j = 0; j < MV_CLASSES - 1; ++j) 1.234 + update_mv(bc, branch_ct_classes[i][j], &mvc->comps[i].classes[j], 1.235 + NMV_UPDATE_PROB); 1.236 + 1.237 + for (j = 0; j < CLASS0_SIZE - 1; ++j) 1.238 + update_mv(bc, branch_ct_class0[i][j], &mvc->comps[i].class0[j], 1.239 + NMV_UPDATE_PROB); 1.240 + 1.241 + for (j = 0; j < MV_OFFSET_BITS; ++j) 1.242 + update_mv(bc, branch_ct_bits[i][j], &mvc->comps[i].bits[j], 1.243 + NMV_UPDATE_PROB); 1.244 + } 1.245 + 1.246 + for (i = 0; i < 2; ++i) { 1.247 + for (j = 0; j < CLASS0_SIZE; ++j) { 1.248 + int k; 1.249 + for (k = 0; k < 3; ++k) 1.250 + update_mv(bc, branch_ct_class0_fp[i][j][k], 1.251 + &mvc->comps[i].class0_fp[j][k], NMV_UPDATE_PROB); 1.252 + } 1.253 + 1.254 + for (j = 0; j < 3; ++j) 1.255 + update_mv(bc, branch_ct_fp[i][j], &mvc->comps[i].fp[j], NMV_UPDATE_PROB); 1.256 + } 1.257 + 1.258 + if (usehp) { 1.259 + for (i = 0; i < 2; ++i) { 1.260 + update_mv(bc, branch_ct_class0_hp[i], &mvc->comps[i].class0_hp, 1.261 + NMV_UPDATE_PROB); 1.262 + update_mv(bc, branch_ct_hp[i], &mvc->comps[i].hp, 1.263 + NMV_UPDATE_PROB); 1.264 + } 1.265 + } 1.266 +} 1.267 + 1.268 +void vp9_encode_mv(VP9_COMP* cpi, vp9_writer* w, 1.269 + const MV* mv, const MV* ref, 1.270 + const nmv_context* mvctx, int usehp) { 1.271 + const MV diff = {mv->row - ref->row, 1.272 + mv->col - ref->col}; 1.273 + const MV_JOINT_TYPE j = vp9_get_mv_joint(&diff); 1.274 + usehp = usehp && vp9_use_mv_hp(ref); 1.275 + 1.276 + write_token(w, vp9_mv_joint_tree, mvctx->joints, &vp9_mv_joint_encodings[j]); 1.277 + if (mv_joint_vertical(j)) 1.278 + encode_mv_component(w, diff.row, &mvctx->comps[0], usehp); 1.279 + 1.280 + if (mv_joint_horizontal(j)) 1.281 + encode_mv_component(w, diff.col, &mvctx->comps[1], usehp); 1.282 + 1.283 + // If auto_mv_step_size is enabled then keep track of the largest 1.284 + // motion vector component used. 1.285 + if (!cpi->dummy_packing && cpi->sf.auto_mv_step_size) { 1.286 + unsigned int maxv = MAX(abs(mv->row), abs(mv->col)) >> 3; 1.287 + cpi->max_mv_magnitude = MAX(maxv, cpi->max_mv_magnitude); 1.288 + } 1.289 +} 1.290 + 1.291 +void vp9_build_nmv_cost_table(int *mvjoint, 1.292 + int *mvcost[2], 1.293 + const nmv_context* const mvctx, 1.294 + int usehp, 1.295 + int mvc_flag_v, 1.296 + int mvc_flag_h) { 1.297 + vp9_clear_system_state(); 1.298 + vp9_cost_tokens(mvjoint, mvctx->joints, vp9_mv_joint_tree); 1.299 + if (mvc_flag_v) 1.300 + build_nmv_component_cost_table(mvcost[0], &mvctx->comps[0], usehp); 1.301 + if (mvc_flag_h) 1.302 + build_nmv_component_cost_table(mvcost[1], &mvctx->comps[1], usehp); 1.303 +} 1.304 + 1.305 +static void inc_mvs(int_mv mv[2], int_mv ref[2], int is_compound, 1.306 + nmv_context_counts *counts) { 1.307 + int i; 1.308 + for (i = 0; i < 1 + is_compound; ++i) { 1.309 + const MV diff = { mv[i].as_mv.row - ref[i].as_mv.row, 1.310 + mv[i].as_mv.col - ref[i].as_mv.col }; 1.311 + vp9_inc_mv(&diff, counts); 1.312 + } 1.313 +} 1.314 + 1.315 +void vp9_update_mv_count(VP9_COMP *cpi, MACROBLOCK *x, int_mv best_ref_mv[2]) { 1.316 + MODE_INFO *mi = x->e_mbd.mi_8x8[0]; 1.317 + MB_MODE_INFO *const mbmi = &mi->mbmi; 1.318 + const int is_compound = has_second_ref(mbmi); 1.319 + 1.320 + if (mbmi->sb_type < BLOCK_8X8) { 1.321 + const int num_4x4_w = num_4x4_blocks_wide_lookup[mbmi->sb_type]; 1.322 + const int num_4x4_h = num_4x4_blocks_high_lookup[mbmi->sb_type]; 1.323 + int idx, idy; 1.324 + 1.325 + for (idy = 0; idy < 2; idy += num_4x4_h) { 1.326 + for (idx = 0; idx < 2; idx += num_4x4_w) { 1.327 + const int i = idy * 2 + idx; 1.328 + if (mi->bmi[i].as_mode == NEWMV) 1.329 + inc_mvs(mi->bmi[i].as_mv, best_ref_mv, is_compound, &cpi->NMVcount); 1.330 + } 1.331 + } 1.332 + } else if (mbmi->mode == NEWMV) { 1.333 + inc_mvs(mbmi->mv, best_ref_mv, is_compound, &cpi->NMVcount); 1.334 + } 1.335 +}