vp9_decodframe.c 63.3 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
  for (q = 0; q < QINDEX_RANGE; q++) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
105 106
    pc->y_dequant[q][0] = (int16_t)vp9_dc_quant(q, pc->y1dc_delta_q);
    pc->uv_dequant[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->y_dequant[q][rc] = (int16_t)vp9_ac_yquant(q);
      pc->uv_dequant[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
  for (i = 0; i < 16; i++)
Dmitry Kovalev's avatar
Dmitry Kovalev committed
139
    mb->block[i].dequant = pc->y_dequant[qindex];
John Koleszar's avatar
John Koleszar committed
140

Dmitry Kovalev's avatar
Dmitry Kovalev committed
141
  for (i = 16; i < 24; i++)
Dmitry Kovalev's avatar
Dmitry Kovalev committed
142
    mb->block[i].dequant = pc->uv_dequant[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
static void skip_recon_sb(VP9D_COMP *pbi, MACROBLOCKD *xd,
                          int mb_row, int mb_col,
                          BLOCK_SIZE_TYPE bsize) {
189
  MODE_INFO *m = xd->mode_info_context;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
190

191
  if (m->mbmi.ref_frame == INTRA_FRAME) {
192 193
    vp9_build_intra_predictors_sbuv_s(xd, bsize);
    vp9_build_intra_predictors_sby_s(xd, bsize);
John Koleszar's avatar
John Koleszar committed
194
  } else {
195
    vp9_build_inter_predictors_sb(xd, mb_row, mb_col, bsize);
John Koleszar's avatar
John Koleszar committed
196
  }
197 198 199 200
#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
201 202
}

203 204
static void decode_16x16(VP9D_COMP *pbi, MACROBLOCKD *xd,
                         BOOL_DECODER* const bc) {
205
  const TX_TYPE tx_type = get_tx_type_16x16(xd, 0);
206

207
  if (tx_type != DCT_DCT) {
208
    vp9_dequant_iht_add_16x16_c(tx_type, xd->plane[0].qcoeff,
209 210 211
                                xd->block[0].dequant, xd->dst.y_buffer,
                                xd->dst.y_buffer, xd->dst.y_stride,
                                xd->dst.y_stride, xd->plane[0].eobs[0]);
212
  } else {
213
    vp9_dequant_idct_add_16x16(xd->plane[0].qcoeff, xd->block[0].dequant,
214 215 216
                               xd->dst.y_buffer, xd->dst.y_buffer,
                               xd->dst.y_stride, xd->dst.y_stride,
                               xd->plane[0].eobs[0]);
217
  }
218 219

  vp9_dequant_idct_add_8x8(xd->plane[1].qcoeff, xd->block[16].dequant,
220 221 222
                           xd->dst.u_buffer, xd->dst.u_buffer,
                           xd->dst.uv_stride, xd->dst.uv_stride,
                           xd->plane[1].eobs[0]);
223

Dmitry Kovalev's avatar
Dmitry Kovalev committed
224
  vp9_dequant_idct_add_8x8(xd->plane[2].qcoeff, xd->block[20].dequant,
225 226 227
                           xd->dst.v_buffer, xd->dst.v_buffer,
                           xd->dst.uv_stride, xd->dst.uv_stride,
                           xd->plane[2].eobs[0]);
228 229 230 231
}

static void decode_8x8(VP9D_COMP *pbi, MACROBLOCKD *xd,
                       BOOL_DECODER* const bc) {
232 233
  const MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode;
  // luma
234
  // if the first one is DCT_DCT assume all the rest are as well
235
  TX_TYPE tx_type = get_tx_type_8x8(xd, 0);
236
  if (tx_type != DCT_DCT || mode == I8X8_PRED) {
237 238 239 240
    int i;
    for (i = 0; i < 4; i++) {
      int ib = vp9_i8x8_block[i];
      int idx = (ib & 0x02) ? (ib + 2) : ib;
241
      int16_t *q  = BLOCK_OFFSET(xd->plane[0].qcoeff, idx, 16);
242 243
      int16_t *dq = xd->block[0].dequant;
      uint8_t *dst = *(xd->block[ib].base_dst) + xd->block[ib].dst;
244
      int stride = xd->dst.y_stride;
245
      if (mode == I8X8_PRED) {
246
        BLOCKD *b = &xd->block[ib];
247
        int i8x8mode = b->bmi.as_mode.first;
248
        vp9_intra8x8_predict(xd, b, i8x8mode, dst, stride);
249
      }
250
      tx_type = get_tx_type_8x8(xd, ib);
251
      if (tx_type != DCT_DCT) {
252
        vp9_dequant_iht_add_8x8_c(tx_type, q, dq, dst, dst, stride, stride,
253
                                  xd->plane[0].eobs[idx]);
254
      } else {
255
        vp9_dequant_idct_add_8x8_c(q, dq, dst, dst, stride, stride,
John Koleszar's avatar
John Koleszar committed
256
                                   xd->plane[0].eobs[idx]);
257 258
      }
    }
259
  } else {
260
    vp9_dequant_idct_add_y_block_8x8(xd->plane[0].qcoeff,
261
                                     xd->block[0].dequant,
262 263
                                     xd->dst.y_buffer,
                                     xd->dst.y_stride,
264 265
                                     xd->dst.y_buffer,
                                     xd->dst.y_stride,
266
                                     xd);
267 268
  }

269 270
  // chroma
  if (mode == I8X8_PRED) {
271 272 273 274 275
    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;
276

277
      b = &xd->block[16 + i];
278 279
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, *(b->base_dst) + b->dst,
                              b->dst_stride);
280
      xd->itxm_add(BLOCK_OFFSET(xd->plane[1].qcoeff, i, 16),
281 282
                   b->dequant, *(b->base_dst) + b->dst,
                   *(b->base_dst) + b->dst, b->dst_stride, b->dst_stride,
John Koleszar's avatar
John Koleszar committed
283
                   xd->plane[1].eobs[i]);
284

285
      b = &xd->block[20 + i];
286 287
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, *(b->base_dst) + b->dst,
                              b->dst_stride);
288
      xd->itxm_add(BLOCK_OFFSET(xd->plane[2].qcoeff, i, 16),
289 290
                   b->dequant, *(b->base_dst) + b->dst,
                   *(b->base_dst) + b->dst, b->dst_stride, b->dst_stride,
John Koleszar's avatar
John Koleszar committed
291
                   xd->plane[2].eobs[i]);
292
    }
293
  } else if (mode == SPLITMV) {
294
    xd->itxm_add_uv_block(xd->plane[1].qcoeff, xd->block[16].dequant,
295
         xd->dst.u_buffer, xd->dst.uv_stride, xd->dst.u_buffer,
John Koleszar's avatar
John Koleszar committed
296
         xd->dst.uv_stride, xd->plane[1].eobs);
297
    xd->itxm_add_uv_block(xd->plane[2].qcoeff, xd->block[16].dequant,
298
         xd->dst.v_buffer, xd->dst.uv_stride, xd->dst.v_buffer,
John Koleszar's avatar
John Koleszar committed
299
         xd->dst.uv_stride, xd->plane[2].eobs);
300
  } else {
301
    vp9_dequant_idct_add_8x8(xd->plane[1].qcoeff, xd->block[16].dequant,
302 303 304
                             xd->dst.u_buffer, xd->dst.u_buffer,
                             xd->dst.uv_stride, xd->dst.uv_stride,
                             xd->plane[1].eobs[0]);
305 306

    vp9_dequant_idct_add_8x8(xd->plane[2].qcoeff, xd->block[16].dequant,
307 308 309
                             xd->dst.v_buffer, xd->dst.v_buffer,
                             xd->dst.uv_stride, xd->dst.uv_stride,
                             xd->plane[2].eobs[0]);
310 311 312 313 314 315
  }
}

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

