vp9_decodframe.c 64.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 56 57 58 59 60
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
static int read_is_valid(const unsigned char *start, size_t len,
                         const unsigned char *end) {
  return start + len > start && start + len <= end;
}

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

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

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

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

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

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

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

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

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
118 119 120 121 122 123 124 125 126 127 128 129 130 131
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)) {
    if (mb->mb_segment_abs_delta == SEGMENT_ABSDATA)
      return vp9_get_segdata(mb, segment_id, SEG_LVL_ALT_Q);  // Abs Value
    else
      return clamp(base_qindex + vp9_get_segdata(mb, segment_id, SEG_LVL_ALT_Q),
                   0, MAXQ);  // Delta Value
  } else {
    return base_qindex;
  }
}

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
134
  VP9_COMMON *const pc = &pbi->common;
135 136
  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
137
  mb->q_index = qindex;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
138

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

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
145
  if (mb->lossless) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
146
    assert(qindex == 0);
Yaowu Xu's avatar
Yaowu Xu committed
147 148
    mb->inv_txm4x4_1      = vp9_short_iwalsh4x4_1;
    mb->inv_txm4x4        = vp9_short_iwalsh4x4;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
149 150 151 152
    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
153 154
    mb->inv_txm4x4_1      = vp9_short_idct4x4_1;
    mb->inv_txm4x4        = vp9_short_idct4x4;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
155 156 157
    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
158
  }
John Koleszar's avatar
John Koleszar committed
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 186
#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

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

John Koleszar's avatar
John Koleszar committed
195
  if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
196
    if (sb_type == BLOCK_SIZE_SB64X64) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
197 198
      vp9_build_intra_predictors_sb64uv_s(xd);
      vp9_build_intra_predictors_sb64y_s(xd);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
199
    } else if (sb_type == BLOCK_SIZE_SB32X32) {
200 201
      vp9_build_intra_predictors_sbuv_s(xd);
      vp9_build_intra_predictors_sby_s(xd);
202
    } else {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
203 204
      vp9_build_intra_predictors_mbuv_s(xd);
      vp9_build_intra_predictors_mby_s(xd);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
205
    }
John Koleszar's avatar
John Koleszar committed
206
  } else {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
207
    if (sb_type == BLOCK_SIZE_SB64X64) {
208
      vp9_build_inter64x64_predictors_sb(xd, mb_row, mb_col);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
209
    } else if (sb_type == BLOCK_SIZE_SB32X32) {
210
      vp9_build_inter32x32_predictors_sb(xd, mb_row, mb_col);
211
    } else {
212 213 214 215 216
      vp9_build_inter16x16_predictors_mb(xd,
                                         xd->dst.y_buffer,
                                         xd->dst.u_buffer,
                                         xd->dst.v_buffer,
                                         xd->dst.y_stride,
217 218
                                         xd->dst.uv_stride,
                                         mb_row, mb_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
219
    }
John Koleszar's avatar
John Koleszar committed
220
  }
221 222 223 224
#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
225 226
}

227 228
static void decode_16x16(VP9D_COMP *pbi, MACROBLOCKD *xd,
                         BOOL_DECODER* const bc) {
229
  const TX_TYPE tx_type = get_tx_type_16x16(xd, 0);
230
#if 0  // def DEC_DEBUG
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
  if (dec_debug) {
    int i;
    printf("\n");
    printf("qcoeff 16x16\n");
    for (i = 0; i < 400; i++) {
      printf("%3d ", xd->qcoeff[i]);
      if (i % 16 == 15) printf("\n");
    }
    printf("\n");
    printf("predictor\n");
    for (i = 0; i < 400; i++) {
      printf("%3d ", xd->predictor[i]);
      if (i % 16 == 15) printf("\n");
    }
  }
#endif
  if (tx_type != DCT_DCT) {
    vp9_ht_dequant_idct_add_16x16_c(tx_type, xd->qcoeff,
                                    xd->block[0].dequant, xd->predictor,
Scott LaVarnway's avatar
Scott LaVarnway committed
250
                                    xd->dst.y_buffer, 16, xd->dst.y_stride,
251
                                    xd->eobs[0]);
252 253 254
  } else {
    vp9_dequant_idct_add_16x16(xd->qcoeff, xd->block[0].dequant,
                               xd->predictor, xd->dst.y_buffer,
255
                               16, xd->dst.y_stride, xd->eobs[0]);
256 257 258 259
  }
  vp9_dequant_idct_add_uv_block_8x8(
      xd->qcoeff + 16 * 16, xd->block[16].dequant,
      xd->predictor + 16 * 16, xd->dst.u_buffer, xd->dst.v_buffer,
260
      xd->dst.uv_stride, xd);
261 262 263 264 265 266
}

