vp9_decodframe.c 64.4 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;
}

John Koleszar's avatar
John Koleszar committed
61 62 63 64 65 66 67 68 69 70 71 72
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;
73 74
}

John Koleszar's avatar
John Koleszar committed
75 76 77
static int inv_remap_prob(int v, int m) {
  const int n = 256;
  const int modulus = MODULUS_PARAM;
78

John Koleszar's avatar
John Koleszar committed
79 80
  v = merge_index(v, n - 1, modulus);
  if ((m << 1) <= n) {
81
    return vp9_inv_recenter_nonneg(v + 1, m);
John Koleszar's avatar
John Koleszar committed
82
  } else {
83
    return n - 1 - vp9_inv_recenter_nonneg(v + 1, n - 1 - m);
John Koleszar's avatar
John Koleszar committed
84
  }
85
}
86

87
static vp9_prob read_prob_diff_update(vp9_reader *const bc, int oldp) {
88
  int delp = vp9_decode_term_subexp(bc, SUBEXP_PARAM, 255);
89
  return (vp9_prob)inv_remap_prob(delp, oldp);
90
}
91

92
void vp9_init_de_quantizer(VP9D_COMP *pbi) {
John Koleszar's avatar
John Koleszar committed
93
  int i;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
94
  int q;
95
  VP9_COMMON *const pc = &pbi->common;
John Koleszar's avatar
John Koleszar committed
96

Dmitry Kovalev's avatar
Dmitry Kovalev committed
97 98 99
  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
100 101 102

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
105 106
      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
107
    }
John Koleszar's avatar
John Koleszar committed
108
  }
John Koleszar's avatar
John Koleszar committed
109 110
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
111 112 113 114 115 116 117 118 119 120 121 122 123 124
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
125 126
  int i;

Dmitry Kovalev's avatar
Dmitry Kovalev committed
127
  VP9_COMMON *const pc = &pbi->common;
128 129
  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
130
  mb->q_index = qindex;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
131

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

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
138
  if (mb->lossless) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
139
    assert(qindex == 0);
Yaowu Xu's avatar
Yaowu Xu committed
140 141
    mb->inv_txm4x4_1      = vp9_short_iwalsh4x4_1;
    mb->inv_txm4x4        = vp9_short_iwalsh4x4;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
142 143 144 145
    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
146 147
    mb->inv_txm4x4_1      = vp9_short_idct4x4_1;
    mb->inv_txm4x4        = vp9_short_idct4x4;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
148 149 150
    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
151
  }
John Koleszar's avatar
John Koleszar committed
152 153
}

154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
#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

180 181 182
/* 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.
 */
183 184
static void skip_recon_mb(VP9D_COMP *pbi, MACROBLOCKD *xd,
                          int mb_row, int mb_col) {
185 186
  MODE_INFO *m = xd->mode_info_context;
  BLOCK_SIZE_TYPE sb_type = m->mbmi.sb_type;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
187

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

220 221
static void decode_16x16(VP9D_COMP *pbi, MACROBLOCKD *xd,
                         BOOL_DECODER* const bc) {
222
  const TX_TYPE tx_type = get_tx_type_16x16(xd, 0);
223
#if 0  // def DEC_DEBUG
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
  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
243
                                    xd->dst.y_buffer, 16, xd->dst.y_stride,
244
                                    xd->eobs[0]);
245 246 247
  } else {
    vp9_dequant_idct_add_16x16(xd->qcoeff, xd->block[0].dequant,
                               xd->predictor, xd->dst.y_buffer,
248
                               16, xd->dst.y_stride, xd->eobs[0]);
249 250 251 252
  }
  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,
253
      xd->dst.uv_stride, xd);
254 255 256 257 258 259
}

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
260
  TX_TYPE tx_type = get_tx_type_8x8(xd, 0);
