/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 | 426k | const nmv_component *mvcomp, int usehp) { |
33 | 426k | int offset; |
34 | 426k | const int sign = comp < 0; |
35 | 426k | const int mag = sign ? -comp : comp; |
36 | 426k | const int mv_class = vp9_get_mv_class(mag - 1, &offset); |
37 | 426k | const int d = offset >> 3; // int mv data |
38 | 426k | const int fr = (offset >> 1) & 3; // fractional mv data |
39 | 426k | const int hp = offset & 1; // high precision mv data |
40 | | |
41 | 426k | assert(comp != 0); |
42 | | |
43 | | // Sign |
44 | 426k | vpx_write(w, sign, mvcomp->sign); |
45 | | |
46 | | // Class |
47 | 426k | vp9_write_token(w, vp9_mv_class_tree, mvcomp->classes, |
48 | 426k | &mv_class_encodings[mv_class]); |
49 | | |
50 | | // Integer bits |
51 | 426k | if (mv_class == MV_CLASS_0) { |
52 | 88.2k | vpx_write(w, d, mvcomp->class0[0]); |
53 | 338k | } else { |
54 | 338k | int i; |
55 | 338k | const int n = mv_class + CLASS0_BITS - 1; // number of bits |
56 | 1.22M | for (i = 0; i < n; ++i) vpx_write(w, (d >> i) & 1, mvcomp->bits[i]); |
57 | 338k | } |
58 | | |
59 | | // Fractional bits |
60 | 426k | vp9_write_token(w, vp9_mv_fp_tree, |
61 | 426k | mv_class == MV_CLASS_0 ? mvcomp->class0_fp[d] : mvcomp->fp, |
62 | 426k | &mv_fp_encodings[fr]); |
63 | | |
64 | | // High precision bit |
65 | 426k | if (usehp) |
66 | 106k | vpx_write(w, hp, mv_class == MV_CLASS_0 ? mvcomp->class0_hp : mvcomp->hp); |
67 | 426k | } |
68 | | |
69 | | static void build_nmv_component_cost_table(int *mvcost, |
70 | | const nmv_component *const mvcomp, |
71 | 69.0k | int usehp) { |
72 | 69.0k | int sign_cost[2], class_cost[MV_CLASSES], class0_cost[CLASS0_SIZE]; |
73 | 69.0k | int bits_cost[MV_OFFSET_BITS][2]; |
74 | 69.0k | int class0_fp_cost[CLASS0_SIZE][MV_FP_SIZE], fp_cost[MV_FP_SIZE]; |
75 | 69.0k | int class0_hp_cost[2], hp_cost[2]; |
76 | 69.0k | int i; |
77 | 69.0k | int c, o; |
78 | | |
79 | 69.0k | sign_cost[0] = vp9_cost_zero(mvcomp->sign); |
80 | 69.0k | sign_cost[1] = vp9_cost_one(mvcomp->sign); |
81 | 69.0k | vp9_cost_tokens(class_cost, mvcomp->classes, vp9_mv_class_tree); |
82 | 69.0k | vp9_cost_tokens(class0_cost, mvcomp->class0, vp9_mv_class0_tree); |
83 | 759k | for (i = 0; i < MV_OFFSET_BITS; ++i) { |
84 | 690k | bits_cost[i][0] = vp9_cost_zero(mvcomp->bits[i]); |
85 | 690k | bits_cost[i][1] = vp9_cost_one(mvcomp->bits[i]); |
86 | 690k | } |
87 | | |
88 | 207k | for (i = 0; i < CLASS0_SIZE; ++i) |
89 | 138k | vp9_cost_tokens(class0_fp_cost[i], mvcomp->class0_fp[i], vp9_mv_fp_tree); |
90 | 69.0k | 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 | 69.0k | class0_hp_cost[0] = vp9_cost_zero(mvcomp->class0_hp); |
94 | 69.0k | class0_hp_cost[1] = vp9_cost_one(mvcomp->class0_hp); |
95 | 69.0k | hp_cost[0] = vp9_cost_zero(mvcomp->hp); |
96 | 69.0k | hp_cost[1] = vp9_cost_one(mvcomp->hp); |
97 | | |
98 | 69.0k | mvcost[0] = 0; |
99 | | // MV_CLASS_0 |
100 | 1.17M | for (o = 0; o < (CLASS0_SIZE << 3); ++o) { |
101 | 1.10M | int d, e, f; |
102 | 1.10M | int cost = class_cost[MV_CLASS_0]; |
103 | 1.10M | int v = o + 1; |
104 | 1.10M | d = (o >> 3); /* int mv data */ |
105 | 1.10M | f = (o >> 1) & 3; /* fractional pel mv data */ |
106 | 1.10M | cost += class0_cost[d]; |
107 | 1.10M | cost += class0_fp_cost[d][f]; |
108 | 1.10M | if (usehp) { |
109 | 844k | e = (o & 1); /* high precision mv data */ |
110 | 844k | cost += class0_hp_cost[e]; |
111 | 844k | } |
112 | 1.10M | mvcost[v] = cost + sign_cost[0]; |
113 | 1.10M | mvcost[-v] = cost + sign_cost[1]; |
114 | 1.10M | } |
115 | 759k | for (c = MV_CLASS_1; c < MV_CLASSES; ++c) { |
116 | 690k | int d; |
117 | 141M | for (d = 0; d < (1 << c); ++d) { |
118 | 141M | int f; |
119 | 141M | int whole_cost = class_cost[c]; |
120 | 141M | int b = c + CLASS0_BITS - 1; /* number of bits */ |
121 | 1.41G | for (i = 0; i < b; ++i) whole_cost += bits_cost[i][((d >> i) & 1)]; |
122 | 706M | for (f = 0; f < 4; ++f) { |
123 | 565M | int cost = whole_cost + fp_cost[f]; |
124 | 565M | int v = (CLASS0_SIZE << (c + 2)) + d * 8 + f * 2 /* + e */ + 1; |
125 | 565M | if (usehp) { |
126 | 432M | mvcost[v] = cost + hp_cost[0] + sign_cost[0]; |
127 | 432M | mvcost[-v] = cost + hp_cost[0] + sign_cost[1]; |
128 | 432M | if (v + 1 > MV_MAX) break; |
129 | 431M | mvcost[v + 1] = cost + hp_cost[1] + sign_cost[0]; |
130 | 431M | mvcost[-v - 1] = cost + hp_cost[1] + sign_cost[1]; |
131 | 431M | } else { |
132 | 133M | mvcost[v] = cost + sign_cost[0]; |
133 | 133M | mvcost[-v] = cost + sign_cost[1]; |
134 | 133M | if (v + 1 > MV_MAX) break; |
135 | 133M | mvcost[v + 1] = cost + sign_cost[0]; |
136 | 133M | mvcost[-v - 1] = cost + sign_cost[1]; |
137 | 133M | } |
138 | 565M | } |
139 | 141M | } |
140 | 690k | } |
141 | 69.0k | } |
142 | | |
143 | | static int update_mv(vpx_writer *w, const unsigned int ct[2], vpx_prob *cur_p, |
144 | 2.34M | vpx_prob upd_p) { |
145 | 2.34M | const vpx_prob new_p = get_binary_prob(ct[0], ct[1]) | 1; |
146 | 2.34M | const int update = cost_branch256(ct, *cur_p) + vp9_cost_zero(upd_p) > |
147 | 2.34M | cost_branch256(ct, new_p) + vp9_cost_one(upd_p) + |
148 | 2.34M | (7 << VP9_PROB_COST_SHIFT); |
149 | 2.34M | vpx_write(w, update, upd_p); |
150 | 2.34M | if (update) { |
151 | 7.65k | *cur_p = new_p; |
152 | 7.65k | vpx_write_literal(w, new_p >> 1, 7); |
153 | 7.65k | } |
154 | 2.34M | return update; |
155 | 2.34M | } |
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 | 379k | vpx_writer *w) { |
161 | 379k | int i; |
162 | 379k | unsigned int branch_ct[32][2]; |
163 | | |
164 | | // Assuming max number of probabilities <= 32 |
165 | 379k | assert(n <= 32); |
166 | | |
167 | 379k | vp9_tree_probs_from_distribution(tree, branch_ct, counts); |
168 | 1.86M | for (i = 0; i < n - 1; ++i) |
169 | 1.48M | update_mv(w, branch_ct[i], &probs[i], MV_UPDATE_PROB); |
170 | 379k | } |
171 | | |
172 | | void vp9_write_nmv_probs(VP9_COMMON *cm, int usehp, vpx_writer *w, |
173 | 34.5k | nmv_context_counts *const counts) { |
174 | 34.5k | int i, j; |
175 | 34.5k | nmv_context *const mvc = &cm->fc->nmvc; |
176 | | |
177 | 34.5k | write_mv_update(vp9_mv_joint_tree, mvc->joints, counts->joints, MV_JOINTS, w); |
178 | | |
179 | 103k | for (i = 0; i < 2; ++i) { |
180 | 69.0k | nmv_component *comp = &mvc->comps[i]; |
181 | 69.0k | nmv_component_counts *comp_counts = &counts->comps[i]; |
182 | | |
183 | 69.0k | update_mv(w, comp_counts->sign, &comp->sign, MV_UPDATE_PROB); |
184 | 69.0k | write_mv_update(vp9_mv_class_tree, comp->classes, comp_counts->classes, |
185 | 69.0k | MV_CLASSES, w); |
186 | 69.0k | write_mv_update(vp9_mv_class0_tree, comp->class0, comp_counts->class0, |
187 | 69.0k | CLASS0_SIZE, w); |
188 | 759k | for (j = 0; j < MV_OFFSET_BITS; ++j) |
189 | 690k | update_mv(w, comp_counts->bits[j], &comp->bits[j], MV_UPDATE_PROB); |
190 | 69.0k | } |
191 | | |
192 | 103k | for (i = 0; i < 2; ++i) { |
193 | 207k | for (j = 0; j < CLASS0_SIZE; ++j) |
194 | 138k | write_mv_update(vp9_mv_fp_tree, mvc->comps[i].class0_fp[j], |
195 | 138k | counts->comps[i].class0_fp[j], MV_FP_SIZE, w); |
196 | | |
197 | 69.0k | write_mv_update(vp9_mv_fp_tree, mvc->comps[i].fp, counts->comps[i].fp, |
198 | 69.0k | MV_FP_SIZE, w); |
199 | 69.0k | } |
200 | | |
201 | 34.5k | if (usehp) { |
202 | 79.1k | for (i = 0; i < 2; ++i) { |
203 | 52.7k | update_mv(w, counts->comps[i].class0_hp, &mvc->comps[i].class0_hp, |
204 | 52.7k | MV_UPDATE_PROB); |
205 | 52.7k | update_mv(w, counts->comps[i].hp, &mvc->comps[i].hp, MV_UPDATE_PROB); |
206 | 52.7k | } |
207 | 26.3k | } |
208 | 34.5k | } |
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 | 250k | unsigned int *const max_mv_magnitude) { |
213 | 250k | const MV diff = { mv->row - ref->row, mv->col - ref->col }; |
214 | 250k | const MV_JOINT_TYPE j = vp9_get_mv_joint(&diff); |
215 | 250k | usehp = usehp && use_mv_hp(ref); |
216 | | |
217 | 250k | vp9_write_token(w, vp9_mv_joint_tree, mvctx->joints, &mv_joint_encodings[j]); |
218 | 250k | if (mv_joint_vertical(j)) |
219 | 212k | encode_mv_component(w, diff.row, &mvctx->comps[0], usehp); |
220 | | |
221 | 250k | if (mv_joint_horizontal(j)) |
222 | 213k | 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 | 250k | if (cpi->sf.mv.auto_mv_step_size) { |
227 | 250k | const unsigned int maxv = VPXMAX(abs(mv->row), abs(mv->col)) >> 3; |
228 | 250k | *max_mv_magnitude = VPXMAX(maxv, *max_mv_magnitude); |
229 | 250k | } |
230 | 250k | } |
231 | | |
232 | | void vp9_build_nmv_cost_table(int *mvjoint, int *mvcost[2], |
233 | 34.5k | const nmv_context *ctx, int usehp) { |
234 | 34.5k | vp9_cost_tokens(mvjoint, ctx->joints, vp9_mv_joint_tree); |
235 | 34.5k | build_nmv_component_cost_table(mvcost[0], &ctx->comps[0], usehp); |
236 | 34.5k | build_nmv_component_cost_table(mvcost[1], &ctx->comps[1], usehp); |
237 | 34.5k | } |
238 | | |
239 | | static void inc_mvs(const MODE_INFO *mi, const MB_MODE_INFO_EXT *mbmi_ext, |
240 | 250k | const int_mv mvs[2], nmv_context_counts *counts) { |
241 | 250k | int i; |
242 | | |
243 | 501k | for (i = 0; i < 1 + has_second_ref(mi); ++i) { |
244 | 250k | const MV *ref = &mbmi_ext->ref_mvs[mi->ref_frame[i]][0].as_mv; |
245 | 250k | const MV diff = { mvs[i].as_mv.row - ref->row, |
246 | 250k | mvs[i].as_mv.col - ref->col }; |
247 | 250k | vp9_inc_mv(&diff, counts); |
248 | 250k | } |
249 | 250k | } |
250 | | |
251 | 582k | void vp9_update_mv_count(ThreadData *td) { |
252 | 582k | const MACROBLOCKD *xd = &td->mb.e_mbd; |
253 | 582k | const MODE_INFO *mi = xd->mi[0]; |
254 | 582k | const MB_MODE_INFO_EXT *mbmi_ext = td->mb.mbmi_ext; |
255 | | |
256 | 582k | if (mi->sb_type < BLOCK_8X8) { |
257 | 280k | const int num_4x4_w = num_4x4_blocks_wide_lookup[mi->sb_type]; |
258 | 280k | const int num_4x4_h = num_4x4_blocks_high_lookup[mi->sb_type]; |
259 | 280k | int idx, idy; |
260 | | |
261 | 828k | for (idy = 0; idy < 2; idy += num_4x4_h) { |
262 | 1.56M | for (idx = 0; idx < 2; idx += num_4x4_w) { |
263 | 1.01M | const int i = idy * 2 + idx; |
264 | 1.01M | if (mi->bmi[i].as_mode == NEWMV) |
265 | 175k | inc_mvs(mi, mbmi_ext, mi->bmi[i].as_mv, &td->counts->mv); |
266 | 1.01M | } |
267 | 548k | } |
268 | 302k | } else { |
269 | 302k | if (mi->mode == NEWMV) inc_mvs(mi, mbmi_ext, mi->mv, &td->counts->mv); |
270 | 302k | } |
271 | 582k | } |