static void decode_8x8(VP9D_COMP *pbi, MACROBLOCKD *xd,
                       BOOL_DECODER* const bc) {
  // First do Y
  // if the first one is DCT_DCT assume all the rest are as well
267
  TX_TYPE tx_type = get_tx_type_8x8(xd, 0);
268
#if 0  // def DEC_DEBUG
269 270 271 272
  if (dec_debug) {
    int i;
    printf("\n");
    printf("qcoeff 8x8\n");
273
    for (i = 0; i < 384; i++) {
274 275 276 277 278 279 280 281 282 283
      printf("%3d ", xd->qcoeff[i]);
      if (i % 16 == 15) printf("\n");
    }
  }
#endif
  if (tx_type != DCT_DCT || xd->mode_info_context->mbmi.mode == I8X8_PRED) {
    int i;
    for (i = 0; i < 4; i++) {
      int ib = vp9_i8x8_block[i];
      int idx = (ib & 0x02) ? (ib + 2) : ib;
284 285 286 287
      int16_t *q  = xd->block[idx].qcoeff;
      int16_t *dq = xd->block[0].dequant;
      uint8_t *pre = xd->block[ib].predictor;
      uint8_t *dst = *(xd->block[ib].base_dst) + xd->block[ib].dst;
288 289 290 291
      int stride = xd->dst.y_stride;
      BLOCKD *b = &xd->block[ib];
      if (xd->mode_info_context->mbmi.mode == I8X8_PRED) {
        int i8x8mode = b->bmi.as_mode.first;
292
        vp9_intra8x8_predict(xd, b, i8x8mode, b->predictor);
293
      }
294
      tx_type = get_tx_type_8x8(xd, ib);
295
      if (tx_type != DCT_DCT) {
Scott LaVarnway's avatar
Scott LaVarnway committed
296
        vp9_ht_dequant_idct_add_8x8_c(tx_type, q, dq, pre, dst, 16, stride,
297
                                      xd->eobs[idx]);
298 299
      } else {
        vp9_dequant_idct_add_8x8_c(q, dq, pre, dst, 16, stride,
300
                                   xd->eobs[idx]);
301 302
      }
    }
303
  } else {
304 305 306 307 308
    vp9_dequant_idct_add_y_block_8x8(xd->qcoeff,
                                     xd->block[0].dequant,
                                     xd->predictor,
                                     xd->dst.y_buffer,
                                     xd->dst.y_stride,
309
                                     xd);
310 311 312 313 314 315 316 317 318
  }

  // Now do UV
  if (xd->mode_info_context->mbmi.mode == I8X8_PRED) {
    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;
319

320
      b = &xd->block[16 + i];
321
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, b->predictor);
Yaowu Xu's avatar
Yaowu Xu committed
322
      xd->itxm_add(b->qcoeff, b->dequant, b->predictor,
323
                   *(b->base_dst) + b->dst, 8, b->dst_stride, xd->eobs[16 + i]);
324

325
      b = &xd->block[20 + i];
326
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, b->predictor);
Yaowu Xu's avatar
Yaowu Xu committed
327
      xd->itxm_add(b->qcoeff, b->dequant, b->predictor,
328
                   *(b->base_dst) + b->dst, 8, b->dst_stride, xd->eobs[20 + i]);
