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


12
#include "vp9/decoder/vp9_onyxd_int.h"
Ronald S. Bultje's avatar
Ronald S. Bultje committed
13
#include "vp9/common/vp9_common.h"
14 15 16
#include "vp9/common/vp9_header.h"
#include "vp9/common/vp9_reconintra.h"
#include "vp9/common/vp9_reconinter.h"
Yaowu Xu's avatar
Yaowu Xu committed
17
#include "vp9/common/vp9_entropy.h"
18
#include "vp9/decoder/vp9_decodframe.h"
19
#include "vp9/decoder/vp9_detokenize.h"
20 21 22 23
#include "vp9/common/vp9_invtrans.h"
#include "vp9/common/vp9_alloccommon.h"
#include "vp9/common/vp9_entropymode.h"
#include "vp9/common/vp9_quant_common.h"
Johann's avatar
Johann committed
24
#include "vpx_scale/vpx_scale.h"
25
#include "vp9/common/vp9_setupintrarecon.h"
Scott LaVarnway's avatar
Scott LaVarnway committed
26

27
#include "vp9/decoder/vp9_decodemv.h"
28 29
#include "vp9/common/vp9_extend.h"
#include "vp9/common/vp9_modecont.h"
John Koleszar's avatar
John Koleszar committed
30
#include "vpx_mem/vpx_mem.h"
31
#include "vp9/decoder/vp9_dboolhuff.h"
John Koleszar's avatar
John Koleszar committed
32

33
#include "vp9/common/vp9_seg_common.h"
34
#include "vp9/common/vp9_tile_common.h"
35
#include "vp9_rtcd.h"
36

John Koleszar's avatar
John Koleszar committed
37 38 39
#include <assert.h>
#include <stdio.h>

40 41
#define COEFCOUNT_TESTING

42
// #define DEC_DEBUG
43 44 45 46
#ifdef DEC_DEBUG
int dec_debug = 0;
#endif

47 48 49 50 51 52 53 54 55
static int read_le16(const uint8_t *p) {
  return (p[1] << 8) | p[0];
}

static int read_le32(const uint8_t *p) {
  return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
}

// len == 0 is not allowed
56 57
static int read_is_valid(const uint8_t *start, size_t len,
                         const uint8_t *end) {
58 59 60
  return start + len > start && start + len <= end;
}

61 62 63 64 65 66 67
static TXFM_MODE read_txfm_mode(vp9_reader *r) {
  TXFM_MODE mode = vp9_read_literal(r, 2);
  if (mode == ALLOW_32X32)
    mode += vp9_read_bit(r);
  return mode;
}

John Koleszar's avatar
John Koleszar committed
68 69 70 71 72 73 74 75 76 77 78 79
static int merge_index(int v, int n, int modulus) {
  int max1 = (n - 1 - modulus / 2) / modulus + 1;
  if (v < max1) v = v * modulus + modulus / 2;
  else {
    int w;
    v -= max1;
    w = v;
    v += (v + modulus - modulus / 2) / modulus;
    while (v % modulus == modulus / 2 ||
           w != v - (v + modulus - modulus / 2) / modulus) v++;
  }
  return v;
80 81
}

John Koleszar's avatar
John Koleszar committed
82 83 84
static int inv_remap_prob(int v, int m) {
  const int n = 256;
  const int modulus = MODULUS_PARAM;
85

John Koleszar's avatar
John Koleszar committed
86 87
  v = merge_index(v, n - 1, modulus);
  if ((m << 1) <= n) {
88
    return vp9_inv_recenter_nonneg(v + 1, m);
John Koleszar's avatar
John Koleszar committed
89
  } else {
90
    return n - 1 - vp9_inv_recenter_nonneg(v + 1, n - 1 - m);
John Koleszar's avatar
John Koleszar committed
91
  }
92
}
93

94
static vp9_prob read_prob_diff_update(vp9_reader *const bc, int oldp) {
95
  int delp = vp9_decode_term_subexp(bc, SUBEXP_PARAM, 255);
96
  return (vp9_prob)inv_remap_prob(delp, oldp);
97
}
98

