vp9_decodframe.c 62.5 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
static void decode_16x16(VP9D_COMP *pbi, MACROBLOCKD *xd,
                         BOOL_DECODER* const bc) {
188
  const TX_TYPE tx_type = get_tx_type_16x16(xd, 0);
189

190
  if (tx_type != DCT_DCT) {
191
    vp9_dequant_iht_add_16x16_c(tx_type, xd->plane[0].qcoeff,
192 193 194
                                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]);
195
  } else {
196
    vp9_dequant_idct_add_16x16(xd->plane[0].qcoeff, xd->block[0].dequant,
197 198 199
                               xd->dst.y_buffer, xd->dst.y_buffer,
                               xd->dst.y_stride, xd->dst.y_stride,
                               xd->plane[0].eobs[0]);
200
  }
201 202

  vp9_dequant_idct_add_8x8(xd->plane[1].qcoeff, xd->block[16].dequant,
203 204 205
                           xd->dst.u_buffer, xd->dst.u_buffer,
                           xd->dst.uv_stride, xd->dst.uv_stride,
                           xd->plane[1].eobs[0]);
206

Dmitry Kovalev's avatar
Dmitry Kovalev committed
207
  vp9_dequant_idct_add_8x8(xd->plane[2].qcoeff, xd->block[20].dequant,
208 209 210
                           xd->dst.v_buffer, xd->dst.v_buffer,
                           xd->dst.uv_stride, xd->dst.uv_stride,
                           xd->plane[2].eobs[0]);
211 212 213 214
}

static void decode_8x8(VP9D_COMP *pbi, MACROBLOCKD *xd,
                       BOOL_DECODER* const bc) {
215 216
  const MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode;
  // luma
217
  // if the first one is DCT_DCT assume all the rest are as well
218
  TX_TYPE tx_type = get_tx_type_8x8(xd, 0);
219
  if (tx_type != DCT_DCT || mode == I8X8_PRED) {
220 221 222 223
    int i;
    for (i = 0; i < 4; i++) {
      int ib = vp9_i8x8_block[i];
      int idx = (ib & 0x02) ? (ib + 2) : ib;
224
      int16_t *q  = BLOCK_OFFSET(xd->plane[0].qcoeff, idx, 16);
225 226
      int16_t *dq = xd->block[0].dequant;
      uint8_t *dst = *(xd->block[ib].base_dst) + xd->block[ib].dst;
227
      int stride = xd->dst.y_stride;
228
      if (mode == I8X8_PRED) {
229
        BLOCKD *b = &xd->block[ib];
230
        int i8x8mode = b->bmi.as_mode.first;
231
        vp9_intra8x8_predict(xd, b, i8x8mode, dst, stride);
232
      }
233
      tx_type = get_tx_type_8x8(xd, ib);
234
      if (tx_type != DCT_DCT) {
235
        vp9_dequant_iht_add_8x8_c(tx_type, q, dq, dst, dst, stride, stride,
236
                                  xd->plane[0].eobs[idx]);
237
      } else {
238
        vp9_dequant_idct_add_8x8_c(q, dq, dst, dst, stride, stride,
John Koleszar's avatar
John Koleszar committed
239
                                   xd->plane[0].eobs[idx]);
240 241
      }
    }
242
  } else {
243
    vp9_dequant_idct_add_y_block_8x8(xd->plane[0].qcoeff,
244
                                     xd->block[0].dequant,
245 246
                                     xd->dst.y_buffer,
                                     xd->dst.y_stride,
247 248
                                     xd->dst.y_buffer,
                                     xd->dst.y_stride,
249
                                     xd);
250 251
  }

252 253
  // chroma
  if (mode == I8X8_PRED) {
254 255 256 257 258
    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;
259

260
      b = &xd->block[16 + i];
261 262
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, *(b->base_dst) + b->dst,
                              b->dst_stride);
263
      xd->itxm_add(BLOCK_OFFSET(xd->plane[1].qcoeff, i, 16),
264 265
                   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
266
                   xd->plane[1].eobs[i]);
267

268
      b = &xd->block[20 + i];
269 270
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, *(b->base_dst) + b->dst,
                              b->dst_stride);
271
      xd->itxm_add(BLOCK_OFFSET(xd->plane[2].qcoeff, i, 16),
272 273
                   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
274
                   xd->plane[2].eobs[i]);
275
    }