435 436 437 438
static INLINE void decode_sby_32x32(MACROBLOCKD *mb, BLOCK_SIZE_TYPE bsize) {
  const int bwl = mb_width_log2(bsize) - 1, bw = 1 << bwl;
  const int bhl = mb_height_log2(bsize) - 1, bh = 1 << bhl;
  const int y_count = bw * bh;
439 440 441
  int n;

  for (n = 0; n < y_count; n++) {
442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> bwl;
    const int y_offset = (y_idx * 32) * mb->dst.y_stride + (x_idx * 32);
    vp9_dequant_idct_add_32x32(BLOCK_OFFSET(mb->plane[0].qcoeff, n, 1024),
                               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 * 64]);
  }
}

static INLINE void decode_sbuv_32x32(MACROBLOCKD *mb, BLOCK_SIZE_TYPE bsize) {
  const int bwl = mb_width_log2(bsize) - 1, bw = (1 << bwl) / 2;
  const int bhl = mb_height_log2(bsize) - 1, bh = (1 << bhl) / 2;
  const int uv_count = bw * bh;
  int n;
  for (n = 0; n < uv_count; n++) {
     const int x_idx = n & (bw - 1);
     const int y_idx = n >> (bwl - 1);
     const int uv_offset = (y_idx * 32) * mb->dst.uv_stride + (x_idx * 32);
     vp9_dequant_idct_add_32x32(BLOCK_OFFSET(mb->plane[1].qcoeff, n, 1024),
                                mb->block[16].dequant,
                                mb->dst.u_buffer + uv_offset,
                                mb->dst.u_buffer + uv_offset,
                                mb->dst.uv_stride, mb->dst.uv_stride,
                                mb->plane[1].eobs[n * 64]);
     vp9_dequant_idct_add_32x32(BLOCK_OFFSET(mb->plane[2].qcoeff, n, 1024),
                                mb->block[20].dequant,
                                mb->dst.v_buffer + uv_offset,
                                mb->dst.v_buffer + uv_offset,
                                mb->dst.uv_stride, mb->dst.uv_stride,
                                mb->plane[2].eobs[n * 64]);
  }
}

