decodemv.c 36 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
/*
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Jingning Han's avatar
Jingning Han committed
3
 *
4 5 6 7 8 9
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Jingning Han's avatar
Jingning Han committed
10 11 12 13
 */

#include <assert.h>

Yaowu Xu's avatar
Yaowu Xu committed
14 15 16 17 18 19 20 21
#include "av1/common/common.h"
#include "av1/common/entropy.h"
#include "av1/common/entropymode.h"
#include "av1/common/entropymv.h"
#include "av1/common/mvref_common.h"
#include "av1/common/pred_common.h"
#include "av1/common/reconinter.h"
#include "av1/common/seg_common.h"
Jingning Han's avatar
Jingning Han committed
22

Yaowu Xu's avatar
Yaowu Xu committed
23
#include "av1/decoder/decodeframe.h"
Jingning Han's avatar
Jingning Han committed
24
#include "av1/decoder/decodemv.h"
Jingning Han's avatar
Jingning Han committed
25

Adrian Grange's avatar
Adrian Grange committed
26
#include "aom_dsp/aom_dsp_common.h"
27

Adrian Grange's avatar
Adrian Grange committed
28
static PREDICTION_MODE read_intra_mode(aom_reader *r, const aom_prob *p) {
29
  return (PREDICTION_MODE)aom_read_tree(r, av1_intra_mode_tree, p);
Jingning Han's avatar
Jingning Han committed
30 31
}

32
static PREDICTION_MODE read_intra_mode_y(AV1_COMMON *cm, MACROBLOCKD *xd,
Adrian Grange's avatar
Adrian Grange committed
33
                                         aom_reader *r, int size_group) {
Jingning Han's avatar
Jingning Han committed
34 35 36
  const PREDICTION_MODE y_mode =
      read_intra_mode(r, cm->fc->y_mode_prob[size_group]);
  FRAME_COUNTS *counts = xd->counts;
clang-format's avatar
clang-format committed
37
  if (counts) ++counts->y_mode[size_group][y_mode];
Jingning Han's avatar
Jingning Han committed
38 39 40
  return y_mode;
}

41
static PREDICTION_MODE read_intra_mode_uv(AV1_COMMON *cm, MACROBLOCKD *xd,
Adrian Grange's avatar
Adrian Grange committed
42
                                          aom_reader *r,
Jingning Han's avatar
Jingning Han committed
43
                                          PREDICTION_MODE y_mode) {
clang-format's avatar
clang-format committed
44 45
  const PREDICTION_MODE uv_mode =
      read_intra_mode(r, cm->fc->uv_mode_prob[y_mode]);
Jingning Han's avatar
Jingning Han committed
46
  FRAME_COUNTS *counts = xd->counts;
clang-format's avatar
clang-format committed
47
  if (counts) ++counts->uv_mode[y_mode][uv_mode];
Jingning Han's avatar
Jingning Han committed
48 49 50
  return uv_mode;
}

