decodeframe.c 87.8 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <assert.h>
#include <stdlib.h>  // qsort()

#include "./vp10_rtcd.h"
#include "./vpx_dsp_rtcd.h"
#include "./vpx_scale_rtcd.h"

#include "vpx_dsp/bitreader_buffer.h"
#include "vpx_dsp/bitreader.h"
20
#include "vpx_dsp/vpx_dsp_common.h"
Jingning Han's avatar
Jingning Han committed
21
22
23
24
25
26
#include "vpx_mem/vpx_mem.h"
#include "vpx_ports/mem.h"
#include "vpx_ports/mem_ops.h"
#include "vpx_scale/vpx_scale.h"
#include "vpx_util/vpx_thread.h"

27
#include "vp10/common/alloccommon.h"
Yaowu Xu's avatar
Yaowu Xu committed
28
29
30
#if CONFIG_CLPF
#include "vp10/common/clpf.h"
#endif
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include "vp10/common/common.h"
#include "vp10/common/entropy.h"
#include "vp10/common/entropymode.h"
#include "vp10/common/idct.h"
#include "vp10/common/thread_common.h"
#include "vp10/common/pred_common.h"
#include "vp10/common/quant_common.h"
#include "vp10/common/reconintra.h"
#include "vp10/common/reconinter.h"
#include "vp10/common/seg_common.h"
#include "vp10/common/tile_common.h"

#include "vp10/decoder/decodeframe.h"
#include "vp10/decoder/detokenize.h"
#include "vp10/decoder/decodemv.h"
#include "vp10/decoder/decoder.h"
#include "vp10/decoder/dsubexp.h"
Jingning Han's avatar
Jingning Han committed
48

49
#define MAX_VP10_HEADER_SIZE 80
Jingning Han's avatar
Jingning Han committed
50

Yaowu Xu's avatar
Yaowu Xu committed
51
static int is_compound_reference_allowed(const VP10_COMMON *cm) {
Jingning Han's avatar
Jingning Han committed
52
  int i;
clang-format's avatar
clang-format committed
53
  if (frame_is_intra_only(cm)) return 0;
Jingning Han's avatar
Jingning Han committed
54
  for (i = 1; i < REFS_PER_FRAME; ++i)
clang-format's avatar
clang-format committed
55
    if (cm->ref_frame_sign_bias[i + 1] != cm->ref_frame_sign_bias[1]) return 1;
Jingning Han's avatar
Jingning Han committed
56
57
58
59

  return 0;
}

Yaowu Xu's avatar
Yaowu Xu committed
60
static void setup_compound_reference_mode(VP10_COMMON *cm) {
Jingning Han's avatar
Jingning Han committed
61
  if (cm->ref_frame_sign_bias[LAST_FRAME] ==
clang-format's avatar
clang-format committed
62
      cm->ref_frame_sign_bias[GOLDEN_FRAME]) {
Jingning Han's avatar
Jingning Han committed
63
64
65
66
    cm->comp_fixed_ref = ALTREF_FRAME;
    cm->comp_var_ref[0] = LAST_FRAME;
    cm->comp_var_ref[1] = GOLDEN_FRAME;
  } else if (cm->ref_frame_sign_bias[LAST_FRAME] ==
clang-format's avatar
clang-format committed
67
             cm->ref_frame_sign_bias[ALTREF_FRAME]) {
Jingning Han's avatar
Jingning Han committed
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
    cm->comp_fixed_ref = GOLDEN_FRAME;
    cm->comp_var_ref[0] = LAST_FRAME;
    cm->comp_var_ref[1] = ALTREF_FRAME;
  } else {
    cm->comp_fixed_ref = LAST_FRAME;
    cm->comp_var_ref[0] = GOLDEN_FRAME;
    cm->comp_var_ref[1] = ALTREF_FRAME;
  }
}

static int read_is_valid(const uint8_t *start, size_t len, const uint8_t *end) {
  return len != 0 && len <= (size_t)(end - start);
}

static int decode_unsigned_max(struct vpx_read_bit_buffer *rb, int max) {
  const int data = vpx_rb_read_literal(rb, get_unsigned_bits(max));
  return data > max ? max : data;
}

87
88
89
90
91
#if CONFIG_MISC_FIXES
static TX_MODE read_tx_mode(struct vpx_read_bit_buffer *rb) {
  return vpx_rb_read_bit(rb) ? TX_MODE_SELECT : vpx_rb_read_literal(rb, 2);
}
#else
Jingning Han's avatar
Jingning Han committed
92
93
static TX_MODE read_tx_mode(vpx_reader *r) {
  TX_MODE tx_mode = vpx_read_literal(r, 2);
clang-format's avatar
clang-format committed
94
  if (tx_mode == ALLOW_32X32) tx_mode += vpx_read_bit(r);
Jingning Han's avatar
Jingning Han committed
95
96
  return tx_mode;
}
97
#endif
Jingning Han's avatar
Jingning Han committed
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

static void read_tx_mode_probs(struct tx_probs *tx_probs, vpx_reader *r) {
  int i, j;

  for (i = 0; i < TX_SIZE_CONTEXTS; ++i)
    for (j = 0; j < TX_SIZES - 3; ++j)
      vp10_diff_update_prob(r, &tx_probs->p8x8[i][j]);

  for (i = 0; i < TX_SIZE_CONTEXTS; ++i)
    for (j = 0; j < TX_SIZES - 2; ++j)
      vp10_diff_update_prob(r, &tx_probs->p16x16[i][j]);

  for (i = 0; i < TX_SIZE_CONTEXTS; ++i)
    for (j = 0; j < TX_SIZES - 1; ++j)
      vp10_diff_update_prob(r, &tx_probs->p32x32[i][j]);
}

static void read_switchable_interp_probs(FRAME_CONTEXT *fc, vpx_reader *r) {
  int i, j;
  for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j)
    for (i = 0; i < SWITCHABLE_FILTERS - 1; ++i)
      vp10_diff_update_prob(r, &fc->switchable_interp_prob[j][i]);
}

static void read_inter_mode_probs(FRAME_CONTEXT *fc, vpx_reader *r) {
  int i, j;
  for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
    for (j = 0; j < INTER_MODES - 1; ++j)
      vp10_diff_update_prob(r, &fc->inter_mode_probs[i][j]);
}

129
#if CONFIG_MISC_FIXES
clang-format's avatar
clang-format committed
130
131
static REFERENCE_MODE read_frame_reference_mode(
    const VP10_COMMON *cm, struct vpx_read_bit_buffer *rb) {
132
  if (is_compound_reference_allowed(cm)) {
clang-format's avatar
clang-format committed
133
134
135
    return vpx_rb_read_bit(rb)
               ? REFERENCE_MODE_SELECT
               : (vpx_rb_read_bit(rb) ? COMPOUND_REFERENCE : SINGLE_REFERENCE);
136
137
138
139
140
  } else {
    return SINGLE_REFERENCE;
  }
}
#else
Yaowu Xu's avatar
Yaowu Xu committed
141
static REFERENCE_MODE read_frame_reference_mode(const VP10_COMMON *cm,
Jingning Han's avatar
Jingning Han committed
142
143
                                                vpx_reader *r) {
  if (is_compound_reference_allowed(cm)) {
clang-format's avatar
clang-format committed
144
145
146
    return vpx_read_bit(r)
               ? (vpx_read_bit(r) ? REFERENCE_MODE_SELECT : COMPOUND_REFERENCE)
               : SINGLE_REFERENCE;
Jingning Han's avatar
Jingning Han committed
147
148
149
150
  } else {
    return SINGLE_REFERENCE;
  }
}
151
#endif
Jingning Han's avatar
Jingning Han committed
152

Yaowu Xu's avatar
Yaowu Xu committed
153
static void read_frame_reference_mode_probs(VP10_COMMON *cm, vpx_reader *r) {
Jingning Han's avatar
Jingning Han committed
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
  FRAME_CONTEXT *const fc = cm->fc;
  int i;

  if (cm->reference_mode == REFERENCE_MODE_SELECT)
    for (i = 0; i < COMP_INTER_CONTEXTS; ++i)
      vp10_diff_update_prob(r, &fc->comp_inter_prob[i]);

  if (cm->reference_mode != COMPOUND_REFERENCE)
    for (i = 0; i < REF_CONTEXTS; ++i) {
      vp10_diff_update_prob(r, &fc->single_ref_prob[i][0]);
      vp10_diff_update_prob(r, &fc->single_ref_prob[i][1]);
    }

  if (cm->reference_mode != SINGLE_REFERENCE)
    for (i = 0; i < REF_CONTEXTS; ++i)
      vp10_diff_update_prob(r, &fc->comp_ref_prob[i]);
}