261
#if 0  // def DEC_DEBUG
262 263 264 265
  if (dec_debug) {
    int i;
    printf("\n");
    printf("qcoeff 8x8\n");
266
    for (i = 0; i < 384; i++) {
267 268 269 270 271 272 273 274 275 276
      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;
277 278 279 280
      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;
281 282 283 284
      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;
285
        vp9_intra8x8_predict(xd, b, i8x8mode, b->predictor);
286
      }
287
      tx_type = get_tx_type_8x8(xd, ib);
288
      if (tx_type != DCT_DCT) {
Scott LaVarnway's avatar
Scott LaVarnway committed
289
        vp9_ht_dequant_idct_add_8x8_c(tx_type, q, dq, pre, dst, 16, stride,
290
                                      xd->eobs[idx]);
291 292
      } else {
        vp9_dequant_idct_add_8x8_c(q, dq, pre, dst, 16, stride,
293
                                   xd->eobs[idx]);
294 295
      }
    }
296
  } else {
297 298 299 300 301
    vp9_dequant_idct_add_y_block_8x8(xd->qcoeff,
                                     xd->block[0].dequant,
                                     xd->predictor,
                                     xd->dst.y_buffer,
                                     xd->dst.y_stride,
302
                                     xd);
303 304 305 306 307 308 309 310 311
  }

  // 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;
312

313
      b = &xd->block[16 + i];
314
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, b->predictor);
Yaowu Xu's avatar
Yaowu Xu committed
315
      xd->itxm_add(b->qcoeff, b->dequant, b->predictor,
316
                   *(b->base_dst) + b->dst, 8, b->dst_stride, xd->eobs[16 + i]);
317

318
      b = &xd->block[20 + i];
319
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, b->predictor);
Yaowu Xu's avatar
Yaowu Xu committed
320
      xd->itxm_add(b->qcoeff, b->dequant, b->predictor,
321
                   *(b->base_dst) + b->dst, 8, b->dst_stride, xd->eobs[20 + i]);
322 323
    }
  } else if (xd->mode_info_context->mbmi.mode == SPLITMV) {
Yaowu Xu's avatar
Yaowu Xu committed
324
    xd->itxm_add_uv_block(xd->qcoeff + 16 * 16, xd->block[16].dequant,
325
         xd->predictor + 16 * 16, xd->dst.u_buffer, xd->dst.v_buffer,
326
         xd->dst.uv_stride, xd);
327 328 329 330
  } 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,
331
         xd->dst.uv_stride, xd);
332
  }
333
#if 0  // def DEC_DEBUG
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
  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;
  int i, eobtotal = 0;
  MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode;
351 352 353 354 355 356 357 358 359 360 361
#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
362 363 364 365 366
  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
367 368
      BLOCKD *b = &xd->block[ib];
      int i8x8mode = b->bmi.as_mode.first;
369
      vp9_intra8x8_predict(xd, b, i8x8mode, b->predictor);
370 371
      for (j = 0; j < 4; j++) {
        b = &xd->block[ib + iblock[j]];
372
        tx_type = get_tx_type_4x4(xd, ib + iblock[j]);
373 374 375 376
        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,
377
                                    b->dst_stride, xd->eobs[ib + iblock[j]]);
378
        } else {
Yaowu Xu's avatar
Yaowu Xu committed
379
          xd->itxm_add(b->qcoeff, b->dequant, b->predictor,
380 381
                       *(b->base_dst) + b->dst, 16, b->dst_stride,
                       xd->eobs[ib + iblock[j]]);
382 383 384
        }
      }
      b = &xd->block[16 + i];
385
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, b->predictor);
Yaowu Xu's avatar
Yaowu Xu committed
386
      xd->itxm_add(b->qcoeff, b->dequant, b->predictor,
387
                   *(b->base_dst) + b->dst, 8, b->dst_stride, xd->eobs[16 + i]);
388
      b = &xd->block[20 + i];