51
static PREDICTION_MODE read_inter_mode(AV1_COMMON *cm, MACROBLOCKD *xd,
52
                                       aom_reader *r, int16_t ctx) {
53 54
#if CONFIG_REF_MV
  FRAME_COUNTS *counts = xd->counts;
55
  int16_t mode_ctx = ctx & NEWMV_CTX_MASK;
56 57 58
  aom_prob mode_prob = cm->fc->newmv_prob[mode_ctx];

  if (aom_read(r, mode_prob) == 0) {
clang-format's avatar
clang-format committed
59
    if (counts) ++counts->newmv_mode[mode_ctx][0];
60 61
    return NEWMV;
  }
clang-format's avatar
clang-format committed
62
  if (counts) ++counts->newmv_mode[mode_ctx][1];
63

clang-format's avatar
clang-format committed
64
  if (ctx & (1 << ALL_ZERO_FLAG_OFFSET)) return ZEROMV;
65

66
  mode_ctx = (ctx >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
67 68 69

  mode_prob = cm->fc->zeromv_prob[mode_ctx];
  if (aom_read(r, mode_prob) == 0) {
clang-format's avatar
clang-format committed
70
    if (counts) ++counts->zeromv_mode[mode_ctx][0];
71 72
    return ZEROMV;
  }
clang-format's avatar
clang-format committed
73
  if (counts) ++counts->zeromv_mode[mode_ctx][1];
74

75
  mode_ctx = (ctx >> REFMV_OFFSET) & REFMV_CTX_MASK;
76

clang-format's avatar
clang-format committed
77 78 79
  if (ctx & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
  if (ctx & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
  if (ctx & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
80

81 82
  mode_prob = cm->fc->refmv_prob[mode_ctx];
  if (aom_read(r, mode_prob) == 0) {
clang-format's avatar
clang-format committed
83
    if (counts) ++counts->refmv_mode[mode_ctx][0];
84 85
    return NEARESTMV;
  } else {
clang-format's avatar
clang-format committed
86
    if (counts) ++counts->refmv_mode[mode_ctx][1];
87 88 89 90 91 92
    return NEARMV;
  }

  // Invalid prediction mode.
  assert(0);
#else
clang-format's avatar
clang-format committed
93
  const int mode =
94
      aom_read_tree(r, av1_inter_mode_tree, cm->fc->inter_mode_probs[ctx]);
Jingning Han's avatar
Jingning Han committed
95
  FRAME_COUNTS *counts = xd->counts;
clang-format's avatar
clang-format committed
96
  if (counts) ++counts->inter_mode[ctx][mode];
Jingning Han's avatar
Jingning Han committed
97 98

  return NEARESTMV + mode;
99
#endif
Jingning Han's avatar
Jingning Han committed
100 101
}

102
#if CONFIG_REF_MV
clang-format's avatar
clang-format committed
103 104
static void read_drl_idx(const AV1_COMMON *cm, MACROBLOCKD *xd,
                         MB_MODE_INFO *mbmi, aom_reader *r) {
105 106 107
  uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
  mbmi->ref_mv_idx = 0;

108 109 110 111 112 113 114 115
  if (mbmi->mode == NEWMV) {
    int idx;
    for (idx = 0; idx < 2; ++idx) {
      if (xd->ref_mv_count[ref_frame_type] > idx + 1) {
        uint8_t drl_ctx = av1_drl_ctx(xd->ref_mv_stack[ref_frame_type], idx);
        aom_prob drl_prob = cm->fc->drl_prob[drl_ctx];
        if (!aom_read(r, drl_prob)) {
          mbmi->ref_mv_idx = idx;
clang-format's avatar
clang-format committed
116
          if (xd->counts) ++xd->counts->drl_mode[drl_ctx][0];
117 118 119
          return;
        }
        mbmi->ref_mv_idx = idx + 1;
clang-format's avatar
clang-format committed
120
        if (xd->counts) ++xd->counts->drl_mode[drl_ctx][1];
121 122 123 124
      }
    }
  }

125 126 127 128 129 130 131 132 133 134 135
  if (mbmi->mode == NEARMV) {
    int idx;
    // Offset the NEARESTMV mode.
    // TODO(jingning): Unify the two syntax decoding loops after the NEARESTMV
    // mode is factored in.
    for (idx = 1; idx < 3; ++idx) {
      if (xd->ref_mv_count[ref_frame_type] > idx + 1) {
        uint8_t drl_ctx = av1_drl_ctx(xd->ref_mv_stack[ref_frame_type], idx);
        aom_prob drl_prob = cm->fc->drl_prob[drl_ctx];
        if (!aom_read(r, drl_prob)) {
          mbmi->ref_mv_idx = idx - 1;
clang-format's avatar
clang-format committed
136
          if (xd->counts) ++xd->counts->drl_mode[drl_ctx][0];
137 138
          return;
        }
139
        mbmi->ref_mv_idx = idx;
clang-format's avatar
clang-format committed
140
        if (xd->counts) ++xd->counts->drl_mode[drl_ctx][1];
141 142 143 144 145 146
      }
    }
  }
}
#endif

147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
#if CONFIG_MOTION_VAR
static MOTION_MODE read_motion_mode(AV1_COMMON *cm, MACROBLOCKD *xd,
                                    MB_MODE_INFO *mbmi, aom_reader *r) {
  if (is_motion_variation_allowed(mbmi)) {
    int motion_mode;
    FRAME_COUNTS *counts = xd->counts;

    motion_mode = aom_read_tree(r, av1_motion_mode_tree,
                                cm->fc->motion_mode_prob[mbmi->sb_type]);
    if (counts) ++counts->motion_mode[mbmi->sb_type][motion_mode];
    return (MOTION_MODE)(SIMPLE_TRANSLATION + motion_mode);
  } else {
    return SIMPLE_TRANSLATION;
  }
}
#endif  // CONFIG_MOTION_VAR

Adrian Grange's avatar
Adrian Grange committed
164
static int read_segment_id(aom_reader *r,
clang-format's avatar
clang-format committed
165
                           const struct segmentation_probs *segp) {
166
  return aom_read_tree(r, av1_segment_tree, segp->tree_probs);
Jingning Han's avatar
Jingning Han committed
167 168
}

169
static TX_SIZE read_selected_tx_size(AV1_COMMON *cm, MACROBLOCKD *xd,
Adrian Grange's avatar
Adrian Grange committed
170
                                     TX_SIZE max_tx_size, aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
171 172
  FRAME_COUNTS *counts = xd->counts;
  const int ctx = get_tx_size_context(xd);
Adrian Grange's avatar
Adrian Grange committed
173 174
  const aom_prob *tx_probs = get_tx_probs(max_tx_size, ctx, &cm->fc->tx_probs);
  int tx_size = aom_read(r, tx_probs[0]);
Jingning Han's avatar
Jingning Han committed
175
  if (tx_size != TX_4X4 && max_tx_size >= TX_16X16) {
Adrian Grange's avatar
Adrian Grange committed
176
    tx_size += aom_read(r, tx_probs[1]);
Jingning Han's avatar
Jingning Han committed
177
    if (tx_size != TX_8X8 && max_tx_size >= TX_32X32)
Adrian Grange's avatar
Adrian Grange committed
178
      tx_size += aom_read(r, tx_probs[2]);
Jingning Han's avatar
Jingning Han committed
179 180
  }

clang-format's avatar
clang-format committed
181
  if (counts) ++get_tx_counts(max_tx_size, ctx, &counts->tx)[tx_size];
Jingning Han's avatar
Jingning Han committed
182 183 184
  return (TX_SIZE)tx_size;
}

185
static TX_SIZE read_tx_size(AV1_COMMON *cm, MACROBLOCKD *xd, int allow_select,
Adrian Grange's avatar
Adrian Grange committed
186
                            aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
187 188 189
  TX_MODE tx_mode = cm->tx_mode;
  BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
  const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
clang-format's avatar
clang-format committed
190
  if (xd->lossless[xd->mi[0]->mbmi.segment_id]) return TX_4X4;
Jingning Han's avatar
Jingning Han committed
191 192 193
  if (allow_select && tx_mode == TX_MODE_SELECT && bsize >= BLOCK_8X8)
    return read_selected_tx_size(cm, xd, max_tx_size, r);
  else
Adrian Grange's avatar
Adrian Grange committed
194
    return AOMMIN(max_tx_size, tx_mode_to_biggest_tx_size[tx_mode]);
Jingning Han's avatar
Jingning Han committed
195 196
}

197
static int dec_get_segment_id(const AV1_COMMON *cm, const uint8_t *segment_ids,
Jingning Han's avatar
Jingning Han committed
198 199 200 201 202
                              int mi_offset, int x_mis, int y_mis) {
  int x, y, segment_id = INT_MAX;

  for (y = 0; y < y_mis; y++)
    for (x = 0; x < x_mis; x++)
203
      segment_id =
Adrian Grange's avatar
Adrian Grange committed
204
          AOMMIN(segment_id, segment_ids[mi_offset + y * cm->mi_cols + x]);
Jingning Han's avatar
Jingning Han committed
205 206 207 208 209

  assert(segment_id >= 0 && segment_id < MAX_SEGMENTS);
  return segment_id;
}

210
static void set_segment_id(AV1_COMMON *cm, int mi_offset, int x_mis, int y_mis,
clang-format's avatar
clang-format committed
211
                           int segment_id) {
Jingning Han's avatar
Jingning Han committed
212 213 214 215 216 217 218 219 220
  int x, y;

  assert(segment_id >= 0 && segment_id < MAX_SEGMENTS);

  for (y = 0; y < y_mis; y++)
    for (x = 0; x < x_mis; x++)
      cm->current_frame_seg_map[mi_offset + y * cm->mi_cols + x] = segment_id;
}

221
static int read_intra_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
222
                                 int mi_offset, int x_mis, int y_mis,
Adrian Grange's avatar
Adrian Grange committed
223
                                 aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
224
  struct segmentation *const seg = &cm->seg;
225 226 227 228 229 230
#if CONFIG_MISC_FIXES
  FRAME_COUNTS *counts = xd->counts;
  struct segmentation_probs *const segp = &cm->fc->seg;
#else
  struct segmentation_probs *const segp = &cm->segp;
#endif
Jingning Han's avatar
Jingning Han committed
231 232
  int segment_id;

233
#if !CONFIG_MISC_FIXES
clang-format's avatar
clang-format committed
234
  (void)xd;
235 236
#endif

clang-format's avatar
clang-format committed
237
  if (!seg->enabled) return 0;  // Default for disabled segmentation
Jingning Han's avatar
Jingning Han committed
238

239
  assert(seg->update_map && !seg->temporal_update);
Jingning Han's avatar
Jingning Han committed
240

241 242
  segment_id = read_segment_id(r, segp);
#if CONFIG_MISC_FIXES
clang-format's avatar
clang-format committed
243
  if (counts) ++counts->seg.tree_total[segment_id];
244
#endif
Jingning Han's avatar
Jingning Han committed
245 246 247 248
  set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
  return segment_id;
}

249
static void copy_segment_id(const AV1_COMMON *cm,
clang-format's avatar
clang-format committed
250 251 252
                            const uint8_t *last_segment_ids,
                            uint8_t *current_segment_ids, int mi_offset,
                            int x_mis, int y_mis) {
253 254 255 256
  int x, y;

  for (y = 0; y < y_mis; y++)
    for (x = 0; x < x_mis; x++)
clang-format's avatar
clang-format committed
257 258 259
      current_segment_ids[mi_offset + y * cm->mi_cols + x] =
          last_segment_ids ? last_segment_ids[mi_offset + y * cm->mi_cols + x]
                           : 0;
260 261
}

262
static int read_inter_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
Adrian Grange's avatar
Adrian Grange committed
263
                                 int mi_row, int mi_col, aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
264
  struct segmentation *const seg = &cm->seg;
265 266 267 268 269 270
#if CONFIG_MISC_FIXES
  FRAME_COUNTS *counts = xd->counts;
  struct segmentation_probs *const segp = &cm->fc->seg;
#else
  struct segmentation_probs *const segp = &cm->segp;
#endif
Jingning Han's avatar
Jingning Han committed
271 272 273 274 275 276 277
  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
  int predicted_segment_id, segment_id;
  const int mi_offset = mi_row * cm->mi_cols + mi_col;
  const int bw = xd->plane[0].n4_w >> 1;
  const int bh = xd->plane[0].n4_h >> 1;

  // TODO(slavarnway): move x_mis, y_mis into xd ?????
Adrian Grange's avatar
Adrian Grange committed
278 279
  const int x_mis = AOMMIN(cm->mi_cols - mi_col, bw);
  const int y_mis = AOMMIN(cm->mi_rows - mi_row, bh);
Jingning Han's avatar
Jingning Han committed
280

clang-format's avatar
clang-format committed
281
  if (!seg->enabled) return 0;  // Default for disabled segmentation
Jingning Han's avatar
Jingning Han committed
282

clang-format's avatar
clang-format committed
283 284 285 286
  predicted_segment_id = cm->last_frame_seg_map
                             ? dec_get_segment_id(cm, cm->last_frame_seg_map,
                                                  mi_offset, x_mis, y_mis)
                             : 0;
Jingning Han's avatar
Jingning Han committed
287 288 289 290 291 292 293 294

  if (!seg->update_map) {
    copy_segment_id(cm, cm->last_frame_seg_map, cm->current_frame_seg_map,
                    mi_offset, x_mis, y_mis);
    return predicted_segment_id;
  }

  if (seg->temporal_update) {
295
    const int ctx = av1_get_pred_context_seg_id(xd);
Adrian Grange's avatar
Adrian Grange committed
296 297
    const aom_prob pred_prob = segp->pred_probs[ctx];
    mbmi->seg_id_predicted = aom_read(r, pred_prob);
298
#if CONFIG_MISC_FIXES
clang-format's avatar
clang-format committed
299
    if (counts) ++counts->seg.pred[ctx][mbmi->seg_id_predicted];
300 301 302 303 304 305
#endif
    if (mbmi->seg_id_predicted) {
      segment_id = predicted_segment_id;
    } else {
      segment_id = read_segment_id(r, segp);
#if CONFIG_MISC_FIXES
clang-format's avatar
clang-format committed
306
      if (counts) ++counts->seg.tree_mispred[segment_id];
307 308
#endif
    }
Jingning Han's avatar
Jingning Han committed
309
  } else {
310 311
    segment_id = read_segment_id(r, segp);
#if CONFIG_MISC_FIXES
clang-format's avatar
clang-format committed
312
    if (counts) ++counts->seg.tree_total[segment_id];
313
#endif
Jingning Han's avatar
Jingning Han committed
314 315 316 317 318
  }
  set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
  return segment_id;
}

319
static int read_skip(AV1_COMMON *cm, const MACROBLOCKD *xd, int segment_id,
Adrian Grange's avatar
Adrian Grange committed
320
                     aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
321 322 323
  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
    return 1;
  } else {
324
    const int ctx = av1_get_skip_context(xd);
Adrian Grange's avatar
Adrian Grange committed
325
    const int skip = aom_read(r, cm->fc->skip_probs[ctx]);
Jingning Han's avatar
Jingning Han committed
326
    FRAME_COUNTS *counts = xd->counts;
clang-format's avatar
clang-format committed
327
    if (counts) ++counts->skip[ctx][skip];
Jingning Han's avatar
Jingning Han committed
328 329 330 331
    return skip;
  }
}

hui su's avatar
hui su committed
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
#if CONFIG_EXT_INTRA
static INLINE int read_uniform(aom_reader *r, int n) {
  const int l = get_unsigned_bits(n);
  const int m = (1 << l) - n;
  const int v = aom_read_literal(r, l - 1);

  assert(l != 0);
  return (v < m) ? v : ((v << 1) - m + aom_read_literal(r, 1));
}

static void read_intra_angle_info(MB_MODE_INFO *const mbmi, aom_reader *r) {
  mbmi->intra_angle_delta[0] = 0;
  mbmi->intra_angle_delta[1] = 0;
  if (mbmi->sb_type < BLOCK_8X8) return;

  if (is_directional_mode(mbmi->mode)) {
    const TX_SIZE max_tx_size = max_txsize_lookup[mbmi->sb_type];
    const int max_angle_delta = av1_max_angle_delta_y[max_tx_size][mbmi->mode];
    mbmi->intra_angle_delta[0] =
        read_uniform(r, 2 * max_angle_delta + 1) - max_angle_delta;
  }

  if (is_directional_mode(mbmi->uv_mode)) {
    mbmi->intra_angle_delta[1] =
        read_uniform(r, 2 * MAX_ANGLE_DELTA_UV + 1) - MAX_ANGLE_DELTA_UV;
  }
}
#endif  // CONFIG_EXT_INTRA

361
static void read_intra_frame_mode_info(AV1_COMMON *const cm,
clang-format's avatar
clang-format committed
362
                                       MACROBLOCKD *const xd, int mi_row,
Adrian Grange's avatar
Adrian Grange committed
363
                                       int mi_col, aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
364 365 366
  MODE_INFO *const mi = xd->mi[0];
  MB_MODE_INFO *const mbmi = &mi->mbmi;
  const MODE_INFO *above_mi = xd->above_mi;
clang-format's avatar
clang-format committed
367
  const MODE_INFO *left_mi = xd->left_mi;
Jingning Han's avatar
Jingning Han committed
368 369 370 371 372 373 374
  const BLOCK_SIZE bsize = mbmi->sb_type;
  int i;
  const int mi_offset = mi_row * cm->mi_cols + mi_col;
  const int bw = xd->plane[0].n4_w >> 1;
  const int bh = xd->plane[0].n4_h >> 1;

  // TODO(slavarnway): move x_mis, y_mis into xd ?????
Adrian Grange's avatar
Adrian Grange committed
375 376
  const int x_mis = AOMMIN(cm->mi_cols - mi_col, bw);
  const int y_mis = AOMMIN(cm->mi_rows - mi_row, bh);
Jingning Han's avatar
Jingning Han committed
377

378
  mbmi->segment_id = read_intra_segment_id(cm, xd, mi_offset, x_mis, y_mis, r);
Jingning Han's avatar
Jingning Han committed
379 380 381 382 383 384 385 386 387
  mbmi->skip = read_skip(cm, xd, mbmi->segment_id, r);
  mbmi->tx_size = read_tx_size(cm, xd, 1, r);
  mbmi->ref_frame[0] = INTRA_FRAME;
  mbmi->ref_frame[1] = NONE;

  switch (bsize) {
    case BLOCK_4X4:
      for (i = 0; i < 4; ++i)
        mi->bmi[i].as_mode =
388
            read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, i));
Jingning Han's avatar
Jingning Han committed
389 390 391 392
      mbmi->mode = mi->bmi[3].as_mode;
      break;
    case BLOCK_4X8:
      mi->bmi[0].as_mode = mi->bmi[2].as_mode =
393
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
Jingning Han's avatar
Jingning Han committed
394
      mi->bmi[1].as_mode = mi->bmi[3].as_mode = mbmi->mode =
395
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 1));
Jingning Han's avatar
Jingning Han committed
396 397 398
      break;
    case BLOCK_8X4:
      mi->bmi[0].as_mode = mi->bmi[1].as_mode =