static void update_mv_probs(vpx_prob *p, int n, vpx_reader *r) {
  int i;
  for (i = 0; i < n; ++i)
175
176
177
#if CONFIG_MISC_FIXES
    vp10_diff_update_prob(r, &p[i]);
#else
clang-format's avatar
clang-format committed
178
    if (vpx_read(r, MV_UPDATE_PROB)) p[i] = (vpx_read_literal(r, 7) << 1) | 1;
179
#endif
Jingning Han's avatar
Jingning Han committed
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
}

static void read_mv_probs(nmv_context *ctx, int allow_hp, vpx_reader *r) {
  int i, j;

  update_mv_probs(ctx->joints, MV_JOINTS - 1, r);

  for (i = 0; i < 2; ++i) {
    nmv_component *const comp_ctx = &ctx->comps[i];
    update_mv_probs(&comp_ctx->sign, 1, r);
    update_mv_probs(comp_ctx->classes, MV_CLASSES - 1, r);
    update_mv_probs(comp_ctx->class0, CLASS0_SIZE - 1, r);
    update_mv_probs(comp_ctx->bits, MV_OFFSET_BITS, r);
  }

  for (i = 0; i < 2; ++i) {
    nmv_component *const comp_ctx = &ctx->comps[i];
    for (j = 0; j < CLASS0_SIZE; ++j)
      update_mv_probs(comp_ctx->class0_fp[j], MV_FP_SIZE - 1, r);
    update_mv_probs(comp_ctx->fp, 3, r);
  }

  if (allow_hp) {
    for (i = 0; i < 2; ++i) {
      nmv_component *const comp_ctx = &ctx->comps[i];
      update_mv_probs(&comp_ctx->class0_hp, 1, r);
      update_mv_probs(&comp_ctx->hp, 1, r);
    }
  }
}

clang-format's avatar
clang-format committed
211
212
213
static void inverse_transform_block_inter(MACROBLOCKD *xd, int plane,
                                          const TX_SIZE tx_size, uint8_t *dst,
                                          int stride, int eob, int block) {
Jingning Han's avatar
Jingning Han committed
214
  struct macroblockd_plane *const pd = &xd->plane[plane];
hui su's avatar
hui su committed
215
  TX_TYPE tx_type = get_tx_type(pd->plane_type, xd, block);
216
  const int seg_id = xd->mi[0]->mbmi.segment_id;
Jingning Han's avatar
Jingning Han committed
217
218
  if (eob > 0) {
    tran_low_t *const dqcoeff = pd->dqcoeff;
219
#if CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
220
    if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
hui su's avatar
hui su committed
221
222
223
      switch (tx_size) {
        case TX_4X4:
          vp10_highbd_inv_txfm_add_4x4(dqcoeff, dst, stride, eob, xd->bd,
224
                                       tx_type, xd->lossless[seg_id]);
hui su's avatar
hui su committed
225
226
227
228
229
230
231
232
233
234
235
236
237
          break;
        case TX_8X8:
          vp10_highbd_inv_txfm_add_8x8(dqcoeff, dst, stride, eob, xd->bd,
                                       tx_type);
          break;
        case TX_16X16:
          vp10_highbd_inv_txfm_add_16x16(dqcoeff, dst, stride, eob, xd->bd,
                                         tx_type);
          break;
        case TX_32X32:
          vp10_highbd_inv_txfm_add_32x32(dqcoeff, dst, stride, eob, xd->bd,
                                         tx_type);
          break;
clang-format's avatar
clang-format committed
238
        default: assert(0 && "Invalid transform size"); return;
Jingning Han's avatar
Jingning Han committed
239
240
      }
    } else {
241
#endif  // CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
242
243
      switch (tx_size) {
        case TX_4X4:
hui su's avatar
hui su committed
244
          vp10_inv_txfm_add_4x4(dqcoeff, dst, stride, eob, tx_type,
245
                                xd->lossless[seg_id]);
Jingning Han's avatar
Jingning Han committed
246
247
          break;
        case TX_8X8:
hui su's avatar
hui su committed
248
          vp10_inv_txfm_add_8x8(dqcoeff, dst, stride, eob, tx_type);
Jingning Han's avatar
Jingning Han committed
249
250
          break;
        case TX_16X16:
hui su's avatar
hui su committed
251
          vp10_inv_txfm_add_16x16(dqcoeff, dst, stride, eob, tx_type);
Jingning Han's avatar
Jingning Han committed
252
253
          break;
        case TX_32X32:
hui su's avatar
hui su committed
254
          vp10_inv_txfm_add_32x32(dqcoeff, dst, stride, eob, tx_type);
Jingning Han's avatar
Jingning Han committed
255
          break;
clang-format's avatar
clang-format committed
256
        default: assert(0 && "Invalid transform size"); return;
Jingning Han's avatar
Jingning Han committed
257
      }
258
#if CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
259
    }
260
#endif  // CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
261
262
263
264

    if (eob == 1) {
      dqcoeff[0] = 0;
    } else {
265
      if (tx_type == DCT_DCT && tx_size <= TX_16X16 && eob <= 10)
Jingning Han's avatar
Jingning Han committed
266
267
268
269
270
271
272
273
274
        memset(dqcoeff, 0, 4 * (4 << tx_size) * sizeof(dqcoeff[0]));
      else if (tx_size == TX_32X32 && eob <= 34)
        memset(dqcoeff, 0, 256 * sizeof(dqcoeff[0]));
      else
        memset(dqcoeff, 0, (16 << (tx_size << 1)) * sizeof(dqcoeff[0]));
    }
  }
}

clang-format's avatar
clang-format committed
275
static void inverse_transform_block_intra(MACROBLOCKD *xd, int plane,
Jingning Han's avatar
Jingning Han committed
276
                                          const TX_TYPE tx_type,
clang-format's avatar
clang-format committed
277
278
                                          const TX_SIZE tx_size, uint8_t *dst,
                                          int stride, int eob) {
Jingning Han's avatar
Jingning Han committed
279
  struct macroblockd_plane *const pd = &xd->plane[plane];
280
  const int seg_id = xd->mi[0]->mbmi.segment_id;
Jingning Han's avatar
Jingning Han committed
281
282
  if (eob > 0) {
    tran_low_t *const dqcoeff = pd->dqcoeff;
283
#if CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
284
    if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
hui su's avatar
hui su committed
285
286
287
      switch (tx_size) {
        case TX_4X4:
          vp10_highbd_inv_txfm_add_4x4(dqcoeff, dst, stride, eob, xd->bd,
288
                                       tx_type, xd->lossless[seg_id]);
hui su's avatar
hui su committed
289
290
291
292
293
294
295
296
297
298
299
300
301
          break;
        case TX_8X8:
          vp10_highbd_inv_txfm_add_8x8(dqcoeff, dst, stride, eob, xd->bd,
                                       tx_type);
          break;
        case TX_16X16:
          vp10_highbd_inv_txfm_add_16x16(dqcoeff, dst, stride, eob, xd->bd,
                                         tx_type);
          break;
        case TX_32X32:
          vp10_highbd_inv_txfm_add_32x32(dqcoeff, dst, stride, eob, xd->bd,
                                         tx_type);
          break;
clang-format's avatar
clang-format committed
302
        default: assert(0 && "Invalid transform size"); return;
Jingning Han's avatar
Jingning Han committed
303
304
      }
    } else {
305
#endif  // CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
306
307
      switch (tx_size) {
        case TX_4X4:
hui su's avatar
hui su committed
308
          vp10_inv_txfm_add_4x4(dqcoeff, dst, stride, eob, tx_type,
309
                                xd->lossless[seg_id]);
Jingning Han's avatar
Jingning Han committed
310
311
          break;
        case TX_8X8:
hui su's avatar
hui su committed
312
          vp10_inv_txfm_add_8x8(dqcoeff, dst, stride, eob, tx_type);
Jingning Han's avatar
Jingning Han committed
313
314
          break;
        case TX_16X16:
hui su's avatar
hui su committed
315
          vp10_inv_txfm_add_16x16(dqcoeff, dst, stride, eob, tx_type);
Jingning Han's avatar
Jingning Han committed
316
317
          break;
        case TX_32X32:
hui su's avatar
hui su committed
318
          vp10_inv_txfm_add_32x32(dqcoeff, dst, stride, eob, tx_type);
Jingning Han's avatar
Jingning Han committed
319
          break;
clang-format's avatar
clang-format committed
320
        default: assert(0 && "Invalid transform size"); return;
Jingning Han's avatar
Jingning Han committed
321
      }
322
#if CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
323
    }
324
#endif  // CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341

    if (eob == 1) {
      dqcoeff[0] = 0;
    } else {
      if (tx_type == DCT_DCT && tx_size <= TX_16X16 && eob <= 10)
        memset(dqcoeff, 0, 4 * (4 << tx_size) * sizeof(dqcoeff[0]));
      else if (tx_size == TX_32X32 && eob <= 34)
        memset(dqcoeff, 0, 256 * sizeof(dqcoeff[0]));
      else
        memset(dqcoeff, 0, (16 << (tx_size << 1)) * sizeof(dqcoeff[0]));
    }
  }
}

