vp9_decodframe.c 53.8 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
// #define DEC_DEBUG
41 42 43 44
#ifdef DEC_DEBUG
int dec_debug = 0;
#endif

45 46 47 48 49 50 51 52 53
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
54 55
static int read_is_valid(const uint8_t *start, size_t len,
                         const uint8_t *end) {
56 57 58
  return start + len > start && start + len <= end;
}

59 60 61 62 63 64 65 66 67 68 69 70 71 72
static void setup_txfm_mode(VP9_COMMON *pc, int lossless, vp9_reader *r) {
  if (lossless) {
    pc->txfm_mode = ONLY_4X4;
  } else {
    pc->txfm_mode = vp9_read_literal(r, 2);
    if (pc->txfm_mode == ALLOW_32X32)
      pc->txfm_mode += vp9_read_bit(r);

    if (pc->txfm_mode == TX_MODE_SELECT) {
      pc->prob_tx[0] = vp9_read_prob(r);
      pc->prob_tx[1] = vp9_read_prob(r);
      pc->prob_tx[2] = vp9_read_prob(r);
    }
  }
73 74
}

75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
static int get_unsigned_bits(unsigned int num_values) {
  int cat = 0;
  if (num_values <= 1)
    return 0;
  num_values--;
  while (num_values > 0) {
    cat++;
    num_values >>= 1;
  }
  return cat;
}

static int inv_recenter_nonneg(int v, int m) {
  if (v > (m << 1))
    return v;
  else if ((v & 1) == 0)
    return (v >> 1) + m;
  else
    return m - ((v + 1) >> 1);
}

96
static int decode_uniform(vp9_reader *r, int n) {
97 98 99 100 101 102
  int v;
  const int l = get_unsigned_bits(n);
  const int m = (1 << l) - n;
  if (!l)
    return 0;

103 104
  v = vp9_read_literal(r, l - 1);
  return v < m ?  v : (v << 1) - m + vp9_read_bit(r);
105 106
}

107
static int decode_term_subexp(vp9_reader *r, int k, int num_syms) {
108 109 110 111 112
  int i = 0, mk = 0, word;
  while (1) {
    const int b = i ? k + i - 1 : k;
    const int a = 1 << b;
    if (num_syms <= mk + 3 * a) {
113
      word = decode_uniform(r, num_syms - mk) + mk;
114 115
      break;
    } else {
116
      if (vp9_read_bit(r)) {
117 118 119
        i++;
        mk += a;
      } else {
120
        word = vp9_read_literal(r, b) + mk;
121 122 123 124 125 126 127
        break;
      }
    }
  }
  return word;
}

128
static int decode_unsigned_max(vp9_reader *r, int max) {
129 130 131
  int data = 0, bit = 0, lmax = max;

  while (lmax) {
132
    data |= vp9_read_bit(r) << bit++;
133 134 135 136 137
    lmax >>= 1;
  }
  return data > max ? max : data;
}

John Koleszar's avatar
John Koleszar committed
138 139 140 141 142 143 144 145 146 147 148 149
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;
150 151
}

John Koleszar's avatar
John Koleszar committed
152 153 154
static int inv_remap_prob(int v, int m) {
  const int n = 256;
  const int modulus = MODULUS_PARAM;
155

John Koleszar's avatar
John Koleszar committed
156 157
  v = merge_index(v, n - 1, modulus);
  if ((m << 1) <= n) {
158
    return inv_recenter_nonneg(v + 1, m);
John Koleszar's avatar
John Koleszar committed
159
  } else {
160
    return n - 1 - inv_recenter_nonneg(v + 1, n - 1 - m);
John Koleszar's avatar
John Koleszar committed
161
  }
162
}
163

164 165
static vp9_prob read_prob_diff_update(vp9_reader *r, int oldp) {
  int delp = decode_term_subexp(r, SUBEXP_PARAM, 255);
166
  return (vp9_prob)inv_remap_prob(delp, oldp);
167
}
168