99
void vp9_init_de_quantizer(VP9D_COMP *pbi) {
John Koleszar's avatar
John Koleszar committed
100
  int i;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
101
  int q;
102
  VP9_COMMON *const pc = &pbi->common;
John Koleszar's avatar
John Koleszar committed
103

Dmitry Kovalev's avatar
Dmitry Kovalev committed
104 105 106
  for (q = 0; q < QINDEX_RANGE; q++) {
    pc->Y1dequant[q][0] = (int16_t)vp9_dc_quant(q, pc->y1dc_delta_q);
    pc->UVdequant[q][0] = (int16_t)vp9_dc_uv_quant(q, pc->uvdc_delta_q);
John Koleszar's avatar
John Koleszar committed
107 108 109

    /* all the ac values =; */
    for (i = 1; i < 16; i++) {
110
      const int rc = vp9_default_zig_zag1d_4x4[i];
John Koleszar's avatar
John Koleszar committed
111

Dmitry Kovalev's avatar
Dmitry Kovalev committed
112 113
      pc->Y1dequant[q][rc] = (int16_t)vp9_ac_yquant(q);
      pc->UVdequant[q][rc] = (int16_t)vp9_ac_uv_quant(q, pc->uvac_delta_q);
John Koleszar's avatar
John Koleszar committed
114
    }
John Koleszar's avatar
John Koleszar committed
115
  }
John Koleszar's avatar
John Koleszar committed
116 117
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
118 119 120
static int get_qindex(MACROBLOCKD *mb, int segment_id, int base_qindex) {
  // Set the Q baseline allowing for any segment level adjustment
  if (vp9_segfeature_active(mb, segment_id, SEG_LVL_ALT_Q)) {
121 122 123 124
    const int data = vp9_get_segdata(mb, segment_id, SEG_LVL_ALT_Q);
    return mb->mb_segment_abs_delta == SEGMENT_ABSDATA ?
               data :  // Abs value
               clamp(base_qindex + data, 0, MAXQ);  // Delta value
Dmitry Kovalev's avatar
Dmitry Kovalev committed
125 126 127 128 129 130
  } else {
    return base_qindex;
  }
}

static void mb_init_dequantizer(VP9D_COMP *pbi, MACROBLOCKD *mb) {
John Koleszar's avatar
John Koleszar committed
131 132
  int i;

Dmitry Kovalev's avatar
Dmitry Kovalev committed
133
  VP9_COMMON *const pc = &pbi->common;
134 135
  const int segment_id = mb->mode_info_context->mbmi.segment_id;
  const int qindex = get_qindex(mb, segment_id, pc->base_qindex);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
136
  mb->q_index = qindex;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
137

Dmitry Kovalev's avatar
Dmitry Kovalev committed
138 139
  for (i = 0; i < 16; i++)
    mb->block[i].dequant = pc->Y1dequant[qindex];
John Koleszar's avatar
John Koleszar committed
140

Dmitry Kovalev's avatar
Dmitry Kovalev committed
141 142
  for (i = 16; i < 24; i++)
    mb->block[i].dequant = pc->UVdequant[qindex];
John Koleszar's avatar
John Koleszar committed
143

Dmitry Kovalev's avatar
Dmitry Kovalev committed
144
  if (mb->lossless) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
145
    assert(qindex == 0);
Yaowu Xu's avatar
Yaowu Xu committed
146 147
    mb->inv_txm4x4_1      = vp9_short_iwalsh4x4_1;
    mb->inv_txm4x4        = vp9_short_iwalsh4x4;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
148 149 150 151
    mb->itxm_add          = vp9_dequant_idct_add_lossless_c;
    mb->itxm_add_y_block  = vp9_dequant_idct_add_y_block_lossless_c;
    mb->itxm_add_uv_block = vp9_dequant_idct_add_uv_block_lossless_c;
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
152 153
    mb->inv_txm4x4_1      = vp9_short_idct4x4_1;
    mb->inv_txm4x4        = vp9_short_idct4x4;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
154 155 156
    mb->itxm_add          = vp9_dequant_idct_add;
    mb->itxm_add_y_block  = vp9_dequant_idct_add_y_block;
    mb->itxm_add_uv_block = vp9_dequant_idct_add_uv_block;
John Koleszar's avatar
John Koleszar committed
157
  }
John Koleszar's avatar
John Koleszar committed
158 159
}

160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
#if CONFIG_CODE_NONZEROCOUNT
static void propagate_nzcs(VP9_COMMON *cm, MACROBLOCKD *xd) {
  MODE_INFO *m = xd->mode_info_context;
  BLOCK_SIZE_TYPE sb_type = m->mbmi.sb_type;
  const int mis = cm->mode_info_stride;
  int n;
  if (sb_type == BLOCK_SIZE_SB64X64) {
    for (n = 0; n < 16; ++n) {
      int i = n >> 2;
      int j = n & 3;
      if (i == 0 && j == 0) continue;
      vpx_memcpy((m + j + mis * i)->mbmi.nzcs, m->mbmi.nzcs,
                 384 * sizeof(m->mbmi.nzcs[0]));
    }
  } else if (sb_type == BLOCK_SIZE_SB32X32) {
    for (n = 0; n < 4; ++n) {
      int i = n >> 1;
      int j = n & 1;
      if (i == 0 && j == 0) continue;
      vpx_memcpy((m + j + mis * i)->mbmi.nzcs, m->mbmi.nzcs,
                 384 * sizeof(m->mbmi.nzcs[0]));
    }
  }
}
#endif

186 187 188
/* skip_recon_mb() is Modified: Instead of writing the result to predictor buffer and then copying it
 *  to dst buffer, we can write the result directly to dst buffer. This eliminates unnecessary copy.
 */
189 190
static void skip_recon_mb(VP9D_COMP *pbi, MACROBLOCKD *xd,
                          int mb_row, int mb_col) {
191 192
  MODE_INFO *m = xd->mode_info_context;
  BLOCK_SIZE_TYPE sb_type = m->mbmi.sb_type;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
193

John Koleszar's avatar
John Koleszar committed
194
  if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
195
    if (sb_type == BLOCK_SIZE_SB64X64) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
196 197
      vp9_build_intra_predictors_sb64uv_s(xd);
      vp9_build_intra_predictors_sb64y_s(xd);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
198
    } else if (sb_type == BLOCK_SIZE_SB32X32) {
199 200
      vp9_build_intra_predictors_sbuv_s(xd);
      vp9_build_intra_predictors_sby_s(xd);
201
    } else {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
202 203
      vp9_build_intra_predictors_mbuv_s(xd);
      vp9_build_intra_predictors_mby_s(xd);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
204
    }
