/src/libvpx/vp9/decoder/vp9_decodemv.c
Line | Count | Source (jump to first uncovered line) |
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 <assert.h> |
12 | | |
13 | | #include "vp9/common/vp9_common.h" |
14 | | #include "vp9/common/vp9_entropy.h" |
15 | | #include "vp9/common/vp9_entropymode.h" |
16 | | #include "vp9/common/vp9_entropymv.h" |
17 | | #include "vp9/common/vp9_mvref_common.h" |
18 | | #include "vp9/common/vp9_pred_common.h" |
19 | | #include "vp9/common/vp9_reconinter.h" |
20 | | #include "vp9/common/vp9_seg_common.h" |
21 | | |
22 | | #include "vp9/decoder/vp9_decodemv.h" |
23 | | #include "vp9/decoder/vp9_decodeframe.h" |
24 | | |
25 | | #include "vpx_dsp/vpx_dsp_common.h" |
26 | | |
27 | 28.1M | static PREDICTION_MODE read_intra_mode(vpx_reader *r, const vpx_prob *p) { |
28 | 28.1M | return (PREDICTION_MODE)vpx_read_tree(r, vp9_intra_mode_tree, p); |
29 | 28.1M | } |
30 | | |
31 | | static PREDICTION_MODE read_intra_mode_y(VP9_COMMON *cm, MACROBLOCKD *xd, |
32 | 6.63M | vpx_reader *r, int size_group) { |
33 | 6.63M | const PREDICTION_MODE y_mode = |
34 | 6.63M | read_intra_mode(r, cm->fc->y_mode_prob[size_group]); |
35 | 6.63M | FRAME_COUNTS *counts = xd->counts; |
36 | 6.63M | if (counts) ++counts->y_mode[size_group][y_mode]; |
37 | 6.63M | return y_mode; |
38 | 6.63M | } |
39 | | |
40 | | static PREDICTION_MODE read_intra_mode_uv(VP9_COMMON *cm, MACROBLOCKD *xd, |
41 | | vpx_reader *r, |
42 | 5.72M | PREDICTION_MODE y_mode) { |
43 | 5.72M | const PREDICTION_MODE uv_mode = |
44 | 5.72M | read_intra_mode(r, cm->fc->uv_mode_prob[y_mode]); |
45 | 5.72M | FRAME_COUNTS *counts = xd->counts; |
46 | 5.72M | if (counts) ++counts->uv_mode[y_mode][uv_mode]; |
47 | 5.72M | return uv_mode; |
48 | 5.72M | } |
49 | | |
50 | | static PREDICTION_MODE read_inter_mode(VP9_COMMON *cm, MACROBLOCKD *xd, |
51 | 11.9M | vpx_reader *r, int ctx) { |
52 | 11.9M | const int mode = |
53 | 11.9M | vpx_read_tree(r, vp9_inter_mode_tree, cm->fc->inter_mode_probs[ctx]); |
54 | 11.9M | FRAME_COUNTS *counts = xd->counts; |
55 | 11.9M | if (counts) ++counts->inter_mode[ctx][mode]; |
56 | | |
57 | 11.9M | return NEARESTMV + mode; |
58 | 11.9M | } |
59 | | |
60 | 3.90M | static int read_segment_id(vpx_reader *r, const struct segmentation *seg) { |
61 | 3.90M | return vpx_read_tree(r, vp9_segment_tree, seg->tree_probs); |
62 | 3.90M | } |
63 | | |
64 | | static TX_SIZE read_selected_tx_size(VP9_COMMON *cm, MACROBLOCKD *xd, |
65 | 3.41M | TX_SIZE max_tx_size, vpx_reader *r) { |
66 | 3.41M | FRAME_COUNTS *counts = xd->counts; |
67 | 3.41M | const int ctx = get_tx_size_context(xd); |
68 | 3.41M | const vpx_prob *tx_probs = get_tx_probs(max_tx_size, ctx, &cm->fc->tx_probs); |
69 | 3.41M | int tx_size = vpx_read(r, tx_probs[0]); |
70 | 3.41M | if (tx_size != TX_4X4 && max_tx_size >= TX_16X16) { |
71 | 1.47M | tx_size += vpx_read(r, tx_probs[1]); |
72 | 1.47M | if (tx_size != TX_8X8 && max_tx_size >= TX_32X32) |
73 | 503k | tx_size += vpx_read(r, tx_probs[2]); |
74 | 1.47M | } |
75 | | |
76 | 3.41M | if (counts) ++get_tx_counts(max_tx_size, ctx, &counts->tx)[tx_size]; |
77 | 3.41M | return (TX_SIZE)tx_size; |
78 | 3.41M | } |
79 | | |
80 | | static INLINE TX_SIZE read_tx_size(VP9_COMMON *cm, MACROBLOCKD *xd, |
81 | 23.1M | int allow_select, vpx_reader *r) { |
82 | 23.1M | TX_MODE tx_mode = cm->tx_mode; |
83 | 23.1M | BLOCK_SIZE bsize = xd->mi[0]->sb_type; |
84 | 23.1M | const TX_SIZE max_tx_size = max_txsize_lookup[bsize]; |
85 | 23.1M | if (allow_select && tx_mode == TX_MODE_SELECT && bsize >= BLOCK_8X8) |
86 | 3.41M | return read_selected_tx_size(cm, xd, max_tx_size, r); |
87 | 19.7M | else |
88 | 19.7M | return VPXMIN(max_tx_size, tx_mode_to_biggest_tx_size[tx_mode]); |
89 | 23.1M | } |
90 | | |
91 | | static int dec_get_segment_id(const VP9_COMMON *cm, const uint8_t *segment_ids, |
92 | 5.87M | int mi_offset, int x_mis, int y_mis) { |
93 | 5.87M | int x, y, segment_id = INT_MAX; |
94 | | |
95 | 21.2M | for (y = 0; y < y_mis; y++) |
96 | 86.0M | for (x = 0; x < x_mis; x++) |
97 | 70.7M | segment_id = |
98 | 70.7M | VPXMIN(segment_id, segment_ids[mi_offset + y * cm->mi_cols + x]); |
99 | | |
100 | 5.87M | assert(segment_id >= 0 && segment_id < MAX_SEGMENTS); |
101 | 5.88M | return segment_id; |
102 | 5.87M | } |
103 | | |
104 | | static void set_segment_id(VP9_COMMON *cm, int mi_offset, int x_mis, int y_mis, |
105 | 4.02M | int segment_id) { |
106 | 4.02M | int x, y; |
107 | | |
108 | 4.02M | assert(segment_id >= 0 && segment_id < MAX_SEGMENTS); |
109 | | |
110 | 22.4M | for (y = 0; y < y_mis; y++) |
111 | 140M | for (x = 0; x < x_mis; x++) |
112 | 122M | cm->current_frame_seg_map[mi_offset + y * cm->mi_cols + x] = segment_id; |
113 | 4.02M | } |
114 | | |
115 | | static void copy_segment_id(const VP9_COMMON *cm, |
116 | | const uint8_t *last_segment_ids, |
117 | | uint8_t *current_segment_ids, int mi_offset, |
118 | 6.35M | int x_mis, int y_mis) { |
119 | 6.35M | int x, y; |
120 | | |
121 | 22.5M | for (y = 0; y < y_mis; y++) |
122 | 91.6M | for (x = 0; x < x_mis; x++) |
123 | 75.4M | current_segment_ids[mi_offset + y * cm->mi_cols + x] = |
124 | 75.4M | last_segment_ids ? last_segment_ids[mi_offset + y * cm->mi_cols + x] |
125 | 75.4M | : 0; |
126 | 6.35M | } |
127 | | |
128 | | static int read_intra_segment_id(VP9_COMMON *const cm, int mi_offset, int x_mis, |
129 | 6.89M | int y_mis, vpx_reader *r) { |
130 | 6.89M | struct segmentation *const seg = &cm->seg; |
131 | 6.89M | int segment_id; |
132 | | |
133 | 6.89M | if (!seg->enabled) return 0; // Default for disabled segmentation |
134 | | |
135 | 4.49M | if (!seg->update_map) { |
136 | 1.50M | copy_segment_id(cm, cm->last_frame_seg_map, cm->current_frame_seg_map, |
137 | 1.50M | mi_offset, x_mis, y_mis); |
138 | 1.50M | return 0; |
139 | 1.50M | } |
140 | | |
141 | 2.98M | segment_id = read_segment_id(r, seg); |
142 | 2.98M | set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id); |
143 | 2.98M | return segment_id; |
144 | 4.49M | } |
145 | | |
146 | | static int read_inter_segment_id(VP9_COMMON *const cm, MACROBLOCKD *const xd, |
147 | | int mi_row, int mi_col, vpx_reader *r, |
148 | 16.2M | int x_mis, int y_mis) { |
149 | 16.2M | struct segmentation *const seg = &cm->seg; |
150 | 16.2M | MODE_INFO *const mi = xd->mi[0]; |
151 | 16.2M | int predicted_segment_id, segment_id; |
152 | 16.2M | const int mi_offset = mi_row * cm->mi_cols + mi_col; |
153 | | |
154 | 16.2M | if (!seg->enabled) return 0; // Default for disabled segmentation |
155 | | |
156 | 5.87M | predicted_segment_id = cm->last_frame_seg_map |
157 | 5.87M | ? dec_get_segment_id(cm, cm->last_frame_seg_map, |
158 | 5.87M | mi_offset, x_mis, y_mis) |
159 | 18.4E | : 0; |
160 | | |
161 | 5.87M | if (!seg->update_map) { |
162 | 4.85M | copy_segment_id(cm, cm->last_frame_seg_map, cm->current_frame_seg_map, |
163 | 4.85M | mi_offset, x_mis, y_mis); |
164 | 4.85M | return predicted_segment_id; |
165 | 4.85M | } |
166 | | |
167 | 1.02M | if (seg->temporal_update) { |
168 | 766k | const vpx_prob pred_prob = vp9_get_pred_prob_seg_id(seg, xd); |
169 | 766k | mi->seg_id_predicted = vpx_read(r, pred_prob); |
170 | 766k | segment_id = |
171 | 766k | mi->seg_id_predicted ? predicted_segment_id : read_segment_id(r, seg); |
172 | 766k | } else { |
173 | 257k | segment_id = read_segment_id(r, seg); |
174 | 257k | } |
175 | 1.02M | set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id); |
176 | 1.02M | return segment_id; |
177 | 5.87M | } |
178 | | |
179 | | static int read_skip(VP9_COMMON *cm, const MACROBLOCKD *xd, int segment_id, |
180 | 23.1M | vpx_reader *r) { |
181 | 23.1M | if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) { |
182 | 7.75M | return 1; |
183 | 15.4M | } else { |
184 | 15.4M | const int ctx = vp9_get_skip_context(xd); |
185 | 15.4M | const int skip = vpx_read(r, cm->fc->skip_probs[ctx]); |
186 | 15.4M | FRAME_COUNTS *counts = xd->counts; |
187 | 15.4M | if (counts) ++counts->skip[ctx][skip]; |
188 | 15.4M | return skip; |
189 | 15.4M | } |
190 | 23.1M | } |
191 | | |
192 | | static void read_intra_frame_mode_info(VP9_COMMON *const cm, |
193 | | MACROBLOCKD *const xd, int mi_row, |
194 | | int mi_col, vpx_reader *r, int x_mis, |
195 | 6.89M | int y_mis) { |
196 | 6.89M | MODE_INFO *const mi = xd->mi[0]; |
197 | 6.89M | const MODE_INFO *above_mi = xd->above_mi; |
198 | 6.89M | const MODE_INFO *left_mi = xd->left_mi; |
199 | 6.89M | const BLOCK_SIZE bsize = mi->sb_type; |
200 | 6.89M | int i; |
201 | 6.89M | const int mi_offset = mi_row * cm->mi_cols + mi_col; |
202 | | |
203 | 6.89M | mi->segment_id = read_intra_segment_id(cm, mi_offset, x_mis, y_mis, r); |
204 | 6.89M | mi->skip = read_skip(cm, xd, mi->segment_id, r); |
205 | 6.89M | mi->tx_size = read_tx_size(cm, xd, 1, r); |
206 | 6.89M | mi->ref_frame[0] = INTRA_FRAME; |
207 | 6.89M | mi->ref_frame[1] = NO_REF_FRAME; |
208 | | |
209 | 6.89M | switch (bsize) { |
210 | 476k | case BLOCK_4X4: |
211 | 2.38M | for (i = 0; i < 4; ++i) |
212 | 1.90M | mi->bmi[i].as_mode = |
213 | 1.90M | read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, i)); |
214 | 476k | mi->mode = mi->bmi[3].as_mode; |
215 | 476k | break; |
216 | 212k | case BLOCK_4X8: |
217 | 212k | mi->bmi[0].as_mode = mi->bmi[2].as_mode = |
218 | 212k | read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 0)); |
219 | 212k | mi->bmi[1].as_mode = mi->bmi[3].as_mode = mi->mode = |
220 | 212k | read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 1)); |
221 | 212k | break; |
222 | 348k | case BLOCK_8X4: |
223 | 348k | mi->bmi[0].as_mode = mi->bmi[1].as_mode = |
224 | 348k | read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 0)); |
225 | 348k | mi->bmi[2].as_mode = mi->bmi[3].as_mode = mi->mode = |
226 | 348k | read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 2)); |
227 | 348k | break; |
228 | 5.88M | default: |
229 | 5.88M | mi->mode = read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 0)); |
230 | 6.89M | } |
231 | | |
232 | 6.92M | mi->uv_mode = read_intra_mode(r, vp9_kf_uv_mode_prob[mi->mode]); |
233 | 6.92M | } |
234 | | |
235 | | static int read_mv_component(vpx_reader *r, const nmv_component *mvcomp, |
236 | 9.59M | int usehp) { |
237 | 9.59M | int mag, d, fr, hp; |
238 | 9.59M | const int sign = vpx_read(r, mvcomp->sign); |
239 | 9.59M | const int mv_class = vpx_read_tree(r, vp9_mv_class_tree, mvcomp->classes); |
240 | 9.59M | const int class0 = mv_class == MV_CLASS_0; |
241 | | |
242 | | // Integer part |
243 | 9.59M | if (class0) { |
244 | 6.25M | d = vpx_read(r, mvcomp->class0[0]); |
245 | 6.25M | mag = 0; |
246 | 6.25M | } else { |
247 | 3.33M | int i; |
248 | 3.33M | const int n = mv_class + CLASS0_BITS - 1; // number of bits |
249 | | |
250 | 3.33M | d = 0; |
251 | 12.0M | for (i = 0; i < n; ++i) d |= vpx_read(r, mvcomp->bits[i]) << i; |
252 | 3.33M | mag = CLASS0_SIZE << (mv_class + 2); |
253 | 3.33M | } |
254 | | |
255 | | // Fractional part |
256 | 9.59M | fr = vpx_read_tree(r, vp9_mv_fp_tree, |
257 | 9.59M | class0 ? mvcomp->class0_fp[d] : mvcomp->fp); |
258 | | |
259 | | // High precision part (if hp is not used, the default value of the hp is 1) |
260 | 9.59M | hp = usehp ? vpx_read(r, class0 ? mvcomp->class0_hp : mvcomp->hp) : 1; |
261 | | |
262 | | // Result |
263 | 9.59M | mag += ((d << 3) | (fr << 1) | hp) + 1; |
264 | 9.59M | return sign ? -mag : mag; |
265 | 9.59M | } |
266 | | |
267 | | static INLINE void read_mv(vpx_reader *r, MV *mv, const MV *ref, |
268 | | const nmv_context *ctx, nmv_context_counts *counts, |
269 | 7.78M | int allow_hp) { |
270 | 7.78M | const MV_JOINT_TYPE joint_type = |
271 | 7.78M | (MV_JOINT_TYPE)vpx_read_tree(r, vp9_mv_joint_tree, ctx->joints); |
272 | 7.78M | const int use_hp = allow_hp && use_mv_hp(ref); |
273 | 7.78M | MV diff = { 0, 0 }; |
274 | | |
275 | 7.78M | if (mv_joint_vertical(joint_type)) |
276 | 5.58M | diff.row = read_mv_component(r, &ctx->comps[0], use_hp); |
277 | | |
278 | 7.78M | if (mv_joint_horizontal(joint_type)) |
279 | 4.01M | diff.col = read_mv_component(r, &ctx->comps[1], use_hp); |
280 | | |
281 | 7.78M | vp9_inc_mv(&diff, counts); |
282 | | |
283 | 7.78M | mv->row = ref->row + diff.row; |
284 | 7.78M | mv->col = ref->col + diff.col; |
285 | 7.78M | } |
286 | | |
287 | | static REFERENCE_MODE read_block_reference_mode(VP9_COMMON *cm, |
288 | | const MACROBLOCKD *xd, |
289 | 10.3M | vpx_reader *r) { |
290 | 10.3M | if (cm->reference_mode == REFERENCE_MODE_SELECT) { |
291 | 6.08M | const int ctx = vp9_get_reference_mode_context(cm, xd); |
292 | 6.08M | const REFERENCE_MODE mode = |
293 | 6.08M | (REFERENCE_MODE)vpx_read(r, cm->fc->comp_inter_prob[ctx]); |
294 | 6.08M | FRAME_COUNTS *counts = xd->counts; |
295 | 6.08M | if (counts) ++counts->comp_inter[ctx][mode]; |
296 | 6.08M | return mode; // SINGLE_REFERENCE or COMPOUND_REFERENCE |
297 | 6.08M | } else { |
298 | 4.22M | return cm->reference_mode; |
299 | 4.22M | } |
300 | 10.3M | } |
301 | | |
302 | | // Read the reference frame |
303 | | static void read_ref_frames(VP9_COMMON *const cm, MACROBLOCKD *const xd, |
304 | | vpx_reader *r, int segment_id, |
305 | 10.5M | MV_REFERENCE_FRAME ref_frame[2]) { |
306 | 10.5M | FRAME_CONTEXT *const fc = cm->fc; |
307 | 10.5M | FRAME_COUNTS *counts = xd->counts; |
308 | | |
309 | 10.5M | if (segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) { |
310 | 246k | ref_frame[0] = (MV_REFERENCE_FRAME)get_segdata(&cm->seg, segment_id, |
311 | 246k | SEG_LVL_REF_FRAME); |
312 | 246k | ref_frame[1] = NO_REF_FRAME; |
313 | 10.3M | } else { |
314 | 10.3M | const REFERENCE_MODE mode = read_block_reference_mode(cm, xd, r); |
315 | | // FIXME(rbultje) I'm pretty sure this breaks segmentation ref frame coding |
316 | 10.3M | if (mode == COMPOUND_REFERENCE) { |
317 | 5.25M | const int idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref]; |
318 | 5.25M | const int ctx = vp9_get_pred_context_comp_ref_p(cm, xd); |
319 | 5.25M | const int bit = vpx_read(r, fc->comp_ref_prob[ctx]); |
320 | 5.25M | if (counts) ++counts->comp_ref[ctx][bit]; |
321 | 5.25M | ref_frame[idx] = cm->comp_fixed_ref; |
322 | 5.25M | ref_frame[!idx] = cm->comp_var_ref[bit]; |
323 | 5.25M | } else if (mode == SINGLE_REFERENCE) { |
324 | 5.05M | const int ctx0 = vp9_get_pred_context_single_ref_p1(xd); |
325 | 5.05M | const int bit0 = vpx_read(r, fc->single_ref_prob[ctx0][0]); |
326 | 5.05M | if (counts) ++counts->single_ref[ctx0][0][bit0]; |
327 | 5.05M | if (bit0) { |
328 | 1.77M | const int ctx1 = vp9_get_pred_context_single_ref_p2(xd); |
329 | 1.77M | const int bit1 = vpx_read(r, fc->single_ref_prob[ctx1][1]); |
330 | 1.77M | if (counts) ++counts->single_ref[ctx1][1][bit1]; |
331 | 1.77M | ref_frame[0] = bit1 ? ALTREF_FRAME : GOLDEN_FRAME; |
332 | 3.28M | } else { |
333 | 3.28M | ref_frame[0] = LAST_FRAME; |
334 | 3.28M | } |
335 | | |
336 | 5.05M | ref_frame[1] = NO_REF_FRAME; |
337 | 5.05M | } else { |
338 | 615 | assert(0 && "Invalid prediction mode."); |
339 | 615 | } |
340 | 10.3M | } |
341 | 10.5M | } |
342 | | |
343 | | static INLINE INTERP_FILTER read_switchable_interp_filter(VP9_COMMON *const cm, |
344 | | MACROBLOCKD *const xd, |
345 | 2.55M | vpx_reader *r) { |
346 | 2.55M | const int ctx = get_pred_context_switchable_interp(xd); |
347 | 2.55M | const INTERP_FILTER type = (INTERP_FILTER)vpx_read_tree( |
348 | 2.55M | r, vp9_switchable_interp_tree, cm->fc->switchable_interp_prob[ctx]); |
349 | 2.55M | FRAME_COUNTS *counts = xd->counts; |
350 | 2.55M | if (counts) ++counts->switchable_interp[ctx][type]; |
351 | 2.55M | return type; |
352 | 2.55M | } |
353 | | |
354 | | static void read_intra_block_mode_info(VP9_COMMON *const cm, |
355 | | MACROBLOCKD *const xd, MODE_INFO *mi, |
356 | 5.72M | vpx_reader *r) { |
357 | 5.72M | const BLOCK_SIZE bsize = mi->sb_type; |
358 | 5.72M | int i; |
359 | | |
360 | 5.72M | switch (bsize) { |
361 | 159k | case BLOCK_4X4: |
362 | 795k | for (i = 0; i < 4; ++i) |
363 | 636k | mi->bmi[i].as_mode = read_intra_mode_y(cm, xd, r, 0); |
364 | 159k | mi->mode = mi->bmi[3].as_mode; |
365 | 159k | break; |
366 | 162k | case BLOCK_4X8: |
367 | 162k | mi->bmi[0].as_mode = mi->bmi[2].as_mode = read_intra_mode_y(cm, xd, r, 0); |
368 | 162k | mi->bmi[1].as_mode = mi->bmi[3].as_mode = mi->mode = |
369 | 162k | read_intra_mode_y(cm, xd, r, 0); |
370 | 162k | break; |
371 | 272k | case BLOCK_8X4: |
372 | 272k | mi->bmi[0].as_mode = mi->bmi[1].as_mode = read_intra_mode_y(cm, xd, r, 0); |
373 | 272k | mi->bmi[2].as_mode = mi->bmi[3].as_mode = mi->mode = |
374 | 272k | read_intra_mode_y(cm, xd, r, 0); |
375 | 272k | break; |
376 | 5.12M | default: mi->mode = read_intra_mode_y(cm, xd, r, size_group_lookup[bsize]); |
377 | 5.72M | } |
378 | | |
379 | 5.72M | mi->uv_mode = read_intra_mode_uv(cm, xd, r, mi->mode); |
380 | | |
381 | | // Initialize interp_filter here so we do not have to check for inter block |
382 | | // modes in get_pred_context_switchable_interp() |
383 | 5.72M | mi->interp_filter = SWITCHABLE_FILTERS; |
384 | | |
385 | 5.72M | mi->ref_frame[0] = INTRA_FRAME; |
386 | 5.72M | mi->ref_frame[1] = NO_REF_FRAME; |
387 | 5.72M | } |
388 | | |
389 | 7.77M | static INLINE int is_mv_valid(const MV *mv) { |
390 | 7.77M | return mv->row > MV_LOW && mv->row < MV_UPP && mv->col > MV_LOW && |
391 | 7.77M | mv->col < MV_UPP; |
392 | 7.77M | } |
393 | | |
394 | 202M | static INLINE void copy_mv_pair(int_mv *dst, const int_mv *src) { |
395 | 202M | memcpy(dst, src, sizeof(*dst) * 2); |
396 | 202M | } |
397 | | |
398 | 1.40M | static INLINE void zero_mv_pair(int_mv *dst) { |
399 | 1.40M | memset(dst, 0, sizeof(*dst) * 2); |
400 | 1.40M | } |
401 | | |
402 | | static INLINE int assign_mv(VP9_COMMON *cm, MACROBLOCKD *xd, |
403 | | PREDICTION_MODE mode, int_mv mv[2], |
404 | | int_mv ref_mv[2], int_mv near_nearest_mv[2], |
405 | 12.7M | int is_compound, int allow_hp, vpx_reader *r) { |
406 | 12.7M | int i; |
407 | 12.7M | int ret = 1; |
408 | | |
409 | 12.7M | switch (mode) { |
410 | 4.86M | case NEWMV: { |
411 | 4.86M | FRAME_COUNTS *counts = xd->counts; |
412 | 4.86M | nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL; |
413 | 12.6M | for (i = 0; i < 1 + is_compound; ++i) { |
414 | 7.78M | read_mv(r, &mv[i].as_mv, &ref_mv[i].as_mv, &cm->fc->nmvc, mv_counts, |
415 | 7.78M | allow_hp); |
416 | 7.78M | ret = ret && is_mv_valid(&mv[i].as_mv); |
417 | 7.78M | } |
418 | 4.86M | break; |
419 | 0 | } |
420 | 1.58M | case NEARMV: |
421 | 6.45M | case NEARESTMV: { |
422 | 6.45M | copy_mv_pair(mv, near_nearest_mv); |
423 | 6.45M | break; |
424 | 1.58M | } |
425 | 1.40M | case ZEROMV: { |
426 | 1.40M | zero_mv_pair(mv); |
427 | 1.40M | break; |
428 | 1.58M | } |
429 | 0 | default: { |
430 | 0 | return 0; |
431 | 1.58M | } |
432 | 12.7M | } |
433 | 12.7M | return ret; |
434 | 12.7M | } |
435 | | |
436 | | static int read_is_inter_block(VP9_COMMON *const cm, MACROBLOCKD *const xd, |
437 | 16.2M | int segment_id, vpx_reader *r) { |
438 | 16.2M | if (segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) { |
439 | 3.00M | return get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME) != INTRA_FRAME; |
440 | 13.2M | } else { |
441 | 13.2M | const int ctx = get_intra_inter_context(xd); |
442 | 13.2M | const int is_inter = vpx_read(r, cm->fc->intra_inter_prob[ctx]); |
443 | 13.2M | FRAME_COUNTS *counts = xd->counts; |
444 | 13.2M | if (counts) ++counts->intra_inter[ctx][is_inter]; |
445 | 13.2M | return is_inter; |
446 | 13.2M | } |
447 | 16.2M | } |
448 | | |
449 | | // This macro is used to add a motion vector mv_ref list if it isn't |
450 | | // already in the list. If it's the second motion vector or early_break |
451 | | // it will also skip all additional processing and jump to Done! |
452 | | #define ADD_MV_REF_LIST_EB(mv, refmv_count, mv_ref_list, Done) \ |
453 | 19.5M | do { \ |
454 | 19.5M | if (refmv_count) { \ |
455 | 4.66M | if ((mv).as_int != (mv_ref_list)[0].as_int) { \ |
456 | 2.17M | (mv_ref_list)[(refmv_count)] = (mv); \ |
457 | 2.17M | refmv_count++; \ |
458 | 2.17M | goto Done; \ |
459 | 2.17M | } \ |
460 | 14.9M | } else { \ |
461 | 14.9M | (mv_ref_list)[(refmv_count)++] = (mv); \ |
462 | 14.9M | if (early_break) goto Done; \ |
463 | 14.9M | } \ |
464 | 19.5M | } while (0) |
465 | | |
466 | | // If either reference frame is different, not INTRA, and they |
467 | | // are different from each other scale and add the mv to our list. |
468 | | #define IF_DIFF_REF_FRAME_ADD_MV_EB(mbmi, ref_frame, ref_sign_bias, \ |
469 | | refmv_count, mv_ref_list, Done) \ |
470 | 3.61M | do { \ |
471 | 3.61M | if (is_inter_block(mbmi)) { \ |
472 | 2.19M | if ((mbmi)->ref_frame[0] != ref_frame) \ |
473 | 2.19M | ADD_MV_REF_LIST_EB(scale_mv((mbmi), 0, ref_frame, ref_sign_bias), \ |
474 | 2.19M | refmv_count, mv_ref_list, Done); \ |
475 | 2.19M | if (has_second_ref(mbmi) && (mbmi)->ref_frame[1] != ref_frame && \ |
476 | 1.32M | (mbmi)->mv[1].as_int != (mbmi)->mv[0].as_int) \ |
477 | 1.32M | ADD_MV_REF_LIST_EB(scale_mv((mbmi), 1, ref_frame, ref_sign_bias), \ |
478 | 1.32M | refmv_count, mv_ref_list, Done); \ |
479 | 1.32M | } \ |
480 | 3.61M | } while (0) |
481 | | |
482 | | // This function searches the neighborhood of a given MB/SB |
483 | | // to try and find candidate reference vectors. |
484 | | static int dec_find_mv_refs(const VP9_COMMON *cm, const MACROBLOCKD *xd, |
485 | | PREDICTION_MODE mode, MV_REFERENCE_FRAME ref_frame, |
486 | | const POSITION *const mv_ref_search, |
487 | | int_mv *mv_ref_list, int mi_row, int mi_col, |
488 | 15.0M | int block) { |
489 | 15.0M | const int *ref_sign_bias = cm->ref_frame_sign_bias; |
490 | 15.0M | int i, refmv_count = 0; |
491 | 15.0M | int different_ref_found = 0; |
492 | 15.0M | const MV_REF *const prev_frame_mvs = |
493 | 15.0M | cm->use_prev_frame_mvs |
494 | 15.0M | ? cm->prev_frame->mvs + mi_row * cm->mi_cols + mi_col |
495 | 15.0M | : NULL; |
496 | 15.0M | const TileInfo *const tile = &xd->tile; |
497 | | // If mode is nearestmv or newmv (uses nearestmv as a reference) then stop |
498 | | // searching after the first mv is found. |
499 | 15.0M | const int early_break = (mode != NEARMV); |
500 | | |
501 | | // Blank the reference vector list |
502 | 15.0M | memset(mv_ref_list, 0, sizeof(*mv_ref_list) * MAX_MV_REF_CANDIDATES); |
503 | | |
504 | 15.0M | i = 0; |
505 | 15.0M | if (block >= 0) { |
506 | | // If the size < 8x8 we get the mv from the bmi substructure for the |
507 | | // nearest two blocks. |
508 | 3.21M | for (i = 0; i < 2; ++i) { |
509 | 2.67M | const POSITION *const mv_ref = &mv_ref_search[i]; |
510 | 2.67M | if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { |
511 | 2.59M | const MODE_INFO *const candidate_mi = |
512 | 2.59M | xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]; |
513 | 2.59M | different_ref_found = 1; |
514 | | |
515 | 2.59M | if (candidate_mi->ref_frame[0] == ref_frame) |
516 | 1.04M | ADD_MV_REF_LIST_EB( |
517 | 2.59M | get_sub_block_mv(candidate_mi, 0, mv_ref->col, block), |
518 | 2.59M | refmv_count, mv_ref_list, Done); |
519 | 1.54M | else if (candidate_mi->ref_frame[1] == ref_frame) |
520 | 760k | ADD_MV_REF_LIST_EB( |
521 | 2.59M | get_sub_block_mv(candidate_mi, 1, mv_ref->col, block), |
522 | 2.59M | refmv_count, mv_ref_list, Done); |
523 | 2.59M | } |
524 | 2.67M | } |
525 | 1.66M | } |
526 | | |
527 | | // Check the rest of the neighbors in much the same way |
528 | | // as before except we don't need to keep track of sub blocks or |
529 | | // mode counts. |
530 | 34.2M | for (; i < MVREF_NEIGHBOURS; ++i) { |
531 | 32.8M | const POSITION *const mv_ref = &mv_ref_search[i]; |
532 | 32.8M | if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { |
533 | 30.8M | const MODE_INFO *const candidate = |
534 | 30.8M | xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]; |
535 | 30.8M | different_ref_found = 1; |
536 | | |
537 | 30.8M | if (candidate->ref_frame[0] == ref_frame) |
538 | 10.5M | ADD_MV_REF_LIST_EB(candidate->mv[0], refmv_count, mv_ref_list, Done); |
539 | 20.3M | else if (candidate->ref_frame[1] == ref_frame) |
540 | 5.33M | ADD_MV_REF_LIST_EB(candidate->mv[1], refmv_count, mv_ref_list, Done); |
541 | 30.8M | } |
542 | 32.8M | } |
543 | | |
544 | | // Check the last frame's mode and mv info. |
545 | 1.44M | if (prev_frame_mvs) { |
546 | 200k | if (prev_frame_mvs->ref_frame[0] == ref_frame) { |
547 | 81.1k | ADD_MV_REF_LIST_EB(prev_frame_mvs->mv[0], refmv_count, mv_ref_list, Done); |
548 | 119k | } else if (prev_frame_mvs->ref_frame[1] == ref_frame) { |
549 | 20.6k | ADD_MV_REF_LIST_EB(prev_frame_mvs->mv[1], refmv_count, mv_ref_list, Done); |
550 | 20.6k | } |
551 | 200k | } |
552 | | |
553 | | // Since we couldn't find 2 mvs from the same reference frame |
554 | | // go back through the neighbors and find motion vectors from |
555 | | // different reference frames. |
556 | 1.36M | if (different_ref_found) { |
557 | 4.61M | for (i = 0; i < MVREF_NEIGHBOURS; ++i) { |
558 | 4.26M | const POSITION *mv_ref = &mv_ref_search[i]; |
559 | 4.26M | if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { |
560 | 3.61M | const MODE_INFO *const candidate = |
561 | 3.61M | xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]; |
562 | | |
563 | | // If the candidate is INTRA we don't want to consider its mv. |
564 | 3.61M | IF_DIFF_REF_FRAME_ADD_MV_EB(candidate, ref_frame, ref_sign_bias, |
565 | 3.61M | refmv_count, mv_ref_list, Done); |
566 | 3.61M | } |
567 | 4.26M | } |
568 | 1.34M | } |
569 | | |
570 | | // Since we still don't have a candidate we'll try the last frame. |
571 | 372k | if (prev_frame_mvs) { |
572 | 40.9k | if (prev_frame_mvs->ref_frame[0] != ref_frame && |
573 | 40.9k | prev_frame_mvs->ref_frame[0] > INTRA_FRAME) { |
574 | 23.8k | int_mv mv = prev_frame_mvs->mv[0]; |
575 | 23.8k | if (ref_sign_bias[prev_frame_mvs->ref_frame[0]] != |
576 | 23.8k | ref_sign_bias[ref_frame]) { |
577 | 18.3k | mv.as_mv.row *= -1; |
578 | 18.3k | mv.as_mv.col *= -1; |
579 | 18.3k | } |
580 | 23.8k | ADD_MV_REF_LIST_EB(mv, refmv_count, mv_ref_list, Done); |
581 | 23.8k | } |
582 | | |
583 | 29.1k | if (prev_frame_mvs->ref_frame[1] > INTRA_FRAME && |
584 | 29.1k | prev_frame_mvs->ref_frame[1] != ref_frame && |
585 | 29.1k | prev_frame_mvs->mv[1].as_int != prev_frame_mvs->mv[0].as_int) { |
586 | 1.54k | int_mv mv = prev_frame_mvs->mv[1]; |
587 | 1.54k | if (ref_sign_bias[prev_frame_mvs->ref_frame[1]] != |
588 | 1.54k | ref_sign_bias[ref_frame]) { |
589 | 983 | mv.as_mv.row *= -1; |
590 | 983 | mv.as_mv.col *= -1; |
591 | 983 | } |
592 | 1.54k | ADD_MV_REF_LIST_EB(mv, refmv_count, mv_ref_list, Done); |
593 | 1.54k | } |
594 | 29.1k | } |
595 | | |
596 | 359k | if (mode == NEARMV) |
597 | 217k | refmv_count = MAX_MV_REF_CANDIDATES; |
598 | 142k | else |
599 | | // we only care about the nearestmv for the remaining modes |
600 | 142k | refmv_count = 1; |
601 | | |
602 | 15.0M | Done: |
603 | | // Clamp vectors |
604 | 32.5M | for (i = 0; i < refmv_count; ++i) clamp_mv_ref(&mv_ref_list[i].as_mv, xd); |
605 | | |
606 | 15.0M | return refmv_count; |
607 | 359k | } |
608 | | |
609 | | static void append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd, |
610 | | const POSITION *const mv_ref_search, |
611 | | PREDICTION_MODE b_mode, int block, |
612 | | int ref, int mi_row, int mi_col, |
613 | 3.11M | int_mv *best_sub8x8) { |
614 | 3.11M | int_mv mv_list[MAX_MV_REF_CANDIDATES]; |
615 | 3.11M | MODE_INFO *const mi = xd->mi[0]; |
616 | 3.11M | b_mode_info *bmi = mi->bmi; |
617 | 3.11M | int n; |
618 | 3.11M | int refmv_count; |
619 | | |
620 | 3.11M | assert(MAX_MV_REF_CANDIDATES == 2); |
621 | | |
622 | 3.11M | switch (block) { |
623 | 1.23M | case 0: |
624 | 1.23M | refmv_count = |
625 | 1.23M | dec_find_mv_refs(cm, xd, b_mode, mi->ref_frame[ref], mv_ref_search, |
626 | 1.23M | mv_list, mi_row, mi_col, block); |
627 | 1.23M | best_sub8x8->as_int = mv_list[refmv_count - 1].as_int; |
628 | 1.23M | break; |
629 | 593k | case 1: |
630 | 1.56M | case 2: |
631 | 1.56M | if (b_mode == NEARESTMV) { |
632 | 1.15M | best_sub8x8->as_int = bmi[0].as_mv[ref].as_int; |
633 | 1.15M | } else { |
634 | 405k | dec_find_mv_refs(cm, xd, b_mode, mi->ref_frame[ref], mv_ref_search, |
635 | 405k | mv_list, mi_row, mi_col, block); |
636 | 405k | best_sub8x8->as_int = 0; |
637 | 601k | for (n = 0; n < 2; ++n) |
638 | 577k | if (bmi[0].as_mv[ref].as_int != mv_list[n].as_int) { |
639 | 381k | best_sub8x8->as_int = mv_list[n].as_int; |
640 | 381k | break; |
641 | 381k | } |
642 | 405k | } |
643 | 1.56M | break; |
644 | 311k | case 3: |
645 | 311k | if (b_mode == NEARESTMV) { |
646 | 226k | best_sub8x8->as_int = bmi[2].as_mv[ref].as_int; |
647 | 226k | } else { |
648 | 84.4k | best_sub8x8->as_int = 0; |
649 | 84.4k | if (bmi[2].as_mv[ref].as_int != bmi[1].as_mv[ref].as_int) { |
650 | 59.0k | best_sub8x8->as_int = bmi[1].as_mv[ref].as_int; |
651 | 59.0k | break; |
652 | 59.0k | } |
653 | 25.3k | if (bmi[2].as_mv[ref].as_int != bmi[0].as_mv[ref].as_int) { |
654 | 5.68k | best_sub8x8->as_int = bmi[0].as_mv[ref].as_int; |
655 | 5.68k | break; |
656 | 5.68k | } |
657 | 19.7k | dec_find_mv_refs(cm, xd, b_mode, mi->ref_frame[ref], mv_ref_search, |
658 | 19.7k | mv_list, mi_row, mi_col, block); |
659 | 38.9k | for (n = 0; n < 2; ++n) |
660 | 32.6k | if (bmi[2].as_mv[ref].as_int != mv_list[n].as_int) { |
661 | 13.3k | best_sub8x8->as_int = mv_list[n].as_int; |
662 | 13.3k | break; |
663 | 13.3k | } |
664 | 19.7k | } |
665 | 246k | break; |
666 | 246k | default: assert(0 && "Invalid block index."); |
667 | 3.11M | } |
668 | 3.11M | } |
669 | | |
670 | | static uint8_t get_mode_context(const VP9_COMMON *cm, const MACROBLOCKD *xd, |
671 | | const POSITION *const mv_ref_search, int mi_row, |
672 | 10.5M | int mi_col) { |
673 | 10.5M | int i; |
674 | 10.5M | int context_counter = 0; |
675 | 10.5M | const TileInfo *const tile = &xd->tile; |
676 | | |
677 | | // Get mode count from nearest 2 blocks |
678 | 31.6M | for (i = 0; i < 2; ++i) { |
679 | 21.1M | const POSITION *const mv_ref = &mv_ref_search[i]; |
680 | 21.1M | if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { |
681 | 20.2M | const MODE_INFO *const candidate = |
682 | 20.2M | xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]; |
683 | | // Keep counts for entropy encoding. |
684 | 20.2M | context_counter += mode_2_counter[candidate->mode]; |
685 | 20.2M | } |
686 | 21.1M | } |
687 | | |
688 | 10.5M | return counter_to_context[context_counter]; |
689 | 10.5M | } |
690 | | |
691 | | static void read_inter_block_mode_info(VP9Decoder *const pbi, |
692 | | MACROBLOCKD *const xd, |
693 | | MODE_INFO *const mi, int mi_row, |
694 | 10.5M | int mi_col, vpx_reader *r) { |
695 | 10.5M | VP9_COMMON *const cm = &pbi->common; |
696 | 10.5M | const BLOCK_SIZE bsize = mi->sb_type; |
697 | 10.5M | const int allow_hp = cm->allow_high_precision_mv; |
698 | 10.5M | int_mv best_ref_mvs[2] = { { 0 }, { 0 } }; |
699 | 10.5M | int ref, is_compound; |
700 | 10.5M | uint8_t inter_mode_ctx; |
701 | 10.5M | const POSITION *const mv_ref_search = mv_ref_blocks[bsize]; |
702 | | |
703 | 10.5M | read_ref_frames(cm, xd, r, mi->segment_id, mi->ref_frame); |
704 | 10.5M | is_compound = has_second_ref(mi); |
705 | 10.5M | inter_mode_ctx = get_mode_context(cm, xd, mv_ref_search, mi_row, mi_col); |
706 | | |
707 | 10.5M | if (segfeature_active(&cm->seg, mi->segment_id, SEG_LVL_SKIP)) { |
708 | 763k | mi->mode = ZEROMV; |
709 | 763k | if (bsize < BLOCK_8X8) { |
710 | 155 | vpx_internal_error(xd->error_info, VPX_CODEC_UNSUP_BITSTREAM, |
711 | 155 | "Invalid usage of segment feature on small blocks"); |
712 | 155 | return; |
713 | 155 | } |
714 | 9.79M | } else { |
715 | 9.79M | if (bsize >= BLOCK_8X8) |
716 | 8.34M | mi->mode = read_inter_mode(cm, xd, r, inter_mode_ctx); |
717 | 9.79M | } |
718 | | |
719 | 10.5M | mi->interp_filter = (cm->interp_filter == SWITCHABLE) |
720 | 10.5M | ? read_switchable_interp_filter(cm, xd, r) |
721 | 10.5M | : cm->interp_filter; |
722 | | |
723 | 10.5M | if (bsize < BLOCK_8X8) { |
724 | 1.43M | const int num_4x4_w = 1 << xd->bmode_blocks_wl; |
725 | 1.43M | const int num_4x4_h = 1 << xd->bmode_blocks_hl; |
726 | 1.43M | int idx, idy; |
727 | 1.43M | PREDICTION_MODE b_mode; |
728 | 1.43M | int got_mv_refs_for_new = 0; |
729 | 1.43M | int_mv best_sub8x8[2]; |
730 | 1.43M | const uint32_t invalid_mv = 0x80008000; |
731 | | // Initialize the 2nd element as even though it won't be used meaningfully |
732 | | // if is_compound is false, copying/clamping it may trigger a MSan warning. |
733 | 1.43M | best_sub8x8[1].as_int = invalid_mv; |
734 | 3.95M | for (idy = 0; idy < 2; idy += num_4x4_h) { |
735 | 6.12M | for (idx = 0; idx < 2; idx += num_4x4_w) { |
736 | 3.60M | const int j = idy * 2 + idx; |
737 | 3.60M | b_mode = read_inter_mode(cm, xd, r, inter_mode_ctx); |
738 | | |
739 | 3.60M | if (b_mode == NEARESTMV || b_mode == NEARMV) { |
740 | 4.98M | for (ref = 0; ref < 1 + is_compound; ++ref) |
741 | 3.11M | append_sub8x8_mvs_for_idx(cm, xd, mv_ref_search, b_mode, j, ref, |
742 | 3.11M | mi_row, mi_col, &best_sub8x8[ref]); |
743 | 1.87M | } else if (b_mode == NEWMV && !got_mv_refs_for_new) { |
744 | 2.71M | for (ref = 0; ref < 1 + is_compound; ++ref) { |
745 | 1.70M | int_mv tmp_mvs[MAX_MV_REF_CANDIDATES]; |
746 | 1.70M | const MV_REFERENCE_FRAME frame = mi->ref_frame[ref]; |
747 | | |
748 | 1.70M | dec_find_mv_refs(cm, xd, NEWMV, frame, mv_ref_search, tmp_mvs, |
749 | 1.70M | mi_row, mi_col, -1); |
750 | | |
751 | 1.70M | lower_mv_precision(&tmp_mvs[0].as_mv, allow_hp); |
752 | 1.70M | best_ref_mvs[ref] = tmp_mvs[0]; |
753 | 1.70M | got_mv_refs_for_new = 1; |
754 | 1.70M | } |
755 | 1.00M | } |
756 | | |
757 | 3.60M | if (!assign_mv(cm, xd, b_mode, mi->bmi[j].as_mv, best_ref_mvs, |
758 | 3.60M | best_sub8x8, is_compound, allow_hp, r)) { |
759 | 5.51k | xd->corrupted |= 1; |
760 | 5.51k | return; |
761 | 5.51k | } |
762 | | |
763 | 3.59M | if (num_4x4_h == 2) mi->bmi[j + 2] = mi->bmi[j]; |
764 | 3.59M | if (num_4x4_w == 2) mi->bmi[j + 1] = mi->bmi[j]; |
765 | 3.59M | } |
766 | 2.53M | } |
767 | | |
768 | 1.42M | mi->mode = b_mode; |
769 | | |
770 | 1.42M | copy_mv_pair(mi->mv, mi->bmi[3].as_mv); |
771 | 9.12M | } else { |
772 | 9.12M | if (mi->mode != ZEROMV) { |
773 | 19.5M | for (ref = 0; ref < 1 + is_compound; ++ref) { |
774 | 11.7M | int_mv tmp_mvs[MAX_MV_REF_CANDIDATES]; |
775 | 11.7M | const MV_REFERENCE_FRAME frame = mi->ref_frame[ref]; |
776 | 11.7M | int refmv_count = |
777 | 11.7M | dec_find_mv_refs(cm, xd, mi->mode, frame, mv_ref_search, tmp_mvs, |
778 | 11.7M | mi_row, mi_col, -1); |
779 | 11.7M | lower_mv_precision(&tmp_mvs[refmv_count - 1].as_mv, allow_hp); |
780 | 11.7M | best_ref_mvs[ref] = tmp_mvs[refmv_count - 1]; |
781 | 11.7M | } |
782 | 7.88M | } |
783 | 9.12M | xd->corrupted |= !assign_mv(cm, xd, mi->mode, mi->mv, best_ref_mvs, |
784 | 9.12M | best_ref_mvs, is_compound, allow_hp, r); |
785 | 9.12M | } |
786 | 10.5M | } |
787 | | |
788 | | static void read_inter_frame_mode_info(VP9Decoder *const pbi, |
789 | | MACROBLOCKD *const xd, int mi_row, |
790 | | int mi_col, vpx_reader *r, int x_mis, |
791 | 16.2M | int y_mis) { |
792 | 16.2M | VP9_COMMON *const cm = &pbi->common; |
793 | 16.2M | MODE_INFO *const mi = xd->mi[0]; |
794 | 16.2M | int inter_block; |
795 | | |
796 | 16.2M | mi->segment_id = |
797 | 16.2M | read_inter_segment_id(cm, xd, mi_row, mi_col, r, x_mis, y_mis); |
798 | 16.2M | mi->skip = read_skip(cm, xd, mi->segment_id, r); |
799 | 16.2M | inter_block = read_is_inter_block(cm, xd, mi->segment_id, r); |
800 | 16.2M | mi->tx_size = read_tx_size(cm, xd, !mi->skip || !inter_block, r); |
801 | | |
802 | 16.2M | if (inter_block) |
803 | 10.5M | read_inter_block_mode_info(pbi, xd, mi, mi_row, mi_col, r); |
804 | 5.70M | else |
805 | 5.70M | read_intra_block_mode_info(cm, xd, mi, r); |
806 | 16.2M | } |
807 | | |
808 | | static INLINE void copy_ref_frame_pair(MV_REFERENCE_FRAME *dst, |
809 | 194M | const MV_REFERENCE_FRAME *src) { |
810 | 194M | memcpy(dst, src, sizeof(*dst) * 2); |
811 | 194M | } |
812 | | |
813 | | void vp9_read_mode_info(TileWorkerData *twd, VP9Decoder *const pbi, int mi_row, |
814 | 23.1M | int mi_col, int x_mis, int y_mis) { |
815 | 23.1M | vpx_reader *r = &twd->bit_reader; |
816 | 23.1M | MACROBLOCKD *const xd = &twd->xd; |
817 | 23.1M | VP9_COMMON *const cm = &pbi->common; |
818 | 23.1M | MODE_INFO *const mi = xd->mi[0]; |
819 | 23.1M | MV_REF *frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col; |
820 | 23.1M | int w, h; |
821 | | |
822 | 23.1M | if (frame_is_intra_only(cm)) { |
823 | 6.89M | read_intra_frame_mode_info(cm, xd, mi_row, mi_col, r, x_mis, y_mis); |
824 | 16.2M | } else { |
825 | | // Cache mi->ref_frame and mi->mv so that the compiler can prove that they |
826 | | // are constant for the duration of the loop and avoids reloading them. |
827 | 16.2M | MV_REFERENCE_FRAME mi_ref_frame[2]; |
828 | 16.2M | int_mv mi_mv[2]; |
829 | | |
830 | 16.2M | read_inter_frame_mode_info(pbi, xd, mi_row, mi_col, r, x_mis, y_mis); |
831 | | |
832 | 16.2M | copy_ref_frame_pair(mi_ref_frame, mi->ref_frame); |
833 | 16.2M | copy_mv_pair(mi_mv, mi->mv); |
834 | | |
835 | 56.2M | for (h = 0; h < y_mis; ++h) { |
836 | 218M | for (w = 0; w < x_mis; ++w) { |
837 | 178M | MV_REF *const mv = frame_mvs + w; |
838 | 178M | copy_ref_frame_pair(mv->ref_frame, mi_ref_frame); |
839 | 178M | copy_mv_pair(mv->mv, mi_mv); |
840 | 178M | } |
841 | 39.9M | frame_mvs += cm->mi_cols; |
842 | 39.9M | } |
843 | 16.2M | } |
844 | | #if 0 // CONFIG_BETTER_HW_COMPATIBILITY && CONFIG_VP9_HIGHBITDEPTH |
845 | | if ((xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) && |
846 | | (xd->above_mi == NULL || xd->left_mi == NULL) && |
847 | | !is_inter_block(mi) && need_top_left[mi->uv_mode]) |
848 | | assert(0); |
849 | | #endif // CONFIG_BETTER_HW_COMPATIBILITY && CONFIG_VP9_HIGHBITDEPTH |
850 | 23.1M | } |