vp9_decodframe.c 64.7 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5 6
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
7
 *  in the file PATENTS.  All contributing project authors may
8
 *  be found in the AUTHORS file in the root of the source tree.
John Koleszar's avatar
John Koleszar committed
9 10 11
 */


12
#include "vp9/decoder/vp9_onyxd_int.h"
Ronald S. Bultje's avatar
Ronald S. Bultje committed
13
#include "vp9/common/vp9_common.h"
14 15 16
#include "vp9/common/vp9_header.h"
#include "vp9/common/vp9_reconintra.h"
#include "vp9/common/vp9_reconinter.h"
Yaowu Xu's avatar
Yaowu Xu committed
17
#include "vp9/common/vp9_entropy.h"
18
#include "vp9/decoder/vp9_decodframe.h"
19
#include "vp9/decoder/vp9_detokenize.h"
20 21 22 23
#include "vp9/common/vp9_invtrans.h"
#include "vp9/common/vp9_alloccommon.h"
#include "vp9/common/vp9_entropymode.h"
#include "vp9/common/vp9_quant_common.h"
Johann's avatar
Johann committed
24
#include "vpx_scale/vpx_scale.h"
25
#include "vp9/common/vp9_setupintrarecon.h"
Scott LaVarnway's avatar
Scott LaVarnway committed
26

27
#include "vp9/decoder/vp9_decodemv.h"
28 29
#include "vp9/common/vp9_extend.h"
#include "vp9/common/vp9_modecont.h"
John Koleszar's avatar
John Koleszar committed
30
#include "vpx_mem/vpx_mem.h"
31
#include "vp9/decoder/vp9_dboolhuff.h"
John Koleszar's avatar
John Koleszar committed
32

33
#include "vp9/common/vp9_seg_common.h"
34
#include "vp9/common/vp9_tile_common.h"
35
#include "vp9_rtcd.h"
36

John Koleszar's avatar
John Koleszar committed
37 38 39
#include <assert.h>
#include <stdio.h>

40 41
#define COEFCOUNT_TESTING

42
// #define DEC_DEBUG
43 44 45 46
#ifdef DEC_DEBUG
int dec_debug = 0;
#endif

47 48 49 50 51 52 53 54 55
static int read_le16(const uint8_t *p) {
  return (p[1] << 8) | p[0];
}

static int read_le32(const uint8_t *p) {
  return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
}

// len == 0 is not allowed
56 57
static int read_is_valid(const uint8_t *start, size_t len,
                         const uint8_t *end) {
58 59 60
  return start + len > start && start + len <= end;
}

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

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

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

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

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

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

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

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

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
118 119 120
static int get_qindex(MACROBLOCKD *mb, int segment_id, int base_qindex) {
  // Set the Q baseline allowing for any segment level adjustment
  if (vp9_segfeature_active(mb, segment_id, SEG_LVL_ALT_Q)) {
121 122 123 124
    const int data = vp9_get_segdata(mb, segment_id, SEG_LVL_ALT_Q);
    return mb->mb_segment_abs_delta == SEGMENT_ABSDATA ?
               data :  // Abs value
               clamp(base_qindex + data, 0, MAXQ);  // Delta value
Dmitry Kovalev's avatar
Dmitry Kovalev committed
125 126 127 128 129 130
  } else {
    return base_qindex;
  }
}

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
133
  VP9_COMMON *const pc = &pbi->common;
134 135
  const int segment_id = mb->mode_info_context->mbmi.segment_id;
  const int qindex = get_qindex(mb, segment_id, pc->base_qindex);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
136
  mb->q_index = qindex;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
137

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

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
144
  if (mb->lossless) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
145
    assert(qindex == 0);
Yaowu Xu's avatar
Yaowu Xu committed
146 147
    mb->inv_txm4x4_1      = vp9_short_iwalsh4x4_1;
    mb->inv_txm4x4        = vp9_short_iwalsh4x4;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
148 149 150 151
    mb->itxm_add          = vp9_dequant_idct_add_lossless_c;
    mb->itxm_add_y_block  = vp9_dequant_idct_add_y_block_lossless_c;
    mb->itxm_add_uv_block = vp9_dequant_idct_add_uv_block_lossless_c;
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
152 153
    mb->inv_txm4x4_1      = vp9_short_idct4x4_1;
    mb->inv_txm4x4        = vp9_short_idct4x4;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
154 155 156
    mb->itxm_add          = vp9_dequant_idct_add;
    mb->itxm_add_y_block  = vp9_dequant_idct_add_y_block;
    mb->itxm_add_uv_block = vp9_dequant_idct_add_uv_block;