169
void vp9_init_de_quantizer(VP9D_COMP *pbi) {
John Koleszar's avatar
John Koleszar committed
170
  int i;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
171
  int q;
172
  VP9_COMMON *const pc = &pbi->common;
John Koleszar's avatar
John Koleszar committed
173

Dmitry Kovalev's avatar
Dmitry Kovalev committed
174
  for (q = 0; q < QINDEX_RANGE; q++) {
175
    // DC value
176 177
    pc->y_dequant[q][0] = (int16_t)vp9_dc_quant(q, pc->y_dc_delta_q);
    pc->uv_dequant[q][0] = (int16_t)vp9_dc_uv_quant(q, pc->uv_dc_delta_q);
John Koleszar's avatar
John Koleszar committed
178

179
    // AC values
John Koleszar's avatar
John Koleszar committed
180
    for (i = 1; i < 16; i++) {
181
      const int rc = vp9_default_zig_zag1d_4x4[i];
John Koleszar's avatar
John Koleszar committed
182

Dmitry Kovalev's avatar
Dmitry Kovalev committed
183
      pc->y_dequant[q][rc] = (int16_t)vp9_ac_yquant(q);
184
      pc->uv_dequant[q][rc] = (int16_t)vp9_ac_uv_quant(q, pc->uv_ac_delta_q);
John Koleszar's avatar
John Koleszar committed
185
    }
John Koleszar's avatar
John Koleszar committed
186
  }
John Koleszar's avatar
John Koleszar committed
187 188
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
189 190 191
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)) {
192 193 194 195
    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
196 197 198 199 200 201
  } else {
    return base_qindex;
  }
}

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
204
  VP9_COMMON *const pc = &pbi->common;
205 206
  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
207
  mb->q_index = qindex;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
208

209 210 211
  mb->plane[0].dequant = pc->y_dequant[qindex];
  for (i = 1; i < MAX_MB_PLANE; i++)
    mb->plane[i].dequant = pc->uv_dequant[qindex];
John Koleszar's avatar
John Koleszar committed
212

Dmitry Kovalev's avatar
Dmitry Kovalev committed
213
  if (mb->lossless) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
214
    assert(qindex == 0);
Yaowu Xu's avatar
Yaowu Xu committed
215 216
    mb->inv_txm4x4_1      = vp9_short_iwalsh4x4_1;
    mb->inv_txm4x4        = vp9_short_iwalsh4x4;
217 218 219
    mb->itxm_add          = vp9_idct_add_lossless_c;
    mb->itxm_add_y_block  = vp9_idct_add_y_block_lossless_c;
    mb->itxm_add_uv_block = vp9_idct_add_uv_block_lossless_c;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
220
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
221 222
    mb->inv_txm4x4_1      = vp9_short_idct4x4_1;
    mb->inv_txm4x4        = vp9_short_idct4x4;
223 224 225
    mb->itxm_add          = vp9_idct_add;
    mb->itxm_add_y_block  = vp9_idct_add_y_block;
    mb->itxm_add_uv_block = vp9_idct_add_uv_block;
John Koleszar's avatar
John Koleszar committed
226
  }
John Koleszar's avatar
John Koleszar committed
227 228
}

229
static void decode_16x16(MACROBLOCKD *xd) {
230
  const TX_TYPE tx_type = get_tx_type_16x16(xd, 0);
231

232 233
  vp9_iht_add_16x16_c(tx_type, xd->plane[0].qcoeff, xd->plane[0].dst.buf,
                      xd->plane[0].dst.stride, xd->plane[0].eobs[0]);
234

235 236
  vp9_idct_add_8x8(xd->plane[1].qcoeff, xd->plane[1].dst.buf,
                   xd->plane[1].dst.stride, xd->plane[1].eobs[0]);
237

238 239
  vp9_idct_add_8x8(xd->plane[2].qcoeff, xd->plane[2].dst.buf,
                   xd->plane[1].dst.stride, xd->plane[2].eobs[0]);
240 241
}

