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 <math.h> 12 13#include "vp9/common/vp9_common.h" 14#include "vp9/common/vp9_entropymode.h" 15 16#include "vp9/encoder/vp9_cost.h" 17#include "vp9/encoder/vp9_encodemv.h" 18 19static struct vp9_token mv_joint_encodings[MV_JOINTS]; 20static struct vp9_token mv_class_encodings[MV_CLASSES]; 21static struct vp9_token mv_fp_encodings[MV_FP_SIZE]; 22static struct vp9_token mv_class0_encodings[CLASS0_SIZE]; 23 24void vp9_entropy_mv_init(void) { 25 vp9_tokens_from_tree(mv_joint_encodings, vp9_mv_joint_tree); 26 vp9_tokens_from_tree(mv_class_encodings, vp9_mv_class_tree); 27 vp9_tokens_from_tree(mv_class0_encodings, vp9_mv_class0_tree); 28 vp9_tokens_from_tree(mv_fp_encodings, vp9_mv_fp_tree); 29} 30 31static void encode_mv_component(vpx_writer* w, int comp, 32 const nmv_component* mvcomp, int usehp) { 33 int offset; 34 const int sign = comp < 0; 35 const int mag = sign ? -comp : comp; 36 const int mv_class = vp9_get_mv_class(mag - 1, &offset); 37 const int d = offset >> 3; // int mv data 38 const int fr = (offset >> 1) & 3; // fractional mv data 39 const int hp = offset & 1; // high precision mv data 40 41 assert(comp != 0); 42 43 // Sign 44 vpx_write(w, sign, mvcomp->sign); 45 46 // Class 47 vp9_write_token(w, vp9_mv_class_tree, mvcomp->classes, 48 &mv_class_encodings[mv_class]); 49 50 // Integer bits 51 if (mv_class == MV_CLASS_0) { 52 vp9_write_token(w, vp9_mv_class0_tree, mvcomp->class0, 53 &mv_class0_encodings[d]); 54 } else { 55 int i; 56 const int n = mv_class + CLASS0_BITS - 1; // number of bits 57 for (i = 0; i < n; ++i) 58 vpx_write(w, (d >> i) & 1, mvcomp->bits[i]); 59 } 60 61 // Fractional bits 62 vp9_write_token(w, vp9_mv_fp_tree, 63 mv_class == MV_CLASS_0 ? mvcomp->class0_fp[d] : mvcomp->fp, 64 &mv_fp_encodings[fr]); 65 66 // High precision bit 67 if (usehp) 68 vpx_write(w, hp, 69 mv_class == MV_CLASS_0 ? mvcomp->class0_hp : mvcomp->hp); 70} 71 72 73static void build_nmv_component_cost_table(int *mvcost, 74 const nmv_component* const mvcomp, 75 int usehp) { 76 int i, v; 77 int sign_cost[2], class_cost[MV_CLASSES], class0_cost[CLASS0_SIZE]; 78 int bits_cost[MV_OFFSET_BITS][2]; 79 int class0_fp_cost[CLASS0_SIZE][MV_FP_SIZE], fp_cost[MV_FP_SIZE]; 80 int class0_hp_cost[2], hp_cost[2]; 81 82 sign_cost[0] = vp9_cost_zero(mvcomp->sign); 83 sign_cost[1] = vp9_cost_one(mvcomp->sign); 84 vp9_cost_tokens(class_cost, mvcomp->classes, vp9_mv_class_tree); 85 vp9_cost_tokens(class0_cost, mvcomp->class0, vp9_mv_class0_tree); 86 for (i = 0; i < MV_OFFSET_BITS; ++i) { 87 bits_cost[i][0] = vp9_cost_zero(mvcomp->bits[i]); 88 bits_cost[i][1] = vp9_cost_one(mvcomp->bits[i]); 89 } 90 91 for (i = 0; i < CLASS0_SIZE; ++i) 92 vp9_cost_tokens(class0_fp_cost[i], mvcomp->class0_fp[i], vp9_mv_fp_tree); 93 vp9_cost_tokens(fp_cost, mvcomp->fp, vp9_mv_fp_tree); 94 95 if (usehp) { 96 class0_hp_cost[0] = vp9_cost_zero(mvcomp->class0_hp); 97 class0_hp_cost[1] = vp9_cost_one(mvcomp->class0_hp); 98 hp_cost[0] = vp9_cost_zero(mvcomp->hp); 99 hp_cost[1] = vp9_cost_one(mvcomp->hp); 100 } 101 mvcost[0] = 0; 102 for (v = 1; v <= MV_MAX; ++v) { 103 int z, c, o, d, e, f, cost = 0; 104 z = v - 1; 105 c = vp9_get_mv_class(z, &o); 106 cost += class_cost[c]; 107 d = (o >> 3); /* int mv data */ 108 f = (o >> 1) & 3; /* fractional pel mv data */ 109 e = (o & 1); /* high precision mv data */ 110 if (c == MV_CLASS_0) { 111 cost += class0_cost[d]; 112 } else { 113 int i, b; 114 b = c + CLASS0_BITS - 1; /* number of bits */ 115 for (i = 0; i < b; ++i) 116 cost += bits_cost[i][((d >> i) & 1)]; 117 } 118 if (c == MV_CLASS_0) { 119 cost += class0_fp_cost[d][f]; 120 } else { 121 cost += fp_cost[f]; 122 } 123 if (usehp) { 124 if (c == MV_CLASS_0) { 125 cost += class0_hp_cost[e]; 126 } else { 127 cost += hp_cost[e]; 128 } 129 } 130 mvcost[v] = cost + sign_cost[0]; 131 mvcost[-v] = cost + sign_cost[1]; 132 } 133} 134 135static int update_mv(vpx_writer *w, const unsigned int ct[2], vpx_prob *cur_p, 136 vpx_prob upd_p) { 137 const vpx_prob new_p = get_binary_prob(ct[0], ct[1]) | 1; 138 const int update = cost_branch256(ct, *cur_p) + vp9_cost_zero(upd_p) > 139 cost_branch256(ct, new_p) + vp9_cost_one(upd_p) + 7 * 256; 140 vpx_write(w, update, upd_p); 141 if (update) { 142 *cur_p = new_p; 143 vpx_write_literal(w, new_p >> 1, 7); 144 } 145 return update; 146} 147 148static void write_mv_update(const vpx_tree_index *tree, 149 vpx_prob probs[/*n - 1*/], 150 const unsigned int counts[/*n - 1*/], 151 int n, vpx_writer *w) { 152 int i; 153 unsigned int branch_ct[32][2]; 154 155 // Assuming max number of probabilities <= 32 156 assert(n <= 32); 157 158 vp9_tree_probs_from_distribution(tree, branch_ct, counts); 159 for (i = 0; i < n - 1; ++i) 160 update_mv(w, branch_ct[i], &probs[i], MV_UPDATE_PROB); 161} 162 163void vp9_write_nmv_probs(VP9_COMMON *cm, int usehp, vpx_writer *w, 164 nmv_context_counts *const counts) { 165 int i, j; 166 nmv_context *const mvc = &cm->fc->nmvc; 167 168 write_mv_update(vp9_mv_joint_tree, mvc->joints, counts->joints, MV_JOINTS, w); 169 170 for (i = 0; i < 2; ++i) { 171 nmv_component *comp = &mvc->comps[i]; 172 nmv_component_counts *comp_counts = &counts->comps[i]; 173 174 update_mv(w, comp_counts->sign, &comp->sign, MV_UPDATE_PROB); 175 write_mv_update(vp9_mv_class_tree, comp->classes, comp_counts->classes, 176 MV_CLASSES, w); 177 write_mv_update(vp9_mv_class0_tree, comp->class0, comp_counts->class0, 178 CLASS0_SIZE, w); 179 for (j = 0; j < MV_OFFSET_BITS; ++j) 180 update_mv(w, comp_counts->bits[j], &comp->bits[j], MV_UPDATE_PROB); 181 } 182 183 for (i = 0; i < 2; ++i) { 184 for (j = 0; j < CLASS0_SIZE; ++j) 185 write_mv_update(vp9_mv_fp_tree, mvc->comps[i].class0_fp[j], 186 counts->comps[i].class0_fp[j], MV_FP_SIZE, w); 187 188 write_mv_update(vp9_mv_fp_tree, mvc->comps[i].fp, counts->comps[i].fp, 189 MV_FP_SIZE, w); 190 } 191 192 if (usehp) { 193 for (i = 0; i < 2; ++i) { 194 update_mv(w, counts->comps[i].class0_hp, &mvc->comps[i].class0_hp, 195 MV_UPDATE_PROB); 196 update_mv(w, counts->comps[i].hp, &mvc->comps[i].hp, MV_UPDATE_PROB); 197 } 198 } 199} 200 201void vp9_encode_mv(VP9_COMP* cpi, vpx_writer* w, 202 const MV* mv, const MV* ref, 203 const nmv_context* mvctx, int usehp) { 204 const MV diff = {mv->row - ref->row, 205 mv->col - ref->col}; 206 const MV_JOINT_TYPE j = vp9_get_mv_joint(&diff); 207 usehp = usehp && vp9_use_mv_hp(ref); 208 209 vp9_write_token(w, vp9_mv_joint_tree, mvctx->joints, &mv_joint_encodings[j]); 210 if (mv_joint_vertical(j)) 211 encode_mv_component(w, diff.row, &mvctx->comps[0], usehp); 212 213 if (mv_joint_horizontal(j)) 214 encode_mv_component(w, diff.col, &mvctx->comps[1], usehp); 215 216 // If auto_mv_step_size is enabled then keep track of the largest 217 // motion vector component used. 218 if (cpi->sf.mv.auto_mv_step_size) { 219 unsigned int maxv = MAX(abs(mv->row), abs(mv->col)) >> 3; 220 cpi->max_mv_magnitude = MAX(maxv, cpi->max_mv_magnitude); 221 } 222} 223 224void vp9_build_nmv_cost_table(int *mvjoint, int *mvcost[2], 225 const nmv_context* ctx, int usehp) { 226 vp9_cost_tokens(mvjoint, ctx->joints, vp9_mv_joint_tree); 227 build_nmv_component_cost_table(mvcost[0], &ctx->comps[0], usehp); 228 build_nmv_component_cost_table(mvcost[1], &ctx->comps[1], usehp); 229} 230 231static void inc_mvs(const MB_MODE_INFO *mbmi, const MB_MODE_INFO_EXT *mbmi_ext, 232 const int_mv mvs[2], 233 nmv_context_counts *counts) { 234 int i; 235 236 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) { 237 const MV *ref = &mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0].as_mv; 238 const MV diff = {mvs[i].as_mv.row - ref->row, 239 mvs[i].as_mv.col - ref->col}; 240 vp9_inc_mv(&diff, counts); 241 } 242} 243 244void vp9_update_mv_count(ThreadData *td) { 245 const MACROBLOCKD *xd = &td->mb.e_mbd; 246 const MODE_INFO *mi = xd->mi[0]; 247 const MB_MODE_INFO *const mbmi = &mi->mbmi; 248 const MB_MODE_INFO_EXT *mbmi_ext = td->mb.mbmi_ext; 249 250 if (mbmi->sb_type < BLOCK_8X8) { 251 const int num_4x4_w = num_4x4_blocks_wide_lookup[mbmi->sb_type]; 252 const int num_4x4_h = num_4x4_blocks_high_lookup[mbmi->sb_type]; 253 int idx, idy; 254 255 for (idy = 0; idy < 2; idy += num_4x4_h) { 256 for (idx = 0; idx < 2; idx += num_4x4_w) { 257 const int i = idy * 2 + idx; 258 if (mi->bmi[i].as_mode == NEWMV) 259 inc_mvs(mbmi, mbmi_ext, mi->bmi[i].as_mv, &td->counts->mv); 260 } 261 } 262 } else { 263 if (mbmi->mode == NEWMV) 264 inc_mvs(mbmi, mbmi_ext, mbmi->mv, &td->counts->mv); 265 } 266} 267 268