329 330
    }
  } else if (xd->mode_info_context->mbmi.mode == SPLITMV) {
Yaowu Xu's avatar
Yaowu Xu committed
331
    xd->itxm_add_uv_block(xd->qcoeff + 16 * 16, xd->block[16].dequant,
332
         xd->predictor + 16 * 16, xd->dst.u_buffer, xd->dst.v_buffer,
333
         xd->dst.uv_stride, xd);
334 335 336 337
  } else {
    vp9_dequant_idct_add_uv_block_8x8
        (xd->qcoeff + 16 * 16, xd->block[16].dequant,
         xd->predictor + 16 * 16, xd->dst.u_buffer, xd->dst.v_buffer,
338
         xd->dst.uv_stride, xd);
339
  }
340
#if 0  // def DEC_DEBUG
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355
  if (dec_debug) {
    int i;
    printf("\n");
    printf("predictor\n");
    for (i = 0; i < 384; i++) {
      printf("%3d ", xd->predictor[i]);
      if (i % 16 == 15) printf("\n");
    }
  }
#endif
}

static void decode_4x4(VP9D_COMP *pbi, MACROBLOCKD *xd,
                       BOOL_DECODER* const bc) {
  TX_TYPE tx_type;
356
  int i = 0;
357
  MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode;
358 359 360 361 362 363 364 365 366 367 368
#if 0  // def DEC_DEBUG
  if (dec_debug) {
    int i;
    printf("\n");
    printf("predictor\n");
    for (i = 0; i < 384; i++) {
      printf("%3d ", xd->predictor[i]);
      if (i % 16 == 15) printf("\n");
    }
  }
#endif
369 370 371 372 373
  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
374 375
      BLOCKD *b = &xd->block[ib];
      int i8x8mode = b->bmi.as_mode.first;
376
      vp9_intra8x8_predict(xd, b, i8x8mode, b->predictor);
377 378
      for (j = 0; j < 4; j++) {
        b = &xd->block[ib + iblock[j]];
379
        tx_type = get_tx_type_4x4(xd, ib + iblock[j]);
380 381 382 383
        if (tx_type != DCT_DCT) {
          vp9_ht_dequant_idct_add_c(tx_type, b->qcoeff,
                                    b->dequant, b->predictor,
                                    *(b->base_dst) + b->dst, 16,
384
                                    b->dst_stride, xd->eobs[ib + iblock[j]]);
385
        } else {
Yaowu Xu's avatar
Yaowu Xu committed
386
          xd->itxm_add(b->qcoeff, b->dequant, b->predictor,
387 388
                       *(b->base_dst) + b->dst, 16, b->dst_stride,
                       xd->eobs[ib + iblock[j]]);
389 390 391
        }
      }
      b = &xd->block[16 + i];
392
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, b->predictor);
Yaowu Xu's avatar
Yaowu Xu committed
393
      xd->itxm_add(b->qcoeff, b->dequant, b->predictor,
394
                   *(b->base_dst) + b->dst, 8, b->dst_stride, xd->eobs[16 + i]);
395
      b = &xd->block[20 + i];
396
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, b->predictor);
Yaowu Xu's avatar
Yaowu Xu committed
397
      xd->itxm_add(b->qcoeff, b->dequant, b->predictor,
398
                   *(b->base_dst) + b->dst, 8, b->dst_stride, xd->eobs[20 + i]);