389
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, b->predictor);
Yaowu Xu's avatar
Yaowu Xu committed
390
      xd->itxm_add(b->qcoeff, b->dequant, b->predictor,
391
                   *(b->base_dst) + b->dst, 8, b->dst_stride, xd->eobs[20 + i]);
392 393 394 395
    }
  } else if (mode == B_PRED) {
    for (i = 0; i < 16; i++) {
      BLOCKD *b = &xd->block[i];
Dmitry Kovalev's avatar
Dmitry Kovalev committed
396
      int b_mode = xd->mode_info_context->bmi[i].as_mode.first;
397 398
#if CONFIG_NEWBINTRAMODES
      xd->mode_info_context->bmi[i].as_mode.context = b->bmi.as_mode.context =
399
          vp9_find_bpred_context(xd, b);
400 401 402 403
#endif
      if (!xd->mode_info_context->mbmi.mb_skip_coeff)
        eobtotal += vp9_decode_coefs_4x4(pbi, xd, bc, PLANE_TYPE_Y_WITH_DC, i);

404
      vp9_intra4x4_predict(xd, b, b_mode, b->predictor);
405
      tx_type = get_tx_type_4x4(xd, i);
406 407 408
      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
409
                                  *(b->base_dst) + b->dst, 16, b->dst_stride,
410
                                  xd->eobs[i]);
411
      } else {
Yaowu Xu's avatar
Yaowu Xu committed
412
        xd->itxm_add(b->qcoeff, b->dequant, b->predictor,
413
                      *(b->base_dst) + b->dst, 16, b->dst_stride, xd->eobs[i]);
414 415 416 417 418 419
      }
    }
    if (!xd->mode_info_context->mbmi.mb_skip_coeff) {
      vp9_decode_mb_tokens_4x4_uv(pbi, xd, bc);
    }
    vp9_build_intra_predictors_mbuv(xd);
Yaowu Xu's avatar
Yaowu Xu committed
420
    xd->itxm_add_uv_block(xd->qcoeff + 16 * 16,
421 422 423 424 425
                           xd->block[16].dequant,
                           xd->predictor + 16 * 16,
                           xd->dst.u_buffer,
                           xd->dst.v_buffer,
                           xd->dst.uv_stride,
426
                           xd);
427
  } else if (mode == SPLITMV || get_tx_type_4x4(xd, 0) == DCT_DCT) {
Yaowu Xu's avatar
Yaowu Xu committed
428
    xd->itxm_add_y_block(xd->qcoeff,
429 430 431 432
                          xd->block[0].dequant,
                          xd->predictor,
                          xd->dst.y_buffer,
                          xd->dst.y_stride,
433
                          xd);
Yaowu Xu's avatar
Yaowu Xu committed
434
    xd->itxm_add_uv_block(xd->qcoeff + 16 * 16,
435 436 437 438 439
                           xd->block[16].dequant,
                           xd->predictor + 16 * 16,
                           xd->dst.u_buffer,
                           xd->dst.v_buffer,
                           xd->dst.uv_stride,
440
                           xd);
441
  } else {
442
#if 0  // def DEC_DEBUG
443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458
    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
459 460
    for (i = 0; i < 16; i++) {
      BLOCKD *b = &xd->block[i];
461
      tx_type = get_tx_type_4x4(xd, i);
462 463 464 465
      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,
466
                                  b->dst_stride, xd->eobs[i]);
467
      } else {
468
        xd->itxm_add(b->qcoeff, b->dequant, b->predictor,
469
                      *(b->base_dst) + b->dst, 16, b->dst_stride, xd->eobs[i]);
470 471
      }
    }
Yaowu Xu's avatar
Yaowu Xu committed
472
    xd->itxm_add_uv_block(xd->qcoeff + 16 * 16,
473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 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 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587
                          xd->block[16].dequant,
                          xd->predictor + 16 * 16,
                          xd->dst.u_buffer,
                          xd->dst.v_buffer,
                          xd->dst.uv_stride,
                          xd);
  }
}