static INLINE void decode_sby_16x16(MACROBLOCKD *mb, BLOCK_SIZE_TYPE bsize) {
  const int bwl = mb_width_log2(bsize), bw = 1 << bwl;
  const int bhl = mb_height_log2(bsize), bh = 1 << bhl;
  const int y_count = bw * bh;
  int n;

  for (n = 0; n < y_count; n++) {
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> bwl;
487
    const int y_offset = (y_idx * 16) * mb->dst.y_stride + (x_idx * 16);
488
    const TX_TYPE tx_type = get_tx_type_16x16(mb,
489
                                (y_idx * (4 * bw) + x_idx) * 4);
490
    if (tx_type == DCT_DCT) {
491
      vp9_dequant_idct_add_16x16(BLOCK_OFFSET(mb->plane[0].qcoeff, n, 256),
492 493 494 495
                                 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
496
                                 mb->plane[0].eobs[n * 16]);
497
    } else {
498 499 500 501 502 503 504
      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]);
505 506
    }
  }
507 508 509 510 511 512 513 514 515
}

static INLINE void decode_sbuv_16x16(MACROBLOCKD *mb, BLOCK_SIZE_TYPE bsize) {
  const int bwl = mb_width_log2(bsize), bw = (1 << bwl) / 2;
  const int bhl = mb_height_log2(bsize), bh = (1 << bhl) / 2;
  const int uv_count = bw * bh;
  int n;

  assert(bsize >= BLOCK_SIZE_SB32X32);
516 517

  for (n = 0; n < uv_count; n++) {
518 519
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> (bwl - 1);
520
    const int uv_offset = (y_idx * 16) * mb->dst.uv_stride + (x_idx * 16);
521
    vp9_dequant_idct_add_16x16(BLOCK_OFFSET(mb->plane[1].qcoeff, n, 256),
522 523 524 525
                               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
526
                               mb->plane[1].eobs[n * 16]);
527
    vp9_dequant_idct_add_16x16(BLOCK_OFFSET(mb->plane[2].qcoeff, n, 256),
528 529 530 531
                               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
532
                               mb->plane[2].eobs[n * 16]);
533 534 535
  }
}