399
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
Jingning Han's avatar
Jingning Han committed
400
      mi->bmi[2].as_mode = mi->bmi[3].as_mode = mbmi->mode =
401
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 2));
Jingning Han's avatar
Jingning Han committed
402 403
      break;
    default:
clang-format's avatar
clang-format committed
404 405
      mbmi->mode =
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
Jingning Han's avatar
Jingning Han committed
406 407
  }

408
  mbmi->uv_mode = read_intra_mode_uv(cm, xd, r, mbmi->mode);
hui su's avatar
hui su committed
409 410 411
#if CONFIG_EXT_INTRA
  read_intra_angle_info(mbmi, r);
#endif  // CONFIG_EXT_INTRA
412

clang-format's avatar
clang-format committed
413
  if (mbmi->tx_size < TX_32X32 && cm->base_qindex > 0 && !mbmi->skip &&
414 415 416
      !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
    FRAME_COUNTS *counts = xd->counts;
    TX_TYPE tx_type_nom = intra_mode_to_tx_type_context[mbmi->mode];
clang-format's avatar
clang-format committed
417
    mbmi->tx_type =
418
        aom_read_tree(r, av1_ext_tx_tree,
clang-format's avatar
clang-format committed
419
                      cm->fc->intra_ext_tx_prob[mbmi->tx_size][tx_type_nom]);
420 421 422 423 424
    if (counts)
      ++counts->intra_ext_tx[mbmi->tx_size][tx_type_nom][mbmi->tx_type];
  } else {
    mbmi->tx_type = DCT_DCT;
  }