static INLINE void decode_sb_8x8(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;

  const int u_qcoeff_offset = 64 * y_count;
  const int v_qcoeff_offset = u_qcoeff_offset + 64 * uv_count;
  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,
                                            (y_idx * 2 * y_size + x_idx) * 2);
    if (tx_type == DCT_DCT) {
      vp9_dequant_idct_add_8x8_c(mb->qcoeff + n * 64,
                                 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 {
      vp9_ht_dequant_idct_add_8x8_c(tx_type, mb->qcoeff + n * 64,
                                    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);

    vp9_dequant_idct_add_8x8_c(mb->qcoeff + u_qcoeff_offset + n * 64,
                               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]);
    vp9_dequant_idct_add_8x8_c(mb->qcoeff + v_qcoeff_offset + n * 64,
                               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;

  const int u_qcoeff_offset = y_count * 16;
  const int v_qcoeff_offset = u_qcoeff_offset + uv_count * 16;
  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);
    const TX_TYPE tx_type = get_tx_type_4x4(mb, y_idx * (y_size*2) + x_idx);
    if (tx_type == DCT_DCT) {
      mb->itxm_add(mb->qcoeff + n * 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]);
    } else {
      vp9_ht_dequant_idct_add_c(tx_type, mb->qcoeff + n * 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]);
    }
  }

  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);
    mb->itxm_add(mb->qcoeff + u_qcoeff_offset + n * 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]);
    mb->itxm_add(mb->qcoeff + v_qcoeff_offset + n * 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]);
588 589 590
  }
}

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

598
  assert(mi->mbmi.sb_type == BLOCK_SIZE_SB64X64);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
599 600

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

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

607
  if (mi->mbmi.mb_skip_coeff) {
608
    vp9_reset_sb64_tokens_context(xd);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
609

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

616
  // do prediction
Ronald S. Bultje's avatar
Ronald S. Bultje committed
617 618 619 620
  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 {
621
    vp9_build_inter64x64_predictors_sb(xd, mb_row, mb_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
622 623
  }

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

630 631 632 633 634 635 636 637
      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
638
          const int y_offset = x_idx * 32 + y_idx * xd->dst.y_stride * 32;
639 640
          vp9_dequant_idct_add_32x32(xd->qcoeff + n * 1024,
              xd->block[0].dequant,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
641 642
              xd->dst.y_buffer + y_offset,
              xd->dst.y_buffer + y_offset,
643 644 645 646 647 648 649 650 651
              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;
652
      case TX_16X16:
653 654
        for (n = 0; n < 16; n++) {
          const int x_idx = n & 3, y_idx = n >> 2;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
655
          const int y_offset = y_idx * 16 * xd->dst.y_stride + x_idx * 16;
656 657 658 659 660
          const TX_TYPE tx_type = get_tx_type_16x16(xd,
                                                    (y_idx * 16 + x_idx) * 4);
          if (tx_type == DCT_DCT) {
            vp9_dequant_idct_add_16x16(xd->qcoeff + n * 256,
                xd->block[0].dequant,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
661 662
                xd->dst.y_buffer + y_offset,
                xd->dst.y_buffer + y_offset,
663 664 665 666
                xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n * 16]);
          } else {
            vp9_ht_dequant_idct_add_16x16_c(tx_type, xd->qcoeff + n * 256,
                xd->block[0].dequant,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
667 668
                xd->dst.y_buffer + y_offset,
                xd->dst.y_buffer + y_offset,
669 670
                xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n * 16]);
          }
671 672 673
        }
        for (n = 0; n < 4; n++) {
          const int x_idx = n & 1, y_idx = n >> 1;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
674
          const int uv_offset = y_idx * 16 * xd->dst.uv_stride + x_idx * 16;
675 676
          vp9_dequant_idct_add_16x16(xd->qcoeff + 4096 + n * 256,
              xd->block[16].dequant,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
677 678
              xd->dst.u_buffer + uv_offset,
              xd->dst.u_buffer + uv_offset,
679 680 681
              xd->dst.uv_stride, xd->dst.uv_stride, xd->eobs[256 + n * 16]);
          vp9_dequant_idct_add_16x16(xd->qcoeff + 4096 + 1024 + n * 256,
              xd->block[20].dequant,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
682 683
              xd->dst.v_buffer + uv_offset,
              xd->dst.v_buffer + uv_offset,
684 685 686
              xd->dst.uv_stride, xd->dst.uv_stride, xd->eobs[320 + n * 16]);
        }
        break;
687
      case TX_8X8:
688
        decode_sb_8x8(xd, 8);
689
        break;
690
      case TX_4X4:
691
        decode_sb_4x4(xd, 16);
692 693
        break;
      default: assert(0);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
694 695
    }
  }
