OLD | NEW |
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 | 11 |
12 #include "vp9/common/vp9_onyxc_int.h" | 12 #include "vp9/common/vp9_onyxc_int.h" |
13 #include "vp9/common/vp9_entropymv.h" | 13 #include "vp9/common/vp9_entropymv.h" |
14 | 14 |
15 #define MV_COUNT_SAT 20 | 15 #define MV_COUNT_SAT 20 |
16 #define MV_MAX_UPDATE_FACTOR 128 | 16 #define MV_MAX_UPDATE_FACTOR 128 |
17 | 17 |
18 /* Integer pel reference mv threshold for use of high-precision 1/8 mv */ | 18 /* Integer pel reference mv threshold for use of high-precision 1/8 mv */ |
19 #define COMPANDED_MVREF_THRESH 8 | 19 #define COMPANDED_MVREF_THRESH 8 |
20 | 20 |
21 const vp9_tree_index vp9_mv_joint_tree[2 * MV_JOINTS - 2] = { | 21 const vp9_tree_index vp9_mv_joint_tree[2 * MV_JOINTS - 2] = { |
22 -MV_JOINT_ZERO, 2, | 22 -MV_JOINT_ZERO, 2, |
23 -MV_JOINT_HNZVZ, 4, | 23 -MV_JOINT_HNZVZ, 4, |
24 -MV_JOINT_HZVNZ, -MV_JOINT_HNZVNZ | 24 -MV_JOINT_HZVNZ, -MV_JOINT_HNZVNZ |
25 }; | 25 }; |
26 struct vp9_token vp9_mv_joint_encodings[MV_JOINTS]; | 26 struct vp9_token vp9_mv_joint_encodings[MV_JOINTS]; |
27 | 27 |
28 const vp9_tree_index vp9_mv_class_tree[2 * MV_CLASSES - 2] = { | 28 const vp9_tree_index vp9_mv_class_tree[2 * MV_CLASSES - 2] = { |
29 -MV_CLASS_0, 2, | 29 -MV_CLASS_0, 2, |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 | 100 |
101 int vp9_use_mv_hp(const MV *ref) { | 101 int vp9_use_mv_hp(const MV *ref) { |
102 return (abs(ref->row) >> 3) < COMPANDED_MVREF_THRESH && | 102 return (abs(ref->row) >> 3) < COMPANDED_MVREF_THRESH && |
103 (abs(ref->col) >> 3) < COMPANDED_MVREF_THRESH; | 103 (abs(ref->col) >> 3) < COMPANDED_MVREF_THRESH; |
104 } | 104 } |
105 | 105 |
106 int vp9_get_mv_mag(MV_CLASS_TYPE c, int offset) { | 106 int vp9_get_mv_mag(MV_CLASS_TYPE c, int offset) { |
107 return mv_class_base(c) + offset; | 107 return mv_class_base(c) + offset; |
108 } | 108 } |
109 | 109 |
110 static void inc_mv_component_count(int v, nmv_component_counts *comp_counts, | |
111 int incr) { | |
112 assert (v != 0); | |
113 comp_counts->mvcount[MV_MAX + v] += incr; | |
114 } | |
115 | |
116 static void inc_mv_component(int v, nmv_component_counts *comp_counts, | 110 static void inc_mv_component(int v, nmv_component_counts *comp_counts, |
117 int incr, int usehp) { | 111 int incr, int usehp) { |
118 int s, z, c, o, d, e, f; | 112 int s, z, c, o, d, e, f; |
119 if (!incr) | 113 if (!incr) |
120 return; | 114 return; |
121 assert (v != 0); /* should not be zero */ | 115 assert (v != 0); /* should not be zero */ |
122 s = v < 0; | 116 s = v < 0; |
123 comp_counts->sign[s] += incr; | 117 comp_counts->sign[s] += incr; |
124 z = (s ? -v : v) - 1; /* magnitude - 1 */ | 118 z = (s ? -v : v) - 1; /* magnitude - 1 */ |
125 | 119 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 | 151 |
158 static void counts_to_context(nmv_component_counts *mvcomp, int usehp) { | 152 static void counts_to_context(nmv_component_counts *mvcomp, int usehp) { |
159 int v; | 153 int v; |
160 vpx_memset(mvcomp->sign, 0, sizeof(nmv_component_counts) - sizeof(mvcomp->mvco
unt)); | 154 vpx_memset(mvcomp->sign, 0, sizeof(nmv_component_counts) - sizeof(mvcomp->mvco
unt)); |
161 for (v = 1; v <= MV_MAX; v++) { | 155 for (v = 1; v <= MV_MAX; v++) { |
162 inc_mv_component(-v, mvcomp, mvcomp->mvcount[MV_MAX - v], usehp); | 156 inc_mv_component(-v, mvcomp, mvcomp->mvcount[MV_MAX - v], usehp); |
163 inc_mv_component( v, mvcomp, mvcomp->mvcount[MV_MAX + v], usehp); | 157 inc_mv_component( v, mvcomp, mvcomp->mvcount[MV_MAX + v], usehp); |
164 } | 158 } |
165 } | 159 } |
166 | 160 |
167 void vp9_inc_mv(const MV *mv, nmv_context_counts *mvctx) { | 161 void vp9_inc_mv(const MV *mv, nmv_context_counts *counts) { |
168 const MV_JOINT_TYPE j = vp9_get_mv_joint(mv); | 162 const MV_JOINT_TYPE j = vp9_get_mv_joint(mv); |
169 mvctx->joints[j]++; | 163 ++counts->joints[j]; |
| 164 |
170 if (mv_joint_vertical(j)) | 165 if (mv_joint_vertical(j)) |
171 inc_mv_component_count(mv->row, &mvctx->comps[0], 1); | 166 ++counts->comps[0].mvcount[MV_MAX + mv->row]; |
172 | 167 |
173 if (mv_joint_horizontal(j)) | 168 if (mv_joint_horizontal(j)) |
174 inc_mv_component_count(mv->col, &mvctx->comps[1], 1); | 169 ++counts->comps[1].mvcount[MV_MAX + mv->col]; |
175 } | 170 } |
176 | 171 |
177 static void adapt_prob(vp9_prob *dest, vp9_prob prep, unsigned int ct[2]) { | 172 static vp9_prob adapt_prob(vp9_prob prep, const unsigned int ct[2]) { |
178 const int count = MIN(ct[0] + ct[1], MV_COUNT_SAT); | 173 return merge_probs2(prep, ct, MV_COUNT_SAT, MV_MAX_UPDATE_FACTOR); |
179 if (count) { | |
180 const vp9_prob newp = get_binary_prob(ct[0], ct[1]); | |
181 const int factor = MV_MAX_UPDATE_FACTOR * count / MV_COUNT_SAT; | |
182 *dest = weighted_prob(prep, newp, factor); | |
183 } else { | |
184 *dest = prep; | |
185 } | |
186 } | 174 } |
187 | 175 |
188 void vp9_counts_process(nmv_context_counts *nmv_count, int usehp) { | 176 void vp9_counts_process(nmv_context_counts *nmv_count, int usehp) { |
189 counts_to_context(&nmv_count->comps[0], usehp); | 177 counts_to_context(&nmv_count->comps[0], usehp); |
190 counts_to_context(&nmv_count->comps[1], usehp); | 178 counts_to_context(&nmv_count->comps[1], usehp); |
191 } | 179 } |
192 | 180 |
193 static unsigned int adapt_probs(unsigned int i, | 181 static unsigned int adapt_probs(unsigned int i, |
194 vp9_tree tree, | 182 vp9_tree tree, |
195 vp9_prob this_probs[], | 183 vp9_prob this_probs[], |
196 const vp9_prob last_probs[], | 184 const vp9_prob last_probs[], |
197 const unsigned int num_events[]) { | 185 const unsigned int num_events[]) { |
198 vp9_prob this_prob; | |
199 | 186 |
200 const uint32_t left = tree[i] <= 0 | 187 |
| 188 const unsigned int left = tree[i] <= 0 |
201 ? num_events[-tree[i]] | 189 ? num_events[-tree[i]] |
202 : adapt_probs(tree[i], tree, this_probs, last_probs, num_events); | 190 : adapt_probs(tree[i], tree, this_probs, last_probs, num_events); |
203 | 191 |
204 const uint32_t right = tree[i + 1] <= 0 | 192 const unsigned int right = tree[i + 1] <= 0 |
205 ? num_events[-tree[i + 1]] | 193 ? num_events[-tree[i + 1]] |
206 : adapt_probs(tree[i + 1], tree, this_probs, last_probs, num_events); | 194 : adapt_probs(tree[i + 1], tree, this_probs, last_probs, num_events); |
207 | 195 const unsigned int ct[2] = { left, right }; |
208 uint32_t weight = left + right; | 196 this_probs[i >> 1] = adapt_prob(last_probs[i >> 1], ct); |
209 if (weight) { | |
210 this_prob = get_binary_prob(left, right); | |
211 weight = weight > MV_COUNT_SAT ? MV_COUNT_SAT : weight; | |
212 this_prob = weighted_prob(last_probs[i >> 1], this_prob, | |
213 MV_MAX_UPDATE_FACTOR * weight / MV_COUNT_SAT); | |
214 } else { | |
215 this_prob = last_probs[i >> 1]; | |
216 } | |
217 this_probs[i >> 1] = this_prob; | |
218 return left + right; | 197 return left + right; |
219 } | 198 } |
220 | 199 |
221 | 200 |
222 void vp9_adapt_mv_probs(VP9_COMMON *cm, int usehp) { | 201 void vp9_adapt_mv_probs(VP9_COMMON *cm, int allow_hp) { |
223 int i, j; | 202 int i, j; |
224 | 203 |
225 FRAME_CONTEXT *pre_fc = &cm->frame_contexts[cm->frame_context_idx]; | 204 FRAME_CONTEXT *pre_fc = &cm->frame_contexts[cm->frame_context_idx]; |
226 | 205 |
227 nmv_context *ctx = &cm->fc.nmvc; | 206 nmv_context *ctx = &cm->fc.nmvc; |
228 nmv_context *pre_ctx = &pre_fc->nmvc; | 207 nmv_context *pre_ctx = &pre_fc->nmvc; |
229 nmv_context_counts *cts = &cm->counts.mv; | 208 nmv_context_counts *cts = &cm->counts.mv; |
230 | 209 |
231 vp9_counts_process(cts, usehp); | 210 vp9_counts_process(cts, allow_hp); |
232 | 211 |
233 adapt_probs(0, vp9_mv_joint_tree, ctx->joints, pre_ctx->joints, cts->joints); | 212 adapt_probs(0, vp9_mv_joint_tree, ctx->joints, pre_ctx->joints, cts->joints); |
234 | 213 |
235 for (i = 0; i < 2; ++i) { | 214 for (i = 0; i < 2; ++i) { |
236 adapt_prob(&ctx->comps[i].sign, pre_ctx->comps[i].sign, cts->comps[i].sign); | 215 ctx->comps[i].sign = adapt_prob(pre_ctx->comps[i].sign, cts->comps[i].sign); |
237 adapt_probs(0, vp9_mv_class_tree, ctx->comps[i].classes, | 216 adapt_probs(0, vp9_mv_class_tree, ctx->comps[i].classes, |
238 pre_ctx->comps[i].classes, cts->comps[i].classes); | 217 pre_ctx->comps[i].classes, cts->comps[i].classes); |
239 adapt_probs(0, vp9_mv_class0_tree, ctx->comps[i].class0, | 218 adapt_probs(0, vp9_mv_class0_tree, ctx->comps[i].class0, |
240 pre_ctx->comps[i].class0, cts->comps[i].class0); | 219 pre_ctx->comps[i].class0, cts->comps[i].class0); |
241 | 220 |
242 for (j = 0; j < MV_OFFSET_BITS; ++j) | 221 for (j = 0; j < MV_OFFSET_BITS; ++j) |
243 adapt_prob(&ctx->comps[i].bits[j], pre_ctx->comps[i].bits[j], | 222 ctx->comps[i].bits[j] = adapt_prob(pre_ctx->comps[i].bits[j], |
244 cts->comps[i].bits[j]); | 223 cts->comps[i].bits[j]); |
245 } | |
246 | 224 |
247 for (i = 0; i < 2; ++i) { | |
248 for (j = 0; j < CLASS0_SIZE; ++j) | 225 for (j = 0; j < CLASS0_SIZE; ++j) |
249 adapt_probs(0, vp9_mv_fp_tree, ctx->comps[i].class0_fp[j], | 226 adapt_probs(0, vp9_mv_fp_tree, ctx->comps[i].class0_fp[j], |
250 pre_ctx->comps[i].class0_fp[j], cts->comps[i].class0_fp[j]); | 227 pre_ctx->comps[i].class0_fp[j], cts->comps[i].class0_fp[j]); |
251 | 228 |
252 adapt_probs(0, vp9_mv_fp_tree, ctx->comps[i].fp, pre_ctx->comps[i].fp, | 229 adapt_probs(0, vp9_mv_fp_tree, ctx->comps[i].fp, pre_ctx->comps[i].fp, |
253 cts->comps[i].fp); | 230 cts->comps[i].fp); |
254 } | |
255 | 231 |
256 if (usehp) { | 232 if (allow_hp) { |
257 for (i = 0; i < 2; ++i) { | 233 ctx->comps[i].class0_hp = adapt_prob(pre_ctx->comps[i].class0_hp, |
258 adapt_prob(&ctx->comps[i].class0_hp, pre_ctx->comps[i].class0_hp, | 234 cts->comps[i].class0_hp); |
259 cts->comps[i].class0_hp); | 235 ctx->comps[i].hp = adapt_prob(pre_ctx->comps[i].hp, cts->comps[i].hp); |
260 adapt_prob(&ctx->comps[i].hp, pre_ctx->comps[i].hp, cts->comps[i].hp); | |
261 } | 236 } |
262 } | 237 } |
263 } | 238 } |
264 | 239 |
265 void vp9_entropy_mv_init() { | 240 void vp9_entropy_mv_init() { |
266 vp9_tokens_from_tree(vp9_mv_joint_encodings, vp9_mv_joint_tree); | 241 vp9_tokens_from_tree(vp9_mv_joint_encodings, vp9_mv_joint_tree); |
267 vp9_tokens_from_tree(vp9_mv_class_encodings, vp9_mv_class_tree); | 242 vp9_tokens_from_tree(vp9_mv_class_encodings, vp9_mv_class_tree); |
268 vp9_tokens_from_tree(vp9_mv_class0_encodings, vp9_mv_class0_tree); | 243 vp9_tokens_from_tree(vp9_mv_class0_encodings, vp9_mv_class0_tree); |
269 vp9_tokens_from_tree(vp9_mv_fp_encodings, vp9_mv_fp_tree); | 244 vp9_tokens_from_tree(vp9_mv_fp_encodings, vp9_mv_fp_tree); |
270 } | 245 } |
271 | 246 |
272 void vp9_init_mv_probs(VP9_COMMON *cm) { | 247 void vp9_init_mv_probs(VP9_COMMON *cm) { |
273 cm->fc.nmvc = default_nmv_context; | 248 cm->fc.nmvc = default_nmv_context; |
274 } | 249 } |
OLD | NEW |