John Koleszar's avatar
John Koleszar committed
205
  } else {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
206
    if (sb_type == BLOCK_SIZE_SB64X64) {
207
      vp9_build_inter64x64_predictors_sb(xd, mb_row, mb_col);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
208
    } else if (sb_type == BLOCK_SIZE_SB32X32) {
209
      vp9_build_inter32x32_predictors_sb(xd, mb_row, mb_col);
210
    } else {
211 212 213 214 215
      vp9_build_inter16x16_predictors_mb(xd,
                                         xd->dst.y_buffer,
                                         xd->dst.u_buffer,
                                         xd->dst.v_buffer,
                                         xd->dst.y_stride,
216 217
                                         xd->dst.uv_stride,
                                         mb_row, mb_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
218
    }
John Koleszar's avatar
John Koleszar committed
219
  }
220 221 222 223
#if CONFIG_CODE_NONZEROCOUNT
  vpx_memset(m->mbmi.nzcs, 0, 384 * sizeof(m->mbmi.nzcs[0]));
  propagate_nzcs(&pbi->common, xd);
#endif
John Koleszar's avatar
John Koleszar committed
224 225
}

226 227
static void decode_16x16(VP9D_COMP *pbi, MACROBLOCKD *xd,
                         BOOL_DECODER* const bc) {
228
  const TX_TYPE tx_type = get_tx_type_16x16(xd, 0);
229
  if (tx_type != DCT_DCT) {
230 231 232 233
    vp9_dequant_iht_add_16x16_c(tx_type, xd->plane[0].qcoeff,
                                xd->block[0].dequant, xd->predictor,
                                xd->dst.y_buffer, 16, xd->dst.y_stride,
                                xd->plane[0].eobs[0]);
234
  } else {
235
    vp9_dequant_idct_add_16x16(xd->plane[0].qcoeff, xd->block[0].dequant,
236
                               xd->predictor, xd->dst.y_buffer,
John Koleszar's avatar
John Koleszar committed
237
                               16, xd->dst.y_stride, xd->plane[0].eobs[0]);
238
  }
239 240 241

  vp9_dequant_idct_add_8x8(xd->plane[1].qcoeff, xd->block[16].dequant,
                           xd->predictor + 16 * 16, xd->dst.u_buffer, 8,
John Koleszar's avatar
John Koleszar committed
242
                           xd->dst.uv_stride, xd->plane[1].eobs[0]);
243 244 245

  vp9_dequant_idct_add_8x8(xd->plane[2].qcoeff, xd->block[16].dequant,
                           xd->predictor + 16 * 16 + 64, xd->dst.v_buffer, 8,
John Koleszar's avatar
John Koleszar committed
246
                           xd->dst.uv_stride, xd->plane[2].eobs[0]);
247 248 249 250
}

static void decode_8x8(VP9D_COMP *pbi, MACROBLOCKD *xd,
                       BOOL_DECODER* const bc) {
251 252
  const MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode;
  // luma
253
  // if the first one is DCT_DCT assume all the rest are as well
254
  TX_TYPE tx_type = get_tx_type_8x8(xd, 0);
255
  if (tx_type != DCT_DCT || mode == I8X8_PRED) {
256 257 258 259
    int i;
    for (i = 0; i < 4; i++) {
      int ib = vp9_i8x8_block[i];
      int idx = (ib & 0x02) ? (ib + 2) : ib;
260
      int16_t *q  = BLOCK_OFFSET(xd->plane[0].qcoeff, idx, 16);
261 262 263
      int16_t *dq = xd->block[0].dequant;
      uint8_t *pre = xd->block[ib].predictor;
      uint8_t *dst = *(xd->block[ib].base_dst) + xd->block[ib].dst;
264 265
      int stride = xd->dst.y_stride;
      BLOCKD *b = &xd->block[ib];
266
      if (mode == I8X8_PRED) {
267
        int i8x8mode = b->bmi.as_mode.first;
268
        vp9_intra8x8_predict(xd, b, i8x8mode, b->predictor);
269
      }
270
      tx_type = get_tx_type_8x8(xd, ib);
271
      if (tx_type != DCT_DCT) {
272 273
        vp9_dequant_iht_add_8x8_c(tx_type, q, dq, pre, dst, 16, stride,
                                  xd->plane[0].eobs[idx]);
274 275
      } else {
        vp9_dequant_idct_add_8x8_c(q, dq, pre, dst, 16, stride,
John Koleszar's avatar
John Koleszar committed
276
                                   xd->plane[0].eobs[idx]);
277 278
      }
    }
279
  } else {
280
    vp9_dequant_idct_add_y_block_8x8(xd->plane[0].qcoeff,
281 282 283 284
                                     xd->block[0].dequant,
                                     xd->predictor,
                                     xd->dst.y_buffer,
                                     xd->dst.y_stride,
285
                                     xd);
286 287
  }

288 289
  // chroma
  if (mode == I8X8_PRED) {
290 291 292 293 294
    int i;
    for (i = 0; i < 4; i++) {
      int ib = vp9_i8x8_block[i];
      BLOCKD *b = &xd->block[ib];
      int i8x8mode = b->bmi.as_mode.first;
295

296
      b = &xd->block[16 + i];
297
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, b->predictor);
298 299
      xd->itxm_add(BLOCK_OFFSET(xd->plane[1].qcoeff, i, 16),
                   b->dequant, b->predictor,
John Koleszar's avatar
John Koleszar committed
300 301
                   *(b->base_dst) + b->dst, 8, b->dst_stride,
                   xd->plane[1].eobs[i]);
302

303
      b = &xd->block[20 + i];
304
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, b->predictor);
305 306
      xd->itxm_add(BLOCK_OFFSET(xd->plane[2].qcoeff, i, 16),
                   b->dequant, b->predictor,
John Koleszar's avatar
John Koleszar committed
307 308
                   *(b->base_dst) + b->dst, 8, b->dst_stride,
                   xd->plane[2].eobs[i]);
309
    }