242
static void decode_8x8(MACROBLOCKD *xd) {
243 244
  const MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode;
  // luma
245
  // if the first one is DCT_DCT assume all the rest are as well
246
  TX_TYPE tx_type = get_tx_type_8x8(xd, 0);
247
  if (tx_type != DCT_DCT || mode == I8X8_PRED) {
248 249 250 251
    int i;
    for (i = 0; i < 4; i++) {
      int ib = vp9_i8x8_block[i];
      int idx = (ib & 0x02) ? (ib + 2) : ib;
252
      int16_t *q  = BLOCK_OFFSET(xd->plane[0].qcoeff, idx, 16);
253
      uint8_t *dst = *(xd->block[ib].base_dst) + xd->block[ib].dst;
254
      int stride = xd->plane[0].dst.stride;
255
      if (mode == I8X8_PRED) {
256
        BLOCKD *b = &xd->block[ib];
257
        int i8x8mode = b->bmi.as_mode.first;
258
        vp9_intra8x8_predict(xd, b, i8x8mode, dst, stride);
259
      }
260
      tx_type = get_tx_type_8x8(xd, ib);
261
      vp9_iht_add_8x8_c(tx_type, q, dst, stride, xd->plane[0].eobs[idx]);
262
    }
263
  } else {
264 265
    vp9_idct_add_y_block_8x8(xd->plane[0].qcoeff, xd->plane[0].dst.buf,
                             xd->plane[0].dst.stride, xd);
266 267
  }

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

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

283
      b = &xd->block[20 + i];
284 285
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, *(b->base_dst) + b->dst,
                              b->dst_stride);
286
      xd->itxm_add(BLOCK_OFFSET(xd->plane[2].qcoeff, i, 16),
287
                   *(b->base_dst) + b->dst, b->dst_stride,
John Koleszar's avatar
John Koleszar committed
288
                   xd->plane[2].eobs[i]);
289
    }
290
  } else if (mode == SPLITMV) {
291 292 293 294
    xd->itxm_add_uv_block(xd->plane[1].qcoeff, xd->plane[1].dst.buf,
        xd->plane[1].dst.stride, xd->plane[1].eobs);
    xd->itxm_add_uv_block(xd->plane[2].qcoeff, xd->plane[2].dst.buf,
        xd->plane[1].dst.stride, xd->plane[2].eobs);
295
  } else {
296 297
    vp9_idct_add_8x8(xd->plane[1].qcoeff, xd->plane[1].dst.buf,
                     xd->plane[1].dst.stride, xd->plane[1].eobs[0]);
298

299 300
    vp9_idct_add_8x8(xd->plane[2].qcoeff, xd->plane[2].dst.buf,
                     xd->plane[1].dst.stride, xd->plane[2].eobs[0]);
301 302 303
  }
}

304 305
static INLINE void dequant_add_y(MACROBLOCKD *xd, TX_TYPE tx_type, int idx) {
  BLOCKD *const b = &xd->block[idx];
306
  struct macroblockd_plane *const y = &xd->plane[0];
307
  if (tx_type != DCT_DCT) {
308 309
    vp9_iht_add_c(tx_type, BLOCK_OFFSET(y->qcoeff, idx, 16),
                  *(b->base_dst) + b->dst, b->dst_stride, y->eobs[idx]);
310
  } else {
311
    xd->itxm_add(BLOCK_OFFSET(y->qcoeff, idx, 16), *(b->base_dst) + b->dst,
312 313 314 315 316
                 b->dst_stride, y->eobs[idx]);
  }
}


317
static void decode_4x4(VP9D_COMP *pbi, MACROBLOCKD *xd, vp9_reader *r) {
318
  TX_TYPE tx_type;
319
  int i = 0;
320
  const MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode;
321 322 323 324 325
  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
326 327
      BLOCKD *b = &xd->block[ib];
      int i8x8mode = b->bmi.as_mode.first;
328 329
      vp9_intra8x8_predict(xd, b, i8x8mode, *(b->base_dst) + b->dst,
                           b->dst_stride);
330
      for (j = 0; j < 4; j++) {
331
        tx_type = get_tx_type_4x4(xd, ib + iblock[j]);
332
        dequant_add_y(xd, tx_type, ib + iblock[j]);
333 334
      }
      b = &xd->block[16 + i];
335 336
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, *(b->base_dst) + b->dst,
                              b->dst_stride);
337
      xd->itxm_add(BLOCK_OFFSET(xd->plane[1].qcoeff, i, 16),
338
                   *(b->base_dst) + b->dst, b->dst_stride,
John Koleszar's avatar
John Koleszar committed
339
                   xd->plane[1].eobs[i]);
340
      b = &xd->block[20 + i];
341 342
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, *(b->base_dst) + b->dst,
                              b->dst_stride);
343
      xd->itxm_add(BLOCK_OFFSET(xd->plane[2].qcoeff, i, 16),
344
                   *(b->base_dst) + b->dst, b->dst_stride,
John Koleszar's avatar
John Koleszar committed
345
                   xd->plane[2].eobs[i]);