John Koleszar's avatar
John Koleszar committed
157
  }
John Koleszar's avatar
John Koleszar committed
158 159
}

160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
#if CONFIG_CODE_NONZEROCOUNT
static void propagate_nzcs(VP9_COMMON *cm, MACROBLOCKD *xd) {
  MODE_INFO *m = xd->mode_info_context;
  BLOCK_SIZE_TYPE sb_type = m->mbmi.sb_type;
  const int mis = cm->mode_info_stride;
  int n;
  if (sb_type == BLOCK_SIZE_SB64X64) {
    for (n = 0; n < 16; ++n) {
      int i = n >> 2;
      int j = n & 3;
      if (i == 0 && j == 0) continue;
      vpx_memcpy((m + j + mis * i)->mbmi.nzcs, m->mbmi.nzcs,
                 384 * sizeof(m->mbmi.nzcs[0]));
    }
  } else if (sb_type == BLOCK_SIZE_SB32X32) {
    for (n = 0; n < 4; ++n) {
      int i = n >> 1;
      int j = n & 1;
      if (i == 0 && j == 0) continue;
      vpx_memcpy((m + j + mis * i)->mbmi.nzcs, m->mbmi.nzcs,
                 384 * sizeof(m->mbmi.nzcs[0]));
    }
  }
}
#endif

186 187 188
/* 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.
 */
189 190
static void skip_recon_mb(VP9D_COMP *pbi, MACROBLOCKD *xd,
                          int mb_row, int mb_col) {
191 192
  MODE_INFO *m = xd->mode_info_context;
  BLOCK_SIZE_TYPE sb_type = m->mbmi.sb_type;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
193

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

226 227
static void decode_16x16(VP9D_COMP *pbi, MACROBLOCKD *xd,
                         BOOL_DECODER* const bc) {
228
  const TX_TYPE tx_type = get_tx_type_16x16(xd, 0);
229

230
  if (tx_type != DCT_DCT) {
231
    vp9_dequant_iht_add_16x16_c(tx_type, xd->plane[0].qcoeff,
232 233 234
                                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]);
235
  } else {
236
    vp9_dequant_idct_add_16x16(xd->plane[0].qcoeff, xd->block[0].dequant,
237 238 239
                               xd->dst.y_buffer, xd->dst.y_buffer,
                               xd->dst.y_stride, xd->dst.y_stride,
                               xd->plane[0].eobs[0]);
240
  }
241 242

  vp9_dequant_idct_add_8x8(xd->plane[1].qcoeff, xd->block[16].dequant,
243 244 245
                           xd->dst.u_buffer, xd->dst.u_buffer,
                           xd->dst.uv_stride, xd->dst.uv_stride,
                           xd->plane[1].eobs[0]);
246

Dmitry Kovalev's avatar
Dmitry Kovalev committed
247
  vp9_dequant_idct_add_8x8(xd->plane[2].qcoeff, xd->block[20].dequant,
248 249 250
                           xd->dst.v_buffer, xd->dst.v_buffer,
                           xd->dst.uv_stride, xd->dst.uv_stride,
                           xd->plane[2].eobs[0]);
251 252 253 254
}

