Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(306)

Side by Side Diff: source/libvpx/vp9/encoder/vp9_encodemv.c

Issue 111463005: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_encodemv.h ('k') | source/libvpx/vp9/encoder/vp9_extend.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include <math.h> 11 #include <math.h>
12 12
13 #include "vp9/common/vp9_common.h" 13 #include "vp9/common/vp9_common.h"
14 #include "vp9/common/vp9_entropymode.h" 14 #include "vp9/common/vp9_entropymode.h"
15 #include "vp9/common/vp9_systemdependent.h" 15 #include "vp9/common/vp9_systemdependent.h"
16 #include "vp9/encoder/vp9_encodemv.h" 16 #include "vp9/encoder/vp9_encodemv.h"
17 17
18
19 #ifdef ENTROPY_STATS 18 #ifdef ENTROPY_STATS
20 extern unsigned int active_section; 19 extern unsigned int active_section;
21 #endif 20 #endif
22 21
22 static struct vp9_token mv_joint_encodings[MV_JOINTS];
23 static struct vp9_token mv_class_encodings[MV_CLASSES];
24 static struct vp9_token mv_fp_encodings[MV_FP_SIZE];
25 static struct vp9_token mv_class0_encodings[CLASS0_SIZE];
26
27 void vp9_entropy_mv_init() {
28 vp9_tokens_from_tree(mv_joint_encodings, vp9_mv_joint_tree);
29 vp9_tokens_from_tree(mv_class_encodings, vp9_mv_class_tree);
30 vp9_tokens_from_tree(mv_class0_encodings, vp9_mv_class0_tree);
31 vp9_tokens_from_tree(mv_fp_encodings, vp9_mv_fp_tree);
32 }
33
23 static void encode_mv_component(vp9_writer* w, int comp, 34 static void encode_mv_component(vp9_writer* w, int comp,
24 const nmv_component* mvcomp, int usehp) { 35 const nmv_component* mvcomp, int usehp) {
25 int offset; 36 int offset;
26 const int sign = comp < 0; 37 const int sign = comp < 0;
27 const int mag = sign ? -comp : comp; 38 const int mag = sign ? -comp : comp;
28 const int mv_class = vp9_get_mv_class(mag - 1, &offset); 39 const int mv_class = vp9_get_mv_class(mag - 1, &offset);
29 const int d = offset >> 3; // int mv data 40 const int d = offset >> 3; // int mv data
30 const int fr = (offset >> 1) & 3; // fractional mv data 41 const int fr = (offset >> 1) & 3; // fractional mv data
31 const int hp = offset & 1; // high precision mv data 42 const int hp = offset & 1; // high precision mv data
32 43
33 assert(comp != 0); 44 assert(comp != 0);
34 45
35 // Sign 46 // Sign
36 vp9_write(w, sign, mvcomp->sign); 47 vp9_write(w, sign, mvcomp->sign);
37 48
38 // Class 49 // Class
39 write_token(w, vp9_mv_class_tree, mvcomp->classes, 50 vp9_write_token(w, vp9_mv_class_tree, mvcomp->classes,
40 &vp9_mv_class_encodings[mv_class]); 51 &mv_class_encodings[mv_class]);
41 52
42 // Integer bits 53 // Integer bits
43 if (mv_class == MV_CLASS_0) { 54 if (mv_class == MV_CLASS_0) {
44 write_token(w, vp9_mv_class0_tree, mvcomp->class0, 55 vp9_write_token(w, vp9_mv_class0_tree, mvcomp->class0,
45 &vp9_mv_class0_encodings[d]); 56 &mv_class0_encodings[d]);
46 } else { 57 } else {
47 int i; 58 int i;
48 const int n = mv_class + CLASS0_BITS - 1; // number of bits 59 const int n = mv_class + CLASS0_BITS - 1; // number of bits
49 for (i = 0; i < n; ++i) 60 for (i = 0; i < n; ++i)
50 vp9_write(w, (d >> i) & 1, mvcomp->bits[i]); 61 vp9_write(w, (d >> i) & 1, mvcomp->bits[i]);
51 } 62 }
52 63
53 // Fractional bits 64 // Fractional bits
54 write_token(w, vp9_mv_fp_tree, 65 vp9_write_token(w, vp9_mv_fp_tree,
55 mv_class == MV_CLASS_0 ? mvcomp->class0_fp[d] : mvcomp->fp, 66 mv_class == MV_CLASS_0 ? mvcomp->class0_fp[d] : mvcomp->fp,
56 &vp9_mv_fp_encodings[fr]); 67 &mv_fp_encodings[fr]);
57 68
58 // High precision bit 69 // High precision bit
59 if (usehp) 70 if (usehp)
60 vp9_write(w, hp, 71 vp9_write(w, hp,
61 mv_class == MV_CLASS_0 ? mvcomp->class0_hp : mvcomp->hp); 72 mv_class == MV_CLASS_0 ? mvcomp->class0_hp : mvcomp->hp);
62 } 73 }
63 74
64 75
65 static void build_nmv_component_cost_table(int *mvcost, 76 static void build_nmv_component_cost_table(int *mvcost,
66 const nmv_component* const mvcomp, 77 const nmv_component* const mvcomp,
67 int usehp) { 78 int usehp) {
68 int i, v; 79 int i, v;
69 int sign_cost[2], class_cost[MV_CLASSES], class0_cost[CLASS0_SIZE]; 80 int sign_cost[2], class_cost[MV_CLASSES], class0_cost[CLASS0_SIZE];
70 int bits_cost[MV_OFFSET_BITS][2]; 81 int bits_cost[MV_OFFSET_BITS][2];
71 int class0_fp_cost[CLASS0_SIZE][4], fp_cost[4]; 82 int class0_fp_cost[CLASS0_SIZE][MV_FP_SIZE], fp_cost[MV_FP_SIZE];
72 int class0_hp_cost[2], hp_cost[2]; 83 int class0_hp_cost[2], hp_cost[2];
73 84
74 sign_cost[0] = vp9_cost_zero(mvcomp->sign); 85 sign_cost[0] = vp9_cost_zero(mvcomp->sign);
75 sign_cost[1] = vp9_cost_one(mvcomp->sign); 86 sign_cost[1] = vp9_cost_one(mvcomp->sign);
76 vp9_cost_tokens(class_cost, mvcomp->classes, vp9_mv_class_tree); 87 vp9_cost_tokens(class_cost, mvcomp->classes, vp9_mv_class_tree);
77 vp9_cost_tokens(class0_cost, mvcomp->class0, vp9_mv_class0_tree); 88 vp9_cost_tokens(class0_cost, mvcomp->class0, vp9_mv_class0_tree);
78 for (i = 0; i < MV_OFFSET_BITS; ++i) { 89 for (i = 0; i < MV_OFFSET_BITS; ++i) {
79 bits_cost[i][0] = vp9_cost_zero(mvcomp->bits[i]); 90 bits_cost[i][0] = vp9_cost_zero(mvcomp->bits[i]);
80 bits_cost[i][1] = vp9_cost_one(mvcomp->bits[i]); 91 bits_cost[i][1] = vp9_cost_one(mvcomp->bits[i]);
81 } 92 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 cost += class0_hp_cost[e]; 128 cost += class0_hp_cost[e];
118 } else { 129 } else {
119 cost += hp_cost[e]; 130 cost += hp_cost[e];
120 } 131 }
121 } 132 }
122 mvcost[v] = cost + sign_cost[0]; 133 mvcost[v] = cost + sign_cost[0];
123 mvcost[-v] = cost + sign_cost[1]; 134 mvcost[-v] = cost + sign_cost[1];
124 } 135 }
125 } 136 }
126 137
127 static int update_mv(vp9_writer *w, const unsigned int ct[2], 138 static int update_mv(vp9_writer *w, const unsigned int ct[2], vp9_prob *cur_p,
128 vp9_prob *cur_p, vp9_prob new_p, vp9_prob upd_p) { 139 vp9_prob upd_p) {
129 vp9_prob mod_p = new_p | 1; 140 const vp9_prob new_p = get_binary_prob(ct[0], ct[1]) | 1;
130 const int cur_b = cost_branch256(ct, *cur_p); 141 const int update = cost_branch256(ct, *cur_p) + vp9_cost_zero(upd_p) >
131 const int mod_b = cost_branch256(ct, mod_p); 142 cost_branch256(ct, new_p) + vp9_cost_one(upd_p) + 7 * 256;
132 const int cost = 7 * 256 + (vp9_cost_one(upd_p) - vp9_cost_zero(upd_p)); 143 vp9_write(w, update, upd_p);
133 if (cur_b - mod_b > cost) { 144 if (update) {
134 *cur_p = mod_p; 145 *cur_p = new_p;
135 vp9_write(w, 1, upd_p); 146 vp9_write_literal(w, new_p >> 1, 7);
136 vp9_write_literal(w, mod_p >> 1, 7);
137 return 1;
138 } else {
139 vp9_write(w, 0, upd_p);
140 return 0;
141 } 147 }
148 return update;
142 } 149 }
143 150
144 static void counts_to_nmv_context( 151 static void write_mv_update(const vp9_tree_index *tree,
145 nmv_context_counts *nmv_count, 152 vp9_prob probs[/*n - 1*/],
146 nmv_context *prob, 153 const unsigned int counts[/*n - 1*/],
147 int usehp, 154 int n, vp9_writer *w) {
148 unsigned int (*branch_ct_joint)[2], 155 int i;
149 unsigned int (*branch_ct_sign)[2], 156 unsigned int branch_ct[32][2];
150 unsigned int (*branch_ct_classes)[MV_CLASSES - 1][2],
151 unsigned int (*branch_ct_class0)[CLASS0_SIZE - 1][2],
152 unsigned int (*branch_ct_bits)[MV_OFFSET_BITS][2],
153 unsigned int (*branch_ct_class0_fp)[CLASS0_SIZE][4 - 1][2],
154 unsigned int (*branch_ct_fp)[4 - 1][2],
155 unsigned int (*branch_ct_class0_hp)[2],
156 unsigned int (*branch_ct_hp)[2]) {
157 int i, j, k;
158 vp9_tree_probs_from_distribution(vp9_mv_joint_tree,
159 prob->joints,
160 branch_ct_joint,
161 nmv_count->joints, 0);
162 for (i = 0; i < 2; ++i) {
163 const uint32_t s0 = nmv_count->comps[i].sign[0];
164 const uint32_t s1 = nmv_count->comps[i].sign[1];
165 157
166 prob->comps[i].sign = get_binary_prob(s0, s1); 158 // Assuming max number of probabilities <= 32
167 branch_ct_sign[i][0] = s0; 159 assert(n <= 32);
168 branch_ct_sign[i][1] = s1;
169 vp9_tree_probs_from_distribution(vp9_mv_class_tree,
170 prob->comps[i].classes,
171 branch_ct_classes[i],
172 nmv_count->comps[i].classes, 0);
173 vp9_tree_probs_from_distribution(vp9_mv_class0_tree,
174 prob->comps[i].class0,
175 branch_ct_class0[i],
176 nmv_count->comps[i].class0, 0);
177 for (j = 0; j < MV_OFFSET_BITS; ++j) {
178 const uint32_t b0 = nmv_count->comps[i].bits[j][0];
179 const uint32_t b1 = nmv_count->comps[i].bits[j][1];
180 160
181 prob->comps[i].bits[j] = get_binary_prob(b0, b1); 161 vp9_tree_probs_from_distribution(tree, branch_ct, counts);
182 branch_ct_bits[i][j][0] = b0; 162 for (i = 0; i < n - 1; ++i)
183 branch_ct_bits[i][j][1] = b1; 163 update_mv(w, branch_ct[i], &probs[i], NMV_UPDATE_PROB);
184 }
185 }
186 for (i = 0; i < 2; ++i) {
187 for (k = 0; k < CLASS0_SIZE; ++k) {
188 vp9_tree_probs_from_distribution(vp9_mv_fp_tree,
189 prob->comps[i].class0_fp[k],
190 branch_ct_class0_fp[i][k],
191 nmv_count->comps[i].class0_fp[k], 0);
192 }
193 vp9_tree_probs_from_distribution(vp9_mv_fp_tree,
194 prob->comps[i].fp,
195 branch_ct_fp[i],
196 nmv_count->comps[i].fp, 0);
197 }
198 if (usehp) {
199 for (i = 0; i < 2; ++i) {
200 const uint32_t c0_hp0 = nmv_count->comps[i].class0_hp[0];
201 const uint32_t c0_hp1 = nmv_count->comps[i].class0_hp[1];
202 const uint32_t hp0 = nmv_count->comps[i].hp[0];
203 const uint32_t hp1 = nmv_count->comps[i].hp[1];
204
205 prob->comps[i].class0_hp = get_binary_prob(c0_hp0, c0_hp1);
206 branch_ct_class0_hp[i][0] = c0_hp0;
207 branch_ct_class0_hp[i][1] = c0_hp1;
208
209 prob->comps[i].hp = get_binary_prob(hp0, hp1);
210 branch_ct_hp[i][0] = hp0;
211 branch_ct_hp[i][1] = hp1;
212 }
213 }
214 } 164 }
215 165
216 void vp9_write_nmv_probs(VP9_COMP* const cpi, int usehp, vp9_writer* const bc) { 166 void vp9_write_nmv_probs(VP9_COMP* const cpi, int usehp, vp9_writer *w) {
217 int i, j; 167 int i, j;
218 nmv_context prob;
219 unsigned int branch_ct_joint[MV_JOINTS - 1][2];
220 unsigned int branch_ct_sign[2][2];
221 unsigned int branch_ct_classes[2][MV_CLASSES - 1][2];
222 unsigned int branch_ct_class0[2][CLASS0_SIZE - 1][2];
223 unsigned int branch_ct_bits[2][MV_OFFSET_BITS][2];
224 unsigned int branch_ct_class0_fp[2][CLASS0_SIZE][4 - 1][2];
225 unsigned int branch_ct_fp[2][4 - 1][2];
226 unsigned int branch_ct_class0_hp[2][2];
227 unsigned int branch_ct_hp[2][2];
228 nmv_context *mvc = &cpi->common.fc.nmvc; 168 nmv_context *mvc = &cpi->common.fc.nmvc;
169 nmv_context_counts *counts = &cpi->NMVcount;
229 170
230 counts_to_nmv_context(&cpi->NMVcount, &prob, usehp, 171 write_mv_update(vp9_mv_joint_tree, mvc->joints, counts->joints, MV_JOINTS, w);
231 branch_ct_joint, branch_ct_sign, branch_ct_classes,
232 branch_ct_class0, branch_ct_bits,
233 branch_ct_class0_fp, branch_ct_fp,
234 branch_ct_class0_hp, branch_ct_hp);
235
236 for (j = 0; j < MV_JOINTS - 1; ++j)
237 update_mv(bc, branch_ct_joint[j], &mvc->joints[j], prob.joints[j],
238 NMV_UPDATE_PROB);
239 172
240 for (i = 0; i < 2; ++i) { 173 for (i = 0; i < 2; ++i) {
241 update_mv(bc, branch_ct_sign[i], &mvc->comps[i].sign, 174 nmv_component *comp = &mvc->comps[i];
242 prob.comps[i].sign, NMV_UPDATE_PROB); 175 nmv_component_counts *comp_counts = &counts->comps[i];
243 for (j = 0; j < MV_CLASSES - 1; ++j)
244 update_mv(bc, branch_ct_classes[i][j], &mvc->comps[i].classes[j],
245 prob.comps[i].classes[j], NMV_UPDATE_PROB);
246 176
247 for (j = 0; j < CLASS0_SIZE - 1; ++j) 177 update_mv(w, comp_counts->sign, &comp->sign, NMV_UPDATE_PROB);
248 update_mv(bc, branch_ct_class0[i][j], &mvc->comps[i].class0[j], 178 write_mv_update(vp9_mv_class_tree, comp->classes, comp_counts->classes,
249 prob.comps[i].class0[j], NMV_UPDATE_PROB); 179 MV_CLASSES, w);
250 180 write_mv_update(vp9_mv_class0_tree, comp->class0, comp_counts->class0,
181 CLASS0_SIZE, w);
251 for (j = 0; j < MV_OFFSET_BITS; ++j) 182 for (j = 0; j < MV_OFFSET_BITS; ++j)
252 update_mv(bc, branch_ct_bits[i][j], &mvc->comps[i].bits[j], 183 update_mv(w, comp_counts->bits[j], &comp->bits[j], NMV_UPDATE_PROB);
253 prob.comps[i].bits[j], NMV_UPDATE_PROB);
254 } 184 }
255 185
256 for (i = 0; i < 2; ++i) { 186 for (i = 0; i < 2; ++i) {
257 for (j = 0; j < CLASS0_SIZE; ++j) { 187 for (j = 0; j < CLASS0_SIZE; ++j)
258 int k; 188 write_mv_update(vp9_mv_fp_tree, mvc->comps[i].class0_fp[j],
259 for (k = 0; k < 3; ++k) 189 counts->comps[i].class0_fp[j], MV_FP_SIZE, w);
260 update_mv(bc, branch_ct_class0_fp[i][j][k],
261 &mvc->comps[i].class0_fp[j][k],
262 prob.comps[i].class0_fp[j][k], NMV_UPDATE_PROB);
263 }
264 190
265 for (j = 0; j < 3; ++j) 191 write_mv_update(vp9_mv_fp_tree, mvc->comps[i].fp, counts->comps[i].fp,
266 update_mv(bc, branch_ct_fp[i][j], &mvc->comps[i].fp[j], 192 MV_FP_SIZE, w);
267 prob.comps[i].fp[j], NMV_UPDATE_PROB);
268 } 193 }
269 194
270 if (usehp) { 195 if (usehp) {
271 for (i = 0; i < 2; ++i) { 196 for (i = 0; i < 2; ++i) {
272 update_mv(bc, branch_ct_class0_hp[i], &mvc->comps[i].class0_hp, 197 update_mv(w, counts->comps[i].class0_hp, &mvc->comps[i].class0_hp,
273 prob.comps[i].class0_hp, NMV_UPDATE_PROB); 198 NMV_UPDATE_PROB);
274 update_mv(bc, branch_ct_hp[i], &mvc->comps[i].hp, 199 update_mv(w, counts->comps[i].hp, &mvc->comps[i].hp, NMV_UPDATE_PROB);
275 prob.comps[i].hp, NMV_UPDATE_PROB);
276 } 200 }
277 } 201 }
278 } 202 }
279 203
280 void vp9_encode_mv(VP9_COMP* cpi, vp9_writer* w, 204 void vp9_encode_mv(VP9_COMP* cpi, vp9_writer* w,
281 const MV* mv, const MV* ref, 205 const MV* mv, const MV* ref,
282 const nmv_context* mvctx, int usehp) { 206 const nmv_context* mvctx, int usehp) {
283 const MV diff = {mv->row - ref->row, 207 const MV diff = {mv->row - ref->row,
284 mv->col - ref->col}; 208 mv->col - ref->col};
285 const MV_JOINT_TYPE j = vp9_get_mv_joint(&diff); 209 const MV_JOINT_TYPE j = vp9_get_mv_joint(&diff);
286 usehp = usehp && vp9_use_mv_hp(ref); 210 usehp = usehp && vp9_use_mv_hp(ref);
287 211
288 write_token(w, vp9_mv_joint_tree, mvctx->joints, &vp9_mv_joint_encodings[j]); 212 vp9_write_token(w, vp9_mv_joint_tree, mvctx->joints, &mv_joint_encodings[j]);
289 if (mv_joint_vertical(j)) 213 if (mv_joint_vertical(j))
290 encode_mv_component(w, diff.row, &mvctx->comps[0], usehp); 214 encode_mv_component(w, diff.row, &mvctx->comps[0], usehp);
291 215
292 if (mv_joint_horizontal(j)) 216 if (mv_joint_horizontal(j))
293 encode_mv_component(w, diff.col, &mvctx->comps[1], usehp); 217 encode_mv_component(w, diff.col, &mvctx->comps[1], usehp);
294 218
295 // If auto_mv_step_size is enabled then keep track of the largest 219 // If auto_mv_step_size is enabled then keep track of the largest
296 // motion vector component used. 220 // motion vector component used.
297 if (!cpi->dummy_packing && cpi->sf.auto_mv_step_size) { 221 if (!cpi->dummy_packing && cpi->sf.auto_mv_step_size) {
298 unsigned int maxv = MAX(abs(mv->row), abs(mv->col)) >> 3; 222 unsigned int maxv = MAX(abs(mv->row), abs(mv->col)) >> 3;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 for (idx = 0; idx < 2; idx += num_4x4_w) { 262 for (idx = 0; idx < 2; idx += num_4x4_w) {
339 const int i = idy * 2 + idx; 263 const int i = idy * 2 + idx;
340 if (mi->bmi[i].as_mode == NEWMV) 264 if (mi->bmi[i].as_mode == NEWMV)
341 inc_mvs(mi->bmi[i].as_mv, best_ref_mv, is_compound, &cpi->NMVcount); 265 inc_mvs(mi->bmi[i].as_mv, best_ref_mv, is_compound, &cpi->NMVcount);
342 } 266 }
343 } 267 }
344 } else if (mbmi->mode == NEWMV) { 268 } else if (mbmi->mode == NEWMV) {
345 inc_mvs(mbmi->mv, best_ref_mv, is_compound, &cpi->NMVcount); 269 inc_mvs(mbmi->mv, best_ref_mv, is_compound, &cpi->NMVcount);
346 } 270 }
347 } 271 }
272
OLDNEW
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_encodemv.h ('k') | source/libvpx/vp9/encoder/vp9_extend.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698