399 400 401 402
    }
  } else if (mode == B_PRED) {
    for (i = 0; i < 16; i++) {
      BLOCKD *b = &xd->block[i];
Dmitry Kovalev's avatar
Dmitry Kovalev committed
403
      int b_mode = xd->mode_info_context->bmi[i].as_mode.first;
404 405
#if CONFIG_NEWBINTRAMODES
      xd->mode_info_context->bmi[i].as_mode.context = b->bmi.as_mode.context =
406
          vp9_find_bpred_context(xd, b);
407 408
      if (!xd->mode_info_context->mbmi.mb_skip_coeff)
        vp9_decode_coefs_4x4(pbi, xd, bc, PLANE_TYPE_Y_WITH_DC, i);
409
#endif
410
      vp9_intra4x4_predict(xd, b, b_mode, b->predictor);
411
      tx_type = get_tx_type_4x4(xd, i);
412 413 414
      if (tx_type != DCT_DCT) {
        vp9_ht_dequant_idct_add_c(tx_type, b->qcoeff,
                                  b->dequant, b->predictor,
Scott LaVarnway's avatar
Scott LaVarnway committed
415
                                  *(b->base_dst) + b->dst, 16, b->dst_stride,
416
                                  xd->eobs[i]);
417
      } else {
Yaowu Xu's avatar
Yaowu Xu committed
418
        xd->itxm_add(b->qcoeff, b->dequant, b->predictor,
419
                      *(b->base_dst) + b->dst, 16, b->dst_stride, xd->eobs[i]);
420 421
      }
    }
422 423 424 425
#if CONFIG_NEWBINTRAMODES
    if (!xd->mode_info_context->mbmi.mb_skip_coeff)
      vp9_decode_mb_tokens_4x4_uv(pbi, xd, bc);
#endif
426
    vp9_build_intra_predictors_mbuv(xd);
Yaowu Xu's avatar
Yaowu Xu committed
427
    xd->itxm_add_uv_block(xd->qcoeff + 16 * 16,
428 429 430 431 432
                           xd->block[16].dequant,
                           xd->predictor + 16 * 16,
                           xd->dst.u_buffer,
                           xd->dst.v_buffer,
                           xd->dst.uv_stride,
433
                           xd);
434
  } else if (mode == SPLITMV || get_tx_type_4x4(xd, 0) == DCT_DCT) {
Yaowu Xu's avatar
Yaowu Xu committed
435
    xd->itxm_add_y_block(xd->qcoeff,
436 437 438 439
                          xd->block[0].dequant,
                          xd->predictor,
                          xd->dst.y_buffer,
                          xd->dst.y_stride,
440
                          xd);
Yaowu Xu's avatar
Yaowu Xu committed
441
    xd->itxm_add_uv_block(xd->qcoeff + 16 * 16,
442 443 444 445 446
                           xd->block[16].dequant,
                           xd->predictor + 16 * 16,
                           xd->dst.u_buffer,
                           xd->dst.v_buffer,
                           xd->dst.uv_stride,
447
                           xd);
448
  } else {
449
#if 0  // def DEC_DEBUG
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465
    if (dec_debug) {
      int i;
      printf("\n");
      printf("qcoeff 4x4\n");
      for (i = 0; i < 400; i++) {
        printf("%3d ", xd->qcoeff[i]);
        if (i % 16 == 15) printf("\n");
      }
      printf("\n");
      printf("predictor\n");
      for (i = 0; i < 400; i++) {
        printf("%3d ", xd->predictor[i]);
        if (i % 16 == 15) printf("\n");
      }
    }
#endif
466 467
    for (i = 0; i < 16; i++) {
      BLOCKD *b = &xd->block[i];
468
      tx_type = get_tx_type_4x4(xd, i);
469 470 471 472
      if (tx_type != DCT_DCT) {
        vp9_ht_dequant_idct_add_c(tx_type, b->qcoeff,
                                  b->dequant, b->predictor,
                                  *(b->base_dst) + b->dst, 16,
473
                                  b->dst_stride, xd->eobs[i]);
474
      } else {
475
        xd->itxm_add(b->qcoeff, b->dequant, b->predictor,
476
                      *(b->base_dst) + b->dst, 16, b->dst_stride, xd->eobs[i]);
477 478
      }
    }
Yaowu Xu's avatar
Yaowu Xu committed
479
    xd->itxm_add_uv_block(xd->qcoeff + 16 * 16,
480 481 482 483 484 485 486 487 488
                          xd->block[16].dequant,
                          xd->predictor + 16 * 16,
                          xd->dst.u_buffer,
                          xd->dst.v_buffer,
                          xd->dst.uv_stride,
                          xd);
  }
}