310
  } else if (mode == SPLITMV) {
311 312
    xd->itxm_add_uv_block(xd->plane[1].qcoeff, xd->block[16].dequant,
         xd->predictor + 16 * 16, xd->dst.u_buffer,
John Koleszar's avatar
John Koleszar committed
313
         xd->dst.uv_stride, xd->plane[1].eobs);
314 315
    xd->itxm_add_uv_block(xd->plane[2].qcoeff, xd->block[16].dequant,
         xd->predictor + 16 * 16 + 64, xd->dst.v_buffer,
John Koleszar's avatar
John Koleszar committed
316
         xd->dst.uv_stride, xd->plane[2].eobs);
317
  } else {
318 319
    vp9_dequant_idct_add_8x8(xd->plane[1].qcoeff, xd->block[16].dequant,
                             xd->predictor + 16 * 16, xd->dst.u_buffer, 8,
John Koleszar's avatar
John Koleszar committed
320
                             xd->dst.uv_stride, xd->plane[1].eobs[0]);
321 322 323

    vp9_dequant_idct_add_8x8(xd->plane[2].qcoeff, xd->block[16].dequant,
                             xd->predictor + 16 * 16 + 64, xd->dst.v_buffer, 8,
John Koleszar's avatar
John Koleszar committed
324
                             xd->dst.uv_stride, xd->plane[2].eobs[0]);
325 326 327 328 329 330
  }
}