Jingning Han's avatar
Jingning Han committed
425 426
}

Adrian Grange's avatar
Adrian Grange committed
427
static int read_mv_component(aom_reader *r, const nmv_component *mvcomp,
clang-format's avatar
clang-format committed
428
                             int usehp) {
Jingning Han's avatar
Jingning Han committed
429
  int mag, d, fr, hp;
Adrian Grange's avatar
Adrian Grange committed
430
  const int sign = aom_read(r, mvcomp->sign);
431
  const int mv_class = aom_read_tree(r, av1_mv_class_tree, mvcomp->classes);
Jingning Han's avatar
Jingning Han committed
432 433 434 435
  const int class0 = mv_class == MV_CLASS_0;

  // Integer part
  if (class0) {
436
    d = aom_read_tree(r, av1_mv_class0_tree, mvcomp->class0);
Jingning Han's avatar
Jingning Han committed
437 438 439 440 441 442
    mag = 0;
  } else {
    int i;
    const int n = mv_class + CLASS0_BITS - 1;  // number of bits

    d = 0;
Adrian Grange's avatar
Adrian Grange committed
443
    for (i = 0; i < n; ++i) d |= aom_read(r, mvcomp->bits[i]) << i;
Jingning Han's avatar
Jingning Han committed
444 445 446 447
    mag = CLASS0_SIZE << (mv_class + 2);
  }

  // Fractional part
448
  fr = aom_read_tree(r, av1_mv_fp_tree,
clang-format's avatar
clang-format committed
449
                     class0 ? mvcomp->class0_fp[d] : mvcomp->fp);
Jingning Han's avatar
Jingning Han committed
450 451

  // High precision part (if hp is not used, the default value of the hp is 1)
Adrian Grange's avatar
Adrian Grange committed
452
  hp = usehp ? aom_read(r, class0 ? mvcomp->class0_hp : mvcomp->hp) : 1;
Jingning Han's avatar
Jingning Han committed
453 454 455 456 457 458

  // Result
  mag += ((d << 3) | (fr << 1) | hp) + 1;
  return sign ? -mag : mag;
}

