/src/libvpx/vp8/encoder/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 "vp8/common/common.h" |
12 | | #include "encodemv.h" |
13 | | #include "vp8/common/entropymode.h" |
14 | | #include "vp8/common/systemdependent.h" |
15 | | #include "vpx_ports/system_state.h" |
16 | | |
17 | | #include <math.h> |
18 | | |
19 | | static void encode_mvcomponent(vp8_writer *const w, const int v, |
20 | 745k | const struct mv_context *mvc) { |
21 | 745k | const vp8_prob *p = mvc->prob; |
22 | 745k | const int x = v < 0 ? -v : v; |
23 | | |
24 | 745k | if (x < mvnum_short) { /* Small */ |
25 | 220k | vp8_write(w, 0, p[mvpis_short]); |
26 | 220k | vp8_treed_write(w, vp8_small_mvtree, p + MVPshort, x, 3); |
27 | | |
28 | 220k | if (!x) return; /* no sign bit */ |
29 | 525k | } else { /* Large */ |
30 | 525k | int i = 0; |
31 | | |
32 | 525k | vp8_write(w, 1, p[mvpis_short]); |
33 | | |
34 | 1.57M | do { |
35 | 1.57M | vp8_write(w, (x >> i) & 1, p[MVPbits + i]); |
36 | 1.57M | } while (++i < 3); |
37 | | |
38 | 525k | i = mvlong_width - 1; /* Skip bit 3, which is sometimes implicit */ |
39 | | |
40 | 3.15M | do { |
41 | 3.15M | vp8_write(w, (x >> i) & 1, p[MVPbits + i]); |
42 | 3.15M | } while (--i > 3); |
43 | | |
44 | 525k | if (x & 0xFFF0) vp8_write(w, (x >> 3) & 1, p[MVPbits + 3]); |
45 | 525k | } |
46 | | |
47 | 637k | vp8_write(w, v < 0, p[MVPsign]); |
48 | 637k | } |
49 | | #if 0 |
50 | | static int max_mv_r = 0; |
51 | | static int max_mv_c = 0; |
52 | | #endif |
53 | | void vp8_encode_motion_vector(vp8_writer *w, const MV *mv, |
54 | 372k | const MV_CONTEXT *mvc) { |
55 | | #if 0 |
56 | | { |
57 | | if (abs(mv->row >> 1) > max_mv_r) |
58 | | { |
59 | | FILE *f = fopen("maxmv.stt", "a"); |
60 | | max_mv_r = abs(mv->row >> 1); |
61 | | fprintf(f, "New Mv Row Max %6d\n", (mv->row >> 1)); |
62 | | |
63 | | if ((abs(mv->row) / 2) != max_mv_r) |
64 | | fprintf(f, "MV Row conversion error %6d\n", abs(mv->row) / 2); |
65 | | |
66 | | fclose(f); |
67 | | } |
68 | | |
69 | | if (abs(mv->col >> 1) > max_mv_c) |
70 | | { |
71 | | FILE *f = fopen("maxmv.stt", "a"); |
72 | | fprintf(f, "New Mv Col Max %6d\n", (mv->col >> 1)); |
73 | | max_mv_c = abs(mv->col >> 1); |
74 | | fclose(f); |
75 | | } |
76 | | } |
77 | | #endif |
78 | | |
79 | 372k | encode_mvcomponent(w, mv->row >> 1, &mvc[0]); |
80 | 372k | encode_mvcomponent(w, mv->col >> 1, &mvc[1]); |
81 | 372k | } |
82 | | |
83 | | static unsigned int cost_mvcomponent(const int v, |
84 | 44.6M | const struct mv_context *mvc) { |
85 | 44.6M | const vp8_prob *p = mvc->prob; |
86 | 44.6M | const int x = v; |
87 | 44.6M | unsigned int cost; |
88 | | |
89 | 44.6M | if (x < mvnum_short) { |
90 | 348k | cost = vp8_cost_zero(p[mvpis_short]) + |
91 | 348k | vp8_treed_cost(vp8_small_mvtree, p + MVPshort, x, 3); |
92 | | |
93 | 348k | if (!x) return cost; |
94 | 44.3M | } else { |
95 | 44.3M | int i = 0; |
96 | 44.3M | cost = vp8_cost_one(p[mvpis_short]); |
97 | | |
98 | 132M | do { |
99 | 132M | cost += vp8_cost_bit(p[MVPbits + i], (x >> i) & 1); |
100 | | |
101 | 132M | } while (++i < 3); |
102 | | |
103 | 44.3M | i = mvlong_width - 1; /* Skip bit 3, which is sometimes implicit */ |
104 | | |
105 | 265M | do { |
106 | 265M | cost += vp8_cost_bit(p[MVPbits + i], (x >> i) & 1); |
107 | | |
108 | 265M | } while (--i > 3); |
109 | | |
110 | 44.3M | if (x & 0xFFF0) cost += vp8_cost_bit(p[MVPbits + 3], (x >> 3) & 1); |
111 | 44.3M | } |
112 | | |
113 | 44.6M | return cost; /* + vp8_cost_bit( p [MVPsign], v < 0); */ |
114 | 44.6M | } |
115 | | |
116 | | void vp8_build_component_cost_table(int *mvcost[2], const MV_CONTEXT *mvc, |
117 | 23.0k | int mvc_flag[2]) { |
118 | 23.0k | int i = 1; |
119 | 23.0k | unsigned int cost0 = 0; |
120 | 23.0k | unsigned int cost1 = 0; |
121 | | |
122 | 23.0k | vpx_clear_system_state(); |
123 | | |
124 | 23.0k | i = 1; |
125 | | |
126 | 23.0k | if (mvc_flag[0]) { |
127 | 21.8k | mvcost[0][0] = cost_mvcomponent(0, &mvc[0]); |
128 | | |
129 | 22.3M | do { |
130 | 22.3M | cost0 = cost_mvcomponent(i, &mvc[0]); |
131 | | |
132 | 22.3M | mvcost[0][i] = cost0 + vp8_cost_zero(mvc[0].prob[MVPsign]); |
133 | 22.3M | mvcost[0][-i] = cost0 + vp8_cost_one(mvc[0].prob[MVPsign]); |
134 | 22.3M | } while (++i <= mv_max); |
135 | 21.8k | } |
136 | | |
137 | 23.0k | i = 1; |
138 | | |
139 | 23.0k | if (mvc_flag[1]) { |
140 | 21.7k | mvcost[1][0] = cost_mvcomponent(0, &mvc[1]); |
141 | | |
142 | 22.2M | do { |
143 | 22.2M | cost1 = cost_mvcomponent(i, &mvc[1]); |
144 | | |
145 | 22.2M | mvcost[1][i] = cost1 + vp8_cost_zero(mvc[1].prob[MVPsign]); |
146 | 22.2M | mvcost[1][-i] = cost1 + vp8_cost_one(mvc[1].prob[MVPsign]); |
147 | 22.2M | } while (++i <= mv_max); |
148 | 21.7k | } |
149 | 23.0k | } |
150 | | |
151 | | /* Motion vector probability table update depends on benefit. |
152 | | * Small correction allows for the fact that an update to an MV probability |
153 | | * may have benefit in subsequent frames as well as the current one. |
154 | | */ |
155 | 2.19M | #define MV_PROB_UPDATE_CORRECTION -1 |
156 | | |
157 | 2.19M | static void calc_prob(vp8_prob *p, const unsigned int ct[2]) { |
158 | 2.19M | const unsigned int tot = ct[0] + ct[1]; |
159 | | |
160 | 2.19M | if (tot) { |
161 | 784k | const vp8_prob x = ((ct[0] * 255) / tot) & ~1u; |
162 | 784k | *p = x ? x : 1; |
163 | 784k | } |
164 | 2.19M | } |
165 | | |
166 | | static void update(vp8_writer *const w, const unsigned int ct[2], |
167 | | vp8_prob *const cur_p, const vp8_prob new_p, |
168 | 2.19M | const vp8_prob update_p, int *updated) { |
169 | 2.19M | const int cur_b = vp8_cost_branch(ct, *cur_p); |
170 | 2.19M | const int new_b = vp8_cost_branch(ct, new_p); |
171 | 2.19M | const int cost = |
172 | 2.19M | 7 + MV_PROB_UPDATE_CORRECTION + |
173 | 2.19M | ((vp8_cost_one(update_p) - vp8_cost_zero(update_p) + 128) >> 8); |
174 | | |
175 | 2.19M | if (cur_b - new_b > cost) { |
176 | 13.5k | *cur_p = new_p; |
177 | 13.5k | vp8_write(w, 1, update_p); |
178 | 13.5k | vp8_write_literal(w, new_p >> 1, 7); |
179 | 13.5k | *updated = 1; |
180 | | |
181 | 13.5k | } else |
182 | 2.18M | vp8_write(w, 0, update_p); |
183 | 2.19M | } |
184 | | |
185 | | static void write_component_probs(vp8_writer *const w, |
186 | | struct mv_context *cur_mvc, |
187 | | const struct mv_context *default_mvc_, |
188 | | const struct mv_context *update_mvc, |
189 | | const unsigned int events[MVvals], |
190 | 115k | unsigned int rc, int *updated) { |
191 | 115k | vp8_prob *Pcur = cur_mvc->prob; |
192 | 115k | const vp8_prob *default_mvc = default_mvc_->prob; |
193 | 115k | const vp8_prob *Pupdate = update_mvc->prob; |
194 | 115k | unsigned int is_short_ct[2], sign_ct[2]; |
195 | | |
196 | 115k | unsigned int bit_ct[mvlong_width][2]; |
197 | | |
198 | 115k | unsigned int short_ct[mvnum_short]; |
199 | 115k | unsigned int short_bct[mvnum_short - 1][2]; |
200 | | |
201 | 115k | vp8_prob Pnew[MVPcount]; |
202 | | |
203 | 115k | (void)rc; |
204 | 115k | vp8_copy_array(Pnew, default_mvc, MVPcount); |
205 | | |
206 | 115k | vp8_zero(is_short_ct); |
207 | 115k | vp8_zero(sign_ct); |
208 | 115k | vp8_zero(bit_ct); |
209 | 115k | vp8_zero(short_ct); |
210 | 115k | vp8_zero(short_bct); |
211 | | |
212 | | /* j=0 */ |
213 | 115k | { |
214 | 115k | const int c = events[mv_max]; |
215 | | |
216 | 115k | is_short_ct[0] += c; /* Short vector */ |
217 | 115k | short_ct[0] += c; /* Magnitude distribution */ |
218 | 115k | } |
219 | | |
220 | | /* j: 1 ~ mv_max (1023) */ |
221 | 115k | { |
222 | 115k | int j = 1; |
223 | | |
224 | 118M | do { |
225 | 118M | const int c1 = events[mv_max + j]; /* positive */ |
226 | 118M | const int c2 = events[mv_max - j]; /* negative */ |
227 | 118M | const int c = c1 + c2; |
228 | 118M | int a = j; |
229 | | |
230 | 118M | sign_ct[0] += c1; |
231 | 118M | sign_ct[1] += c2; |
232 | | |
233 | 118M | if (a < mvnum_short) { |
234 | 809k | is_short_ct[0] += c; /* Short vector */ |
235 | 809k | short_ct[a] += c; /* Magnitude distribution */ |
236 | 117M | } else { |
237 | 117M | int k = mvlong_width - 1; |
238 | 117M | is_short_ct[1] += c; /* Long vector */ |
239 | | |
240 | | /* bit 3 not always encoded. */ |
241 | 1.17G | do { |
242 | 1.17G | bit_ct[k][(a >> k) & 1] += c; |
243 | | |
244 | 1.17G | } while (--k >= 0); |
245 | 117M | } |
246 | 118M | } while (++j <= mv_max); |
247 | 115k | } |
248 | | |
249 | 115k | calc_prob(Pnew + mvpis_short, is_short_ct); |
250 | | |
251 | 115k | calc_prob(Pnew + MVPsign, sign_ct); |
252 | | |
253 | 115k | { |
254 | 115k | vp8_prob p[mvnum_short - 1]; /* actually only need branch ct */ |
255 | 115k | int j = 0; |
256 | | |
257 | 115k | vp8_tree_probs_from_distribution(8, vp8_small_mvencodings, vp8_small_mvtree, |
258 | 115k | p, short_bct, short_ct, 256, 1); |
259 | | |
260 | 809k | do { |
261 | 809k | calc_prob(Pnew + MVPshort + j, short_bct[j]); |
262 | | |
263 | 809k | } while (++j < mvnum_short - 1); |
264 | 115k | } |
265 | | |
266 | 115k | { |
267 | 115k | int j = 0; |
268 | | |
269 | 1.15M | do { |
270 | 1.15M | calc_prob(Pnew + MVPbits + j, bit_ct[j]); |
271 | | |
272 | 1.15M | } while (++j < mvlong_width); |
273 | 115k | } |
274 | | |
275 | 115k | update(w, is_short_ct, Pcur + mvpis_short, Pnew[mvpis_short], *Pupdate++, |
276 | 115k | updated); |
277 | | |
278 | 115k | update(w, sign_ct, Pcur + MVPsign, Pnew[MVPsign], *Pupdate++, updated); |
279 | | |
280 | 115k | { |
281 | 115k | const vp8_prob *const new_p = Pnew + MVPshort; |
282 | 115k | vp8_prob *const cur_p = Pcur + MVPshort; |
283 | | |
284 | 115k | int j = 0; |
285 | | |
286 | 809k | do { |
287 | 809k | update(w, short_bct[j], cur_p + j, new_p[j], *Pupdate++, updated); |
288 | | |
289 | 809k | } while (++j < mvnum_short - 1); |
290 | 115k | } |
291 | | |
292 | 115k | { |
293 | 115k | const vp8_prob *const new_p = Pnew + MVPbits; |
294 | 115k | vp8_prob *const cur_p = Pcur + MVPbits; |
295 | | |
296 | 115k | int j = 0; |
297 | | |
298 | 1.15M | do { |
299 | 1.15M | update(w, bit_ct[j], cur_p + j, new_p[j], *Pupdate++, updated); |
300 | | |
301 | 1.15M | } while (++j < mvlong_width); |
302 | 115k | } |
303 | 115k | } |
304 | | |
305 | 57.8k | void vp8_write_mvprobs(VP8_COMP *cpi) { |
306 | 57.8k | vp8_writer *const w = cpi->bc; |
307 | 57.8k | MV_CONTEXT *mvc = cpi->common.fc.mvc; |
308 | 57.8k | int flags[2] = { 0, 0 }; |
309 | 57.8k | write_component_probs(w, &mvc[0], &vp8_default_mv_context[0], |
310 | 57.8k | &vp8_mv_update_probs[0], cpi->mb.MVcount[0], 0, |
311 | 57.8k | &flags[0]); |
312 | 57.8k | write_component_probs(w, &mvc[1], &vp8_default_mv_context[1], |
313 | 57.8k | &vp8_mv_update_probs[1], cpi->mb.MVcount[1], 1, |
314 | 57.8k | &flags[1]); |
315 | | |
316 | 57.8k | if (flags[0] || flags[1]) { |
317 | 4.45k | vp8_build_component_cost_table( |
318 | 4.45k | cpi->mb.mvcost, (const MV_CONTEXT *)cpi->common.fc.mvc, flags); |
319 | 4.45k | } |
320 | 57.8k | } |