536 537 538 539
static INLINE void decode_sby_8x8(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize) {
  const int bwl = mb_width_log2(bsize)  + 1, bw = 1 << bwl;
  const int bhl = mb_height_log2(bsize) + 1, bh = 1 << bhl;
  const int y_count = bw * bh;
540 541 542 543
  int n;

  // luma
  for (n = 0; n < y_count; n++) {
544 545
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> bwl;
546 547
    const int y_offset = (y_idx * 8) * xd->dst.y_stride + (x_idx * 8);
    const TX_TYPE tx_type = get_tx_type_8x8(xd,
548
                                            (y_idx * (2 * bw) + x_idx) * 2);
549
    if (tx_type == DCT_DCT) {
550 551 552 553 554
      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
555
                                 xd->plane[0].eobs[n * 4]);
556
    } else {
557 558 559 560 561 562 563
      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]);
564 565
    }
  }
566 567 568 569 570 571 572
}

static INLINE void decode_sbuv_8x8(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize) {
  const int bwl = mb_width_log2(bsize)  + 1, bw = 1 << (bwl - 1);
  const int bhl = mb_height_log2(bsize) + 1, bh = 1 << (bhl - 1);
  const int uv_count = bw * bh;
  int n;
573 574 575

  // chroma
  for (n = 0; n < uv_count; n++) {
576 577
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> (bwl - 1);
578 579 580 581 582 583
    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
584
                               xd->plane[1].eobs[n * 4]);
585 586 587 588 589
    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
590
                               xd->plane[2].eobs[n * 4]);
591 592 593
  }
}

594 595 596 597
static INLINE void decode_sby_4x4(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize) {
  const int bwl = mb_width_log2(bsize)  + 2, bw = 1 << bwl;
  const int bhl = mb_height_log2(bsize) + 2, bh = 1 << bhl;
  const int y_count = bw * bh;
598 599 600
  int n;

  for (n = 0; n < y_count; n++) {
601 602
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> bwl;
603
    const int y_offset = (y_idx * 4) * xd->dst.y_stride + (x_idx * 4);
604
    const TX_TYPE tx_type = get_tx_type_4x4(xd, n);
605
    if (tx_type == DCT_DCT) {
606 607 608 609 610
      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
611
                   xd->plane[0].eobs[n]);
612
    } else {
613 614 615 616 617 618 619 620
      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]);
621 622
    }
  }
623 624 625 626 627 628 629
}

static INLINE void decode_sbuv_4x4(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize) {
  const int bwl = mb_width_log2(bsize)  + 2, bw = 1 << (bwl - 1);
  const int bhl = mb_height_log2(bsize) + 2, bh = 1 << (bhl - 1);
  const int uv_count = bw * bh;
  int n;
630 631

  for (n = 0; n < uv_count; n++) {
632 633
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> (bwl - 1);
634 635 636 637 638
    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
639
        xd->dst.uv_stride, xd->dst.uv_stride, xd->plane[1].eobs[n]);
640 641 642 643
    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
644
        xd->dst.uv_stride, xd->dst.uv_stride, xd->plane[2].eobs[n]);
645 646 647
  }
}

648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669
// TODO(jingning): combine luma and chroma dequantization and inverse
// transform into a single function looping over planes.
static void decode_sb_32x32(MACROBLOCKD *mb, BLOCK_SIZE_TYPE bsize) {
  decode_sby_32x32(mb, bsize);
  if (bsize == BLOCK_SIZE_SB64X64)
    decode_sbuv_32x32(mb, bsize);
  else
    decode_sbuv_16x16(mb, bsize);
}

static void decode_sb_16x16(MACROBLOCKD *mb, BLOCK_SIZE_TYPE bsize) {
  decode_sby_16x16(mb, bsize);
  if (bsize >= BLOCK_SIZE_SB32X32)
    decode_sbuv_16x16(mb, bsize);
  else
    decode_sbuv_8x8(mb, bsize);
}