static void decode_8x8(VP9D_COMP *pbi, MACROBLOCKD *xd,
                       BOOL_DECODER* const bc) {
255 256
  const MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode;
  // luma
257
  // if the first one is DCT_DCT assume all the rest are as well
258
  TX_TYPE tx_type = get_tx_type_8x8(xd, 0);
259
  if (tx_type != DCT_DCT || mode == I8X8_PRED) {
260 261 262 263
    int i;
    for (i = 0; i < 4; i++) {
      int ib = vp9_i8x8_block[i];
      int idx = (ib & 0x02) ? (ib + 2) : ib;
264
      int16_t *q  = BLOCK_OFFSET(xd->plane[0].qcoeff, idx, 16);
265 266
      int16_t *dq = xd->block[0].dequant;
      uint8_t *dst = *(xd->block[ib].base_dst) + xd->block[ib].dst;
267
      int stride = xd->dst.y_stride;
268
      if (mode == I8X8_PRED) {
269
        BLOCKD *b = &xd->block[ib];
270
        int i8x8mode = b->bmi.as_mode.first;
271
        vp9_intra8x8_predict(xd, b, i8x8mode, dst, stride);
272
      }
273
      tx_type = get_tx_type_8x8(xd, ib);
274
      if (tx_type != DCT_DCT) {
275
        vp9_dequant_iht_add_8x8_c(tx_type, q, dq, dst, dst, stride, stride,
276
                                  xd->plane[0].eobs[idx]);
277
      } else {
278
        vp9_dequant_idct_add_8x8_c(q, dq, dst, dst, stride, stride,
John Koleszar's avatar
John Koleszar committed
279
                                   xd->plane[0].eobs[idx]);
280 281
      }
    }
282
  } else {
283
    vp9_dequant_idct_add_y_block_8x8(xd->plane[0].qcoeff,
284
                                     xd->block[0].dequant,
285 286
                                     xd->dst.y_buffer,
                                     xd->dst.y_stride,
287 288
                                     xd->dst.y_buffer,
                                     xd->dst.y_stride,
289
                                     xd);
290 291
  }

292 293
  // chroma
  if (mode == I8X8_PRED) {
294 295 296 297 298
    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;
299

300
      b = &xd->block[16 + i];
301 302
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, *(b->base_dst) + b->dst,
                              b->dst_stride);
303
      xd->itxm_add(BLOCK_OFFSET(xd->plane[1].qcoeff, i, 16),
304 305
                   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
306
                   xd->plane[1].eobs[i]);
307

308
      b = &xd->block[20 + i];
309 310
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, *(b->base_dst) + b->dst,
                              b->dst_stride);
311
      xd->itxm_add(BLOCK_OFFSET(xd->plane[2].qcoeff, i, 16),
312 313
                   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
314
                   xd->plane[2].eobs[i]);
315
    }
316
  } else if (mode == SPLITMV) {
317
    xd->itxm_add_uv_block(xd->plane[1].qcoeff, xd->block[16].dequant,
318
         xd->dst.u_buffer, xd->dst.uv_stride, xd->dst.u_buffer,
John Koleszar's avatar
John Koleszar committed
319
         xd->dst.uv_stride, xd->plane[1].eobs);
320
    xd->itxm_add_uv_block(xd->plane[2].qcoeff, xd->block[16].dequant,
321
         xd->dst.v_buffer, xd->dst.uv_stride, xd->dst.v_buffer,
John Koleszar's avatar
John Koleszar committed
322
         xd->dst.uv_stride, xd->plane[2].eobs);
323
  } else {
324
    vp9_dequant_idct_add_8x8(xd->plane[1].qcoeff, xd->block[16].dequant,
325 326 327
                             xd->dst.u_buffer, xd->dst.u_buffer,
                             xd->dst.uv_stride, xd->dst.uv_stride,
                             xd->plane[1].eobs[0]);
328 329

    vp9_dequant_idct_add_8x8(xd->plane[2].qcoeff, xd->block[16].dequant,
330 331 332
                             xd->dst.v_buffer, xd->dst.v_buffer,
                             xd->dst.uv_stride, xd->dst.uv_stride,
                             xd->plane[2].eobs[0]);
333 334 335 336 337 338
  }
}

static void decode_4x4(VP9D_COMP *pbi, MACROBLOCKD *xd,
                       BOOL_DECODER* const bc) {
  TX_TYPE tx_type;
339
  int i = 0;
340
  const MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode;
341 342 343 344 345
  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
346 347
      BLOCKD *b = &xd->block[ib];
      int i8x8mode = b->bmi.as_mode.first;
348 349
      vp9_intra8x8_predict(xd, b, i8x8mode, *(b->base_dst) + b->dst,
                           b->dst_stride);
350 351
      for (j = 0; j < 4; j++) {
        b = &xd->block[ib + iblock[j]];
352
        tx_type = get_tx_type_4x4(xd, ib + iblock[j]);
353
        if (tx_type != DCT_DCT) {
354
          vp9_dequant_iht_add_c(tx_type,
355
              BLOCK_OFFSET(xd->plane[0].qcoeff, ib + iblock[j], 16),
356 357
                                    b->dequant, *(b->base_dst) + b->dst,
                                    *(b->base_dst) + b->dst, b->dst_stride,
John Koleszar's avatar
John Koleszar committed
358 359
                                    b->dst_stride,
                                    xd->plane[0].eobs[ib + iblock[j]]);
360
        } else {
361
          xd->itxm_add(BLOCK_OFFSET(xd->plane[0].qcoeff, ib + iblock[j], 16),
362 363
                       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
364
                       xd->plane[0].eobs[ib + iblock[j]]);
365 366 367
        }
      }
      b = &xd->block[16 + i];
368 369
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, *(b->base_dst) + b->dst,
                              b->dst_stride);