static void decode_4x4(VP9D_COMP *pbi, MACROBLOCKD *xd,
                       BOOL_DECODER* const bc) {
  TX_TYPE tx_type;
331
  int i = 0;
332
  const MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode;
333 334 335 336 337
  if (mode == I8X8_PRED) {
    for (i = 0; i < 4; i++) {
      int ib = vp9_i8x8_block[i];
      const int iblock[4] = {0, 1, 4, 5};
      int j;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
338 339
      BLOCKD *b = &xd->block[ib];
      int i8x8mode = b->bmi.as_mode.first;
340
      vp9_intra8x8_predict(xd, b, i8x8mode, b->predictor);
341 342
      for (j = 0; j < 4; j++) {
        b = &xd->block[ib + iblock[j]];
343
        tx_type = get_tx_type_4x4(xd, ib + iblock[j]);
344
        if (tx_type != DCT_DCT) {
345
          vp9_dequant_iht_add_c(tx_type,
346
              BLOCK_OFFSET(xd->plane[0].qcoeff, ib + iblock[j], 16),
347 348
                                    b->dequant, b->predictor,
                                    *(b->base_dst) + b->dst, 16,
John Koleszar's avatar
John Koleszar committed
349 350
                                    b->dst_stride,
                                    xd->plane[0].eobs[ib + iblock[j]]);
351
        } else {
352 353
          xd->itxm_add(BLOCK_OFFSET(xd->plane[0].qcoeff, ib + iblock[j], 16),
                       b->dequant, b->predictor,
354
                       *(b->base_dst) + b->dst, 16, b->dst_stride,
John Koleszar's avatar
John Koleszar committed
355
                       xd->plane[0].eobs[ib + iblock[j]]);
356 357 358
        }
      }
      b = &xd->block[16 + i];
359
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, b->predictor);
360 361
      xd->itxm_add(BLOCK_OFFSET(xd->plane[1].qcoeff, i, 16),
                   b->dequant, b->predictor,
John Koleszar's avatar
John Koleszar committed
362 363
                   *(b->base_dst) + b->dst, 8, b->dst_stride,
                   xd->plane[1].eobs[i]);
364
      b = &xd->block[20 + i];
365
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, b->predictor);
366 367
      xd->itxm_add(BLOCK_OFFSET(xd->plane[2].qcoeff, i, 16),
                   b->dequant, b->predictor,
John Koleszar's avatar
John Koleszar committed
368 369
                   *(b->base_dst) + b->dst, 8, b->dst_stride,
                   xd->plane[2].eobs[i]);
370 371 372 373
    }
  } else if (mode == B_PRED) {
    for (i = 0; i < 16; i++) {
      BLOCKD *b = &xd->block[i];
Dmitry Kovalev's avatar
Dmitry Kovalev committed
374
      int b_mode = xd->mode_info_context->bmi[i].as_mode.first;
375 376
#if CONFIG_NEWBINTRAMODES
      xd->mode_info_context->bmi[i].as_mode.context = b->bmi.as_mode.context =
377
          vp9_find_bpred_context(xd, b);
378 379
      if (!xd->mode_info_context->mbmi.mb_skip_coeff)
        vp9_decode_coefs_4x4(pbi, xd, bc, PLANE_TYPE_Y_WITH_DC, i);
380
#endif
381
      vp9_intra4x4_predict(xd, b, b_mode, b->predictor);
382
      tx_type = get_tx_type_4x4(xd, i);
383
      if (tx_type != DCT_DCT) {
384 385 386 387 388
        vp9_dequant_iht_add_c(tx_type,
                              BLOCK_OFFSET(xd->plane[0].qcoeff, i, 16),
                              b->dequant, b->predictor,
                              *(b->base_dst) + b->dst, 16, b->dst_stride,
                               xd->plane[0].eobs[i]);
389
      } else {
390 391
        xd->itxm_add(BLOCK_OFFSET(xd->plane[0].qcoeff, i, 16),
                     b->dequant, b->predictor,
John Koleszar's avatar
John Koleszar committed
392 393
                     *(b->base_dst) + b->dst, 16, b->dst_stride,
                     xd->plane[0].eobs[i]);
394 395
      }
    }
396 397 398 399
#if CONFIG_NEWBINTRAMODES
    if (!xd->mode_info_context->mbmi.mb_skip_coeff)
      vp9_decode_mb_tokens_4x4_uv(pbi, xd, bc);
#endif
400
    vp9_build_intra_predictors_mbuv(xd);
401 402
    xd->itxm_add_uv_block(xd->plane[1].qcoeff, xd->block[16].dequant,
         xd->predictor + 16 * 16, xd->dst.u_buffer,
John Koleszar's avatar
John Koleszar committed
403
         xd->dst.uv_stride, xd->plane[1].eobs);
404 405
    xd->itxm_add_uv_block(xd->plane[2].qcoeff, xd->block[16].dequant,
         xd->predictor + 16 * 16 + 64, xd->dst.v_buffer,
John Koleszar's avatar
John Koleszar committed
406
         xd->dst.uv_stride, xd->plane[2].eobs);
407
  } else if (mode == SPLITMV || get_tx_type_4x4(xd, 0) == DCT_DCT) {
408
    xd->itxm_add_y_block(xd->plane[0].qcoeff,
409 410 411 412
                          xd->block[0].dequant,
                          xd->predictor,
                          xd->dst.y_buffer,
                          xd->dst.y_stride,
413
                          xd);
414 415
    xd->itxm_add_uv_block(xd->plane[1].qcoeff, xd->block[16].dequant,
         xd->predictor + 16 * 16, xd->dst.u_buffer,
John Koleszar's avatar
John Koleszar committed
416
         xd->dst.uv_stride, xd->plane[1].eobs);
417 418
    xd->itxm_add_uv_block(xd->plane[2].qcoeff, xd->block[16].dequant,
         xd->predictor + 16 * 16 + 64, xd->dst.v_buffer,
John Koleszar's avatar
John Koleszar committed
419
         xd->dst.uv_stride, xd->plane[2].eobs);
420
  } else {
421 422
    for (i = 0; i < 16; i++) {
      BLOCKD *b = &xd->block[i];
423
      tx_type = get_tx_type_4x4(xd, i);
424
      if (tx_type != DCT_DCT) {
425 426 427 428 429
        vp9_dequant_iht_add_c(tx_type,
                              BLOCK_OFFSET(xd->plane[0].qcoeff, i, 16),
                              b->dequant, b->predictor,
                              *(b->base_dst) + b->dst, 16,
                              b->dst_stride, xd->plane[0].eobs[i]);
430
      } else {
431 432
        xd->itxm_add(BLOCK_OFFSET(xd->plane[0].qcoeff, i, 16),
                     b->dequant, b->predictor,
John Koleszar's avatar
John Koleszar committed
433 434
                     *(b->base_dst) + b->dst, 16, b->dst_stride,
                     xd->plane[0].eobs[i]);
435 436
      }
    }
437 438
    xd->itxm_add_uv_block(xd->plane[1].qcoeff, xd->block[16].dequant,
                          xd->predictor + 16 * 16, xd->dst.u_buffer,
John Koleszar's avatar
John Koleszar committed
439
                          xd->dst.uv_stride, xd->plane[1].eobs);
440 441
    xd->itxm_add_uv_block(xd->plane[2].qcoeff, xd->block[16].dequant,
                          xd->predictor + 16 * 16 + 64, xd->dst.v_buffer,
John Koleszar's avatar
John Koleszar committed
442
                          xd->dst.uv_stride, xd->plane[2].eobs);
443 444 445
  }
}