static void predict_and_reconstruct_intra_block(MACROBLOCKD *const xd,
                                                vpx_reader *r,
                                                MB_MODE_INFO *const mbmi,
clang-format's avatar
clang-format committed
342
                                                int plane, int row, int col,
Jingning Han's avatar
Jingning Han committed
343
344
345
                                                TX_SIZE tx_size) {
  struct macroblockd_plane *const pd = &xd->plane[plane];
  PREDICTION_MODE mode = (plane == 0) ? mbmi->mode : mbmi->uv_mode;
hui su's avatar
hui su committed
346
  PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
Jingning Han's avatar
Jingning Han committed
347
  uint8_t *dst;
hui su's avatar
hui su committed
348
  int block_idx = (row << 1) + col;
Jingning Han's avatar
Jingning Han committed
349
350
351
  dst = &pd->dst.buf[4 * row * pd->dst.stride + 4 * col];

  if (mbmi->sb_type < BLOCK_8X8)
clang-format's avatar
clang-format committed
352
    if (plane == 0) mode = xd->mi[0]->bmi[(row << 1) + col].as_mode;
Jingning Han's avatar
Jingning Han committed
353

clang-format's avatar
clang-format committed
354
355
356
  vp10_predict_intra_block(xd, pd->n4_wl, pd->n4_hl, tx_size, mode, dst,
                           pd->dst.stride, dst, pd->dst.stride, col, row,
                           plane);
Jingning Han's avatar
Jingning Han committed
357
358

  if (!mbmi->skip) {
hui su's avatar
hui su committed
359
360
    TX_TYPE tx_type = get_tx_type(plane_type, xd, block_idx);
    const scan_order *sc = get_scan(tx_size, tx_type);
Jingning Han's avatar
Jingning Han committed
361
    const int eob = vp10_decode_block_tokens(xd, plane, sc, col, row, tx_size,
hui su's avatar
hui su committed
362
                                             r, mbmi->segment_id);
clang-format's avatar
clang-format committed
363
364
    inverse_transform_block_intra(xd, plane, tx_type, tx_size, dst,
                                  pd->dst.stride, eob);
Jingning Han's avatar
Jingning Han committed
365
366
367
368
  }
}

static int reconstruct_inter_block(MACROBLOCKD *const xd, vpx_reader *r,
clang-format's avatar
clang-format committed
369
370
                                   MB_MODE_INFO *const mbmi, int plane, int row,
                                   int col, TX_SIZE tx_size) {
Jingning Han's avatar
Jingning Han committed
371
  struct macroblockd_plane *const pd = &xd->plane[plane];
hui su's avatar
hui su committed
372
373
374
375
  PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
  int block_idx = (row << 1) + col;
  TX_TYPE tx_type = get_tx_type(plane_type, xd, block_idx);
  const scan_order *sc = get_scan(tx_size, tx_type);
Jingning Han's avatar
Jingning Han committed
376
  const int eob = vp10_decode_block_tokens(xd, plane, sc, col, row, tx_size, r,
clang-format's avatar
clang-format committed
377
                                           mbmi->segment_id);
Jingning Han's avatar
Jingning Han committed
378

clang-format's avatar
clang-format committed
379
380
381
  inverse_transform_block_inter(
      xd, plane, tx_size, &pd->dst.buf[4 * row * pd->dst.stride + 4 * col],
      pd->dst.stride, eob, block_idx);
Jingning Han's avatar
Jingning Han committed
382
383
384
  return eob;
}

clang-format's avatar
clang-format committed
385
386
387
static void build_mc_border(const uint8_t *src, int src_stride, uint8_t *dst,
                            int dst_stride, int x, int y, int b_w, int b_h,
                            int w, int h) {
Jingning Han's avatar
Jingning Han committed
388
389
390
391
392
393
394
395
396
397
398
399
  // Get a pointer to the start of the real data for this row.
  const uint8_t *ref_row = src - x - y * src_stride;

  if (y >= h)
    ref_row += (h - 1) * src_stride;
  else if (y > 0)
    ref_row += y * src_stride;

  do {
    int right = 0, copy;
    int left = x < 0 ? -x : 0;

clang-format's avatar
clang-format committed
400
    if (left > b_w) left = b_w;
Jingning Han's avatar
Jingning Han committed
401

clang-format's avatar
clang-format committed
402
    if (x + b_w > w) right = x + b_w - w;
Jingning Han's avatar
Jingning Han committed
403

clang-format's avatar
clang-format committed
404
    if (right > b_w) right = b_w;
Jingning Han's avatar
Jingning Han committed
405
406
407

    copy = b_w - left - right;

clang-format's avatar
clang-format committed
408
    if (left) memset(dst, ref_row[0], left);
Jingning Han's avatar
Jingning Han committed
409

clang-format's avatar
clang-format committed
410
    if (copy) memcpy(dst + left, ref_row + x + left, copy);
Jingning Han's avatar
Jingning Han committed
411

clang-format's avatar
clang-format committed
412
    if (right) memset(dst + left + copy, ref_row[w - 1], right);
Jingning Han's avatar
Jingning Han committed
413
414
415
416

    dst += dst_stride;
    ++y;

clang-format's avatar
clang-format committed
417
    if (y > 0 && y < h) ref_row += src_stride;
Jingning Han's avatar
Jingning Han committed
418
419
420
  } while (--b_h);
}

421
#if CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
422
static void high_build_mc_border(const uint8_t *src8, int src_stride,
clang-format's avatar
clang-format committed
423
424
                                 uint16_t *dst, int dst_stride, int x, int y,
                                 int b_w, int b_h, int w, int h) {
Jingning Han's avatar
Jingning Han committed
425
426
427
428
429
430
431
432
433
434
435
436
437
  // Get a pointer to the start of the real data for this row.
  const uint16_t *src = CONVERT_TO_SHORTPTR(src8);
  const uint16_t *ref_row = src - x - y * src_stride;

  if (y >= h)
    ref_row += (h - 1) * src_stride;
  else if (y > 0)
    ref_row += y * src_stride;

  do {
    int right = 0, copy;
    int left = x < 0 ? -x : 0;

clang-format's avatar
clang-format committed
438
    if (left > b_w) left = b_w;
Jingning Han's avatar
Jingning Han committed
439

clang-format's avatar
clang-format committed
440
    if (x + b_w > w) right = x + b_w - w;
Jingning Han's avatar
Jingning Han committed
441

clang-format's avatar
clang-format committed
442
    if (right > b_w) right = b_w;
Jingning Han's avatar
Jingning Han committed
443
444
445

    copy = b_w - left - right;

clang-format's avatar
clang-format committed
446
    if (left) vpx_memset16(dst, ref_row[0], left);
Jingning Han's avatar
Jingning Han committed
447

clang-format's avatar
clang-format committed
448
    if (copy) memcpy(dst + left, ref_row + x + left, copy * sizeof(uint16_t));
Jingning Han's avatar
Jingning Han committed
449

clang-format's avatar
clang-format committed
450
    if (right) vpx_memset16(dst + left + copy, ref_row[w - 1], right);
Jingning Han's avatar
Jingning Han committed
451
452
453
454

    dst += dst_stride;
    ++y;

clang-format's avatar
clang-format committed
455
    if (y > 0 && y < h) ref_row += src_stride;
Jingning Han's avatar
Jingning Han committed
456
457
  } while (--b_h);
}
458
#endif  // CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
459