696 697 698
#if CONFIG_CODE_NONZEROCOUNT
  propagate_nzcs(&pbi->common, xd);
#endif
Ronald S. Bultje's avatar
Ronald S. Bultje committed
699 700
}

701 702
static void decode_sb32(VP9D_COMP *pbi, MACROBLOCKD *xd, int mb_row, int mb_col,
                        BOOL_DECODER* const bc) {
703
  int n, eobtotal;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
704
  VP9_COMMON *const pc = &pbi->common;
705
  MODE_INFO *mi = xd->mode_info_context;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
706 707
  const int mis = pc->mode_info_stride;

708
  assert(mi->mbmi.sb_type == BLOCK_SIZE_SB32X32);
709

710
  if (pbi->common.frame_type != KEY_FRAME)
711
    vp9_setup_interp_filters(xd, mi->mbmi.interp_filter, pc);
712

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

717
  if (mi->mbmi.mb_skip_coeff) {
718
    vp9_reset_sb_tokens_context(xd);
719

720 721
    // Special case:  Force the loopfilter to skip when eobtotal and
    // mb_skip_coeff are zero.
722
    skip_recon_mb(pbi, xd, mb_row, mb_col);
723 724 725
    return;
  }

726 727

  // do prediction
728
  if (mi->mbmi.ref_frame == INTRA_FRAME) {
729 730 731
    vp9_build_intra_predictors_sby_s(xd);
    vp9_build_intra_predictors_sbuv_s(xd);
  } else {
732
    vp9_build_inter32x32_predictors_sb(xd, mb_row, mb_col);
733 734
  }

735
  // dequantization and idct
736 737
  eobtotal = vp9_decode_sb_tokens(pbi, xd, bc);
  if (eobtotal == 0) {  // skip loopfilter
738
    mi->mbmi.mb_skip_coeff = 1;
739
    if (mb_col + 1 < pc->mb_cols)
740
      mi[1].mbmi.mb_skip_coeff = 1;
741
    if (mb_row + 1 < pc->mb_rows) {
742
      mi[mis].mbmi.mb_skip_coeff = 1;
743
      if (mb_col + 1 < pc->mb_cols)
744
        mi[mis + 1].mbmi.mb_skip_coeff = 1;
745
    }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
746
  } else {
747 748 749 750 751 752 753 754 755 756 757 758
    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;
759
      case TX_16X16:
760 761
        for (n = 0; n < 4; n++) {
          const int x_idx = n & 1, y_idx = n >> 1;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
762
          const int y_offset = y_idx * 16 * xd->dst.y_stride + x_idx * 16;
763 764 765 766 767
          const TX_TYPE tx_type = get_tx_type_16x16(xd,
                                                    (y_idx * 8 + x_idx) * 4);
          if (tx_type == DCT_DCT) {
            vp9_dequant_idct_add_16x16(
                xd->qcoeff + n * 256, xd->block[0].dequant,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
768 769
                xd->dst.y_buffer + y_offset,
                xd->dst.y_buffer + y_offset,
770 771 772 773
                xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n * 16]);
          } else {
            vp9_ht_dequant_idct_add_16x16_c(tx_type, xd->qcoeff + n * 256,
                xd->block[0].dequant,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
774 775
                xd->dst.y_buffer + y_offset,
                xd->dst.y_buffer + y_offset,
776 777
                xd->dst.y_stride, xd->dst.y_stride, xd->eobs[n * 16]);
          }
778 779 780 781 782 783 784
        }
        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;
785
      case TX_8X8:
786
        decode_sb_8x8(xd, 4);
787
        break;
788
      case TX_4X4:
789
        decode_sb_4x4(xd, 8);
790 791
        break;
      default: assert(0);
792
    }