446
static void decode_sb_16x16(MACROBLOCKD *mb, int y_size) {
447 448 449 450 451 452 453 454 455
  const int y_count = y_size * y_size;
  const int uv_size = y_size / 2;
  const int uv_count = uv_size * uv_size;
  int n;

  for (n = 0; n < y_count; n++) {
    const int x_idx = n % y_size;
    const int y_idx = n / y_size;
    const int y_offset = (y_idx * 16) * mb->dst.y_stride + (x_idx * 16);
456 457
    const TX_TYPE tx_type = get_tx_type_16x16(mb,
                                (y_idx * (4 * y_size) + x_idx) * 4);
458
    if (tx_type == DCT_DCT) {
459
      vp9_dequant_idct_add_16x16(BLOCK_OFFSET(mb->plane[0].qcoeff, n, 256),
460 461 462 463
                                 mb->block[0].dequant ,
                                 mb->dst.y_buffer + y_offset,
                                 mb->dst.y_buffer + y_offset,
                                 mb->dst.y_stride, mb->dst.y_stride,
John Koleszar's avatar
John Koleszar committed
464
                                 mb->plane[0].eobs[n * 16]);
465
    } else {
466 467 468 469 470 471 472
      vp9_dequant_iht_add_16x16_c(tx_type,
                                  BLOCK_OFFSET(mb->plane[0].qcoeff, n, 256),
                                  mb->block[0].dequant,
                                  mb->dst.y_buffer + y_offset,
                                  mb->dst.y_buffer + y_offset,
                                  mb->dst.y_stride, mb->dst.y_stride,
                                  mb->plane[0].eobs[n * 16]);
473 474 475 476 477 478 479
    }
  }

  for (n = 0; n < uv_count; n++) {
    const int x_idx = n % uv_size;
    const int y_idx = n / uv_size;
    const int uv_offset = (y_idx * 16) * mb->dst.uv_stride + (x_idx * 16);
480
    vp9_dequant_idct_add_16x16(BLOCK_OFFSET(mb->plane[1].qcoeff, n, 256),
481 482 483 484
                               mb->block[16].dequant,
                               mb->dst.u_buffer + uv_offset,
                               mb->dst.u_buffer + uv_offset,
                               mb->dst.uv_stride, mb->dst.uv_stride,
John Koleszar's avatar
John Koleszar committed
485
                               mb->plane[1].eobs[n * 16]);
486
    vp9_dequant_idct_add_16x16(BLOCK_OFFSET(mb->plane[2].qcoeff, n, 256),
487 488 489 490
                               mb->block[20].dequant,
                               mb->dst.v_buffer + uv_offset,
                               mb->dst.v_buffer + uv_offset,
                               mb->dst.uv_stride, mb->dst.uv_stride,
John Koleszar's avatar
John Koleszar committed
491
                               mb->plane[2].eobs[n * 16]);
492 493 494
  }
}

495
static INLINE void decode_sb_8x8(MACROBLOCKD *xd, int y_size) {
496 497 498 499 500 501 502 503 504
  const int y_count = y_size * y_size;
  const int uv_size = y_size / 2;
  const int uv_count = uv_size * uv_size;
  int n;

  // luma
  for (n = 0; n < y_count; n++) {
    const int x_idx = n % y_size;
    const int y_idx = n / y_size;
505 506
    const int y_offset = (y_idx * 8) * xd->dst.y_stride + (x_idx * 8);
    const TX_TYPE tx_type = get_tx_type_8x8(xd,
507
                                            (y_idx * (2 * y_size) + x_idx) * 2);
508
    if (tx_type == DCT_DCT) {
509 510 511 512 513
      vp9_dequant_idct_add_8x8_c(BLOCK_OFFSET(xd->plane[0].qcoeff, n, 64),
                                 xd->block[0].dequant,
                                 xd->dst.y_buffer + y_offset,
                                 xd->dst.y_buffer + y_offset,
                                 xd->dst.y_stride, xd->dst.y_stride,
John Koleszar's avatar
John Koleszar committed
514
                                 xd->plane[0].eobs[n * 4]);
515
    } else {
516 517 518 519 520 521 522
      vp9_dequant_iht_add_8x8_c(tx_type,
                                BLOCK_OFFSET(xd->plane[0].qcoeff, n, 64),
                                xd->block[0].dequant,
                                xd->dst.y_buffer + y_offset,
                                xd->dst.y_buffer + y_offset,
                                xd->dst.y_stride, xd->dst.y_stride,
                                xd->plane[0].eobs[n * 4]);
523 524 525 526 527 528 529
    }
  }

  // chroma
  for (n = 0; n < uv_count; n++) {
    const int x_idx = n % uv_size;
    const int y_idx = n / uv_size;
530 531 532 533 534 535
    const int uv_offset = (y_idx * 8) * xd->dst.uv_stride + (x_idx * 8);
    vp9_dequant_idct_add_8x8_c(BLOCK_OFFSET(xd->plane[1].qcoeff, n, 64),
                               xd->block[16].dequant,
                               xd->dst.u_buffer + uv_offset,
                               xd->dst.u_buffer + uv_offset,
                               xd->dst.uv_stride, xd->dst.uv_stride,
John Koleszar's avatar
John Koleszar committed
536
                               xd->plane[1].eobs[n * 4]);
537 538 539 540 541
    vp9_dequant_idct_add_8x8_c(BLOCK_OFFSET(xd->plane[2].qcoeff, n, 64),
                               xd->block[20].dequant,
                               xd->dst.v_buffer + uv_offset,
                               xd->dst.v_buffer + uv_offset,
                               xd->dst.uv_stride, xd->dst.uv_stride,
John Koleszar's avatar
John Koleszar committed
542
                               xd->plane[2].eobs[n * 4]);
543 544 545 546
  }
}