370
      xd->itxm_add(BLOCK_OFFSET(xd->plane[1].qcoeff, i, 16),
371 372
                   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
373
                   xd->plane[1].eobs[i]);
374
      b = &xd->block[20 + i];
375 376
      vp9_intra_uv4x4_predict(xd, b, i8x8mode, *(b->base_dst) + b->dst,
                              b->dst_stride);
377
      xd->itxm_add(BLOCK_OFFSET(xd->plane[2].qcoeff, i, 16),
378 379
                   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
380
                   xd->plane[2].eobs[i]);
381 382 383 384
    }
  } else if (mode == B_PRED) {
    for (i = 0; i < 16; i++) {
      BLOCKD *b = &xd->block[i];
Dmitry Kovalev's avatar
Dmitry Kovalev committed
385
      int b_mode = xd->mode_info_context->bmi[i].as_mode.first;
386 387
#if CONFIG_NEWBINTRAMODES
      xd->mode_info_context->bmi[i].as_mode.context = b->bmi.as_mode.context =
388
          vp9_find_bpred_context(xd, b);
389 390
      if (!xd->mode_info_context->mbmi.mb_skip_coeff)
        vp9_decode_coefs_4x4(pbi, xd, bc, PLANE_TYPE_Y_WITH_DC, i);
391
#endif
392 393
      vp9_intra4x4_predict(xd, b, b_mode, *(b->base_dst) + b->dst,
                           b->dst_stride);
394
      tx_type = get_tx_type_4x4(xd, i);
395
      if (tx_type != DCT_DCT) {
396 397
        vp9_dequant_iht_add_c(tx_type,
                              BLOCK_OFFSET(xd->plane[0].qcoeff, i, 16),
398 399 400
                              b->dequant, *(b->base_dst) + b->dst,
                              *(b->base_dst) + b->dst, b->dst_stride,
                              b->dst_stride, xd->plane[0].eobs[i]);
401
      } else {
402
        xd->itxm_add(BLOCK_OFFSET(xd->plane[0].qcoeff, i, 16),
403 404
                     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
405
                     xd->plane[0].eobs[i]);
406 407
      }
    }
408 409 410 411
#if CONFIG_NEWBINTRAMODES
    if (!xd->mode_info_context->mbmi.mb_skip_coeff)
      vp9_decode_mb_tokens_4x4_uv(pbi, xd, bc);
#endif
412
    vp9_build_intra_predictors_mbuv_s(xd);
413
    xd->itxm_add_uv_block(xd->plane[1].qcoeff, xd->block[16].dequant,
414
         xd->dst.u_buffer, xd->dst.uv_stride, xd->dst.u_buffer,
John Koleszar's avatar
John Koleszar committed
415
         xd->dst.uv_stride, xd->plane[1].eobs);
416
    xd->itxm_add_uv_block(xd->plane[2].qcoeff, xd->block[16].dequant,
417
         xd->dst.v_buffer, xd->dst.uv_stride, xd->dst.v_buffer,
John Koleszar's avatar
John Koleszar committed
418
         xd->dst.uv_stride, xd->plane[2].eobs);
419
  } else if (mode == SPLITMV || get_tx_type_4x4(xd, 0) == DCT_DCT) {
420
    xd->itxm_add_y_block(xd->plane[0].qcoeff,
421
                          xd->block[0].dequant,
422
                          xd->dst.y_buffer, xd->dst.y_stride,
423 424
                          xd->dst.y_buffer,
                          xd->dst.y_stride,
425
                          xd);
426
    xd->itxm_add_uv_block(xd->plane[1].qcoeff, xd->block[16].dequant,
427
         xd->dst.u_buffer, xd->dst.uv_stride, xd->dst.u_buffer,
John Koleszar's avatar
John Koleszar committed
428
         xd->dst.uv_stride, xd->plane[1].eobs);
429
    xd->itxm_add_uv_block(xd->plane[2].qcoeff, xd->block[16].dequant,
430
         xd->dst.v_buffer, xd->dst.uv_stride, xd->dst.v_buffer,
John Koleszar's avatar
John Koleszar committed
431
         xd->dst.uv_stride, xd->plane[2].eobs);
432
  } else {
433 434
    for (i = 0; i < 16; i++) {
      BLOCKD *b = &xd->block[i];
435
      tx_type = get_tx_type_4x4(xd, i);
436
      if (tx_type != DCT_DCT) {
437 438
        vp9_dequant_iht_add_c(tx_type,
                              BLOCK_OFFSET(xd->plane[0].qcoeff, i, 16),
439 440
                              b->dequant, *(b->base_dst) + b->dst,
                              *(b->base_dst) + b->dst, b->dst_stride,
441
                              b->dst_stride, xd->plane[0].eobs[i]);
442
      } else {
443
        xd->itxm_add(BLOCK_OFFSET(xd->plane[0].qcoeff, i, 16),
444 445
                     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
446
                     xd->plane[0].eobs[i]);
447 448
      }
    }
449
    xd->itxm_add_uv_block(xd->plane[1].qcoeff, xd->block[16].dequant,
450
                          xd->dst.u_buffer, xd->dst.uv_stride, xd->dst.u_buffer,
John Koleszar's avatar
John Koleszar committed
451
                          xd->dst.uv_stride, xd->plane[1].eobs);
452
    xd->itxm_add_uv_block(xd->plane[2].qcoeff, xd->block[16].dequant,
453
                          xd->dst.v_buffer, xd->dst.uv_stride, xd->dst.v_buffer,
John Koleszar's avatar
John Koleszar committed
454
                          xd->dst.uv_stride, xd->plane[2].eobs);
455 456 457
  }
}

