/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 | 9.10M | static PREDICTION_MODE read_intra_mode(vpx_reader *r, const vpx_prob *p) { |
28 | 9.10M | return (PREDICTION_MODE)vpx_read_tree(r, vp9_intra_mode_tree, p); |
29 | 9.10M | } |
30 | | |
31 | | static PREDICTION_MODE read_intra_mode_y(VP9_COMMON *cm, MACROBLOCKD *xd, |
32 | 1.23M | vpx_reader *r, int size_group) { |
33 | 1.23M | const PREDICTION_MODE y_mode = |
34 | 1.23M | read_intra_mode(r, cm->fc->y_mode_prob[size_group]); |
35 | 1.23M | FRAME_COUNTS *counts = xd->counts; |
36 | 1.23M | if (counts) ++counts->y_mode[size_group][y_mode]; |
37 | 1.23M | return y_mode; |
38 | 1.23M | } |
39 | | |
40 | | static PREDICTION_MODE read_intra_mode_uv(VP9_COMMON *cm, MACROBLOCKD *xd, |
41 | | vpx_reader *r, |
42 | 1.09M | PREDICTION_MODE y_mode) { |
43 | 1.09M | const PREDICTION_MODE uv_mode = |
44 | 1.09M | read_intra_mode(r, cm->fc->uv_mode_prob[y_mode]); |
45 | 1.09M | FRAME_COUNTS *counts = xd->counts; |
46 | 1.09M | if (counts) ++counts->uv_mode[y_mode][uv_mode]; |
47 | 1.09M | return uv_mode; |
48 | 1.09M | } |
49 | | |
50 | | static PREDICTION_MODE read_inter_mode(VP9_COMMON *cm, MACROBLOCKD *xd, |
51 | 3.24M | vpx_reader *r, int ctx) { |
52 | 3.24M | const int mode = |
53 | 3.24M | vpx_read_tree(r, vp9_inter_mode_tree, cm->fc->inter_mode_probs[ctx]); |
54 | 3.24M | FRAME_COUNTS *counts = xd->counts; |
55 | 3.24M | if (counts) ++counts->inter_mode[ctx][mode]; |
56 | | |
57 | 3.24M | return NEARESTMV + mode; |
58 | 3.24M | } |
59 | | |
60 | 1.06M | static int read_segment_id(vpx_reader *r, const struct segmentation *seg) { |
61 | 1.06M | return vpx_read_tree(r, vp9_segment_tree, seg->tree_probs); |
62 | 1.06M | } |
63 | | |
64 | | static TX_SIZE read_selected_tx_size(VP9_COMMON *cm, MACROBLOCKD *xd, |
65 | 765k | TX_SIZE max_tx_size, vpx_reader *r) { |
66 | 765k | FRAME_COUNTS *counts = xd->counts; |
67 | 765k | const int ctx = get_tx_size_context(xd); |
68 | 765k | const vpx_prob *tx_probs = get_tx_probs(max_tx_size, ctx, &cm->fc->tx_probs); |
69 | 765k | int tx_size = vpx_read(r, tx_probs[0]); |
70 | 765k | if (tx_size != TX_4X4 && max_tx_size >= TX_16X16) { |
71 | 190k | tx_size += vpx_read(r, tx_probs[1]); |
72 | 190k | if (tx_size != TX_8X8 && max_tx_size >= TX_32X32) |
73 | 50.7k | tx_size += vpx_read(r, tx_probs[2]); |
74 | 190k | } |
75 | | |
76 | 765k | if (counts) ++get_tx_counts(max_tx_size, ctx, &counts->tx)[tx_size]; |
77 | 765k | return (TX_SIZE)tx_size; |
78 | 765k | } |
79 | | |
80 | | static INLINE TX_SIZE read_tx_size(VP9_COMMON *cm, MACROBLOCKD *xd, |
81 | 6.58M | int allow_select, vpx_reader *r) { |
82 | 6.58M | TX_MODE tx_mode = cm->tx_mode; |
83 | 6.58M | BLOCK_SIZE bsize = xd->mi[0]->sb_type; |
84 | 6.58M | const TX_SIZE max_tx_size = max_txsize_lookup[bsize]; |
85 | 6.58M | if (allow_select && tx_mode == TX_MODE_SELECT && bsize >= BLOCK_8X8) |
86 | 765k | return read_selected_tx_size(cm, xd, max_tx_size, r); |
87 | 5.81M | else |
88 | 5.81M | return VPXMIN(max_tx_size, tx_mode_to_biggest_tx_size[tx_mode]); |
89 | 6.58M | } |
90 | | |
91 | | static int dec_get_segment_id(const VP9_COMMON *cm, const uint8_t *segment_ids, |
92 | 647k | int mi_offset, int x_mis, int y_mis) { |
93 | 647k | int x, y, segment_id = INT_MAX; |
94 | | |
95 | 2.36M | for (y = 0; y < y_mis; y++) |
96 | 7.98M | for (x = 0; x < x_mis; x++) |
97 | 6.26M | segment_id = |
98 | 6.26M | VPXMIN(segment_id, segment_ids[mi_offset + y * cm->mi_cols + x]); |
99 | | |
100 | 647k | assert(segment_id >= 0 && segment_id < MAX_SEGMENTS); |
101 | 647k | return segment_id; |
102 | 647k | } |
103 | | |
104 | | static void set_segment_id(VP9_COMMON *cm, int mi_offset, int x_mis, int y_mis, |
105 | 1.09M | int segment_id) { |
106 | 1.09M | int x, y; |
107 | | |
108 | 1.09M | assert(segment_id >= 0 && segment_id < MAX_SEGMENTS); |
109 | | |
110 | 4.22M | for (y = 0; y < y_mis; y++) |
111 | 15.4M | for (x = 0; x < x_mis; x++) |
112 | 12.3M | cm->current_frame_seg_map[mi_offset + y * cm->mi_cols + x] = segment_id; |
113 | 1.09M | } |
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 | 1.98M | int x_mis, int y_mis) { |
119 | 1.98M | int x, y; |
120 | | |
121 | 7.82M | for (y = 0; y < y_mis; y++) |
122 | 35.5M | for (x = 0; x < x_mis; x++) |
123 | 29.6M | current_segment_ids[mi_offset + y * cm->mi_cols + x] = |
124 | 29.6M | last_segment_ids ? last_segment_ids[mi_offset + y * cm->mi_cols + x] |
125 | 29.6M | : 0; |
126 | 1.98M | } |
127 | | |
128 | | static int read_intra_segment_id(VP9_COMMON *const cm, int mi_offset, int x_mis, |
129 | 2.75M | int y_mis, vpx_reader *r) { |
130 | 2.75M | struct segmentation *const seg = &cm->seg; |
131 | 2.75M | int segment_id; |
132 | | |
133 | 2.75M | if (!seg->enabled) return 0; // Default for disabled segmentation |
134 | | |
135 | 2.43M | if (!seg->update_map) { |
136 | 1.66M | copy_segment_id(cm, cm->last_frame_seg_map, cm->current_frame_seg_map, |
137 | 1.66M | mi_offset, x_mis, y_mis); |
138 | 1.66M | return 0; |
139 | 1.66M | } |
140 | | |
141 | 765k | segment_id = read_segment_id(r, seg); |
142 | 765k | set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id); |
143 | 765k | return segment_id; |
144 | 2.43M | } |
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 | 3.82M | int x_mis, int y_mis) { |
149 | 3.82M | struct segmentation *const seg = &cm->seg; |
150 | 3.82M | MODE_INFO *const mi = xd->mi[0]; |
151 | 3.82M | int predicted_segment_id, segment_id; |
152 | 3.82M | const int mi_offset = mi_row * cm->mi_cols + mi_col; |
153 | | |
154 | 3.82M | if (!seg->enabled) return 0; // Default for disabled segmentation |
155 | | |
156 | 647k | predicted_segment_id = cm->last_frame_seg_map |
157 | 647k | ? dec_get_segment_id(cm, cm->last_frame_seg_map, |
158 | 647k | mi_offset, x_mis, y_mis) |
159 | 647k | : 0; |
160 | | |
161 | 647k | if (!seg->update_map) { |
162 | 314k | copy_segment_id(cm, cm->last_frame_seg_map, cm->current_frame_seg_map, |
163 | 314k | mi_offset, x_mis, y_mis); |
164 | 314k | return predicted_segment_id; |
165 | 314k | } |
166 | | |
167 | 333k | if (seg->temporal_update) { |
168 | 117k | const vpx_prob pred_prob = vp9_get_pred_prob_seg_id(seg, xd); |
169 | 117k | mi->seg_id_predicted = vpx_read(r, pred_prob); |
170 | 117k | segment_id = |
171 | 117k | mi->seg_id_predicted ? predicted_segment_id : read_segment_id(r, seg); |
172 | 215k | } else { |
173 | 215k | segment_id = read_segment_id(r, seg); |
174 | 215k | } |
175 | 333k | set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id); |
176 | 333k | return segment_id; |
177 | 647k | } |
178 | | |
179 | | static int read_skip(VP9_COMMON *cm, const MACROBLOCKD *xd, int segment_id, |
180 | 6.58M | vpx_reader *r) { |
181 | 6.58M | if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) { |
182 | 2.30M | return 1; |
183 | 4.27M | } else { |
184 | 4.27M | const int ctx = vp9_get_skip_context(xd); |
185 | 4.27M | const int skip = vpx_read(r, cm->fc->skip_probs[ctx]); |
186 | 4.27M | FRAME_COUNTS *counts = xd->counts; |
187 | 4.27M | if (counts) ++counts->skip[ctx][skip]; |
188 | 4.27M | return skip; |
189 | 4.27M | } |
190 | 6.58M | } |
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 | 2.75M | int y_mis) { |
196 | 2.75M | MODE_INFO *const mi = xd->mi[0]; |
197 | 2.75M | const MODE_INFO *above_mi = xd->above_mi; |
198 | 2.75M | const MODE_INFO *left_mi = xd->left_mi; |
199 | 2.75M | const BLOCK_SIZE bsize = mi->sb_type; |
200 | 2.75M | int i; |
201 | 2.75M | const int mi_offset = mi_row * cm->mi_cols + mi_col; |
202 | | |
203 | 2.75M | mi->segment_id = read_intra_segment_id(cm, mi_offset, x_mis, y_mis, r); |
204 | 2.75M | mi->skip = read_skip(cm, xd, mi->segment_id, r); |
205 | 2.75M | mi->tx_size = read_tx_size(cm, xd, 1, r); |
206 | 2.75M | mi->ref_frame[0] = INTRA_FRAME; |
207 | 2.75M | mi->ref_frame[1] = NO_REF_FRAME; |
208 | | |
209 | 2.75M | switch (bsize) { |
210 | 309k | case BLOCK_4X4: |
211 | 1.54M | for (i = 0; i < 4; ++i) |
212 | 1.23M | mi->bmi[i].as_mode = |
213 | 1.23M | read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, i)); |
214 | 309k | mi->mode = mi->bmi[3].as_mode; |
215 | 309k | break; |
216 | 139k | case BLOCK_4X8: |
217 | 139k | mi->bmi[0].as_mode = mi->bmi[2].as_mode = |
218 | 139k | read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 0)); |
219 | 139k | mi->bmi[1].as_mode = mi->bmi[3].as_mode = mi->mode = |
220 | 139k | read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 1)); |
221 | 139k | break; |
222 | 203k | case BLOCK_8X4: |
223 | 203k | mi->bmi[0].as_mode = mi->bmi[1].as_mode = |
224 | 203k | read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 0)); |
225 | 203k | mi->bmi[2].as_mode = mi->bmi[3].as_mode = mi->mode = |
226 | 203k | read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 2)); |
227 | 203k | break; |
228 | 2.09M | default: |
229 | 2.09M | mi->mode = read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 0)); |
230 | 2.75M | } |
231 | | |
232 | 2.75M | mi->uv_mode = read_intra_mode(r, vp9_kf_uv_mode_prob[mi->mode]); |
233 | 2.75M | } |
234 | | |
235 | | static int read_mv_component(vpx_reader *r, const nmv_component *mvcomp, |
236 | 2.54M | int usehp) { |
237 | 2.54M | int mag, d, fr, hp; |
238 | 2.54M | const int sign = vpx_read(r, mvcomp->sign); |
239 | 2.54M | const int mv_class = vpx_read_tree(r, vp9_mv_class_tree, mvcomp->classes); |
240 | 2.54M | const int class0 = mv_class == MV_CLASS_0; |
241 | | |
242 | | // Integer part |
243 | 2.54M | if (class0) { |
244 | 2.05M | d = vpx_read(r, mvcomp->class0[0]); |
245 | 2.05M | mag = 0; |
246 | 2.05M | } else { |
247 | 493k | int i; |
248 | 493k | const int n = mv_class + CLASS0_BITS - 1; // number of bits |
249 | | |
250 | 493k | d = 0; |
251 | 1.65M | for (i = 0; i < n; ++i) d |= vpx_read(r, mvcomp->bits[i]) << i; |
252 | 493k | mag = CLASS0_SIZE << (mv_class + 2); |
253 | 493k | } |
254 | | |
255 | | // Fractional part |
256 | 2.54M | fr = vpx_read_tree(r, vp9_mv_fp_tree, |
257 | 2.54M | 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 | 2.54M | hp = usehp ? vpx_read(r, class0 ? mvcomp->class0_hp : mvcomp->hp) : 1; |
261 | | |
262 | | // Result |
263 | 2.54M | mag += ((d << 3) | (fr << 1) | hp) + 1; |
264 | 2.54M | return sign ? -mag : mag; |
265 | 2.54M | } |
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 | 1.96M | int allow_hp) { |
270 | 1.96M | const MV_JOINT_TYPE joint_type = |
271 | 1.96M | (MV_JOINT_TYPE)vpx_read_tree(r, vp9_mv_joint_tree, ctx->joints); |
272 | 1.96M | const int use_hp = allow_hp && use_mv_hp(ref); |
273 | 1.96M | MV diff = { 0, 0 }; |
274 | | |
275 | 1.96M | if (mv_joint_vertical(joint_type)) |
276 | 1.27M | diff.row = read_mv_component(r, &ctx->comps[0], use_hp); |
277 | | |
278 | 1.96M | if (mv_joint_horizontal(joint_type)) |
279 | 1.27M | diff.col = read_mv_component(r, &ctx->comps[1], use_hp); |
280 | | |
281 | 1.96M | vp9_inc_mv(&diff, counts); |
282 | | |
283 | 1.96M | mv->row = ref->row + diff.row; |
284 | 1.96M | mv->col = ref->col + diff.col; |
285 | 1.96M | } |
286 | | |
287 | | static REFERENCE_MODE read_block_reference_mode(VP9_COMMON *cm, |
288 | | const MACROBLOCKD *xd, |
289 | 2.58M | vpx_reader *r) { |
290 | 2.58M | if (cm->reference_mode == REFERENCE_MODE_SELECT) { |
291 | 951k | const int ctx = vp9_get_reference_mode_context(cm, xd); |
292 | 951k | const REFERENCE_MODE mode = |
293 | 951k | (REFERENCE_MODE)vpx_read(r, cm->fc->comp_inter_prob[ctx]); |
294 | 951k | FRAME_COUNTS *counts = xd->counts; |
295 | 951k | if (counts) ++counts->comp_inter[ctx][mode]; |
296 | 951k | return mode; // SINGLE_REFERENCE or COMPOUND_REFERENCE |
297 | 1.63M | } else { |
298 | 1.63M | return cm->reference_mode; |
299 | 1.63M | } |
300 | 2.58M | } |
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 | 2.73M | MV_REFERENCE_FRAME ref_frame[2]) { |
306 | 2.73M | FRAME_CONTEXT *const fc = cm->fc; |
307 | 2.73M | FRAME_COUNTS *counts = xd->counts; |
308 | | |
309 | 2.73M | if (segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) { |
310 | 151k | ref_frame[0] = (MV_REFERENCE_FRAME)get_segdata(&cm->seg, segment_id, |
311 | 151k | SEG_LVL_REF_FRAME); |
312 | 151k | ref_frame[1] = NO_REF_FRAME; |
313 | 2.58M | } else { |
314 | 2.58M | 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 | 2.58M | if (mode == COMPOUND_REFERENCE) { |
317 | 1.40M | const int idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref]; |
318 | 1.40M | const int ctx = vp9_get_pred_context_comp_ref_p(cm, xd); |
319 | 1.40M | const int bit = vpx_read(r, fc->comp_ref_prob[ctx]); |
320 | 1.40M | if (counts) ++counts->comp_ref[ctx][bit]; |
321 | 1.40M | ref_frame[idx] = cm->comp_fixed_ref; |
322 | 1.40M | ref_frame[!idx] = cm->comp_var_ref[bit]; |
323 | 1.40M | } else if (mode == SINGLE_REFERENCE) { |
324 | 1.17M | const int ctx0 = vp9_get_pred_context_single_ref_p1(xd); |
325 | 1.17M | const int bit0 = vpx_read(r, fc->single_ref_prob[ctx0][0]); |
326 | 1.17M | if (counts) ++counts->single_ref[ctx0][0][bit0]; |
327 | 1.17M | if (bit0) { |
328 | 494k | const int ctx1 = vp9_get_pred_context_single_ref_p2(xd); |
329 | 494k | const int bit1 = vpx_read(r, fc->single_ref_prob[ctx1][1]); |
330 | 494k | if (counts) ++counts->single_ref[ctx1][1][bit1]; |
331 | 494k | ref_frame[0] = bit1 ? ALTREF_FRAME : GOLDEN_FRAME; |
332 | 679k | } else { |
333 | 679k | ref_frame[0] = LAST_FRAME; |
334 | 679k | } |
335 | | |
336 | 1.17M | ref_frame[1] = NO_REF_FRAME; |
337 | 1.17M | } else { |
338 | 0 | assert(0 && "Invalid prediction mode."); |
339 | 0 | } |
340 | 2.58M | } |
341 | 2.73M | } |
342 | | |
343 | | static INLINE INTERP_FILTER read_switchable_interp_filter(VP9_COMMON *const cm, |
344 | | MACROBLOCKD *const xd, |
345 | 1.88M | vpx_reader *r) { |
346 | 1.88M | const int ctx = get_pred_context_switchable_interp(xd); |
347 | 1.88M | const INTERP_FILTER type = (INTERP_FILTER)vpx_read_tree( |
348 | 1.88M | r, vp9_switchable_interp_tree, cm->fc->switchable_interp_prob[ctx]); |
349 | 1.88M | FRAME_COUNTS *counts = xd->counts; |
350 | 1.88M | if (counts) ++counts->switchable_interp[ctx][type]; |
351 | 1.88M | return type; |
352 | 1.88M | } |
353 | | |
354 | | static void read_intra_block_mode_info(VP9_COMMON *const cm, |
355 | | MACROBLOCKD *const xd, MODE_INFO *mi, |
356 | 1.09M | vpx_reader *r) { |
357 | 1.09M | const BLOCK_SIZE bsize = mi->sb_type; |
358 | 1.09M | int i; |
359 | | |
360 | 1.09M | switch (bsize) { |
361 | 24.7k | case BLOCK_4X4: |
362 | 123k | for (i = 0; i < 4; ++i) |
363 | 99.1k | mi->bmi[i].as_mode = read_intra_mode_y(cm, xd, r, 0); |
364 | 24.7k | mi->mode = mi->bmi[3].as_mode; |
365 | 24.7k | break; |
366 | 25.6k | case BLOCK_4X8: |
367 | 25.6k | mi->bmi[0].as_mode = mi->bmi[2].as_mode = read_intra_mode_y(cm, xd, r, 0); |
368 | 25.6k | mi->bmi[1].as_mode = mi->bmi[3].as_mode = mi->mode = |
369 | 25.6k | read_intra_mode_y(cm, xd, r, 0); |
370 | 25.6k | break; |
371 | 41.0k | case BLOCK_8X4: |
372 | 41.0k | mi->bmi[0].as_mode = mi->bmi[1].as_mode = read_intra_mode_y(cm, xd, r, 0); |
373 | 41.0k | mi->bmi[2].as_mode = mi->bmi[3].as_mode = mi->mode = |
374 | 41.0k | read_intra_mode_y(cm, xd, r, 0); |
375 | 41.0k | break; |
376 | 1.00M | default: mi->mode = read_intra_mode_y(cm, xd, r, size_group_lookup[bsize]); |
377 | 1.09M | } |
378 | | |
379 | 1.09M | 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 | 1.09M | mi->interp_filter = SWITCHABLE_FILTERS; |
384 | | |
385 | 1.09M | mi->ref_frame[0] = INTRA_FRAME; |
386 | 1.09M | mi->ref_frame[1] = NO_REF_FRAME; |
387 | 1.09M | } |
388 | | |
389 | 1.96M | static INLINE int is_mv_valid(const MV *mv) { |
390 | 1.96M | return mv->row > MV_LOW && mv->row < MV_UPP && mv->col > MV_LOW && |
391 | 1.96M | mv->col < MV_UPP; |
392 | 1.96M | } |
393 | | |
394 | 34.5M | static INLINE void copy_mv_pair(int_mv *dst, const int_mv *src) { |
395 | 34.5M | memcpy(dst, src, sizeof(*dst) * 2); |
396 | 34.5M | } |
397 | | |
398 | 219k | static INLINE void zero_mv_pair(int_mv *dst) { |
399 | 219k | memset(dst, 0, sizeof(*dst) * 2); |
400 | 219k | } |
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 | 3.34M | int is_compound, int allow_hp, vpx_reader *r) { |
406 | 3.34M | int i; |
407 | 3.34M | int ret = 1; |
408 | | |
409 | 3.34M | switch (mode) { |
410 | 1.29M | case NEWMV: { |
411 | 1.29M | FRAME_COUNTS *counts = xd->counts; |
412 | 1.29M | nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL; |
413 | 3.26M | for (i = 0; i < 1 + is_compound; ++i) { |
414 | 1.96M | read_mv(r, &mv[i].as_mv, &ref_mv[i].as_mv, &cm->fc->nmvc, mv_counts, |
415 | 1.96M | allow_hp); |
416 | 1.96M | ret = ret && is_mv_valid(&mv[i].as_mv); |
417 | 1.96M | } |
418 | 1.29M | break; |
419 | 0 | } |
420 | 454k | case NEARMV: |
421 | 1.82M | case NEARESTMV: { |
422 | 1.82M | copy_mv_pair(mv, near_nearest_mv); |
423 | 1.82M | break; |
424 | 454k | } |
425 | 219k | case ZEROMV: { |
426 | 219k | zero_mv_pair(mv); |
427 | 219k | break; |
428 | 454k | } |
429 | 0 | default: { |
430 | 0 | return 0; |
431 | 454k | } |
432 | 3.34M | } |
433 | 3.34M | return ret; |
434 | 3.34M | } |
435 | | |
436 | | static int read_is_inter_block(VP9_COMMON *const cm, MACROBLOCKD *const xd, |
437 | 3.82M | int segment_id, vpx_reader *r) { |
438 | 3.82M | if (segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) { |
439 | 272k | return get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME) != INTRA_FRAME; |
440 | 3.55M | } else { |
441 | 3.55M | const int ctx = get_intra_inter_context(xd); |
442 | 3.55M | const int is_inter = vpx_read(r, cm->fc->intra_inter_prob[ctx]); |
443 | 3.55M | FRAME_COUNTS *counts = xd->counts; |
444 | 3.55M | if (counts) ++counts->intra_inter[ctx][is_inter]; |
445 | 3.55M | return is_inter; |
446 | 3.55M | } |
447 | 3.82M | } |
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 | 5.35M | do { \ |
454 | 5.35M | if (refmv_count) { \ |
455 | 1.29M | if ((mv).as_int != (mv_ref_list)[0].as_int) { \ |
456 | 603k | (mv_ref_list)[(refmv_count)] = (mv); \ |
457 | 603k | refmv_count++; \ |
458 | 603k | goto Done; \ |
459 | 603k | } \ |
460 | 4.05M | } else { \ |
461 | 4.05M | (mv_ref_list)[(refmv_count)++] = (mv); \ |
462 | 4.05M | if (early_break) goto Done; \ |
463 | 4.05M | } \ |
464 | 5.35M | } 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 | 1.08M | do { \ |
471 | 1.08M | if (is_inter_block(mbmi)) { \ |
472 | 638k | if ((mbmi)->ref_frame[0] != ref_frame) \ |
473 | 638k | ADD_MV_REF_LIST_EB(scale_mv((mbmi), 0, ref_frame, ref_sign_bias), \ |
474 | 638k | refmv_count, mv_ref_list, Done); \ |
475 | 638k | if (has_second_ref(mbmi) && (mbmi)->ref_frame[1] != ref_frame && \ |
476 | 335k | (mbmi)->mv[1].as_int != (mbmi)->mv[0].as_int) \ |
477 | 335k | ADD_MV_REF_LIST_EB(scale_mv((mbmi), 1, ref_frame, ref_sign_bias), \ |
478 | 335k | refmv_count, mv_ref_list, Done); \ |
479 | 335k | } \ |
480 | 1.08M | } 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 | 4.18M | int block) { |
489 | 4.18M | const int *ref_sign_bias = cm->ref_frame_sign_bias; |
490 | 4.18M | int i, refmv_count = 0; |
491 | 4.18M | int different_ref_found = 0; |
492 | 4.18M | const MV_REF *const prev_frame_mvs = |
493 | 4.18M | cm->use_prev_frame_mvs |
494 | 4.18M | ? cm->prev_frame->mvs + mi_row * cm->mi_cols + mi_col |
495 | 4.18M | : NULL; |
496 | 4.18M | 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 | 4.18M | const int early_break = (mode != NEARMV); |
500 | | |
501 | | // Blank the reference vector list |
502 | 4.18M | memset(mv_ref_list, 0, sizeof(*mv_ref_list) * MAX_MV_REF_CANDIDATES); |
503 | | |
504 | 4.18M | i = 0; |
505 | 4.18M | if (block >= 0) { |
506 | | // If the size < 8x8 we get the mv from the bmi substructure for the |
507 | | // nearest two blocks. |
508 | 948k | for (i = 0; i < 2; ++i) { |
509 | 778k | const POSITION *const mv_ref = &mv_ref_search[i]; |
510 | 778k | if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { |
511 | 646k | const MODE_INFO *const candidate_mi = |
512 | 646k | xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]; |
513 | 646k | different_ref_found = 1; |
514 | | |
515 | 646k | if (candidate_mi->ref_frame[0] == ref_frame) |
516 | 330k | ADD_MV_REF_LIST_EB( |
517 | 646k | get_sub_block_mv(candidate_mi, 0, mv_ref->col, block), |
518 | 646k | refmv_count, mv_ref_list, Done); |
519 | 316k | else if (candidate_mi->ref_frame[1] == ref_frame) |
520 | 169k | ADD_MV_REF_LIST_EB( |
521 | 646k | get_sub_block_mv(candidate_mi, 1, mv_ref->col, block), |
522 | 646k | refmv_count, mv_ref_list, Done); |
523 | 646k | } |
524 | 778k | } |
525 | 470k | } |
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 | 10.6M | for (; i < MVREF_NEIGHBOURS; ++i) { |
531 | 10.0M | const POSITION *const mv_ref = &mv_ref_search[i]; |
532 | 10.0M | if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { |
533 | 7.57M | const MODE_INFO *const candidate = |
534 | 7.57M | xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]; |
535 | 7.57M | different_ref_found = 1; |
536 | | |
537 | 7.57M | if (candidate->ref_frame[0] == ref_frame) |
538 | 2.77M | ADD_MV_REF_LIST_EB(candidate->mv[0], refmv_count, mv_ref_list, Done); |
539 | 4.80M | else if (candidate->ref_frame[1] == ref_frame) |
540 | 1.50M | ADD_MV_REF_LIST_EB(candidate->mv[1], refmv_count, mv_ref_list, Done); |
541 | 7.57M | } |
542 | 10.0M | } |
543 | | |
544 | | // Check the last frame's mode and mv info. |
545 | 600k | if (prev_frame_mvs) { |
546 | 94.7k | if (prev_frame_mvs->ref_frame[0] == ref_frame) { |
547 | 18.2k | ADD_MV_REF_LIST_EB(prev_frame_mvs->mv[0], refmv_count, mv_ref_list, Done); |
548 | 76.5k | } else if (prev_frame_mvs->ref_frame[1] == ref_frame) { |
549 | 16.6k | ADD_MV_REF_LIST_EB(prev_frame_mvs->mv[1], refmv_count, mv_ref_list, Done); |
550 | 16.6k | } |
551 | 94.7k | } |
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 | 574k | if (different_ref_found) { |
557 | 1.90M | for (i = 0; i < MVREF_NEIGHBOURS; ++i) { |
558 | 1.75M | const POSITION *mv_ref = &mv_ref_search[i]; |
559 | 1.75M | if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { |
560 | 1.08M | const MODE_INFO *const candidate = |
561 | 1.08M | 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 | 1.08M | IF_DIFF_REF_FRAME_ADD_MV_EB(candidate, ref_frame, ref_sign_bias, |
565 | 1.08M | refmv_count, mv_ref_list, Done); |
566 | 1.08M | } |
567 | 1.75M | } |
568 | 509k | } |
569 | | |
570 | | // Since we still don't have a candidate we'll try the last frame. |
571 | 213k | if (prev_frame_mvs) { |
572 | 38.8k | if (prev_frame_mvs->ref_frame[0] != ref_frame && |
573 | 38.8k | prev_frame_mvs->ref_frame[0] > INTRA_FRAME) { |
574 | 17.0k | int_mv mv = prev_frame_mvs->mv[0]; |
575 | 17.0k | if (ref_sign_bias[prev_frame_mvs->ref_frame[0]] != |
576 | 17.0k | ref_sign_bias[ref_frame]) { |
577 | 5.99k | mv.as_mv.row *= -1; |
578 | 5.99k | mv.as_mv.col *= -1; |
579 | 5.99k | } |
580 | 17.0k | ADD_MV_REF_LIST_EB(mv, refmv_count, mv_ref_list, Done); |
581 | 17.0k | } |
582 | | |
583 | 25.7k | if (prev_frame_mvs->ref_frame[1] > INTRA_FRAME && |
584 | 25.7k | prev_frame_mvs->ref_frame[1] != ref_frame && |
585 | 25.7k | prev_frame_mvs->mv[1].as_int != prev_frame_mvs->mv[0].as_int) { |
586 | 810 | int_mv mv = prev_frame_mvs->mv[1]; |
587 | 810 | if (ref_sign_bias[prev_frame_mvs->ref_frame[1]] != |
588 | 810 | ref_sign_bias[ref_frame]) { |
589 | 607 | mv.as_mv.row *= -1; |
590 | 607 | mv.as_mv.col *= -1; |
591 | 607 | } |
592 | 810 | ADD_MV_REF_LIST_EB(mv, refmv_count, mv_ref_list, Done); |
593 | 810 | } |
594 | 25.7k | } |
595 | | |
596 | 199k | if (mode == NEARMV) |
597 | 97.7k | refmv_count = MAX_MV_REF_CANDIDATES; |
598 | 101k | else |
599 | | // we only care about the nearestmv for the remaining modes |
600 | 101k | refmv_count = 1; |
601 | | |
602 | 4.18M | Done: |
603 | | // Clamp vectors |
604 | 9.06M | for (i = 0; i < refmv_count; ++i) clamp_mv_ref(&mv_ref_list[i].as_mv, xd); |
605 | | |
606 | 4.18M | return refmv_count; |
607 | 199k | } |
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 | 887k | int_mv *best_sub8x8) { |
614 | 887k | int_mv mv_list[MAX_MV_REF_CANDIDATES]; |
615 | 887k | MODE_INFO *const mi = xd->mi[0]; |
616 | 887k | b_mode_info *bmi = mi->bmi; |
617 | 887k | int n; |
618 | 887k | int refmv_count; |
619 | | |
620 | 887k | assert(MAX_MV_REF_CANDIDATES == 2); |
621 | | |
622 | 887k | switch (block) { |
623 | 352k | case 0: |
624 | 352k | refmv_count = |
625 | 352k | dec_find_mv_refs(cm, xd, b_mode, mi->ref_frame[ref], mv_ref_search, |
626 | 352k | mv_list, mi_row, mi_col, block); |
627 | 352k | best_sub8x8->as_int = mv_list[refmv_count - 1].as_int; |
628 | 352k | break; |
629 | 195k | case 1: |
630 | 442k | case 2: |
631 | 442k | if (b_mode == NEARESTMV) { |
632 | 329k | best_sub8x8->as_int = bmi[0].as_mv[ref].as_int; |
633 | 329k | } else { |
634 | 112k | dec_find_mv_refs(cm, xd, b_mode, mi->ref_frame[ref], mv_ref_search, |
635 | 112k | mv_list, mi_row, mi_col, block); |
636 | 112k | best_sub8x8->as_int = 0; |
637 | 183k | for (n = 0; n < 2; ++n) |
638 | 170k | if (bmi[0].as_mv[ref].as_int != mv_list[n].as_int) { |
639 | 99.5k | best_sub8x8->as_int = mv_list[n].as_int; |
640 | 99.5k | break; |
641 | 99.5k | } |
642 | 112k | } |
643 | 442k | break; |
644 | 92.1k | case 3: |
645 | 92.1k | if (b_mode == NEARESTMV) { |
646 | 66.7k | best_sub8x8->as_int = bmi[2].as_mv[ref].as_int; |
647 | 66.7k | } else { |
648 | 25.4k | best_sub8x8->as_int = 0; |
649 | 25.4k | if (bmi[2].as_mv[ref].as_int != bmi[1].as_mv[ref].as_int) { |
650 | 18.3k | best_sub8x8->as_int = bmi[1].as_mv[ref].as_int; |
651 | 18.3k | break; |
652 | 18.3k | } |
653 | 7.13k | if (bmi[2].as_mv[ref].as_int != bmi[0].as_mv[ref].as_int) { |
654 | 1.53k | best_sub8x8->as_int = bmi[0].as_mv[ref].as_int; |
655 | 1.53k | break; |
656 | 1.53k | } |
657 | 5.59k | dec_find_mv_refs(cm, xd, b_mode, mi->ref_frame[ref], mv_ref_search, |
658 | 5.59k | mv_list, mi_row, mi_col, block); |
659 | 10.1k | for (n = 0; n < 2; ++n) |
660 | 9.09k | if (bmi[2].as_mv[ref].as_int != mv_list[n].as_int) { |
661 | 4.52k | best_sub8x8->as_int = mv_list[n].as_int; |
662 | 4.52k | break; |
663 | 4.52k | } |
664 | 5.59k | } |
665 | 72.3k | break; |
666 | 72.3k | default: assert(0 && "Invalid block index."); |
667 | 887k | } |
668 | 887k | } |
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 | 2.73M | int mi_col) { |
673 | 2.73M | int i; |
674 | 2.73M | int context_counter = 0; |
675 | 2.73M | const TileInfo *const tile = &xd->tile; |
676 | | |
677 | | // Get mode count from nearest 2 blocks |
678 | 8.20M | for (i = 0; i < 2; ++i) { |
679 | 5.46M | const POSITION *const mv_ref = &mv_ref_search[i]; |
680 | 5.46M | if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { |
681 | 4.67M | const MODE_INFO *const candidate = |
682 | 4.67M | xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]; |
683 | | // Keep counts for entropy encoding. |
684 | 4.67M | context_counter += mode_2_counter[candidate->mode]; |
685 | 4.67M | } |
686 | 5.46M | } |
687 | | |
688 | 2.73M | return counter_to_context[context_counter]; |
689 | 2.73M | } |
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 | 2.73M | int mi_col, vpx_reader *r) { |
695 | 2.73M | VP9_COMMON *const cm = &pbi->common; |
696 | 2.73M | const BLOCK_SIZE bsize = mi->sb_type; |
697 | 2.73M | const int allow_hp = cm->allow_high_precision_mv; |
698 | 2.73M | int_mv best_ref_mvs[2] = { { 0 }, { 0 } }; |
699 | 2.73M | int ref, is_compound; |
700 | 2.73M | uint8_t inter_mode_ctx; |
701 | 2.73M | const POSITION *const mv_ref_search = mv_ref_blocks[bsize]; |
702 | | |
703 | 2.73M | read_ref_frames(cm, xd, r, mi->segment_id, mi->ref_frame); |
704 | 2.73M | is_compound = has_second_ref(mi); |
705 | 2.73M | inter_mode_ctx = get_mode_context(cm, xd, mv_ref_search, mi_row, mi_col); |
706 | | |
707 | 2.73M | if (segfeature_active(&cm->seg, mi->segment_id, SEG_LVL_SKIP)) { |
708 | 103k | mi->mode = ZEROMV; |
709 | 103k | if (bsize < BLOCK_8X8) { |
710 | 1.03k | vpx_internal_error(xd->error_info, VPX_CODEC_UNSUP_BITSTREAM, |
711 | 1.03k | "Invalid usage of segment feature on small blocks"); |
712 | 1.03k | return; |
713 | 1.03k | } |
714 | 2.63M | } else { |
715 | 2.63M | if (bsize >= BLOCK_8X8) |
716 | 2.23M | mi->mode = read_inter_mode(cm, xd, r, inter_mode_ctx); |
717 | 2.63M | } |
718 | | |
719 | 2.73M | mi->interp_filter = (cm->interp_filter == SWITCHABLE) |
720 | 2.73M | ? read_switchable_interp_filter(cm, xd, r) |
721 | 2.73M | : cm->interp_filter; |
722 | | |
723 | 2.73M | if (bsize < BLOCK_8X8) { |
724 | 398k | const int num_4x4_w = 1 << xd->bmode_blocks_wl; |
725 | 398k | const int num_4x4_h = 1 << xd->bmode_blocks_hl; |
726 | 398k | int idx, idy; |
727 | 398k | PREDICTION_MODE b_mode; |
728 | 398k | int got_mv_refs_for_new = 0; |
729 | 398k | int_mv best_sub8x8[2]; |
730 | 398k | 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 | 398k | best_sub8x8[1].as_int = invalid_mv; |
734 | 1.07M | for (idy = 0; idy < 2; idy += num_4x4_h) { |
735 | 1.68M | for (idx = 0; idx < 2; idx += num_4x4_w) { |
736 | 1.00M | const int j = idy * 2 + idx; |
737 | 1.00M | b_mode = read_inter_mode(cm, xd, r, inter_mode_ctx); |
738 | | |
739 | 1.00M | if (b_mode == NEARESTMV || b_mode == NEARMV) { |
740 | 1.46M | for (ref = 0; ref < 1 + is_compound; ++ref) |
741 | 887k | append_sub8x8_mvs_for_idx(cm, xd, mv_ref_search, b_mode, j, ref, |
742 | 887k | mi_row, mi_col, &best_sub8x8[ref]); |
743 | 580k | } else if (b_mode == NEWMV && !got_mv_refs_for_new) { |
744 | 665k | for (ref = 0; ref < 1 + is_compound; ++ref) { |
745 | 399k | int_mv tmp_mvs[MAX_MV_REF_CANDIDATES]; |
746 | 399k | const MV_REFERENCE_FRAME frame = mi->ref_frame[ref]; |
747 | | |
748 | 399k | dec_find_mv_refs(cm, xd, NEWMV, frame, mv_ref_search, tmp_mvs, |
749 | 399k | mi_row, mi_col, -1); |
750 | | |
751 | 399k | lower_mv_precision(&tmp_mvs[0].as_mv, allow_hp); |
752 | 399k | best_ref_mvs[ref] = tmp_mvs[0]; |
753 | 399k | got_mv_refs_for_new = 1; |
754 | 399k | } |
755 | 265k | } |
756 | | |
757 | 1.00M | if (!assign_mv(cm, xd, b_mode, mi->bmi[j].as_mv, best_ref_mvs, |
758 | 1.00M | best_sub8x8, is_compound, allow_hp, r)) { |
759 | 1.29k | xd->corrupted |= 1; |
760 | 1.29k | return; |
761 | 1.29k | } |
762 | | |
763 | 1.00M | if (num_4x4_h == 2) mi->bmi[j + 2] = mi->bmi[j]; |
764 | 1.00M | if (num_4x4_w == 2) mi->bmi[j + 1] = mi->bmi[j]; |
765 | 1.00M | } |
766 | 679k | } |
767 | | |
768 | 397k | mi->mode = b_mode; |
769 | | |
770 | 397k | copy_mv_pair(mi->mv, mi->bmi[3].as_mv); |
771 | 2.33M | } else { |
772 | 2.33M | if (mi->mode != ZEROMV) { |
773 | 5.46M | for (ref = 0; ref < 1 + is_compound; ++ref) { |
774 | 3.31M | int_mv tmp_mvs[MAX_MV_REF_CANDIDATES]; |
775 | 3.31M | const MV_REFERENCE_FRAME frame = mi->ref_frame[ref]; |
776 | 3.31M | int refmv_count = |
777 | 3.31M | dec_find_mv_refs(cm, xd, mi->mode, frame, mv_ref_search, tmp_mvs, |
778 | 3.31M | mi_row, mi_col, -1); |
779 | 3.31M | lower_mv_precision(&tmp_mvs[refmv_count - 1].as_mv, allow_hp); |
780 | 3.31M | best_ref_mvs[ref] = tmp_mvs[refmv_count - 1]; |
781 | 3.31M | } |
782 | 2.15M | } |
783 | 2.33M | xd->corrupted |= !assign_mv(cm, xd, mi->mode, mi->mv, best_ref_mvs, |
784 | 2.33M | best_ref_mvs, is_compound, allow_hp, r); |
785 | 2.33M | } |
786 | 2.73M | } |
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 | 3.82M | int y_mis) { |
792 | 3.82M | VP9_COMMON *const cm = &pbi->common; |
793 | 3.82M | MODE_INFO *const mi = xd->mi[0]; |
794 | 3.82M | int inter_block; |
795 | | |
796 | 3.82M | mi->segment_id = |
797 | 3.82M | read_inter_segment_id(cm, xd, mi_row, mi_col, r, x_mis, y_mis); |
798 | 3.82M | mi->skip = read_skip(cm, xd, mi->segment_id, r); |
799 | 3.82M | inter_block = read_is_inter_block(cm, xd, mi->segment_id, r); |
800 | 3.82M | mi->tx_size = read_tx_size(cm, xd, !mi->skip || !inter_block, r); |
801 | | |
802 | 3.82M | if (inter_block) |
803 | 2.73M | read_inter_block_mode_info(pbi, xd, mi, mi_row, mi_col, r); |
804 | 1.09M | else |
805 | 1.09M | read_intra_block_mode_info(cm, xd, mi, r); |
806 | 3.82M | } |
807 | | |
808 | | static INLINE void copy_ref_frame_pair(MV_REFERENCE_FRAME *dst, |
809 | 32.3M | const MV_REFERENCE_FRAME *src) { |
810 | 32.3M | memcpy(dst, src, sizeof(*dst) * 2); |
811 | 32.3M | } |
812 | | |
813 | | void vp9_read_mode_info(TileWorkerData *twd, VP9Decoder *const pbi, int mi_row, |
814 | 6.58M | int mi_col, int x_mis, int y_mis) { |
815 | 6.58M | vpx_reader *r = &twd->bit_reader; |
816 | 6.58M | MACROBLOCKD *const xd = &twd->xd; |
817 | 6.58M | VP9_COMMON *const cm = &pbi->common; |
818 | 6.58M | MODE_INFO *const mi = xd->mi[0]; |
819 | 6.58M | MV_REF *frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col; |
820 | 6.58M | int w, h; |
821 | | |
822 | 6.58M | if (frame_is_intra_only(cm)) { |
823 | 2.75M | read_intra_frame_mode_info(cm, xd, mi_row, mi_col, r, x_mis, y_mis); |
824 | 3.82M | } 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 | 3.82M | MV_REFERENCE_FRAME mi_ref_frame[2]; |
828 | 3.82M | int_mv mi_mv[2]; |
829 | | |
830 | 3.82M | read_inter_frame_mode_info(pbi, xd, mi_row, mi_col, r, x_mis, y_mis); |
831 | | |
832 | 3.82M | copy_ref_frame_pair(mi_ref_frame, mi->ref_frame); |
833 | 3.82M | copy_mv_pair(mi_mv, mi->mv); |
834 | | |
835 | 11.9M | for (h = 0; h < y_mis; ++h) { |
836 | 36.6M | for (w = 0; w < x_mis; ++w) { |
837 | 28.5M | MV_REF *const mv = frame_mvs + w; |
838 | 28.5M | copy_ref_frame_pair(mv->ref_frame, mi_ref_frame); |
839 | 28.5M | copy_mv_pair(mv->mv, mi_mv); |
840 | 28.5M | } |
841 | 8.15M | frame_mvs += cm->mi_cols; |
842 | 8.15M | } |
843 | 3.82M | } |
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 | 6.58M | } |