460
#if CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
461
462
463
static void extend_and_predict(const uint8_t *buf_ptr1, int pre_buf_stride,
                               int x0, int y0, int b_w, int b_h,
                               int frame_width, int frame_height,
clang-format's avatar
clang-format committed
464
465
                               int border_offset, uint8_t *const dst,
                               int dst_buf_stride, int subpel_x, int subpel_y,
Jingning Han's avatar
Jingning Han committed
466
                               const InterpKernel *kernel,
clang-format's avatar
clang-format committed
467
                               const struct scale_factors *sf, MACROBLOCKD *xd,
Jingning Han's avatar
Jingning Han committed
468
469
470
471
472
                               int w, int h, int ref, int xs, int ys) {
  DECLARE_ALIGNED(16, uint16_t, mc_buf_high[80 * 2 * 80 * 2]);
  const uint8_t *buf_ptr;

  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
clang-format's avatar
clang-format committed
473
474
    high_build_mc_border(buf_ptr1, pre_buf_stride, mc_buf_high, b_w, x0, y0,
                         b_w, b_h, frame_width, frame_height);
Jingning Han's avatar
Jingning Han committed
475
476
    buf_ptr = CONVERT_TO_BYTEPTR(mc_buf_high) + border_offset;
  } else {
clang-format's avatar
clang-format committed
477
478
    build_mc_border(buf_ptr1, pre_buf_stride, (uint8_t *)mc_buf_high, b_w, x0,
                    y0, b_w, b_h, frame_width, frame_height);
Jingning Han's avatar
Jingning Han committed
479
480
481
482
    buf_ptr = ((uint8_t *)mc_buf_high) + border_offset;
  }

  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
clang-format's avatar
clang-format committed
483
484
    high_inter_predictor(buf_ptr, b_w, dst, dst_buf_stride, subpel_x, subpel_y,
                         sf, w, h, ref, kernel, xs, ys, xd->bd);
Jingning Han's avatar
Jingning Han committed
485
  } else {
clang-format's avatar
clang-format committed
486
487
    inter_predictor(buf_ptr, b_w, dst, dst_buf_stride, subpel_x, subpel_y, sf,
                    w, h, ref, kernel, xs, ys);
Jingning Han's avatar
Jingning Han committed
488
489
490
491
492
493
  }
}
#else
static void extend_and_predict(const uint8_t *buf_ptr1, int pre_buf_stride,
                               int x0, int y0, int b_w, int b_h,
                               int frame_width, int frame_height,
clang-format's avatar
clang-format committed
494
495
                               int border_offset, uint8_t *const dst,
                               int dst_buf_stride, int subpel_x, int subpel_y,
Jingning Han's avatar
Jingning Han committed
496
                               const InterpKernel *kernel,
clang-format's avatar
clang-format committed
497
498
                               const struct scale_factors *sf, int w, int h,
                               int ref, int xs, int ys) {
Jingning Han's avatar
Jingning Han committed
499
500
501
  DECLARE_ALIGNED(16, uint8_t, mc_buf[80 * 2 * 80 * 2]);
  const uint8_t *buf_ptr;

clang-format's avatar
clang-format committed
502
503
  build_mc_border(buf_ptr1, pre_buf_stride, mc_buf, b_w, x0, y0, b_w, b_h,
                  frame_width, frame_height);
Jingning Han's avatar
Jingning Han committed
504
505
  buf_ptr = mc_buf + border_offset;

clang-format's avatar
clang-format committed
506
507
  inter_predictor(buf_ptr, b_w, dst, dst_buf_stride, subpel_x, subpel_y, sf, w,
                  h, ref, kernel, xs, ys);
Jingning Han's avatar
Jingning Han committed
508
}
509
#endif  // CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
510

clang-format's avatar
clang-format committed
511
512
513
514
515
516
static void dec_build_inter_predictors(
    VP10Decoder *const pbi, MACROBLOCKD *xd, int plane, int bw, int bh, int x,
    int y, int w, int h, int mi_x, int mi_y, const InterpKernel *kernel,
    const struct scale_factors *sf, struct buf_2d *pre_buf,
    struct buf_2d *dst_buf, const MV *mv, RefCntBuffer *ref_frame_buf,
    int is_scaled, int ref) {
517
  VP10_COMMON *const cm = &pbi->common;
Jingning Han's avatar
Jingning Han committed
518
519
520
  struct macroblockd_plane *const pd = &xd->plane[plane];
  uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x;
  MV32 scaled_mv;
clang-format's avatar
clang-format committed
521
522
  int xs, ys, x0, y0, x0_16, y0_16, frame_width, frame_height, buf_stride,
      subpel_x, subpel_y;
Jingning Han's avatar
Jingning Han committed
523
524
525
526
527
528
529
530
531
532
  uint8_t *ref_frame, *buf_ptr;

  // Get reference frame pointer, width and height.
  if (plane == 0) {
    frame_width = ref_frame_buf->buf.y_crop_width;
    frame_height = ref_frame_buf->buf.y_crop_height;
    ref_frame = ref_frame_buf->buf.y_buffer;
  } else {
    frame_width = ref_frame_buf->buf.uv_crop_width;
    frame_height = ref_frame_buf->buf.uv_crop_height;
clang-format's avatar
clang-format committed
533
534
    ref_frame =
        plane == 1 ? ref_frame_buf->buf.u_buffer : ref_frame_buf->buf.v_buffer;
Jingning Han's avatar
Jingning Han committed
535
536
537
  }

  if (is_scaled) {
clang-format's avatar
clang-format committed
538
539
    const MV mv_q4 = clamp_mv_to_umv_border_sb(
        xd, mv, bw, bh, pd->subsampling_x, pd->subsampling_y);
Jingning Han's avatar
Jingning Han committed
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
    // Co-ordinate of containing block to pixel precision.
    int x_start = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x));
    int y_start = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y));

    // Co-ordinate of the block to 1/16th pixel precision.
    x0_16 = (x_start + x) << SUBPEL_BITS;
    y0_16 = (y_start + y) << SUBPEL_BITS;

    // Co-ordinate of current block in reference frame
    // to 1/16th pixel precision.
    x0_16 = sf->scale_value_x(x0_16, sf);
    y0_16 = sf->scale_value_y(y0_16, sf);

    // Map the top left corner of the block into the reference frame.
    x0 = sf->scale_value_x(x_start + x, sf);
    y0 = sf->scale_value_y(y_start + y, sf);

    // Scale the MV and incorporate the sub-pixel offset of the block
    // in the reference frame.
    scaled_mv = vp10_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf);
    xs = sf->x_step_q4;
    ys = sf->y_step_q4;
  } else {
    // Co-ordinate of containing block to pixel precision.
    x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x;
    y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y;

    // Co-ordinate of the block to 1/16th pixel precision.
    x0_16 = x0 << SUBPEL_BITS;
    y0_16 = y0 << SUBPEL_BITS;

    scaled_mv.row = mv->row * (1 << (1 - pd->subsampling_y));
    scaled_mv.col = mv->col * (1 << (1 - pd->subsampling_x));
    xs = ys = 16;
  }
  subpel_x = scaled_mv.col & SUBPEL_MASK;
  subpel_y = scaled_mv.row & SUBPEL_MASK;

  // Calculate the top left corner of the best matching block in the
  // reference frame.
  x0 += scaled_mv.col >> SUBPEL_BITS;
  y0 += scaled_mv.row >> SUBPEL_BITS;
  x0_16 += scaled_mv.col;
  y0_16 += scaled_mv.row;

  // Get reference block pointer.
  buf_ptr = ref_frame + y0 * pre_buf->stride + x0;
  buf_stride = pre_buf->stride;

  // Do border extension if there is motion or the
  // width/height is not a multiple of 8 pixels.