489
static void decode_sb_16x16(MACROBLOCKD *mb, int y_size) {
490 491 492 493 494 495 496 497 498 499 500 501 502 503
  const int y_count = y_size * y_size;
  const int uv_size = y_size / 2;
  const int uv_count = uv_size * uv_size;

  const int u_qcoeff_offset = (16 * 16) * y_count;
  const int v_qcoeff_offset = u_qcoeff_offset + (16 * 16) * uv_count;
  const int u_eob_offset = 16 * y_count;
  const int v_eob_offset = u_eob_offset + 16 * uv_count;
  int n;

  for (n = 0; n < y_count; n++) {
    const int x_idx = n % y_size;
    const int y_idx = n / y_size;
    const int y_offset = (y_idx * 16) * mb->dst.y_stride + (x_idx * 16);
504 505
    const TX_TYPE tx_type = get_tx_type_16x16(mb,
                                (y_idx * (4 * y_size) + x_idx) * 4);
506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542
    if (tx_type == DCT_DCT) {
      vp9_dequant_idct_add_16x16(mb->qcoeff + n * 16 * 16,
                                 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->eobs[n * 16]);
    } else {
      vp9_ht_dequant_idct_add_16x16_c(tx_type,
                                      mb->qcoeff + n * 16 * 16,
                                      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->eobs[n * 16]);
    }
  }

  for (n = 0; n < uv_count; n++) {
    const int x_idx = n % uv_size;
    const int y_idx = n / uv_size;
    const int uv_offset = (y_idx * 16) * mb->dst.uv_stride + (x_idx * 16);
    vp9_dequant_idct_add_16x16(mb->qcoeff + u_qcoeff_offset + n * 16 * 16,
                               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->eobs[u_eob_offset + n * 16]);
    vp9_dequant_idct_add_16x16(mb->qcoeff + v_qcoeff_offset + n * 16 * 16,
                               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->eobs[v_eob_offset + n * 16]);
  }
}

543
static void decode_sb_8x8(MACROBLOCKD *mb, int y_size) {
544 545 546 547
  const int y_count = y_size * y_size;
  const int uv_size = y_size / 2;
  const int uv_count = uv_size * uv_size;

548 549
  const int u_qcoeff_offset = (8 * 8) * y_count;
  const int v_qcoeff_offset = u_qcoeff_offset + (8 * 8) * uv_count;
550 551 552 553 554 555 556 557 558 559
  const int u_eob_offset = 4 * y_count;
  const int v_eob_offset = u_eob_offset + 4 * uv_count;
  int n;

  // luma
  for (n = 0; n < y_count; n++) {
    const int x_idx = n % y_size;
    const int y_idx = n / y_size;
    const int y_offset = (y_idx * 8) * mb->dst.y_stride + (x_idx * 8);
    const TX_TYPE tx_type = get_tx_type_8x8(mb,
560
                                            (y_idx * (2 * y_size) + x_idx) * 2);
561
    if (tx_type == DCT_DCT) {
562
      vp9_dequant_idct_add_8x8_c(mb->qcoeff + n * 8 * 8,
563 564 565 566 567 568
                                 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->eobs[n * 4]);
    } else {
569 570
      vp9_ht_dequant_idct_add_8x8_c(tx_type,
                                    mb->qcoeff + n * 8 * 8,
571 572 573 574 575 576 577 578 579 580 581 582 583
                                    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->eobs[n * 4]);
    }
  }

  // chroma
  for (n = 0; n < uv_count; n++) {
    const int x_idx = n % uv_size;
    const int y_idx = n / uv_size;
    const int uv_offset = (y_idx * 8) * mb->dst.uv_stride + (x_idx * 8);
584
    vp9_dequant_idct_add_8x8_c(mb->qcoeff + u_qcoeff_offset + n * 8 * 8,
585 586 587 588 589
                               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->eobs[u_eob_offset + n * 4]);
590
    vp9_dequant_idct_add_8x8_c(mb->qcoeff + v_qcoeff_offset + n * 8 * 8,
591 592 593 594 595 596 597 598 599 600 601 602 603 604
                               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->eobs[v_eob_offset + n * 4]);
  }
}