Adrian Grange's avatar
Adrian Grange committed
459
static INLINE void read_mv(aom_reader *r, MV *mv, const MV *ref,
clang-format's avatar
clang-format committed
460 461
                           const nmv_context *ctx, nmv_context_counts *counts,
                           int allow_hp) {
Jingning Han's avatar
Jingning Han committed
462
  const MV_JOINT_TYPE joint_type =
463 464
      (MV_JOINT_TYPE)aom_read_tree(r, av1_mv_joint_tree, ctx->joints);
  const int use_hp = allow_hp && av1_use_mv_hp(ref);
clang-format's avatar
clang-format committed
465
  MV diff = { 0, 0 };
Jingning Han's avatar
Jingning Han committed
466 467 468 469 470 471 472

  if (mv_joint_vertical(joint_type))
    diff.row = read_mv_component(r, &ctx->comps[0], use_hp);

  if (mv_joint_horizontal(joint_type))
    diff.col = read_mv_component(r, &ctx->comps[1], use_hp);

473
  av1_inc_mv(&diff, counts, use_hp);
Jingning Han's avatar
Jingning Han committed
474 475 476 477 478

  mv->row = ref->row + diff.row;
  mv->col = ref->col + diff.col;
}

479
static REFERENCE_MODE read_block_reference_mode(AV1_COMMON *cm,
Jingning Han's avatar
Jingning Han committed
480
                                                const MACROBLOCKD *xd,
Adrian Grange's avatar
Adrian Grange committed
481
                                                aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
482
  if (cm->reference_mode == REFERENCE_MODE_SELECT) {
483
    const int ctx = av1_get_reference_mode_context(cm, xd);
Jingning Han's avatar
Jingning Han committed
484
    const REFERENCE_MODE mode =
Adrian Grange's avatar
Adrian Grange committed
485
        (REFERENCE_MODE)aom_read(r, cm->fc->comp_inter_prob[ctx]);
Jingning Han's avatar
Jingning Han committed
486
    FRAME_COUNTS *counts = xd->counts;
clang-format's avatar
clang-format committed
487
    if (counts) ++counts->comp_inter[ctx][mode];
Jingning Han's avatar
Jingning Han committed
488 489 490 491 492 493 494
    return mode;  // SINGLE_REFERENCE or COMPOUND_REFERENCE
  } else {
    return cm->reference_mode;
  }
}

// Read the referncence frame
495
static void read_ref_frames(AV1_COMMON *const cm, MACROBLOCKD *const xd,
Adrian Grange's avatar
Adrian Grange committed
496
                            aom_reader *r, int segment_id,
clang-format's avatar
clang-format committed
497
                            MV_REFERENCE_FRAME ref_frame[2]) {
Jingning Han's avatar
Jingning Han committed
498 499 500 501 502 503 504 505 506 507 508
  FRAME_CONTEXT *const fc = cm->fc;
  FRAME_COUNTS *counts = xd->counts;

  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) {
    ref_frame[0] = (MV_REFERENCE_FRAME)get_segdata(&cm->seg, segment_id,
                                                   SEG_LVL_REF_FRAME);
    ref_frame[1] = NONE;
  } else {
    const REFERENCE_MODE mode = read_block_reference_mode(cm, xd, r);
    // FIXME(rbultje) I'm pretty sure this breaks segmentation ref frame coding
    if (mode == COMPOUND_REFERENCE) {
509 510
#if CONFIG_EXT_REFS
      const int idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
511
      // Read forward references.
512 513 514 515 516 517 518 519 520 521 522 523 524 525
      const int ctx_fwd = av1_get_pred_context_comp_fwdref_p(cm, xd);
      const int bit_fwd = aom_read(r, fc->comp_fwdref_prob[ctx_fwd][0]);
      if (counts) ++counts->comp_fwdref[ctx_fwd][0][bit_fwd];
      if (!bit_fwd) {
        const int ctx_fwd1 = av1_get_pred_context_comp_fwdref_p1(cm, xd);
        const int bit_fwd1 = aom_read(r, fc->comp_fwdref_prob[ctx_fwd1][1]);
        if (counts) ++counts->comp_fwdref[ctx_fwd1][1][bit_fwd1];
        ref_frame[!idx] = cm->comp_fwd_ref[bit_fwd1 ? 0 : 1];
      } else {
        const int ctx_fwd2 = av1_get_pred_context_comp_fwdref_p2(cm, xd);
        const int bit_fwd2 = aom_read(r, fc->comp_fwdref_prob[ctx_fwd2][2]);
        if (counts) ++counts->comp_fwdref[ctx_fwd2][2][bit_fwd2];
        ref_frame[!idx] = cm->comp_fwd_ref[bit_fwd2 ? 3 : 2];
      }
526 527 528 529 530 531 532
      // Read backward references.
      {
        const int ctx_bwd = av1_get_pred_context_comp_bwdref_p(cm, xd);
        const int bit_bwd = aom_read(r, fc->comp_bwdref_prob[ctx_bwd][0]);
        if (counts) ++counts->comp_bwdref[ctx_bwd][0][bit_bwd];
        ref_frame[idx] = cm->comp_bwd_ref[bit_bwd];
      }
533
#else
Jingning Han's avatar
Jingning Han committed
534
      const int idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
535
      const int ctx = av1_get_pred_context_comp_ref_p(cm, xd);
Adrian Grange's avatar
Adrian Grange committed
536
      const int bit = aom_read(r, fc->comp_ref_prob[ctx]);
clang-format's avatar
clang-format committed
537
      if (counts) ++counts->comp_ref[ctx][bit];
Jingning Han's avatar
Jingning Han committed
538 539
      ref_frame[idx] = cm->comp_fixed_ref;
      ref_frame[!idx] = cm->comp_var_ref[bit];
540
#endif  // CONFIG_EXT_REFS
Jingning Han's avatar
Jingning Han committed
541
    } else if (mode == SINGLE_REFERENCE) {
542 543 544 545 546 547 548 549 550 551 552 553 554
#if CONFIG_EXT_REFS
      const int ctx0 = av1_get_pred_context_single_ref_p1(xd);
      const int bit0 = aom_read(r, fc->single_ref_prob[ctx0][0]);
      if (counts) ++counts->single_ref[ctx0][0][bit0];
      if (bit0) {
        const int ctx1 = av1_get_pred_context_single_ref_p2(xd);
        const int bit1 = aom_read(r, fc->single_ref_prob[ctx1][1]);
        if (counts) ++counts->single_ref[ctx1][1][bit1];
        ref_frame[0] = bit1 ? ALTREF_FRAME : BWDREF_FRAME;
      } else {
        const int ctx2 = av1_get_pred_context_single_ref_p3(xd);
        const int bit2 = aom_read(r, fc->single_ref_prob[ctx2][2]);
        if (counts) ++counts->single_ref[ctx2][2][bit2];
555
        if (!bit2) {
556 557 558 559
          const int ctx3 = av1_get_pred_context_single_ref_p4(xd);
          const int bit3 = aom_read(r, fc->single_ref_prob[ctx3][3]);
          if (counts) ++counts->single_ref[ctx3][3][bit3];
          ref_frame[0] = bit3 ? LAST2_FRAME : LAST_FRAME;
560 561 562 563 564
        } else {
          const int ctx4 = av1_get_pred_context_single_ref_p5(xd);
          const int bit4 = aom_read(r, fc->single_ref_prob[ctx4][4]);
          if (counts) ++counts->single_ref[ctx4][4][bit4];
          ref_frame[0] = bit4 ? GOLDEN_FRAME : LAST3_FRAME;
565 566 567
        }
      }
#else
568
      const int ctx0 = av1_get_pred_context_single_ref_p1(xd);
Adrian Grange's avatar
Adrian Grange committed
569
      const int bit0 = aom_read(r, fc->single_ref_prob[ctx0][0]);
clang-format's avatar
clang-format committed
570
      if (counts) ++counts->single_ref[ctx0][0][bit0];
Jingning Han's avatar
Jingning Han committed
571
      if (bit0) {
572
        const int ctx1 = av1_get_pred_context_single_ref_p2(xd);
Adrian Grange's avatar
Adrian Grange committed
573
        const int bit1 = aom_read(r, fc->single_ref_prob[ctx1][1]);
clang-format's avatar
clang-format committed
574
        if (counts) ++counts->single_ref[ctx1][1][bit1];
Jingning Han's avatar
Jingning Han committed
575 576 577 578
        ref_frame[0] = bit1 ? ALTREF_FRAME : GOLDEN_FRAME;
      } else {
        ref_frame[0] = LAST_FRAME;
      }
579
#endif  // CONFIG_EXT_REFS
Jingning Han's avatar
Jingning Han committed
580 581 582 583 584 585 586 587

      ref_frame[1] = NONE;
    } else {
      assert(0 && "Invalid prediction mode.");
    }
  }
}