458 459 460 461
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;
462 463 464
  int n;

  for (n = 0; n < y_count; n++) {
465 466 467 468 469 470 471 472 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
    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;
510
    const int y_offset = (y_idx * 16) * mb->dst.y_stride + (x_idx * 16);
511
    const TX_TYPE tx_type = get_tx_type_16x16(mb,
512
                                (y_idx * (4 * bw) + x_idx) * 4);
513
    if (tx_type == DCT_DCT) {
514
      vp9_dequant_idct_add_16x16(BLOCK_OFFSET(mb->plane[0].qcoeff, n, 256),
515 516 517 518
                                 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
519
                                 mb->plane[0].eobs[n * 16]);
520
    } else {
521 522 523 524 525 526 527
      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]);
528 529
    }
  }
530 531 532 533 534 535 536 537 538
}

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);
539 540

  for (n = 0; n < uv_count; n++) {
541 542
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> (bwl - 1);
543
    const int uv_offset = (y_idx * 16) * mb->dst.uv_stride + (x_idx * 16);
544
    vp9_dequant_idct_add_16x16(BLOCK_OFFSET(mb->plane[1].qcoeff, n, 256),
545 546 547 548
                               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
549
                               mb->plane[1].eobs[n * 16]);
550
    vp9_dequant_idct_add_16x16(BLOCK_OFFSET(mb->plane[2].qcoeff, n, 256),
551 552 553 554
                               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
555
                               mb->plane[2].eobs[n * 16]);
556 557 558
  }
}

559 560 561 562
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;
563 564 565 566
  int n;

  // luma
  for (n = 0; n < y_count; n++) {
567 568
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> bwl;
569 570
    const int y_offset = (y_idx * 8) * xd->dst.y_stride + (x_idx * 8);
    const TX_TYPE tx_type = get_tx_type_8x8(xd,
571
                                            (y_idx * (2 * bw) + x_idx) * 2);
572
    if (tx_type == DCT_DCT) {
573 574 575 576 577
      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
578
                                 xd->plane[0].eobs[n * 4]);
579
    } else {
580 581 582 583 584 585 586
      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]);
587 588
    }
  }
589 590 591 592 593 594 595
}

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;
596 597 598

  // chroma
  for (n = 0; n < uv_count; n++) {
599 600
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> (bwl - 1);
601 602 603 604 605 606
    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
607
                               xd->plane[1].eobs[n * 4]);
608 609 610 611 612
    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
613
                               xd->plane[2].eobs[n * 4]);
614 615 616
  }
}

617 618 619 620
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;
621 622 623
  int n;

  for (n = 0; n < y_count; n++) {
624 625
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> bwl;
626
    const int y_offset = (y_idx * 4) * xd->dst.y_stride + (x_idx * 4);
627
    const TX_TYPE tx_type = get_tx_type_4x4(xd, n);
628
    if (tx_type == DCT_DCT) {
629 630 631 632 633
      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
634
                   xd->plane[0].eobs[n]);
635
    } else {
636 637 638 639 640 641 642 643
      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]);
644 645
    }
  }