clang-format's avatar
clang-format committed
591
592
  if (is_scaled || scaled_mv.col || scaled_mv.row || (frame_width & 0x7) ||
      (frame_height & 0x7)) {
Jingning Han's avatar
Jingning Han committed
593
594
595
596
597
598
599
    int y1 = ((y0_16 + (h - 1) * ys) >> SUBPEL_BITS) + 1;

    // Get reference block bottom right horizontal coordinate.
    int x1 = ((x0_16 + (w - 1) * xs) >> SUBPEL_BITS) + 1;
    int x_pad = 0, y_pad = 0;

    if (subpel_x || (sf->x_step_q4 != SUBPEL_SHIFTS)) {
600
601
      x0 -= VPX_INTERP_EXTEND - 1;
      x1 += VPX_INTERP_EXTEND;
Jingning Han's avatar
Jingning Han committed
602
603
604
605
      x_pad = 1;
    }

    if (subpel_y || (sf->y_step_q4 != SUBPEL_SHIFTS)) {
606
607
      y0 -= VPX_INTERP_EXTEND - 1;
      y1 += VPX_INTERP_EXTEND;
Jingning Han's avatar
Jingning Han committed
608
609
610
611
612
      y_pad = 1;
    }

    // Wait until reference block is ready. Pad 7 more pixels as last 7
    // pixels of each superblock row can be changed by next superblock row.
613
    if (cm->frame_parallel_decode)
Jingning Han's avatar
Jingning Han committed
614
      vp10_frameworker_wait(pbi->frame_worker_owner, ref_frame_buf,
615
                            VPXMAX(0, (y1 + 7)) << (plane == 0 ? 0 : 1));
Jingning Han's avatar
Jingning Han committed
616
617
618
619
620
621
622
623
624
625

    // Skip border extension if block is inside the frame.
    if (x0 < 0 || x0 > frame_width - 1 || x1 < 0 || x1 > frame_width - 1 ||
        y0 < 0 || y0 > frame_height - 1 || y1 < 0 || y1 > frame_height - 1) {
      // Extend the border.
      const uint8_t *const buf_ptr1 = ref_frame + y0 * buf_stride + x0;
      const int b_w = x1 - x0 + 1;
      const int b_h = y1 - y0 + 1;
      const int border_offset = y_pad * 3 * b_w + x_pad * 3;

clang-format's avatar
clang-format committed
626
627
628
      extend_and_predict(buf_ptr1, buf_stride, x0, y0, b_w, b_h, frame_width,
                         frame_height, border_offset, dst, dst_buf->stride,
                         subpel_x, subpel_y, kernel, sf,
629
#if CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
630
631
632
633
634
635
636
637
                         xd,
#endif
                         w, h, ref, xs, ys);
      return;
    }
  } else {
    // Wait until reference block is ready. Pad 7 more pixels as last 7
    // pixels of each superblock row can be changed by next superblock row.
clang-format's avatar
clang-format committed
638
639
640
641
642
    if (cm->frame_parallel_decode) {
      const int y1 = (y0_16 + (h - 1) * ys) >> SUBPEL_BITS;
      vp10_frameworker_wait(pbi->frame_worker_owner, ref_frame_buf,
                            VPXMAX(0, (y1 + 7)) << (plane == 0 ? 0 : 1));
    }
Jingning Han's avatar
Jingning Han committed
643
  }
644
#if CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
645
646
647
648
649
650
651
652
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
    high_inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride, subpel_x,
                         subpel_y, sf, w, h, ref, kernel, xs, ys, xd->bd);
  } else {
    inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride, subpel_x,
                    subpel_y, sf, w, h, ref, kernel, xs, ys);
  }
#else
clang-format's avatar
clang-format committed
653
654
  inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride, subpel_x, subpel_y,
                  sf, w, h, ref, kernel, xs, ys);
655
#endif  // CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
656
657
}

Yaowu Xu's avatar
Yaowu Xu committed
658
static void dec_build_inter_predictors_sb(VP10Decoder *const pbi,
clang-format's avatar
clang-format committed
659
660
                                          MACROBLOCKD *xd, int mi_row,
                                          int mi_col) {
Jingning Han's avatar
Jingning Han committed
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
  int plane;
  const int mi_x = mi_col * MI_SIZE;
  const int mi_y = mi_row * MI_SIZE;
  const MODE_INFO *mi = xd->mi[0];
  const InterpKernel *kernel = vp10_filter_kernels[mi->mbmi.interp_filter];
  const BLOCK_SIZE sb_type = mi->mbmi.sb_type;
  const int is_compound = has_second_ref(&mi->mbmi);

  for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
    struct macroblockd_plane *const pd = &xd->plane[plane];
    struct buf_2d *const dst_buf = &pd->dst;
    const int num_4x4_w = pd->n4_w;
    const int num_4x4_h = pd->n4_h;

    const int n4w_x4 = 4 * num_4x4_w;
    const int n4h_x4 = 4 * num_4x4_h;
    int ref;

    for (ref = 0; ref < 1 + is_compound; ++ref) {
      const struct scale_factors *const sf = &xd->block_refs[ref]->sf;
      struct buf_2d *const pre_buf = &pd->pre[ref];
      const int idx = xd->block_refs[ref]->idx;
      BufferPool *const pool = pbi->common.buffer_pool;
      RefCntBuffer *const ref_frame_buf = &pool->frame_bufs[idx];
      const int is_scaled = vp10_is_scaled(sf);

      if (sb_type < BLOCK_8X8) {
688
689
690
691
692
693
694
        const PARTITION_TYPE bp = BLOCK_8X8 - sb_type;
        const int have_vsplit = bp != PARTITION_HORZ;
        const int have_hsplit = bp != PARTITION_VERT;
        const int num_4x4_w = 2 >> ((!have_vsplit) | pd->subsampling_x);
        const int num_4x4_h = 2 >> ((!have_hsplit) | pd->subsampling_y);
        const int pw = 8 >> (have_vsplit | pd->subsampling_x);
        const int ph = 8 >> (have_hsplit | pd->subsampling_y);
695
        int x, y;
Jingning Han's avatar
Jingning Han committed
696
697
        for (y = 0; y < num_4x4_h; ++y) {
          for (x = 0; x < num_4x4_w; ++x) {
698
            const MV mv = average_split_mvs(pd, mi, ref, y * 2 + x);
clang-format's avatar
clang-format committed
699
700
701
702
            dec_build_inter_predictors(pbi, xd, plane, n4w_x4, n4h_x4, 4 * x,
                                       4 * y, pw, ph, mi_x, mi_y, kernel, sf,
                                       pre_buf, dst_buf, &mv, ref_frame_buf,
                                       is_scaled, ref);
Jingning Han's avatar
Jingning Han committed
703
704
705
706
          }
        }
      } else {
        const MV mv = mi->mbmi.mv[ref].as_mv;
clang-format's avatar
clang-format committed
707
708
709
        dec_build_inter_predictors(pbi, xd, plane, n4w_x4, n4h_x4, 0, 0, n4w_x4,
                                   n4h_x4, mi_x, mi_y, kernel, sf, pre_buf,
                                   dst_buf, &mv, ref_frame_buf, is_scaled, ref);
Jingning Han's avatar
Jingning Han committed
710
711
712
713
714
      }
    }
  }
}

715
716
static INLINE TX_SIZE
    dec_get_uv_tx_size(const MB_MODE_INFO *mbmi, int n4_wl, int n4_hl) {
Jingning Han's avatar
Jingning Han committed
717
  // get minimum log2 num4x4s dimension
718
  const int x = VPXMIN(n4_wl, n4_hl);
clang-format's avatar
clang-format committed
719
  return VPXMIN(mbmi->tx_size, x);
Jingning Han's avatar
Jingning Han committed
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
}

static INLINE void dec_reset_skip_context(MACROBLOCKD *xd) {
  int i;
  for (i = 0; i < MAX_MB_PLANE; i++) {
    struct macroblockd_plane *const pd = &xd->plane[i];
    memset(pd->above_context, 0, sizeof(ENTROPY_CONTEXT) * pd->n4_w);
    memset(pd->left_context, 0, sizeof(ENTROPY_CONTEXT) * pd->n4_h);
  }
}