346
    }
Yaowu Xu's avatar
Yaowu Xu committed
347
  } else if (mode == I4X4_PRED) {
348 349
    for (i = 0; i < 16; i++) {
      BLOCKD *b = &xd->block[i];
Dmitry Kovalev's avatar
Dmitry Kovalev committed
350
      int b_mode = xd->mode_info_context->bmi[i].as_mode.first;
351 352
#if CONFIG_NEWBINTRAMODES
      xd->mode_info_context->bmi[i].as_mode.context = b->bmi.as_mode.context =
353
          vp9_find_bpred_context(xd, b);
354
      if (!xd->mode_info_context->mbmi.mb_skip_coeff)
355 356
        vp9_decode_coefs_4x4(pbi, xd, r, PLANE_TYPE_Y_WITH_DC, i,
                             xd->plane[0].dequant);
357
#endif
358 359
      vp9_intra4x4_predict(xd, b, b_mode, *(b->base_dst) + b->dst,
                           b->dst_stride);
360
      tx_type = get_tx_type_4x4(xd, i);
361
      dequant_add_y(xd, tx_type, i);
362
    }
363 364
#if CONFIG_NEWBINTRAMODES
    if (!xd->mode_info_context->mbmi.mb_skip_coeff)
365
      vp9_decode_mb_tokens_4x4_uv(pbi, xd, r, xd->plane[1].dequant);
366
#endif
367
    vp9_build_intra_predictors_sbuv_s(xd, BLOCK_SIZE_MB16X16);
368 369 370 371
    xd->itxm_add_uv_block(xd->plane[1].qcoeff, xd->plane[1].dst.buf,
        xd->plane[1].dst.stride, xd->plane[1].eobs);
    xd->itxm_add_uv_block(xd->plane[2].qcoeff, xd->plane[2].dst.buf,
        xd->plane[1].dst.stride, xd->plane[2].eobs);
372
  } else if (mode == SPLITMV || get_tx_type_4x4(xd, 0) == DCT_DCT) {
373 374 375 376 377 378
    xd->itxm_add_y_block(xd->plane[0].qcoeff, xd->plane[0].dst.buf,
        xd->plane[0].dst.stride, xd);
    xd->itxm_add_uv_block(xd->plane[1].qcoeff, xd->plane[1].dst.buf,
        xd->plane[1].dst.stride, xd->plane[1].eobs);
    xd->itxm_add_uv_block(xd->plane[2].qcoeff, xd->plane[2].dst.buf,
        xd->plane[1].dst.stride, xd->plane[2].eobs);
379
  } else {
380
    for (i = 0; i < 16; i++) {
381
      tx_type = get_tx_type_4x4(xd, i);
382
      dequant_add_y(xd, tx_type, i);
383
    }
384 385 386 387
    xd->itxm_add_uv_block(xd->plane[1].qcoeff, xd->plane[1].dst.buf,
                          xd->plane[1].dst.stride, xd->plane[1].eobs);
    xd->itxm_add_uv_block(xd->plane[2].qcoeff, xd->plane[2].dst.buf,
                          xd->plane[1].dst.stride, xd->plane[2].eobs);
388 389 390
  }
}

391 392 393 394
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;
395 396 397
  int n;

  for (n = 0; n < y_count; n++) {
398 399
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> bwl;
400
    const int y_offset = (y_idx * 32) * mb->plane[0].dst.stride + (x_idx * 32);
401 402 403 404
    vp9_idct_add_32x32(BLOCK_OFFSET(mb->plane[0].qcoeff, n, 1024),
                       mb->plane[0].dst.buf + y_offset,
                       mb->plane[0].dst.stride,
                       mb->plane[0].eobs[n * 64]);
405 406 407 408 409 410 411 412 413 414 415
  }
}

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);
416 417
     const int uv_offset = (y_idx * 32) * mb->plane[1].dst.stride +
         (x_idx * 32);
418 419 420 421 422 423 424 425
     vp9_idct_add_32x32(BLOCK_OFFSET(mb->plane[1].qcoeff, n, 1024),
                        mb->plane[1].dst.buf + uv_offset,
                        mb->plane[1].dst.stride,
                        mb->plane[1].eobs[n * 64]);
     vp9_idct_add_32x32(BLOCK_OFFSET(mb->plane[2].qcoeff, n, 1024),
                        mb->plane[2].dst.buf + uv_offset,
                        mb->plane[1].dst.stride,
                        mb->plane[2].eobs[n * 64]);