646 647 648 649 650 651 652
}

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;
653 654

  for (n = 0; n < uv_count; n++) {
655 656
    const int x_idx = n & (bw - 1);
    const int y_idx = n >> (bwl - 1);
657 658 659 660 661
    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
662
        xd->dst.uv_stride, xd->dst.uv_stride, xd->plane[1].eobs[n]);
663 664 665 666
    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
667
        xd->dst.uv_stride, xd->dst.uv_stride, xd->plane[2].eobs[n]);
668 669 670
  }
}

671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692
// 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;
693
  int n, eobtotal;
694
  VP9_COMMON *const pc = &pbi->common;
695
  MODE_INFO *mi = xd->mode_info_context;
696
  const int mis = pc->mode_info_stride;
697

698
  assert(mi->mbmi.sb_type == bsize);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
699 700

  if (pbi->common.frame_type != KEY_FRAME)
701
    vp9_setup_interp_filters(xd, mi->mbmi.interp_filter, pc);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
702 703 704 705 706

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

707
  if (mi->mbmi.mb_skip_coeff) {
708
    vp9_reset_sb_tokens_context(xd, bsize);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
709

710 711
    // Special case:  Force the loopfilter to skip when eobtotal and
    // mb_skip_coeff are zero.
712
    skip_recon_mb(pbi, xd, mb_row, mb_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
713 714 715
    return;
  }

716 717 718 719 720 721 722 723 724 725 726
  // TODO(jingning): need to combine intra/inter predictor functions and
  // make them block size independent.
  // generate prediction
  if (bsize == BLOCK_SIZE_SB64X64) {
    assert(bsize == BLOCK_SIZE_SB64X64);
    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 {
      vp9_build_inter64x64_predictors_sb(xd, mb_row, mb_col);
    }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
727
  } else {
728 729 730 731 732 733 734
    assert(bsize == BLOCK_SIZE_SB32X32);
    if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
      vp9_build_intra_predictors_sby_s(xd);
      vp9_build_intra_predictors_sbuv_s(xd);
    } else {
      vp9_build_inter32x32_predictors_sb(xd, mb_row, mb_col);
    }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
735 736
  }

737
  // dequantization and idct
738
  eobtotal = vp9_decode_tokens(pbi, xd, bc, bsize);
739
  if (eobtotal == 0) {  // skip loopfilter
740 741
    for (n = 0; n < bw * bh; n++) {
      const int x_idx = n & (bw - 1), y_idx = n >> bwl;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
742

743 744 745 746 747 748
      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:
749
        decode_sb_32x32(xd, bsize);
750
        break;
751
      case TX_16X16:
752
        decode_sb_16x16(xd, bsize);
753
        break;
754
      case TX_8X8:
755 756
        decode_sby_8x8(xd, bsize);
        decode_sbuv_8x8(xd, bsize);
757
        break;
758
      case TX_4X4:
759 760
        decode_sby_4x4(xd, bsize);
        decode_sbuv_4x4(xd, bsize);
761 762
        break;
      default: assert(0);
763
    }
764
  }
765 766 767
#if CONFIG_CODE_NONZEROCOUNT
  propagate_nzcs(&pbi->common, xd);
#endif
768 769
}

770 771
// TODO(jingning): Need to merge SB and MB decoding. The MB decoding currently
// couples special handles on I8x8, B_PRED, and splitmv modes.
772 773 774
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
775
  int eobtotal = 0;
776 777
  const MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode;
  const int tx_size = xd->mode_info_context->mbmi.txfm_size;
778

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

Jingning Han's avatar
Jingning Han committed
781 782 783 784
  // re-initialize macroblock dequantizer before detokenization
  if (xd->segmentation_enabled)
    mb_init_dequantizer(pbi, xd);

John Koleszar's avatar
John Koleszar committed
785
  if (xd->mode_info_context->mbmi.mb_skip_coeff) {
786
    vp9_reset_sb_tokens_context(xd, BLOCK_SIZE_MB16X16);
787
  } else if (!bool_error(bc)) {
788 789 790
#if CONFIG_NEWBINTRAMODES
    if (mode != B_PRED)
#endif
791
      eobtotal = vp9_decode_tokens(pbi, xd, bc, BLOCK_SIZE_MB16X16);
John Koleszar's avatar
John Koleszar committed
792
  }
793

Deb Mukherjee's avatar
Deb Mukherjee committed
794
  //mode = xd->mode_info_context->mbmi.mode;
795
  if (pbi->common.frame_type != KEY_FRAME)
796
    vp9_setup_interp_filters(xd, xd->mode_info_context->mbmi.interp_filter,