static void decode_sb(VP9D_COMP *pbi, MACROBLOCKD *xd, int mb_row, int mb_col,
                      BOOL_DECODER* const bc, BLOCK_SIZE_TYPE bsize) {
  const int bwl = mb_width_log2(bsize), bhl = mb_height_log2(bsize);
  const int bw = 1 << bwl, bh = 1 << bhl;
670
  int n, eobtotal;
671
  VP9_COMMON *const pc = &pbi->common;
672
  MODE_INFO *mi = xd->mode_info_context;
673
  const int mis = pc->mode_info_stride;
674

675
  assert(mi->mbmi.sb_type == bsize);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
676 677

  if (pbi->common.frame_type != KEY_FRAME)
678
    vp9_setup_interp_filters(xd, mi->mbmi.interp_filter, pc);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
679 680 681 682 683

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

684
  if (mi->mbmi.mb_skip_coeff) {
685
    vp9_reset_sb_tokens_context(xd, bsize);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
686

687 688
    // Special case:  Force the loopfilter to skip when eobtotal and
    // mb_skip_coeff are zero.
689
    skip_recon_sb(pbi, xd, mb_row, mb_col, bsize);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
690 691 692
    return;
  }

693
  // generate prediction
694 695 696
  if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
    vp9_build_intra_predictors_sby_s(xd, bsize);
    vp9_build_intra_predictors_sbuv_s(xd, bsize);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
697
  } else {
698
    vp9_build_inter_predictors_sb(xd, mb_row, mb_col, bsize);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
699 700
  }

701
  // dequantization and idct
702
  eobtotal = vp9_decode_tokens(pbi, xd, bc, bsize);
703
  if (eobtotal == 0) {  // skip loopfilter
704 705
    for (n = 0; n < bw * bh; n++) {
      const int x_idx = n & (bw - 1), y_idx = n >> bwl;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
706

707 708 709 710 711 712
      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:
713
        decode_sb_32x32(xd, bsize);
714
        break;
715
      case TX_16X16:
716
        decode_sb_16x16(xd, bsize);
717
        break;
718
      case TX_8X8:
719 720
        decode_sby_8x8(xd, bsize);
        decode_sbuv_8x8(xd, bsize);
721
        break;
722
      case TX_4X4:
723 724
        decode_sby_4x4(xd, bsize);
        decode_sbuv_4x4(xd, bsize);
725 726
        break;
      default: assert(0);
727
    }
728
  }
729 730 731
#if CONFIG_CODE_NONZEROCOUNT
  propagate_nzcs(&pbi->common, xd);
#endif
732 733
}

734 735
// TODO(jingning): Need to merge SB and MB decoding. The MB decoding currently
// couples special handles on I8x8, B_PRED, and splitmv modes.
736 737 738
static void decode_mb(VP9D_COMP *pbi, MACROBLOCKD *xd,
                     int mb_row, int mb_col,
                     BOOL_DECODER* const bc) {
John Koleszar's avatar
John Koleszar committed
739
  int eobtotal = 0;
740 741
  const MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode;
  const int tx_size = xd->mode_info_context->mbmi.txfm_size;
742

Ronald S. Bultje's avatar
Ronald S. Bultje committed
743
  assert(!xd->mode_info_context->mbmi.sb_type);
John Koleszar's avatar
John Koleszar committed
744

Jingning Han's avatar
Jingning Han committed
745 746 747 748
  // re-initialize macroblock dequantizer before detokenization
  if (xd->segmentation_enabled)
    mb_init_dequantizer(pbi, xd);

John Koleszar's avatar
John Koleszar committed
749
  if (xd->mode_info_context->mbmi.mb_skip_coeff) {
750
    vp9_reset_sb_tokens_context(xd, BLOCK_SIZE_MB16X16);
751
  } else if (!bool_error(bc)) {
752
#if CONFIG_NEWBINTRAMODES
Yaowu Xu's avatar
Yaowu Xu committed
753
    if (mode != I4X4_PRED)
754
#endif
755
      eobtotal = vp9_decode_tokens(pbi, xd, bc, BLOCK_SIZE_MB16X16);
John Koleszar's avatar
John Koleszar committed
756
  }
757

Deb Mukherjee's avatar
Deb Mukherjee committed
758
  //mode = xd->mode_info_context->mbmi.mode;