426 427 428 429 430 431 432 433 434 435 436 437
  }
}

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;
438
    const int y_offset = (y_idx * 16) * mb->plane[0].dst.stride + (x_idx * 16);
439
    const TX_TYPE tx_type = get_tx_type_16x16(mb,
440
                                (y_idx * (4 * bw) + x_idx) * 4);
441 442 443
    vp9_iht_add_16x16_c(tx_type, BLOCK_OFFSET(mb->plane[0].qcoeff, n, 256),
                        mb->plane[0].dst.buf + y_offset,
                        mb->plane[0].dst.stride, mb->plane[0].eobs[n * 16]);
444
  }
445 446 447 448 449 450 451 452 453
}

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);
454 455

  for (n = 0; n < uv_count; n++) {
456 457
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> (bwl - 1);
458
    const int uv_offset = (y_idx * 16) * mb->plane[1].dst.stride + (x_idx * 16);
459 460 461 462 463 464
    vp9_idct_add_16x16(BLOCK_OFFSET(mb->plane[1].qcoeff, n, 256),
                       mb->plane[1].dst.buf + uv_offset,
                       mb->plane[1].dst.stride, mb->plane[1].eobs[n * 16]);
    vp9_idct_add_16x16(BLOCK_OFFSET(mb->plane[2].qcoeff, n, 256),
                       mb->plane[2].dst.buf + uv_offset,
                       mb->plane[1].dst.stride, mb->plane[2].eobs[n * 16]);
465 466 467
  }
}

468 469 470 471
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;
472 473 474 475
  int n;

  // luma
  for (n = 0; n < y_count; n++) {
476 477
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> bwl;
478
    const int y_offset = (y_idx * 8) * xd->plane[0].dst.stride + (x_idx * 8);
479
    const TX_TYPE tx_type = get_tx_type_8x8(xd,
480
                                            (y_idx * (2 * bw) + x_idx) * 2);
481

482 483 484
    vp9_iht_add_8x8_c(tx_type, BLOCK_OFFSET(xd->plane[0].qcoeff, n, 64),
                      xd->plane[0].dst.buf + y_offset, xd->plane[0].dst.stride,
                      xd->plane[0].eobs[n * 4]);
485
  }
486 487 488 489 490 491 492
}

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;
493 494 495

  // chroma
  for (n = 0; n < uv_count; n++) {
496 497
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> (bwl - 1);
498
    const int uv_offset = (y_idx * 8) * xd->plane[1].dst.stride + (x_idx * 8);
499 500 501 502 503 504
    vp9_idct_add_8x8(BLOCK_OFFSET(xd->plane[1].qcoeff, n, 64),
                     xd->plane[1].dst.buf + uv_offset, xd->plane[1].dst.stride,
                     xd->plane[1].eobs[n * 4]);
    vp9_idct_add_8x8(BLOCK_OFFSET(xd->plane[2].qcoeff, n, 64),
                     xd->plane[2].dst.buf + uv_offset, xd->plane[1].dst.stride,
                     xd->plane[2].eobs[n * 4]);
505 506 507
  }
}

508 509 510 511
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;
512 513 514
  int n;

  for (n = 0; n < y_count; n++) {
515 516
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> bwl;
517
    const int y_offset = (y_idx * 4) * xd->plane[0].dst.stride + (x_idx * 4);
518
    const TX_TYPE tx_type = get_tx_type_4x4(xd, n);
519
    if (tx_type == DCT_DCT) {
520
      xd->itxm_add(BLOCK_OFFSET(xd->plane[0].qcoeff, n, 16),
521
                   xd->plane[0].dst.buf + y_offset, xd->plane[0].dst.stride,
John Koleszar's avatar
John Koleszar committed
522
                   xd->plane[0].eobs[n]);
523
    } else {
524 525 526
      vp9_iht_add_c(tx_type, BLOCK_OFFSET(xd->plane[0].qcoeff, n, 16),
                    xd->plane[0].dst.buf + y_offset, xd->plane[0].dst.stride,
                    xd->plane[0].eobs[n]);
527 528
    }
  }
