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