547
static void decode_sb_4x4(MACROBLOCKD *xd, int y_size) {
548 549 550 551 552 553 554 555
  const int y_count = y_size * y_size;
  const int uv_size = y_size / 2;
  const int uv_count = uv_size * uv_size;
  int n;

  for (n = 0; n < y_count; n++) {
    const int x_idx = n % y_size;
    const int y_idx = n / y_size;
556 557
    const int y_offset = (y_idx * 4) * xd->dst.y_stride + (x_idx * 4);
    const TX_TYPE tx_type = get_tx_type_4x4(xd, y_idx * y_size + x_idx);
558
    if (tx_type == DCT_DCT) {
559 560 561 562 563
      xd->itxm_add(BLOCK_OFFSET(xd->plane[0].qcoeff, n, 16),
                   xd->block[0].dequant,
                   xd->dst.y_buffer + y_offset,
                   xd->dst.y_buffer + y_offset,
                   xd->dst.y_stride, xd->dst.y_stride,
John Koleszar's avatar
John Koleszar committed
564
                   xd->plane[0].eobs[n]);
565
    } else {
566 567 568 569 570 571 572 573
      vp9_dequant_iht_add_c(tx_type,
                            BLOCK_OFFSET(xd->plane[0].qcoeff, n, 16),
                            xd->block[0].dequant,
                            xd->dst.y_buffer + y_offset,
                            xd->dst.y_buffer + y_offset,
                            xd->dst.y_stride,
                            xd->dst.y_stride,
                            xd->plane[0].eobs[n]);
574 575 576 577 578 579
    }
  }

  for (n = 0; n < uv_count; n++) {
    const int x_idx = n % uv_size;
    const int y_idx = n / uv_size;
580 581 582 583 584
    const int uv_offset = (y_idx * 4) * xd->dst.uv_stride + (x_idx * 4);
    xd->itxm_add(BLOCK_OFFSET(xd->plane[1].qcoeff, n, 16),
        xd->block[16].dequant,
        xd->dst.u_buffer + uv_offset,
        xd->dst.u_buffer + uv_offset,
John Koleszar's avatar
John Koleszar committed
585
        xd->dst.uv_stride, xd->dst.uv_stride, xd->plane[1].eobs[n]);
586 587 588 589
    xd->itxm_add(BLOCK_OFFSET(xd->plane[2].qcoeff, n, 16),
        xd->block[20].dequant,
        xd->dst.v_buffer + uv_offset,
        xd->dst.v_buffer + uv_offset,
John Koleszar's avatar
John Koleszar committed
590
        xd->dst.uv_stride, xd->dst.uv_stride, xd->plane[2].eobs[n]);
591 592 593
  }
}