static void set_plane_n4(MACROBLOCKD *const xd, int bw, int bh, int bwl,
                         int bhl) {
  int i;
  for (i = 0; i < MAX_MB_PLANE; i++) {
    xd->plane[i].n4_w = (bw << 1) >> xd->plane[i].subsampling_x;
    xd->plane[i].n4_h = (bh << 1) >> xd->plane[i].subsampling_y;
    xd->plane[i].n4_wl = bwl - xd->plane[i].subsampling_x;
    xd->plane[i].n4_hl = bhl - xd->plane[i].subsampling_y;
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
742
static MB_MODE_INFO *set_offsets(VP10_COMMON *const cm, MACROBLOCKD *const xd,
Jingning Han's avatar
Jingning Han committed
743
                                 BLOCK_SIZE bsize, int mi_row, int mi_col,
clang-format's avatar
clang-format committed
744
745
                                 int bw, int bh, int x_mis, int y_mis, int bwl,
                                 int bhl) {
Jingning Han's avatar
Jingning Han committed
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
  const int offset = mi_row * cm->mi_stride + mi_col;
  int x, y;
  const TileInfo *const tile = &xd->tile;

  xd->mi = cm->mi_grid_visible + offset;
  xd->mi[0] = &cm->mi[offset];
  // TODO(slavarnway): Generate sb_type based on bwl and bhl, instead of
  // passing bsize from decode_partition().
  xd->mi[0]->mbmi.sb_type = bsize;
  for (y = 0; y < y_mis; ++y)
    for (x = !y; x < x_mis; ++x) {
      xd->mi[y * cm->mi_stride + x] = xd->mi[0];
    }

  set_plane_n4(xd, bw, bh, bwl, bhl);

  set_skip_context(xd, mi_row, mi_col);

  // Distance of Mb to the various image edges. These are specified to 8th pel
  // as they are always compared to values that are in 1/8th pel units
  set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols);

  vp10_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
  return &xd->mi[0]->mbmi;
}

Yaowu Xu's avatar
Yaowu Xu committed
772
static void decode_block(VP10Decoder *const pbi, MACROBLOCKD *const xd,
clang-format's avatar
clang-format committed
773
774
                         int mi_row, int mi_col, vpx_reader *r,
                         BLOCK_SIZE bsize, int bwl, int bhl) {
Yaowu Xu's avatar
Yaowu Xu committed
775
  VP10_COMMON *const cm = &pbi->common;
Jingning Han's avatar
Jingning Han committed
776
777
778
  const int less8x8 = bsize < BLOCK_8X8;
  const int bw = 1 << (bwl - 1);
  const int bh = 1 << (bhl - 1);
779
780
  const int x_mis = VPXMIN(bw, cm->mi_cols - mi_col);
  const int y_mis = VPXMIN(bh, cm->mi_rows - mi_row);
Jingning Han's avatar
Jingning Han committed
781

clang-format's avatar
clang-format committed
782
783
  MB_MODE_INFO *mbmi = set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis,
                                   y_mis, bwl, bhl);
Jingning Han's avatar
Jingning Han committed
784
785
786
787
788

  if (bsize >= BLOCK_8X8 && (cm->subsampling_x || cm->subsampling_y)) {
    const BLOCK_SIZE uv_subsize =
        ss_size_lookup[bsize][cm->subsampling_x][cm->subsampling_y];
    if (uv_subsize == BLOCK_INVALID)
clang-format's avatar
clang-format committed
789
790
      vpx_internal_error(xd->error_info, VPX_CODEC_CORRUPT_FRAME,
                         "Invalid block size.");
Jingning Han's avatar
Jingning Han committed
791
792
793
794
795
796
797
798
799
800
801
802
803
804
  }

  vp10_read_mode_info(pbi, xd, mi_row, mi_col, r, x_mis, y_mis);

  if (mbmi->skip) {
    dec_reset_skip_context(xd);
  }

  if (!is_inter_block(mbmi)) {
    int plane;
    for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
      const struct macroblockd_plane *const pd = &xd->plane[plane];
      const TX_SIZE tx_size =
          plane ? dec_get_uv_tx_size(mbmi, pd->n4_wl, pd->n4_hl)
clang-format's avatar
clang-format committed
805
                : mbmi->tx_size;
Jingning Han's avatar
Jingning Han committed
806
807
808
809
      const int num_4x4_w = pd->n4_w;
      const int num_4x4_h = pd->n4_h;
      const int step = (1 << tx_size);
      int row, col;
clang-format's avatar
clang-format committed
810
811
812
813
814
815
816
817
      const int max_blocks_wide =
          num_4x4_w + (xd->mb_to_right_edge >= 0
                           ? 0
                           : xd->mb_to_right_edge >> (5 + pd->subsampling_x));
      const int max_blocks_high =
          num_4x4_h + (xd->mb_to_bottom_edge >= 0
                           ? 0
                           : xd->mb_to_bottom_edge >> (5 + pd->subsampling_y));
Jingning Han's avatar
Jingning Han committed
818
819
820

      for (row = 0; row < max_blocks_high; row += step)
        for (col = 0; col < max_blocks_wide; col += step)
clang-format's avatar
clang-format committed
821
822
          predict_and_reconstruct_intra_block(xd, r, mbmi, plane, row, col,
                                              tx_size);
Jingning Han's avatar
Jingning Han committed
823
824
825
826
827
828
829
830
831
832
833
834
835
836
    }
  } else {
    // Prediction
    dec_build_inter_predictors_sb(pbi, xd, mi_row, mi_col);

    // Reconstruction
    if (!mbmi->skip) {
      int eobtotal = 0;
      int plane;

      for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
        const struct macroblockd_plane *const pd = &xd->plane[plane];
        const TX_SIZE tx_size =
            plane ? dec_get_uv_tx_size(mbmi, pd->n4_wl, pd->n4_hl)
clang-format's avatar
clang-format committed
837
                  : mbmi->tx_size;
Jingning Han's avatar
Jingning Han committed
838
839
840
841
        const int num_4x4_w = pd->n4_w;
        const int num_4x4_h = pd->n4_h;
        const int step = (1 << tx_size);
        int row, col;
clang-format's avatar
clang-format committed
842
843
844
845
846
847
848
849
        const int max_blocks_wide =
            num_4x4_w + (xd->mb_to_right_edge >= 0
                             ? 0
                             : xd->mb_to_right_edge >> (5 + pd->subsampling_x));
        const int max_blocks_high =
            num_4x4_h +
            (xd->mb_to_bottom_edge >= 0 ? 0 : xd->mb_to_bottom_edge >>
                                                  (5 + pd->subsampling_y));
Jingning Han's avatar
Jingning Han committed
850
851
852

        for (row = 0; row < max_blocks_high; row += step)
          for (col = 0; col < max_blocks_wide; col += step)
clang-format's avatar
clang-format committed
853
854
            eobtotal +=
                reconstruct_inter_block(xd, r, mbmi, plane, row, col, tx_size);
Jingning Han's avatar
Jingning Han committed
855
856
857
      }

      if (!less8x8 && eobtotal == 0)
858
859
860
#if CONFIG_MISC_FIXES
        mbmi->has_no_coeffs = 1;  // skip loopfilter
#else
Jingning Han's avatar
Jingning Han committed
861
        mbmi->skip = 1;  // skip loopfilter
862
#endif
Jingning Han's avatar
Jingning Han committed
863
864
865
866
867
868
    }
  }

  xd->corrupted |= vpx_reader_has_error(r);
}

clang-format's avatar
clang-format committed
869
870
static INLINE int dec_partition_plane_context(const MACROBLOCKD *xd, int mi_row,
                                              int mi_col, int bsl) {
Jingning Han's avatar
Jingning Han committed
871
872
  const PARTITION_CONTEXT *above_ctx = xd->above_seg_context + mi_col;
  const PARTITION_CONTEXT *left_ctx = xd->left_seg_context + (mi_row & MI_MASK);
clang-format's avatar
clang-format committed
873
  int above = (*above_ctx >> bsl) & 1, left = (*left_ctx >> bsl) & 1;
Jingning Han's avatar
Jingning Han committed
874

clang-format's avatar
clang-format committed
875
  //  assert(bsl >= 0);
Jingning Han's avatar
Jingning Han committed
876
877
878
879

  return (left * 2 + above) + bsl * PARTITION_PLOFFSET;
}

clang-format's avatar
clang-format committed
880
881
static INLINE void dec_update_partition_context(MACROBLOCKD *xd, int mi_row,
                                                int mi_col, BLOCK_SIZE subsize,
Jingning Han's avatar
Jingning Han committed
882
883
884
885
886
887
888
889
890
891
892
                                                int bw) {
  PARTITION_CONTEXT *const above_ctx = xd->above_seg_context + mi_col;
  PARTITION_CONTEXT *const left_ctx = xd->left_seg_context + (mi_row & MI_MASK);

  // update the partition context at the end notes. set partition bits
  // of block sizes larger than the current one to be one, and partition
  // bits of smaller block sizes to be zero.
  memset(above_ctx, partition_context_lookup[subsize].above, bw);
  memset(left_ctx, partition_context_lookup[subsize].left, bw);
}

893
894
static PARTITION_TYPE read_partition(VP10_COMMON *cm, MACROBLOCKD *xd,
                                     int mi_row, int mi_col, vpx_reader *r,
Jingning Han's avatar
Jingning Han committed
895
896
                                     int has_rows, int has_cols, int bsl) {
  const int ctx = dec_partition_plane_context(xd, mi_row, mi_col, bsl);
897
  const vpx_prob *const probs = cm->fc->partition_prob[ctx];
Jingning Han's avatar
Jingning Han committed
898
899
900
901
902
903
904
905
906
907
908
909
  FRAME_COUNTS *counts = xd->counts;
  PARTITION_TYPE p;

  if (has_rows && has_cols)
    p = (PARTITION_TYPE)vpx_read_tree(r, vp10_partition_tree, probs);
  else if (!has_rows && has_cols)
    p = vpx_read(r, probs[1]) ? PARTITION_SPLIT : PARTITION_HORZ;
  else if (has_rows && !has_cols)
    p = vpx_read(r, probs[2]) ? PARTITION_SPLIT : PARTITION_VERT;
  else
    p = PARTITION_SPLIT;

clang-format's avatar
clang-format committed
910
  if (counts) ++counts->partition[ctx][p];
Jingning Han's avatar
Jingning Han committed
911
912
913
914
915

  return p;
}