529 530 531 532 533 534 535
}

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;
536 537

  for (n = 0; n < uv_count; n++) {
538 539
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> (bwl - 1);
540
    const int uv_offset = (y_idx * 4) * xd->plane[1].dst.stride + (x_idx * 4);
541
    xd->itxm_add(BLOCK_OFFSET(xd->plane[1].qcoeff, n, 16),
542 543
        xd->plane[1].dst.buf + uv_offset, xd->plane[1].dst.stride,
        xd->plane[1].eobs[n]);
544
    xd->itxm_add(BLOCK_OFFSET(xd->plane[2].qcoeff, n, 16),
545 546
        xd->plane[2].dst.buf + uv_offset, xd->plane[1].dst.stride,
        xd->plane[2].eobs[n]);
547 548 549
  }
}

550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568
// 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,
569
                      vp9_reader *r, BLOCK_SIZE_TYPE bsize) {
570 571
  const int bwl = mb_width_log2(bsize), bhl = mb_height_log2(bsize);
  const int bw = 1 << bwl, bh = 1 << bhl;
572
  int n, eobtotal;
573
  VP9_COMMON *const pc = &pbi->common;
574
  MODE_INFO *mi = xd->mode_info_context;
575
  const int mis = pc->mode_info_stride;
576

577
  assert(mi->mbmi.sb_type == bsize);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
578 579

  if (pbi->common.frame_type != KEY_FRAME)
580
    vp9_setup_interp_filters(xd, mi->mbmi.interp_filter, pc);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
581

582
  // generate prediction
583 584 585
  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
586
  } else {
587
    vp9_build_inter_predictors_sb(xd, mb_row, mb_col, bsize);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
588 589
  }

Yunqing Wang's avatar
Yunqing Wang committed
590 591
  if (mi->mbmi.mb_skip_coeff) {
    vp9_reset_sb_tokens_context(xd, bsize);
592
  } else {
Yunqing Wang's avatar
Yunqing Wang committed
593 594 595 596 597
    // re-initialize macroblock dequantizer before detokenization
    if (xd->segmentation_enabled)
      mb_init_dequantizer(pbi, xd);

    // dequantization and idct
598
    eobtotal = vp9_decode_tokens(pbi, xd, r, bsize, xd->plane[0].dequant);
Yunqing Wang's avatar
Yunqing Wang committed
599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623
    if (eobtotal == 0) {  // skip loopfilter
      for (n = 0; n < bw * bh; n++) {
        const int x_idx = n & (bw - 1), y_idx = n >> bwl;

        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 = 1;
      }
    } else {
      switch (xd->mode_info_context->mbmi.txfm_size) {
        case TX_32X32:
          decode_sb_32x32(xd, bsize);
          break;
        case TX_16X16:
          decode_sb_16x16(xd, bsize);
          break;
        case TX_8X8:
          decode_sby_8x8(xd, bsize);
          decode_sbuv_8x8(xd, bsize);
          break;
        case TX_4X4:
          decode_sby_4x4(xd, bsize);
          decode_sbuv_4x4(xd, bsize);
          break;
        default: assert(0);
      }
624
    }
625
  }
626 627
}

628 629
// TODO(jingning): Need to merge SB and MB decoding. The MB decoding currently
// couples special handles on I8x8, B_PRED, and splitmv modes.
630 631
static void decode_mb(VP9D_COMP *pbi, MACROBLOCKD *xd,
                     int mb_row, int mb_col,
632
                     vp9_reader *r) {
John Koleszar's avatar
John Koleszar committed
633
  int eobtotal = 0;
634 635
  const MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode;
  const int tx_size = xd->mode_info_context->mbmi.txfm_size;
636

637
  assert(xd->mode_info_context->mbmi.sb_type == BLOCK_SIZE_MB16X16);
John Koleszar's avatar
John Koleszar committed
638

Deb Mukherjee's avatar
Deb Mukherjee committed
639
  //mode = xd->mode_info_context->mbmi.mode;
640
  if (pbi->common.frame_type != KEY_FRAME)
641
    vp9_setup_interp_filters(xd, xd->mode_info_context->mbmi.interp_filter,
642
                             &pbi->common);
Gaute Strokkenes's avatar
Gaute Strokkenes committed
643

644
  // do prediction
John Koleszar's avatar
John Koleszar committed
645 646
  if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
    if (mode != I8X8_PRED) {
647
      vp9_build_intra_predictors_sbuv_s(xd, BLOCK_SIZE_MB16X16);
Yaowu Xu's avatar
Yaowu Xu committed
648
      if (mode != I4X4_PRED)
649
        vp9_build_intra_predictors_sby_s(xd, BLOCK_SIZE_MB16X16);
John Koleszar's avatar
John Koleszar committed
650
    }
John Koleszar's avatar
John Koleszar committed
651
  } else {
652
#if 0  // def DEC_DEBUG
653 654 655 656 657
  if (dec_debug)
    printf("Decoding mb:  %d %d interp %d\n",
           xd->mode_info_context->mbmi.mode, tx_size,
           xd->mode_info_context->mbmi.interp_filter);
#endif
658
    vp9_build_inter_predictors_sb(xd, mb_row, mb_col, BLOCK_SIZE_MB16X16);
John Koleszar's avatar
John Koleszar committed
659 660
  }