static void decode_sb_4x4(MACROBLOCKD *mb, int y_size) {
  const int y_count = y_size * y_size;
  const int uv_size = y_size / 2;
  const int uv_count = uv_size * uv_size;

605 606
  const int u_qcoeff_offset = (4 * 4) * y_count;
  const int v_qcoeff_offset = u_qcoeff_offset + (4 * 4) * uv_count;
607 608 609 610 611 612 613 614
  const int u_eob_offset = y_count;
  const int v_eob_offset = u_eob_offset + uv_count;
  int n;

  for (n = 0; n < y_count; n++) {
    const int x_idx = n % y_size;
    const int y_idx = n / y_size;
    const int y_offset = (y_idx * 4) * mb->dst.y_stride + (x_idx * 4);
615
    const TX_TYPE tx_type = get_tx_type_4x4(mb, y_idx * y_size + x_idx);
616
    if (tx_type == DCT_DCT) {
617
      mb->itxm_add(mb->qcoeff + n * 4 * 4,
618 619 620 621 622 623
                   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->eobs[n]);
    } else {
624 625
      vp9_ht_dequant_idct_add_c(tx_type,
                                mb->qcoeff + n * 4 * 4,
626 627 628
                                mb->block[0].dequant,
                                mb->dst.y_buffer + y_offset,
                                mb->dst.y_buffer + y_offset,
629
                                mb->dst.y_stride, mb->dst.y_stride,
630 631 632 633 634 635 636 637
                                mb->eobs[n]);
    }
  }

  for (n = 0; n < uv_count; n++) {
    const int x_idx = n % uv_size;
    const int y_idx = n / uv_size;
    const int uv_offset = (y_idx * 4) * mb->dst.uv_stride + (x_idx * 4);
638
    mb->itxm_add(mb->qcoeff + u_qcoeff_offset + n * 4 * 4,
639 640 641 642 643
                 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->eobs[u_eob_offset + n]);
644
    mb->itxm_add(mb->qcoeff + v_qcoeff_offset + n * 4 * 4,
645 646 647 648 649
                 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->eobs[v_eob_offset + n]);
650 651 652
  }
}