James Zern's avatar
James Zern committed
588 589 590
static INLINE InterpFilter read_switchable_interp_filter(AV1_COMMON *const cm,
                                                         MACROBLOCKD *const xd,
                                                         aom_reader *r) {
591 592 593 594 595 596
  if (cm->interp_filter == SWITCHABLE) {
#if CONFIG_EXT_INTERP
    if (is_interp_needed(xd))
#endif
    {
      const int ctx = av1_get_pred_context_switchable_interp(xd);
597 598 599 600 601
#if CONFIG_DAALA_EC
      const InterpFilter type =
          (InterpFilter)av1_switchable_interp_inv[aom_read_tree_cdf(
              r, cm->fc->switchable_interp_cdf[ctx], SWITCHABLE_FILTERS)];
#else
602 603
      const InterpFilter type = (InterpFilter)aom_read_tree(
          r, av1_switchable_interp_tree, cm->fc->switchable_interp_prob[ctx]);
604
#endif
605 606 607 608 609 610 611 612
      FRAME_COUNTS *counts = xd->counts;
      if (counts) ++counts->switchable_interp[ctx][type];
      return type;
    }
    return EIGHTTAP;
  } else {
    return cm->interp_filter;
  }
Jingning Han's avatar
Jingning Han committed
613 614
}

615
static void read_intra_block_mode_info(AV1_COMMON *const cm,
Jingning Han's avatar
Jingning Han committed
616
                                       MACROBLOCKD *const xd, MODE_INFO *mi,
Adrian Grange's avatar
Adrian Grange committed
617
                                       aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
618 619 620 621 622 623 624 625 626 627 628 629 630 631
  MB_MODE_INFO *const mbmi = &mi->mbmi;
  const BLOCK_SIZE bsize = mi->mbmi.sb_type;
  int i;

  mbmi->ref_frame[0] = INTRA_FRAME;
  mbmi->ref_frame[1] = NONE;

  switch (bsize) {
    case BLOCK_4X4:
      for (i = 0; i < 4; ++i)
        mi->bmi[i].as_mode = read_intra_mode_y(cm, xd, r, 0);
      mbmi->mode = mi->bmi[3].as_mode;
      break;
    case BLOCK_4X8:
clang-format's avatar
clang-format committed
632
      mi->bmi[0].as_mode = mi->bmi[2].as_mode = read_intra_mode_y(cm, xd, r, 0);
Jingning Han's avatar
Jingning Han committed
633 634 635 636
      mi->bmi[1].as_mode = mi->bmi[3].as_mode = mbmi->mode =
          read_intra_mode_y(cm, xd, r, 0);
      break;
    case BLOCK_8X4:
clang-format's avatar
clang-format committed
637
      mi->bmi[0].as_mode = mi->bmi[1].as_mode = read_intra_mode_y(cm, xd, r, 0);
Jingning Han's avatar
Jingning Han committed
638 639 640 641 642 643 644 645
      mi->bmi[2].as_mode = mi->bmi[3].as_mode = mbmi->mode =
          read_intra_mode_y(cm, xd, r, 0);
      break;
    default:
      mbmi->mode = read_intra_mode_y(cm, xd, r, size_group_lookup[bsize]);
  }

  mbmi->uv_mode = read_intra_mode_uv(cm, xd, r, mbmi->mode);
hui su's avatar
hui su committed
646 647 648
#if CONFIG_EXT_INTRA
  read_intra_angle_info(mbmi, r);
#endif  // CONFIG_EXT_INTRA
Jingning Han's avatar
Jingning Han committed
649 650 651
}

static INLINE int is_mv_valid(const MV *mv) {
clang-format's avatar
clang-format committed
652 653
  return mv->row > MV_LOW && mv->row < MV_UPP && mv->col > MV_LOW &&
         mv->col < MV_UPP;
Jingning Han's avatar
Jingning Han committed
654 655
}