Yunqing Wang's avatar
Yunqing Wang committed
661 662
  if (xd->mode_info_context->mbmi.mb_skip_coeff) {
    vp9_reset_sb_tokens_context(xd, BLOCK_SIZE_MB16X16);
663
  } else {
Yunqing Wang's avatar
Yunqing Wang committed
664 665 666 667
    // re-initialize macroblock dequantizer before detokenization
    if (xd->segmentation_enabled)
      mb_init_dequantizer(pbi, xd);

668
    if (!vp9_reader_has_error(r)) {
Yunqing Wang's avatar
Yunqing Wang committed
669 670 671
#if CONFIG_NEWBINTRAMODES
    if (mode != I4X4_PRED)
#endif
672
      eobtotal = vp9_decode_tokens(pbi, xd, r, BLOCK_SIZE_MB16X16,
673
                                   xd->plane[0].dequant);
Yunqing Wang's avatar
Yunqing Wang committed
674 675 676 677 678 679 680
    }
  }

  if (eobtotal == 0 &&
      mode != I4X4_PRED &&
      mode != SPLITMV &&
      mode != I8X8_PRED &&
681
      !vp9_reader_has_error(r)) {
Yunqing Wang's avatar
Yunqing Wang committed
682 683 684 685 686 687 688 689
    xd->mode_info_context->mbmi.mb_skip_coeff = 1;
  } else {
#if 0  // def DEC_DEBUG
  if (dec_debug)
    printf("Decoding mb:  %d %d\n", xd->mode_info_context->mbmi.mode, tx_size);
#endif

    if (tx_size == TX_16X16) {
690
      decode_16x16(xd);
Yunqing Wang's avatar
Yunqing Wang committed
691
    } else if (tx_size == TX_8X8) {
692
      decode_8x8(xd);
Yunqing Wang's avatar
Yunqing Wang committed
693
    } else {
694
      decode_4x4(pbi, xd, r);
Yunqing Wang's avatar
Yunqing Wang committed
695
    }
696
  }
Yunqing Wang's avatar
Yunqing Wang committed
697

698 699 700 701
#ifdef DEC_DEBUG
  if (dec_debug) {
    int i, j;
    printf("\n");
702 703 704 705 706 707 708
    printf("predictor y\n");
    for (i = 0; i < 16; i++) {
      for (j = 0; j < 16; j++)
        printf("%3d ", xd->predictor[i * 16 + j]);
      printf("\n");
    }
    printf("\n");
709
    printf("final y\n");
John Koleszar's avatar
John Koleszar committed
710
    for (i = 0; i < 16; i++) {
711
      for (j = 0; j < 16; j++)
712
        printf("%3d ", xd->plane[0].dst.buf[i * xd->plane[0].dst.stride + j]);
713
      printf("\n");
John Koleszar's avatar
John Koleszar committed
714
    }
715 716 717 718
    printf("\n");
    printf("final u\n");
    for (i = 0; i < 8; i++) {
      for (j = 0; j < 8; j++)
719
        printf("%3d ", xd->plane[1].dst.buf[i * xd->plane[1].dst.stride + j]);
720
      printf("\n");
721
    }
722 723 724 725
    printf("\n");
    printf("final v\n");
    for (i = 0; i < 8; i++) {
      for (j = 0; j < 8; j++)
726
        printf("%3d ", xd->plane[2].dst.buf[i * xd->plane[1].dst.stride + j]);
727
      printf("\n");
728
    }
729
    fflush(stdout);
John Koleszar's avatar
John Koleszar committed
730
  }