793
  }
794 795 796
#if CONFIG_CODE_NONZEROCOUNT
  propagate_nzcs(&pbi->common, xd);
#endif
797 798
}

799 800 801
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
802
  int eobtotal = 0;
803 804
  const MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode;
  const int tx_size = xd->mode_info_context->mbmi.txfm_size;
805

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

Jingning Han's avatar
Jingning Han committed
808 809 810 811
  // re-initialize macroblock dequantizer before detokenization
  if (xd->segmentation_enabled)
    mb_init_dequantizer(pbi, xd);

John Koleszar's avatar
John Koleszar committed
812
  if (xd->mode_info_context->mbmi.mb_skip_coeff) {
813
    vp9_reset_mb_tokens_context(xd);
814
  } else if (!bool_error(bc)) {
815
    if (mode != B_PRED)
816
      eobtotal = vp9_decode_mb_tokens(pbi, xd, bc);
John Koleszar's avatar
John Koleszar committed
817
  }
818

Deb Mukherjee's avatar
Deb Mukherjee committed
819
  //mode = xd->mode_info_context->mbmi.mode;
820
  if (pbi->common.frame_type != KEY_FRAME)
821
    vp9_setup_interp_filters(xd, xd->mode_info_context->mbmi.interp_filter,
822
                             &pbi->common);
Gaute Strokkenes's avatar
Gaute Strokkenes committed
823

Dmitry Kovalev's avatar
Dmitry Kovalev committed
824 825 826 827 828
  if (eobtotal == 0 &&
      mode != B_PRED &&
      mode != SPLITMV &&
      mode != I8X8_PRED &&
      !bool_error(bc)) {
829 830
    // Special case:  Force the loopfilter to skip when eobtotal and
    // mb_skip_coeff are zero.
John Koleszar's avatar
John Koleszar committed
831
    xd->mode_info_context->mbmi.mb_skip_coeff = 1;
832
    skip_recon_mb(pbi, xd, mb_row, mb_col);
833
    return;
John Koleszar's avatar
John Koleszar committed
834
  }
835
#if 0  // def DEC_DEBUG
836 837 838
  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
839

Jingning Han's avatar
Jingning Han committed
840
  // moved to be performed before detokenization
841 842
  //  if (xd->segmentation_enabled)
  //    mb_init_dequantizer(pbi, xd);
843

844
  // do prediction
John Koleszar's avatar
John Koleszar committed
845 846
  if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
    if (mode != I8X8_PRED) {
847
      vp9_build_intra_predictors_mbuv(xd);
848
      if (mode != B_PRED)
849
        vp9_build_intra_predictors_mby(xd);
John Koleszar's avatar
John Koleszar committed
850
    }
John Koleszar's avatar
John Koleszar committed
851
  } else {
852
#if 0  // def DEC_DEBUG
853 854 855 856 857
  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
858
    vp9_build_inter_predictors_mb(xd, mb_row, mb_col);
John Koleszar's avatar
John Koleszar committed
859 860
  }

861 862 863 864 865