// TODO(slavarnway): eliminate bsize and subsize in future commits
Yaowu Xu's avatar
Yaowu Xu committed
916
static void decode_partition(VP10Decoder *const pbi, MACROBLOCKD *const xd,
clang-format's avatar
clang-format committed
917
918
                             int mi_row, int mi_col, vpx_reader *r,
                             BLOCK_SIZE bsize, int n4x4_l2) {
Yaowu Xu's avatar
Yaowu Xu committed
919
  VP10_COMMON *const cm = &pbi->common;
Jingning Han's avatar
Jingning Han committed
920
921
922
923
924
925
926
927
  const int n8x8_l2 = n4x4_l2 - 1;
  const int num_8x8_wh = 1 << n8x8_l2;
  const int hbs = num_8x8_wh >> 1;
  PARTITION_TYPE partition;
  BLOCK_SIZE subsize;
  const int has_rows = (mi_row + hbs) < cm->mi_rows;
  const int has_cols = (mi_col + hbs) < cm->mi_cols;

clang-format's avatar
clang-format committed
928
  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
Jingning Han's avatar
Jingning Han committed
929

clang-format's avatar
clang-format committed
930
931
  partition =
      read_partition(cm, xd, mi_row, mi_col, r, has_rows, has_cols, n8x8_l2);
Jingning Han's avatar
Jingning Han committed
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
  subsize = subsize_lookup[partition][bsize];  // get_subsize(bsize, partition);
  if (!hbs) {
    // calculate bmode block dimensions (log 2)
    xd->bmode_blocks_wl = 1 >> !!(partition & PARTITION_VERT);
    xd->bmode_blocks_hl = 1 >> !!(partition & PARTITION_HORZ);
    decode_block(pbi, xd, mi_row, mi_col, r, subsize, 1, 1);
  } else {
    switch (partition) {
      case PARTITION_NONE:
        decode_block(pbi, xd, mi_row, mi_col, r, subsize, n4x4_l2, n4x4_l2);
        break;
      case PARTITION_HORZ:
        decode_block(pbi, xd, mi_row, mi_col, r, subsize, n4x4_l2, n8x8_l2);
        if (has_rows)
          decode_block(pbi, xd, mi_row + hbs, mi_col, r, subsize, n4x4_l2,
                       n8x8_l2);
        break;
      case PARTITION_VERT:
        decode_block(pbi, xd, mi_row, mi_col, r, subsize, n8x8_l2, n4x4_l2);
        if (has_cols)
          decode_block(pbi, xd, mi_row, mi_col + hbs, r, subsize, n8x8_l2,
                       n4x4_l2);
        break;
      case PARTITION_SPLIT:
        decode_partition(pbi, xd, mi_row, mi_col, r, subsize, n8x8_l2);
        decode_partition(pbi, xd, mi_row, mi_col + hbs, r, subsize, n8x8_l2);
        decode_partition(pbi, xd, mi_row + hbs, mi_col, r, subsize, n8x8_l2);
        decode_partition(pbi, xd, mi_row + hbs, mi_col + hbs, r, subsize,
                         n8x8_l2);
        break;
clang-format's avatar
clang-format committed
962
      default: assert(0 && "Invalid partition type");
Jingning Han's avatar
Jingning Han committed
963
964
965
966
967
968
969
970
971
    }
  }

  // update partition context
  if (bsize >= BLOCK_8X8 &&
      (bsize == BLOCK_8X8 || partition != PARTITION_SPLIT))
    dec_update_partition_context(xd, mi_row, mi_col, subsize, num_8x8_wh);
}

clang-format's avatar
clang-format committed
972
static void setup_token_decoder(const uint8_t *data, const uint8_t *data_end,
Jingning Han's avatar
Jingning Han committed
973
974
                                size_t read_size,
                                struct vpx_internal_error_info *error_info,
clang-format's avatar
clang-format committed
975
                                vpx_reader *r, vpx_decrypt_cb decrypt_cb,
Jingning Han's avatar
Jingning Han committed
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
                                void *decrypt_state) {
  // Validate the calculated partition length. If the buffer
  // described by the partition can't be fully read, then restrict
  // it to the portion that can be (for EC mode) or throw an error.
  if (!read_is_valid(data, read_size, data_end))
    vpx_internal_error(error_info, VPX_CODEC_CORRUPT_FRAME,
                       "Truncated packet or corrupt tile length");

  if (vpx_reader_init(r, data, read_size, decrypt_cb, decrypt_state))
    vpx_internal_error(error_info, VPX_CODEC_MEM_ERROR,
                       "Failed to allocate bool decoder %d", 1);
}

static void read_coef_probs_common(vp10_coeff_probs_model *coef_probs,
                                   vpx_reader *r) {
  int i, j, k, l, m;

  if (vpx_read_bit(r))
    for (i = 0; i < PLANE_TYPES; ++i)
      for (j = 0; j < REF_TYPES; ++j)
        for (k = 0; k < COEF_BANDS; ++k)
          for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l)
            for (m = 0; m < UNCONSTRAINED_NODES; ++m)
              vp10_diff_update_prob(r, &coef_probs[i][j][k][l][m]);
}

clang-format's avatar
clang-format committed
1002
1003
1004
1005
1006
static void read_coef_probs(FRAME_CONTEXT *fc, TX_MODE tx_mode, vpx_reader *r) {
  const TX_SIZE max_tx_size = tx_mode_to_biggest_tx_size[tx_mode];
  TX_SIZE tx_size;
  for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size)
    read_coef_probs_common(fc->coef_probs[tx_size], r);
Jingning Han's avatar
Jingning Han committed
1007
1008
}

1009
static void setup_segmentation(VP10_COMMON *const cm,
Jingning Han's avatar
Jingning Han committed
1010
                               struct vpx_read_bit_buffer *rb) {
1011
  struct segmentation *const seg = &cm->seg;
1012
1013
1014
#if !CONFIG_MISC_FIXES
  struct segmentation_probs *const segp = &cm->segp;
#endif
Jingning Han's avatar
Jingning Han committed
1015
1016
1017
1018
1019
1020
  int i, j;

  seg->update_map = 0;
  seg->update_data = 0;

  seg->enabled = vpx_rb_read_bit(rb);
clang-format's avatar
clang-format committed
1021
  if (!seg->enabled) return;
Jingning Han's avatar
Jingning Han committed
1022
1023

  // Segmentation map update
1024
1025
1026
1027
1028
  if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
    seg->update_map = 1;
  } else {
    seg->update_map = vpx_rb_read_bit(rb);
  }
Jingning Han's avatar
Jingning Han committed
1029
  if (seg->update_map) {
1030
#if !CONFIG_MISC_FIXES
Jingning Han's avatar
Jingning Han committed
1031
    for (i = 0; i < SEG_TREE_PROBS; i++)
clang-format's avatar
clang-format committed
1032
1033
      segp->tree_probs[i] =
          vpx_rb_read_bit(rb) ? vpx_rb_read_literal(rb, 8) : MAX_PROB;
1034
#endif
1035
1036
1037
1038
1039
    if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
      seg->temporal_update = 0;
    } else {
      seg->temporal_update = vpx_rb_read_bit(rb);
    }
1040
#if !CONFIG_MISC_FIXES
Jingning Han's avatar
Jingning Han committed
1041
1042
    if (seg->temporal_update) {
      for (i = 0; i < PREDICTION_PROBS; i++)
clang-format's avatar
clang-format committed
1043
1044
        segp->pred_probs[i] =
            vpx_rb_read_bit(rb) ? vpx_rb_read_literal(rb, 8) : MAX_PROB;
Jingning Han's avatar
Jingning Han committed
1045
    } else {
clang-format's avatar
clang-format committed
1046
      for (i = 0; i < PREDICTION_PROBS; i++) segp->pred_probs[i] = MAX_PROB;
Jingning Han's avatar
Jingning Han committed
1047
    }
