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