653 654
static void decode_sb64(VP9D_COMP *pbi, MACROBLOCKD *xd, int mb_row, int mb_col,
                        BOOL_DECODER* const bc) {
655
  int n, eobtotal;
656
  VP9_COMMON *const pc = &pbi->common;
657
  MODE_INFO *mi = xd->mode_info_context;
658
  const int mis = pc->mode_info_stride;
659

660
  assert(mi->mbmi.sb_type == BLOCK_SIZE_SB64X64);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
661 662

  if (pbi->common.frame_type != KEY_FRAME)
663
    vp9_setup_interp_filters(xd, mi->mbmi.interp_filter, pc);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
664 665 666 667 668

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

669
  if (mi->mbmi.mb_skip_coeff) {
670
    vp9_reset_sb64_tokens_context(xd);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
671

672 673
    // Special case:  Force the loopfilter to skip when eobtotal and
    // mb_skip_coeff are zero.
674
    skip_recon_mb(pbi, xd, mb_row, mb_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
675 676 677
    return;
  }

678
  // do prediction
Ronald S. Bultje's avatar
Ronald S. Bultje committed
679 680 681 682
  if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
    vp9_build_intra_predictors_sb64y_s(xd);
    vp9_build_intra_predictors_sb64uv_s(xd);
  } else {
683
    vp9_build_inter64x64_predictors_sb(xd, mb_row, mb_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
684 685
  }

686
  // dequantization and idct
687 688
  eobtotal = vp9_decode_sb64_tokens(pbi, xd, bc);
  if (eobtotal == 0) {  // skip loopfilter
Ronald S. Bultje's avatar
Ronald S. Bultje committed
689
    for (n = 0; n < 16; n++) {
690
      const int x_idx = n & 3, y_idx = n >> 2;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
691

692 693 694 695 696 697 698 699
      if (mb_col + x_idx < pc->mb_cols && mb_row + y_idx < pc->mb_rows)
        mi[y_idx * mis + x_idx].mbmi.mb_skip_coeff = mi->mbmi.mb_skip_coeff;
    }
  } else {
    switch (xd->mode_info_context->mbmi.txfm_size) {
      case TX_32X32:
        for (n = 0; n < 4; n++) {
          const int x_idx = n & 1, y_idx = n >> 1;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
700
          const int y_offset = x_idx * 32 + y_idx * xd->dst.y_stride * 32;
701 702
          vp9_dequant_idct_add_32x32(xd->qcoeff + n * 1024,
              xd->block[0].dequant,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
703 704
              xd->dst.y_buffer + y_offset,
              xd->dst.y_buffer + y_offset,
705 706 707 708 709 710 711 712 713
              xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n * 64]);
        }
        vp9_dequant_idct_add_32x32(xd->qcoeff + 4096,
            xd->block[16].dequant, xd->dst.u_buffer, xd->dst.u_buffer,
            xd->dst.uv_stride, xd->dst.uv_stride, xd->eobs[256]);
        vp9_dequant_idct_add_32x32(xd->qcoeff + 4096 + 1024,
            xd->block[20].dequant, xd->dst.v_buffer, xd->dst.v_buffer,
            xd->dst.uv_stride, xd->dst.uv_stride, xd->eobs[320]);
        break;
714
      case TX_16X16:
715
        decode_sb_16x16(xd, 4);
716
        break;
717
      case TX_8X8:
718
        decode_sb_8x8(xd, 8);
719
        break;
720
      case TX_4X4:
721
        decode_sb_4x4(xd, 16);
722 723
        break;
      default: assert(0);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
724 725
    }
  }
726 727 728
#if CONFIG_CODE_NONZEROCOUNT
  propagate_nzcs(&pbi->common, xd);
#endif
Ronald S. Bultje's avatar
Ronald S. Bultje committed
729 730
}