276
  } else if (mode == SPLITMV) {
277
    xd->itxm_add_uv_block(xd->plane[1].qcoeff, xd->block[16].dequant,
278
         xd->dst.u_buffer, xd->dst.uv_stride, xd->dst.u_buffer,
John Koleszar's avatar
John Koleszar committed
279
         xd->dst.uv_stride, xd->plane[1].eobs);
280
    xd->itxm_add_uv_block(xd->plane[2].qcoeff, xd->block[16].dequant,
281
         xd->dst.v_buffer, xd->dst.uv_stride, xd->dst.v_buffer,
John Koleszar's avatar
John Koleszar committed
282
         xd->dst.uv_stride, xd->plane[2].eobs);
283
  } else {
284
    vp9_dequant_idct_add_8x8(xd->plane[1].qcoeff, xd->block[16].dequant,
285 286 287
                             xd->dst.u_buffer, xd->dst.u_buffer,
                             xd->dst.uv_stride, xd->dst.uv_stride,
                             xd->plane[1].eobs[0]);
288 289

    vp9_dequant_idct_add_8x8(xd->plane[2].qcoeff, xd->block[16].dequant,
290 291 292
                             xd->dst.v_buffer, xd->dst.v_buffer,
                             xd->dst.uv_stride, xd->dst.uv_stride,
                             xd->plane[2].eobs[0]);
293 294 295 296 297 298
  }
}

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

418 419 420 421
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;
422 423 424
  int n;

  for (n = 0; n < y_count; n++) {
425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 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
    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;
470
    const int y_offset = (y_idx * 16) * mb->dst.y_stride + (x_idx * 16);
471
    const TX_TYPE tx_type = get_tx_type_16x16(mb,
472
                                (y_idx * (4 * bw) + x_idx) * 4);
473
    if (tx_type == DCT_DCT) {
474
      vp9_dequant_idct_add_16x16(BLOCK_OFFSET(mb->plane[0].qcoeff, n, 256),
475 476 477 478
                                 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
479
                                 mb->plane[0].eobs[n * 16]);
480
    } else {
481 482 483 484 485 486 487
      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]);
488 489
    }
  }
490 491 492 493 494 495 496 497 498
}

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);
499 500

  for (n = 0; n < uv_count; n++) {
501 502
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> (bwl - 1);
503
    const int uv_offset = (y_idx * 16) * mb->dst.uv_stride + (x_idx * 16);
504
    vp9_dequant_idct_add_16x16(BLOCK_OFFSET(mb->plane[1].qcoeff, n, 256),
505 506 507 508
                               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
509
                               mb->plane[1].eobs[n * 16]);
510
    vp9_dequant_idct_add_16x16(BLOCK_OFFSET(mb->plane[2].qcoeff, n, 256),
511 512 513 514
                               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
515
                               mb->plane[2].eobs[n * 16]);
516 517 518
  }
}

519 520 521 522
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;
523 524 525 526
  int n;

  // luma
  for (n = 0; n < y_count; n++) {
527 528
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> bwl;
529 530
    const int y_offset = (y_idx * 8) * xd->dst.y_stride + (x_idx * 8);
    const TX_TYPE tx_type = get_tx_type_8x8(xd,
531
                                            (y_idx * (2 * bw) + x_idx) * 2);
532
    if (tx_type == DCT_DCT) {
533 534 535 536 537
      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
538
                                 xd->plane[0].eobs[n * 4]);
539
    } else {
540 541 542 543 544 545 546
      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]);
547 548
    }
  }
549 550 551 552 553 554 555
}

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;
556 557 558

  // chroma
  for (n = 0; n < uv_count; n++) {
559 560
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> (bwl - 1);
561 562 563 564 565 566
    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
567
                               xd->plane[1].eobs[n * 4]);
568 569 570 571 572
    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
573
                               xd->plane[2].eobs[n * 4]);
574 575 576
  }
}

577 578 579 580
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;
581 582 583
  int n;

  for (n = 0; n < y_count; n++) {
584 585
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> bwl;
586
    const int y_offset = (y_idx * 4) * xd->dst.y_stride + (x_idx * 4);
587
    const TX_TYPE tx_type = get_tx_type_4x4(xd, n);
588
    if (tx_type == DCT_DCT) {
589 590 591 592 593
      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
594
                   xd->plane[0].eobs[n]);
595
    } else {
596 597 598 599 600 601 602 603
      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]);
604 605
    }
  }
606 607 608 609 610 611 612
}

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;
613 614

  for (n = 0; n < uv_count; n++) {
615 616
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> (bwl - 1);
617 618 619 620 621
    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
622
        xd->dst.uv_stride, xd->dst.uv_stride, xd->plane[1].eobs[n]);
623 624 625 626
    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
627
        xd->dst.uv_stride, xd->dst.uv_stride, xd->plane[2].eobs[n]);
628 629 630
  }
}

631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652
// 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;
653
  int n, eobtotal;
654
  VP9_COMMON *const pc = &pbi->common;