594 595
static void decode_sb64(VP9D_COMP *pbi, MACROBLOCKD *xd, int mb_row, int mb_col,
                        BOOL_DECODER* const bc) {
596
  int n, eobtotal;
597
  VP9_COMMON *const pc = &pbi->common;
598
  MODE_INFO *mi = xd->mode_info_context;
599
  const int mis = pc->mode_info_stride;
600

601
  assert(mi->mbmi.sb_type == BLOCK_SIZE_SB64X64);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
602 603

  if (pbi->common.frame_type != KEY_FRAME)
604
    vp9_setup_interp_filters(xd, mi->mbmi.interp_filter, pc);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
605 606 607 608 609

  // re-initialize macroblock dequantizer before detokenization
  if (xd->segmentation_enabled)
    mb_init_dequantizer(pbi, xd);

610
  if (mi->mbmi.mb_skip_coeff) {
611
    vp9_reset_sb_tokens_context(xd, BLOCK_SIZE_SB64X64);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
612

613 614
    // Special case:  Force the loopfilter to skip when eobtotal and
    // mb_skip_coeff are zero.
615
    skip_recon_mb(pbi, xd, mb_row, mb_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
616 617 618
    return;
  }

619
  // do prediction
Ronald S. Bultje's avatar
Ronald S. Bultje committed
620 621 622 623
  if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
    vp9_build_intra_predictors_sb64y_s(xd);
    vp9_build_intra_predictors_sb64uv_s(xd);
  } else {
624
    vp9_build_inter64x64_predictors_sb(xd, mb_row, mb_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
625 626
  }

627
  // dequantization and idct
628
  eobtotal = vp9_decode_tokens(pbi, xd, bc, BLOCK_SIZE_SB64X64);
629
  if (eobtotal == 0) {  // skip loopfilter
Ronald S. Bultje's avatar
Ronald S. Bultje committed
630
    for (n = 0; n < 16; n++) {
631
      const int x_idx = n & 3, y_idx = n >> 2;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
632

633 634 635 636 637 638 639 640
      if (mb_col + x_idx < pc->mb_cols && mb_row + y_idx < pc->mb_rows)
        mi[y_idx * mis + x_idx].mbmi.mb_skip_coeff = mi->mbmi.mb_skip_coeff;
    }
  } else {
    switch (xd->mode_info_context->mbmi.txfm_size) {
      case TX_32X32:
        for (n = 0; n < 4; n++) {
          const int x_idx = n & 1, y_idx = n >> 1;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
641
          const int y_offset = x_idx * 32 + y_idx * xd->dst.y_stride * 32;
642
          vp9_dequant_idct_add_32x32(BLOCK_OFFSET(xd->plane[0].qcoeff, n, 1024),
643
              xd->block[0].dequant,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
644 645
              xd->dst.y_buffer + y_offset,
              xd->dst.y_buffer + y_offset,
John Koleszar's avatar
John Koleszar committed
646
              xd->dst.y_stride, xd->dst.y_stride, xd->plane[0].eobs[n * 64]);
647
        }
648
        vp9_dequant_idct_add_32x32(xd->plane[1].qcoeff,
649
            xd->block[16].dequant, xd->dst.u_buffer, xd->dst.u_buffer,
John Koleszar's avatar
John Koleszar committed
650
            xd->dst.uv_stride, xd->dst.uv_stride, xd->plane[1].eobs[0]);
651
        vp9_dequant_idct_add_32x32(xd->plane[2].qcoeff,
652
            xd->block[20].dequant, xd->dst.v_buffer, xd->dst.v_buffer,
John Koleszar's avatar
John Koleszar committed
653
            xd->dst.uv_stride, xd->dst.uv_stride, xd->plane[2].eobs[0]);
654
        break;
655
      case TX_16X16:
656
        decode_sb_16x16(xd, 4);
657
        break;
658
      case TX_8X8:
659
        decode_sb_8x8(xd, 8);
660
        break;
661
      case TX_4X4:
662
        decode_sb_4x4(xd, 16);
663 664
        break;
      default: assert(0);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
665 666
    }
  }
667 668 669
#if CONFIG_CODE_NONZEROCOUNT
  propagate_nzcs(&pbi->common, xd);
#endif
Ronald S. Bultje's avatar
Ronald S. Bultje committed
670 671
}

672 673
static void decode_sb32(VP9D_COMP *pbi, MACROBLOCKD *xd, int mb_row, int mb_col,
                        BOOL_DECODER* const bc) {
674
  int eobtotal;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
675
  VP9_COMMON *const pc = &pbi->common;
676
  MODE_INFO *mi = xd->mode_info_context;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
677 678
  const int mis = pc->mode_info_stride;

679
  assert(mi->mbmi.sb_type == BLOCK_SIZE_SB32X32);
680

681
  if (pbi->common.frame_type != KEY_FRAME)
682
    vp9_setup_interp_filters(xd, mi->mbmi.interp_filter, pc);
683

684 685 686 687
  // re-initialize macroblock dequantizer before detokenization
  if (xd->segmentation_enabled)
    mb_init_dequantizer(pbi, xd);

688
  if (mi->mbmi.mb_skip_coeff) {
689
    vp9_reset_sb_tokens_context(xd, BLOCK_SIZE_SB32X32);
690

691 692
    // Special case:  Force the loopfilter to skip when eobtotal and
    // mb_skip_coeff are zero.
693
    skip_recon_mb(pbi, xd, mb_row, mb_col);
694 695 696
    return;
  }

697 698

  // do prediction
699
  if (mi->mbmi.ref_frame == INTRA_FRAME) {
700 701 702
    vp9_build_intra_predictors_sby_s(xd);
    vp9_build_intra_predictors_sbuv_s(xd);
  } else {
703
    vp9_build_inter32x32_predictors_sb(xd, mb_row, mb_col);
704 705
  }

706
  // dequantization and idct
707
  eobtotal = vp9_decode_tokens(pbi, xd, bc, BLOCK_SIZE_SB32X32);
708
  if (eobtotal == 0) {  // skip loopfilter
709
    mi->mbmi.mb_skip_coeff = 1;
710
    if (mb_col + 1 < pc->mb_cols)
711
      mi[1].mbmi.mb_skip_coeff = 1;
712
    if (mb_row + 1 < pc->mb_rows) {
713
      mi[mis].mbmi.mb_skip_coeff = 1;
714
      if (mb_col + 1 < pc->mb_cols)
715
        mi[mis + 1].mbmi.mb_skip_coeff = 1;
716
    }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
717
  } else {
718 719
    switch (xd->mode_info_context->mbmi.txfm_size) {
      case TX_32X32:
720
        vp9_dequant_idct_add_32x32(xd->plane[0].qcoeff, xd->block[0].dequant,
721 722
                                   xd->dst.y_buffer, xd->dst.y_buffer,
                                   xd->dst.y_stride, xd->dst.y_stride,
John Koleszar's avatar
John Koleszar committed
723
                                   xd->plane[0].eobs[0]);
724 725 726
        vp9_dequant_idct_add_16x16(xd->plane[1].qcoeff, xd->block[16].dequant,
                                   xd->dst.u_buffer, xd->dst.u_buffer,
                                   xd->dst.uv_stride, xd->dst.uv_stride,
John Koleszar's avatar
John Koleszar committed
727
                                   xd->plane[1].eobs[0]);
728 729 730
        vp9_dequant_idct_add_16x16(xd->plane[2].qcoeff, xd->block[16].dequant,
                                   xd->dst.v_buffer, xd->dst.v_buffer,
                                   xd->dst.uv_stride, xd->dst.uv_stride,
John Koleszar's avatar
John Koleszar committed
731
                                   xd->plane[2].eobs[0]);
732
        break;
733
      case TX_16X16:
734
        decode_sb_16x16(xd, 2);
735
        break;
736
      case TX_8X8:
737
        decode_sb_8x8(xd, 4);
738
        break;
739
      case TX_4X4:
740
        decode_sb_4x4(xd, 8);
741 742
        break;
      default: assert(0);
743
    }
Ronald S. Bultje's avatar