656
static INLINE int assign_mv(AV1_COMMON *cm, MACROBLOCKD *xd,
657
                            PREDICTION_MODE mode, int block, int_mv mv[2],
clang-format's avatar
clang-format committed
658 659
                            int_mv ref_mv[2], int_mv nearest_mv[2],
                            int_mv near_mv[2], int is_compound, int allow_hp,
Adrian Grange's avatar
Adrian Grange committed
660
                            aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
661 662 663
  int i;
  int ret = 1;

664 665 666
#if CONFIG_REF_MV
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
  BLOCK_SIZE bsize = mbmi->sb_type;
clang-format's avatar
clang-format committed
667 668
  int_mv *pred_mv =
      (bsize >= BLOCK_8X8) ? mbmi->pred_mv : xd->mi[0]->bmi[block].pred_mv;
669 670 671 672
#else
  (void)block;
#endif

Jingning Han's avatar
Jingning Han committed
673 674 675
  switch (mode) {
    case NEWMV: {
      FRAME_COUNTS *counts = xd->counts;
676
#if !CONFIG_REF_MV
Jingning Han's avatar
Jingning Han committed
677
      nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
678
#endif
Jingning Han's avatar
Jingning Han committed
679
      for (i = 0; i < 1 + is_compound; ++i) {
680
#if CONFIG_REF_MV
681 682 683 684
        int8_t rf_type = av1_ref_frame_type(mbmi->ref_frame);
        int nmv_ctx =
            av1_nmv_ctx(xd->ref_mv_count[rf_type], xd->ref_mv_stack[rf_type], i,
                        mbmi->ref_mv_idx);
685 686 687 688 689
        nmv_context_counts *const mv_counts =
            counts ? &counts->mv[nmv_ctx] : NULL;
        read_mv(r, &mv[i].as_mv, &ref_mv[i].as_mv, &cm->fc->nmvc[nmv_ctx],
                mv_counts, allow_hp);
#else
Jingning Han's avatar
Jingning Han committed
690 691
        read_mv(r, &mv[i].as_mv, &ref_mv[i].as_mv, &cm->fc->nmvc, mv_counts,
                allow_hp);
692
#endif
Jingning Han's avatar
Jingning Han committed
693
        ret = ret && is_mv_valid(&mv[i].as_mv);
694 695 696
#if CONFIG_REF_MV
        pred_mv[i].as_int = ref_mv[i].as_int;
#endif
Jingning Han's avatar
Jingning Han committed
697 698 699 700 701
      }
      break;
    }
    case NEARESTMV: {
      mv[0].as_int = nearest_mv[0].as_int;
clang-format's avatar
clang-format committed
702
      if (is_compound) mv[1].as_int = nearest_mv[1].as_int;
703 704
#if CONFIG_REF_MV
      pred_mv[0].as_int = nearest_mv[0].as_int;
clang-format's avatar
clang-format committed
705
      if (is_compound) pred_mv[1].as_int = nearest_mv[1].as_int;
706
#endif
Jingning Han's avatar
Jingning Han committed
707 708 709 710
      break;
    }
    case NEARMV: {
      mv[0].as_int = near_mv[0].as_int;
clang-format's avatar
clang-format committed
711
      if (is_compound) mv[1].as_int = near_mv[1].as_int;
712 713
#if CONFIG_REF_MV
      pred_mv[0].as_int = near_mv[0].as_int;
clang-format's avatar
clang-format committed
714
      if (is_compound) pred_mv[1].as_int = near_mv[1].as_int;
715
#endif
Jingning Han's avatar
Jingning Han committed
716 717 718 719
      break;
    }
    case ZEROMV: {
      mv[0].as_int = 0;
clang-format's avatar
clang-format committed
720
      if (is_compound) mv[1].as_int = 0;
721 722
#if CONFIG_REF_MV
      pred_mv[0].as_int = 0;
clang-format's avatar
clang-format committed
723
      if (is_compound) pred_mv[1].as_int = 0;
724
#endif
Jingning Han's avatar
Jingning Han committed
725 726
      break;
    }
clang-format's avatar
clang-format committed
727
    default: { return 0; }
Jingning Han's avatar
Jingning Han committed
728 729 730 731
  }
  return ret;
}

732
static int read_is_inter_block(AV1_COMMON *const cm, MACROBLOCKD *const xd,
Adrian Grange's avatar
Adrian Grange committed
733
                               int segment_id, aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
734 735 736
  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) {
    return get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME) != INTRA_FRAME;
  } else {
737
    const int ctx = av1_get_intra_inter_context(xd);
Adrian Grange's avatar
Adrian Grange committed
738
    const int is_inter = aom_read(r, cm->fc->intra_inter_prob[ctx]);
Jingning Han's avatar
Jingning Han committed
739
    FRAME_COUNTS *counts = xd->counts;
clang-format's avatar
clang-format committed
740
    if (counts) ++counts->intra_inter[ctx][is_inter];
Jingning Han's avatar
Jingning Han committed
741 742 743 744 745
    return is_inter;
  }
}

static void fpm_sync(void *const data, int mi_row) {
746 747
  AV1Decoder *const pbi = (AV1Decoder *)data;
  av1_frameworker_wait(pbi->frame_worker_owner, pbi->common.prev_frame,
748
                       mi_row << MAX_MIB_SIZE_LOG2);
Jingning Han's avatar
Jingning Han committed
749 750
}

751
static void read_inter_block_mode_info(AV1Decoder *const pbi,
Jingning Han's avatar
Jingning Han committed
752
                                       MACROBLOCKD *const xd,
clang-format's avatar
clang-format committed
753
                                       MODE_INFO *const mi, int mi_row,
Adrian Grange's avatar
Adrian Grange committed
754
                                       int mi_col, aom_reader *r) {
755
  AV1_COMMON *const cm = &pbi->common;
Jingning Han's avatar
Jingning Han committed
756 757 758 759
  MB_MODE_INFO *const mbmi = &mi->mbmi;
  const BLOCK_SIZE bsize = mbmi->sb_type;
  const int allow_hp = cm->allow_high_precision_mv;
  int_mv nearestmv[2], nearmv[2];
760
  int_mv ref_mvs[MODE_CTX_REF_FRAMES][MAX_MV_REF_CANDIDATES];
Jingning Han's avatar
Jingning Han committed
761
  int ref, is_compound;
762
  int16_t inter_mode_ctx[MODE_CTX_REF_FRAMES];
763
  int16_t mode_ctx = 0;
Jingning Han's avatar
Jingning Han committed
764 765 766 767 768 769 770 771 772

  read_ref_frames(cm, xd, r, mbmi->segment_id, mbmi->ref_frame);
  is_compound = has_second_ref(mbmi);

  for (ref = 0; ref < 1 + is_compound; ++ref) {
    const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
    RefBuffer *ref_buf = &cm->frame_refs[frame - LAST_FRAME];

    xd->block_refs[ref] = ref_buf;
773
    if ((!av1_is_valid_scale(&ref_buf->sf)))
Adrian Grange's avatar
Adrian Grange committed
774
      aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM,
Jingning Han's avatar
Jingning Han committed
775
                         "Reference frame has invalid dimensions");
776
    av1_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col, &ref_buf->sf);
777

778
    av1_find_mv_refs(cm, xd, mi, frame,
779
#if CONFIG_REF_MV
780
                     &xd->ref_mv_count[frame], xd->ref_mv_stack[frame],
781
#endif
782
                     ref_mvs[frame], mi_row, mi_col, fpm_sync, (void *)pbi,
clang-format's avatar
clang-format committed
783
                     inter_mode_ctx);
Jingning Han's avatar
Jingning Han committed
784 785
  }