655
  MODE_INFO *mi = xd->mode_info_context;
656
  const int mis = pc->mode_info_stride;
657

658
  assert(mi->mbmi.sb_type == bsize);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
659 660

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

663
  // generate prediction
664 665 666
  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
667
  } else {
668
    vp9_build_inter_predictors_sb(xd, mb_row, mb_col, bsize);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
669 670
  }

Yunqing Wang's avatar
Yunqing Wang committed
671 672 673 674 675
  if (mi->mbmi.mb_skip_coeff) {
    vp9_reset_sb_tokens_context(xd, bsize);
#if CONFIG_CODE_NONZEROCOUNT
    vpx_memset(mi->mbmi.nzcs, 0, 384 * sizeof(mi->mbmi.nzcs[0]));
#endif
676
  } else {
Yunqing Wang's avatar
Yunqing Wang committed
677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707
    // re-initialize macroblock dequantizer before detokenization
    if (xd->segmentation_enabled)
      mb_init_dequantizer(pbi, xd);

    // dequantization and idct
    eobtotal = vp9_decode_tokens(pbi, xd, bc, bsize);
    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);
      }
708
    }
709
  }
Yunqing Wang's avatar
Yunqing Wang committed
710

711 712 713
#if CONFIG_CODE_NONZEROCOUNT
  propagate_nzcs(&pbi->common, xd);
#endif
714 715
}

716 717
// TODO(jingning): Need to merge SB and MB decoding. The MB decoding currently
// couples special handles on I8x8, B_PRED, and splitmv modes.
718 719 720
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
721
  int eobtotal = 0;
722 723
  const MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode;
  const int tx_size = xd->mode_info_context->mbmi.txfm_size;
724

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

Deb Mukherjee's avatar
Deb Mukherjee committed
727
  //mode = xd->mode_info_context->mbmi.mode;
728
  if (pbi->common.frame_type != KEY_FRAME)
729
    vp9_setup_interp_filters(xd, xd->mode_info_context->mbmi.interp_filter,
730
                             &pbi->common);
Gaute Strokkenes's avatar
Gaute Strokkenes committed
731

732
  // do prediction
John Koleszar's avatar
John Koleszar committed
733 734
  if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
    if (mode != I8X8_PRED) {
735
      vp9_build_intra_predictors_sbuv_s(xd, BLOCK_SIZE_MB16X16);
Yaowu Xu's avatar
Yaowu Xu committed
736
      if (mode != I4X4_PRED)
737
        vp9_build_intra_predictors_sby_s(xd, BLOCK_SIZE_MB16X16);
John Koleszar's avatar
John Koleszar committed
738
    }
John Koleszar's avatar
John Koleszar committed
739
  } else {
740
#if 0  // def DEC_DEBUG
741 742 743 744 745
  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
746
    vp9_build_inter_predictors_mb_s(xd, mb_row, mb_col);
John Koleszar's avatar
John Koleszar committed
747 748
  }

Yunqing Wang's avatar
Yunqing Wang committed
749 750
  if (xd->mode_info_context->mbmi.mb_skip_coeff) {
    vp9_reset_sb_tokens_context(xd, BLOCK_SIZE_MB16X16);
751
  } else {
Yunqing Wang's avatar
Yunqing Wang committed
752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782
    // re-initialize macroblock dequantizer before detokenization
    if (xd->segmentation_enabled)
      mb_init_dequantizer(pbi, xd);

    if (!bool_error(bc)) {
#if CONFIG_NEWBINTRAMODES
    if (mode != I4X4_PRED)
#endif
      eobtotal = vp9_decode_tokens(pbi, xd, bc, BLOCK_SIZE_MB16X16);
    }
  }

  if (eobtotal == 0 &&
      mode != I4X4_PRED &&
      mode != SPLITMV &&
      mode != I8X8_PRED &&
      !bool_error(bc)) {
    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) {
      decode_16x16(pbi, xd, bc);
    } else if (tx_size == TX_8X8) {
      decode_8x8(pbi, xd, bc);
    } else {
      decode_4x4(pbi, xd, bc);
    }
783
  }
Yunqing Wang's avatar
Yunqing Wang committed
784

785 786 787 788
#ifdef DEC_DEBUG
  if (dec_debug) {
    int i, j;
    printf("\n");
789 790 791 792 793 794 795
    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");
796
    printf("final y\n");
John Koleszar's avatar
John Koleszar committed
797
    for (i = 0; i < 16; i++) {
798 799 800
      for (j = 0; j < 16; j++)
        printf("%3d ", xd->dst.y_buffer[i * xd->dst.y_stride + j]);
      printf("\n");
John Koleszar's avatar
John Koleszar committed
801
    }