731 732
static void decode_sb32(VP9D_COMP *pbi, MACROBLOCKD *xd, int mb_row, int mb_col,
                        BOOL_DECODER* const bc) {
733
  int eobtotal;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
734
  VP9_COMMON *const pc = &pbi->common;
735
  MODE_INFO *mi = xd->mode_info_context;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
736 737
  const int mis = pc->mode_info_stride;

738
  assert(mi->mbmi.sb_type == BLOCK_SIZE_SB32X32);
739

740
  if (pbi->common.frame_type != KEY_FRAME)
741
    vp9_setup_interp_filters(xd, mi->mbmi.interp_filter, pc);
742

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

747
  if (mi->mbmi.mb_skip_coeff) {
748
    vp9_reset_sb_tokens_context(xd);
749

750 751
    // Special case:  Force the loopfilter to skip when eobtotal and
    // mb_skip_coeff are zero.
752
    skip_recon_mb(pbi, xd, mb_row, mb_col);
753 754 755
    return;
  }

756 757

  // do prediction
758
  if (mi->mbmi.ref_frame == INTRA_FRAME) {
759 760 761
    vp9_build_intra_predictors_sby_s(xd);
    vp9_build_intra_predictors_sbuv_s(xd);
  } else {
762
    vp9_build_inter32x32_predictors_sb(xd, mb_row, mb_col);
763 764
  }

765
  // dequantization and idct
766 767
  eobtotal = vp9_decode_sb_tokens(pbi, xd, bc);
  if (eobtotal == 0) {  // skip loopfilter
768
    mi->mbmi.mb_skip_coeff = 1;
769
    if (mb_col + 1 < pc->mb_cols)
770
      mi[1].mbmi.mb_skip_coeff = 1;
771
    if (mb_row + 1 < pc->mb_rows) {
772
      mi[mis].mbmi.mb_skip_coeff = 1;
773
      if (mb_col + 1 < pc->mb_cols)
774
        mi[mis + 1].mbmi.mb_skip_coeff = 1;
775
    }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
776
  } else {
777 778 779 780 781 782 783 784 785 786 787 788
    switch (xd->mode_info_context->mbmi.txfm_size) {
      case TX_32X32:
        vp9_dequant_idct_add_32x32(xd->qcoeff, xd->block[0].dequant,
                                   xd->dst.y_buffer, xd->dst.y_buffer,
                                   xd->dst.y_stride, xd->dst.y_stride,
                                   xd->eobs[0]);
        vp9_dequant_idct_add_uv_block_16x16_c(xd->qcoeff + 1024,
                                              xd->block[16].dequant,
                                              xd->dst.u_buffer,
                                              xd->dst.v_buffer,
                                              xd->dst.uv_stride, xd);
        break;
789
      case TX_16X16:
790
        decode_sb_16x16(xd, 2);
791
        break;
792
      case TX_8X8:
793
        decode_sb_8x8(xd, 4);
794
        break;
795
      case TX_4X4:
796
        decode_sb_4x4(xd, 8);
797 798
        break;
      default: assert(0);
799
    }
800
  }
801 802 803
#if CONFIG_CODE_NONZEROCOUNT
  propagate_nzcs(&pbi->common, xd);
#endif
804 805
}

806 807 808
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
809
  int eobtotal = 0;
810 811
  const MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode;
  const int tx_size = xd->mode_info_context->mbmi.txfm_size;
812

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

Jingning Han's avatar
Jingning Han committed
815 816 817 818
  // re-initialize macroblock dequantizer before detokenization
  if (xd->segmentation_enabled)
    mb_init_dequantizer(pbi, xd);

John Koleszar's avatar
John Koleszar committed
819
  if (xd->mode_info_context->mbmi.mb_skip_coeff) {
820
    vp9_reset_mb_tokens_context(xd);
821
  } else if (!bool_error(bc)) {
822 823 824 825
#if CONFIG_NEWBINTRAMODES
    if (mode != B_PRED)
#endif
      eobtotal = vp9_decode_mb_tokens(pbi, xd, bc);
John Koleszar's avatar
John Koleszar committed
826
  }
827

Deb Mukherjee's avatar
Deb Mukherjee committed
828
  //mode = xd->mode_info_context->mbmi.mode;
829
  if (pbi->common.frame_type != KEY_FRAME)
830
    vp9_setup_interp_filters(xd, xd->mode_info_context->mbmi.interp_filter,
831
                             &pbi->common);
Gaute Strokkenes's avatar
Gaute Strokkenes committed
832

Dmitry Kovalev's avatar
Dmitry Kovalev committed
833 834 835 836 837
  if (eobtotal == 0 &&
      mode != B_PRED &&
      mode != SPLITMV &&
      mode != I8X8_PRED &&
      !bool_error(bc)) {
838 839
    // Special case:  Force the loopfilter to skip when eobtotal and
    // mb_skip_coeff are zero.
John Koleszar's avatar
John Koleszar committed
840
    xd->mode_info_context->mbmi.mb_skip_coeff = 1;
841
    skip_recon_mb(pbi, xd, mb_row, mb_col);
842
    return;
John Koleszar's avatar
John Koleszar committed
843
  }
844
#if 0  // def DEC_DEBUG
845 846 847
  if (dec_debug)
    printf("Decoding mb:  %d %d\n", xd->mode_info_context->mbmi.mode, tx_size);
#endif
Yaowu Xu's avatar
Yaowu Xu committed
848

Jingning Han's avatar
Jingning Han committed