731
#endif
Yaowu Xu's avatar
Yaowu Xu committed
732
}
John Koleszar's avatar
John Koleszar committed
733

734 735 736 737
static int get_delta_q(vp9_reader *r, int *dq) {
  const int old_value = *dq;

  if (vp9_read_bit(r)) {  // Update bit
738 739
    const int value = vp9_read_literal(r, 4);
    *dq = vp9_read_and_apply_sign(r, value);
John Koleszar's avatar
John Koleszar committed
740
  }
John Koleszar's avatar
John Koleszar committed
741

742
  // Trigger a quantizer update if the delta-q value has changed
743
  return old_value != *dq;
John Koleszar's avatar
John Koleszar committed
744 745
}

746
static void set_offsets(VP9D_COMP *pbi, BLOCK_SIZE_TYPE bsize,
Ronald S. Bultje's avatar
Ronald S. Bultje committed
747
                        int mb_row, int mb_col) {
748 749
  const int bh = 1 << mb_height_log2(bsize);
  const int bw = 1 << mb_width_log2(bsize);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
750 751
  VP9_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;
John Koleszar's avatar
John Koleszar committed
752

753 754 755 756 757 758
  const int mb_idx = mb_row * cm->mode_info_stride + mb_col;
  const YV12_BUFFER_CONFIG *dst_fb = &cm->yv12_fb[cm->new_fb_idx];
  const int recon_yoffset = (16 * mb_row) * dst_fb->y_stride + (16 * mb_col);
  const int recon_uvoffset = (8 * mb_row) * dst_fb->uv_stride + (8 * mb_col);

  xd->mode_info_context = cm->mi + mb_idx;
759
  xd->mode_info_context->mbmi.sb_type = bsize;
760 761 762
  xd->prev_mode_info_context = cm->prev_mi + mb_idx;
  xd->above_context = cm->above_context + mb_col;
  xd->left_context = cm->left_context + mb_row % 4;
763 764
  xd->above_seg_context = cm->above_seg_context + mb_col;
  xd->left_seg_context  = cm->left_seg_context + (mb_row & 3);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
765

766 767
  // 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
768
  set_mb_row_col(cm, xd, mb_row, bh, mb_col, bw);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
769

770 771 772
  xd->plane[0].dst.buf = dst_fb->y_buffer + recon_yoffset;
  xd->plane[1].dst.buf = dst_fb->u_buffer + recon_uvoffset;
  xd->plane[2].dst.buf = dst_fb->v_buffer + recon_uvoffset;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
773
}
John Koleszar's avatar
John Koleszar committed
774

775
static void set_refs(VP9D_COMP *pbi, int mb_row, int mb_col) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
776 777
  VP9_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;
778
  MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
779 780

  if (mbmi->ref_frame > INTRA_FRAME) {
781
    // Select the appropriate reference frame for this MB
782 783 784
    const int fb_idx = cm->active_ref_idx[mbmi->ref_frame - 1];
    const YV12_BUFFER_CONFIG *cfg = &cm->yv12_fb[fb_idx];
    xd->scale_factor[0]    = cm->active_ref_scale[mbmi->ref_frame - 1];
785
    xd->scale_factor_uv[0] = cm->active_ref_scale[mbmi->ref_frame - 1];
786 787
    setup_pre_planes(xd, cfg, NULL, mb_row, mb_col,
                     xd->scale_factor, xd->scale_factor_uv);
788
    xd->corrupted |= cfg->corrupted;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
789

Ronald S. Bultje's avatar
Ronald S. Bultje committed
790
    if (mbmi->second_ref_frame > INTRA_FRAME) {
791
      // Select the appropriate reference frame for this MB
792 793
      const int second_fb_idx = cm->active_ref_idx[mbmi->second_ref_frame - 1];
      const YV12_BUFFER_CONFIG *second_cfg = &cm->yv12_fb[second_fb_idx];
Yunqing Wang's avatar
Yunqing Wang committed
794 795
      xd->scale_factor[1]    = cm->active_ref_scale[mbmi->second_ref_frame - 1];
      xd->scale_factor_uv[1] = cm->active_ref_scale[mbmi->second_ref_frame - 1];