1048
#endif
Jingning Han's avatar
Jingning Han committed
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
  }

  // Segmentation data update
  seg->update_data = vpx_rb_read_bit(rb);
  if (seg->update_data) {
    seg->abs_delta = vpx_rb_read_bit(rb);

    vp10_clearall_segfeatures(seg);

    for (i = 0; i < MAX_SEGMENTS; i++) {
      for (j = 0; j < SEG_LVL_MAX; j++) {
        int data = 0;
        const int feature_enabled = vpx_rb_read_bit(rb);
        if (feature_enabled) {
          vp10_enable_segfeature(seg, i, j);
          data = decode_unsigned_max(rb, vp10_seg_feature_data_max(j));
          if (vp10_is_segfeature_signed(j))
            data = vpx_rb_read_bit(rb) ? -data : data;
        }
        vp10_set_segdata(seg, i, j, data);
      }
    }
  }
}

static void setup_loopfilter(struct loopfilter *lf,
                             struct vpx_read_bit_buffer *rb) {
  lf->filter_level = vpx_rb_read_literal(rb, 6);
  lf->sharpness_level = vpx_rb_read_literal(rb, 3);

  // Read in loop filter deltas applied at the MB level based on mode or ref
  // frame.
  lf->mode_ref_delta_update = 0;

  lf->mode_ref_delta_enabled = vpx_rb_read_bit(rb);
  if (lf->mode_ref_delta_enabled) {
    lf->mode_ref_delta_update = vpx_rb_read_bit(rb);
    if (lf->mode_ref_delta_update) {
      int i;

1089
      for (i = 0; i < MAX_REF_FRAMES; i++)
Jingning Han's avatar
Jingning Han committed
1090
        if (vpx_rb_read_bit(rb))
1091
          lf->ref_deltas[i] = vpx_rb_read_inv_signed_literal(rb, 6);
Jingning Han's avatar
Jingning Han committed
1092
1093
1094

      for (i = 0; i < MAX_MODE_LF_DELTAS; i++)
        if (vpx_rb_read_bit(rb))
1095
          lf->mode_deltas[i] = vpx_rb_read_inv_signed_literal(rb, 6);
Jingning Han's avatar
Jingning Han committed
1096
1097
1098
1099
    }
  }
}

Steinar Midtskogen's avatar
Steinar Midtskogen committed
1100
1101
1102
1103
1104
1105
#if CONFIG_CLPF
static void setup_clpf(VP10_COMMON *cm, struct vpx_read_bit_buffer *rb) {
  cm->clpf = vpx_rb_read_literal(rb, 1);
}
#endif

Jingning Han's avatar
Jingning Han committed
1106
static INLINE int read_delta_q(struct vpx_read_bit_buffer *rb) {
clang-format's avatar
clang-format committed
1107
1108
1109
  return vpx_rb_read_bit(rb)
             ? vpx_rb_read_inv_signed_literal(rb, CONFIG_MISC_FIXES ? 6 : 4)
             : 0;
Jingning Han's avatar
Jingning Han committed
1110
1111
}

1112
static void setup_quantization(VP10_COMMON *const cm,
Jingning Han's avatar
Jingning Han committed
1113
1114
1115
1116
1117
1118
                               struct vpx_read_bit_buffer *rb) {
  cm->base_qindex = vpx_rb_read_literal(rb, QINDEX_BITS);
  cm->y_dc_delta_q = read_delta_q(rb);
  cm->uv_dc_delta_q = read_delta_q(rb);
  cm->uv_ac_delta_q = read_delta_q(rb);
  cm->dequant_bit_depth = cm->bit_depth;
1119
1120
#if CONFIG_AOM_QM
  cm->using_qmatrix = vpx_rb_read_bit(rb);
1121
1122
1123
1124
1125
1126
1127
  if (cm->using_qmatrix) {
    cm->min_qmlevel = vpx_rb_read_literal(rb, QM_LEVEL_BITS);
    cm->max_qmlevel = vpx_rb_read_literal(rb, QM_LEVEL_BITS);
  } else {
    cm->min_qmlevel = 0;
    cm->max_qmlevel = 0;
  }
1128
#endif
Jingning Han's avatar
Jingning Han committed
1129
1130
}

Yaowu Xu's avatar
Yaowu Xu committed
1131
static void setup_segmentation_dequant(VP10_COMMON *const cm) {
Jingning Han's avatar
Jingning Han committed
1132
  // Build y/uv dequant values based on segmentation.
1133
1134
1135
1136
  int i = 0;
#if CONFIG_AOM_QM
  int lossless;
  int j = 0;
1137
  int qmlevel;
1138
  int using_qm = cm->using_qmatrix;
1139
1140
  int minqm = cm->min_qmlevel;
  int maxqm = cm->max_qmlevel;
1141
#endif
Jingning Han's avatar
Jingning Han committed
1142
1143
1144
  if (cm->seg.enabled) {
    for (i = 0; i < MAX_SEGMENTS; ++i) {
      const int qindex = vp10_get_qindex(&cm->seg, i, cm->base_qindex);
clang-format's avatar
clang-format committed
1145
1146
      cm->y_dequant[i][0] =
          vp10_dc_quant(qindex, cm->y_dc_delta_q, cm->bit_depth);
Jingning Han's avatar
Jingning Han committed
1147
      cm->y_dequant[i][1] = vp10_ac_quant(qindex, 0, cm->bit_depth);
clang-format's avatar
clang-format committed
1148
1149
1150
1151
      cm->uv_dequant[i][0] =
          vp10_dc_quant(qindex, cm->uv_dc_delta_q, cm->bit_depth);
      cm->uv_dequant[i][1] =
          vp10_ac_quant(qindex, cm->uv_ac_delta_q, cm->bit_depth);
1152
1153
1154
1155
#if CONFIG_AOM_QM
      lossless = qindex == 0 && cm->y_dc_delta_q == 0 &&
                 cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0;
      // NB: depends on base index so there is only 1 set per frame
1156
      // No quant weighting when lossless or signalled not using QM
1157
1158
1159
      qmlevel = (lossless || using_qm == 0)
                    ? NUM_QM_LEVELS - 1
                    : aom_get_qmlevel(cm->base_qindex, minqm, maxqm);
1160
      for (j = 0; j < TX_SIZES; ++j) {
1161
1162
1163
1164
        cm->y_iqmatrix[i][1][j] = aom_iqmatrix(cm, qmlevel, 0, j, 1);
        cm->y_iqmatrix[i][0][j] = aom_iqmatrix(cm, qmlevel, 0, j, 0);
        cm->uv_iqmatrix[i][1][j] = aom_iqmatrix(cm, qmlevel, 1, j, 1);
        cm->uv_iqmatrix[i][0][j] = aom_iqmatrix(cm, qmlevel, 1, j, 0);
1165
1166
      }
#endif
Jingning Han's avatar
Jingning Han committed
1167
1168
1169
1170
1171
    }
  } else {
    const int qindex = cm->base_qindex;
    // When segmentation is disabled, only the first value is used.  The
    // remaining are don't cares.
clang-format's avatar
clang-format committed
1172
1173
    cm->y_dequant[0][0] =
        vp10_dc_quant(qindex, cm->y_dc_delta_q, cm->bit_depth);
Jingning Han's avatar
Jingning Han committed
1174
    cm->y_dequant[0][1] = vp10_ac_quant(qindex, 0, cm->bit_depth);
clang-format's avatar
clang-format committed
1175
1176
1177
1178
    cm->uv_dequant[0][0] =
        vp10_dc_quant(qindex, cm->uv_dc_delta_q, cm->bit_depth);
    cm->uv_dequant[0][1] =
        vp10_ac_quant(qindex, cm->uv_ac_delta_q, cm->bit_depth);
1179
1180
1181
#if CONFIG_AOM_QM
    lossless = qindex == 0 && cm->y_dc_delta_q == 0 && cm->uv_dc_delta_q == 0 &&
               cm->uv_ac_delta_q == 0;
1182
    // No quant weighting when lossless or signalled not using QM
1183
1184
1185
    qmlevel = (lossless || using_qm == 0)
                  ? NUM_QM_LEVELS - 1
                  : aom_get_qmlevel(cm->base_qindex, minqm, maxqm);
1186
    for (j = 0; j < TX_SIZES; ++j) {
1187
1188
1189
1190
      cm->y_iqmatrix[i][1][j] = aom_iqmatrix(cm, qmlevel, 0, j, 1);
      cm->y_iqmatrix[i][0][j] = aom_iqmatrix(cm, qmlevel, 0, j, 0);
      cm->uv_iqmatrix[i][1][j] = aom_iqmatrix(cm, qmlevel, 1, j, 1);
      cm->uv_iqmatrix[i][0][j] = aom_iqmatrix(cm