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