786
#if CONFIG_REF_MV
787 788 789
  if (is_compound) {
    MV_REFERENCE_FRAME ref_frame;
    ref_frame = av1_ref_frame_type(mbmi->ref_frame);
clang-format's avatar
clang-format committed
790 791 792
    av1_find_mv_refs(cm, xd, mi, ref_frame, &xd->ref_mv_count[ref_frame],
                     xd->ref_mv_stack[ref_frame], ref_mvs[ref_frame], mi_row,
                     mi_col, fpm_sync, (void *)pbi, inter_mode_ctx);
793 794 795 796 797 798 799 800 801 802 803 804 805 806

    if (xd->ref_mv_count[ref_frame] < 2) {
      MV_REFERENCE_FRAME rf[2];
      av1_set_ref_frame(rf, ref_frame);
      for (ref = 0; ref < 2; ++ref) {
        lower_mv_precision(&ref_mvs[rf[ref]][0].as_mv, allow_hp);
        lower_mv_precision(&ref_mvs[rf[ref]][1].as_mv, allow_hp);
      }

      if (ref_mvs[rf[0]][0].as_int != 0 || ref_mvs[rf[0]][1].as_int != 0 ||
          ref_mvs[rf[1]][0].as_int != 0 || ref_mvs[rf[1]][1].as_int != 0)
        inter_mode_ctx[ref_frame] &= ~(1 << ALL_ZERO_FLAG_OFFSET);
    }
  }
807

clang-format's avatar
clang-format committed
808 809
  mode_ctx =
      av1_mode_context_analyzer(inter_mode_ctx, mbmi->ref_frame, bsize, -1);
810
  mbmi->ref_mv_idx = 0;
811 812
#else
  mode_ctx = inter_mode_ctx[mbmi->ref_frame[0]];
813 814
#endif

Jingning Han's avatar
Jingning Han committed
815 816 817
  if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
    mbmi->mode = ZEROMV;
    if (bsize < BLOCK_8X8) {
Adrian Grange's avatar
Adrian Grange committed
818
      aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM,
819
                         "Invalid usage of segment feature on small blocks");
clang-format's avatar
clang-format committed
820
      return;
Jingning Han's avatar
Jingning Han committed
821 822
    }
  } else {
823 824 825
    if (bsize >= BLOCK_8X8) {
      mbmi->mode = read_inter_mode(cm, xd, r, mode_ctx);
#if CONFIG_REF_MV
826
      if (mbmi->mode == NEARMV || mbmi->mode == NEWMV)
827
        read_drl_idx(cm, xd, mbmi, r);
828 829
#endif
    }
Jingning Han's avatar
Jingning Han committed
830 831 832 833
  }

  if (bsize < BLOCK_8X8 || mbmi->mode != ZEROMV) {
    for (ref = 0; ref < 1 + is_compound; ++ref) {
834
      av1_find_best_ref_mvs(allow_hp, ref_mvs[mbmi->ref_frame[ref]],
clang-format's avatar
clang-format committed
835
                            &nearestmv[ref], &nearmv[ref]);
Jingning Han's avatar
Jingning Han committed
836 837 838
    }
  }

839
#if CONFIG_REF_MV
840 841 842
  if (mbmi->ref_mv_idx > 0) {
    int_mv cur_mv =
        xd->ref_mv_stack[mbmi->ref_frame[0]][1 + mbmi->ref_mv_idx].this_mv;
843 844 845 846
    lower_mv_precision(&cur_mv.as_mv, cm->allow_high_precision_mv);
    nearmv[0] = cur_mv;
  }

847 848 849 850 851 852 853 854 855
  if (is_compound && bsize >= BLOCK_8X8 && mbmi->mode != NEWMV &&
      mbmi->mode != ZEROMV) {
    uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);

    if (xd->ref_mv_count[ref_frame_type] == 1 && mbmi->mode == NEARESTMV) {
      int i;
      nearestmv[0] = xd->ref_mv_stack[ref_frame_type][0].this_mv;
      nearestmv[1] = xd->ref_mv_stack[ref_frame_type][0].comp_mv;

clang-format's avatar
clang-format committed
856
      for (i = 0; i < 2; ++i) lower_mv_precision(&nearestmv[i].as_mv, allow_hp);
857 858 859 860
    }

    if (xd->ref_mv_count[ref_frame_type] > 1) {
      int i;
861
      const int ref_mv_idx = 1 + mbmi->ref_mv_idx;
862 863
      nearestmv[0] = xd->ref_mv_stack[ref_frame_type][0].this_mv;
      nearestmv[1] = xd->ref_mv_stack[ref_frame_type][0].comp_mv;
864 865
      nearmv[0] = xd->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
      nearmv[1] = xd->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
866

867
      for (i = 0; i < 2; ++i) {
868 869 870 871 872 873 874
        lower_mv_precision(&nearestmv[i].as_mv, allow_hp);
        lower_mv_precision(&nearmv[i].as_mv, allow_hp);
      }
    }
  }
#endif

875 876 877
#if !CONFIG_EXT_INTERP
  mbmi->interp_filter = read_switchable_interp_filter(cm, xd, r);
#endif  // CONFIG_EXT_INTERP
Jingning Han's avatar
Jingning Han committed
878 879 880 881 882 883 884 885 886 887 888

  if (bsize < BLOCK_8X8) {
    const int num_4x4_w = 1 << xd->bmode_blocks_wl;
    const int num_4x4_h = 1 << xd->bmode_blocks_hl;
    int idx, idy;
    PREDICTION_MODE b_mode;
    int_mv nearest_sub8x8[2], near_sub8x8[2];
    for (idy = 0; idy < 2; idy += num_4x4_h) {
      for (idx = 0; idx < 2; idx += num_4x4_w) {
        int_mv block[2];
        const int j = idy * 2 + idx;
889
#if CONFIG_REF_MV
clang-format's avatar
clang-format committed
890
        mode_ctx = av1_mode_context_analyzer(inter_mode_ctx, mbmi->ref_frame,
891 892
                                             bsize, j);
#endif
893
        b_mode = read_inter_mode(cm, xd, r, mode_ctx);
Jingning Han's avatar
Jingning Han committed
894 895 896

        if (b_mode == NEARESTMV || b_mode == NEARMV) {
          for (ref = 0; ref < 1 + is_compound; ++ref)
897
            av1_append_sub8x8_mvs_for_idx(cm, xd, j, ref, mi_row, mi_col,
clang-format's avatar
clang-format committed
898 899
                                          &nearest_sub8x8[ref],
                                          &near_sub8x8[ref]);
Jingning Han's avatar
Jingning Han committed
900 901
        }