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
866
867
868
869
870
871
  if (tx_size == TX_16X16) {
    decode_16x16(pbi, xd, bc);
  } else if (tx_size == TX_8X8) {
    decode_8x8(pbi, xd, bc);
  } else {
    decode_4x4(pbi, xd, bc);
  }
#ifdef DEC_DEBUG
  if (dec_debug) {
    int i, j;
    printf("\n");
872
873
874
875
876
877
878
    printf("predictor y\n");
    for (i = 0; i < 16; i++) {
      for (j = 0; j < 16; j++)
        printf("%3d ", xd->predictor[i * 16 + j]);
      printf("\n");
    }
    printf("\n");
879
    printf("final y\n");
John Koleszar's avatar
John Koleszar committed
880
    for (i = 0; i < 16; i++) {
881
882
883
      for (j = 0; j < 16; j++)
        printf("%3d ", xd->dst.y_buffer[i * xd->dst.y_stride + j]);
      printf("\n");
John Koleszar's avatar
John Koleszar committed
884
    }
885
886
887
888
889
890
    printf("\n");
    printf("final u\n");
    for (i = 0; i < 8; i++) {
      for (j = 0; j < 8; j++)
        printf("%3d ", xd->dst.u_buffer[i * xd->dst.uv_stride + j]);
      printf("\n");
891
    }
892
893
894
895
896
897
    printf("\n");
    printf("final v\n");
    for (i = 0; i < 8; i++) {
      for (j = 0; j < 8; j++)
        printf("%3d ", xd->dst.v_buffer[i * xd->dst.uv_stride + j]);
      printf("\n");
898
    }
899
    fflush(stdout);
John Koleszar's avatar
John Koleszar committed
900
  }
901
#endif
Yaowu Xu's avatar
Yaowu Xu committed
902
}
John Koleszar's avatar
John Koleszar committed
903

904

905
static int get_delta_q(vp9_reader *bc, int prev, int *q_update) {
John Koleszar's avatar
John Koleszar committed
906
  int ret_val = 0;
John Koleszar's avatar
John Koleszar committed
907

908
909
  if (vp9_read_bit(bc)) {
    ret_val = vp9_read_literal(bc, 4);
John Koleszar's avatar
John Koleszar committed
910

911
    if (vp9_read_bit(bc))
John Koleszar's avatar
John Koleszar committed
912
913
      ret_val = -ret_val;
  }
John Koleszar's avatar
John Koleszar committed
914

915
  // Trigger a quantizer update if the delta-q value has changed
John Koleszar's avatar
John Koleszar committed
916
917
  if (ret_val != prev)
    *q_update = 1;
John Koleszar's avatar
John Koleszar committed
918

John Koleszar's avatar
John Koleszar committed
919
  return ret_val;
John Koleszar's avatar
John Koleszar committed
920
921
922
923
924
925
926
}

#ifdef PACKET_TESTING
#include <stdio.h>
FILE *vpxlog = 0;
#endif

Ronald S. Bultje's avatar
Ronald S. Bultje committed
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
static void set_offsets(VP9D_COMP *pbi, int block_size,
                        int mb_row, int mb_col) {
  VP9_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;
  const int mis = cm->mode_info_stride;
  const int idx = mis * mb_row + mb_col;
  const int dst_fb_idx = cm->new_fb_idx;
  const int recon_y_stride = cm->yv12_fb[dst_fb_idx].y_stride;
  const int recon_uv_stride = cm->yv12_fb[dst_fb_idx].uv_stride;
  const int recon_yoffset = mb_row * 16 * recon_y_stride + 16 * mb_col;
  const int recon_uvoffset = mb_row * 8 * recon_uv_stride + 8 * mb_col;

  xd->mode_info_context = cm->mi + idx;
  xd->mode_info_context->mbmi.sb_type = block_size >> 5;
  xd->prev_mode_info_context = cm->prev_mi + idx;
  xd->above_context = cm->above_context + mb_col;
  xd->left_context = cm->left_context + (mb_row & 3);
John Koleszar's avatar
John Koleszar committed
944

945
946
947
  // Distance of Mb to the various image edges.
  // These are specified to 8th pel as they are always compared to
  // values that are in 1/8th pel units
Ronald S. Bultje's avatar
Ronald S. Bultje committed
948
949
  block_size >>= 4;  // in mb units

950
951
  set_mb_row(cm, xd, mb_row, block_size);
  set_mb_col(cm, xd, mb_col, block_size);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
952
953
954
955
956

  xd->dst.y_buffer = cm->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
  xd->dst.u_buffer = cm->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
  xd->dst.v_buffer = cm->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
}
John Koleszar's avatar
John Koleszar committed
957

958
static void set_refs(VP9D_COMP *pbi, int block_size, int mb_row, int mb_col) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
959
960
  VP9_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;
961
  MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
962
963

  if (mbmi->ref_frame > INTRA_FRAME) {
964
    // Select the appropriate reference frame for this MB
965
966
967
    const int fb_idx = cm->active_ref_idx[mbmi->ref_frame - 1];
    const YV12_BUFFER_CONFIG *cfg = &cm->yv12_fb[fb_idx];
    xd->scale_factor[0]    = cm->active_ref_scale[mbmi->ref_frame - 1];
968
    xd->scale_factor_uv[0] = cm->active_ref_scale[mbmi->ref_frame - 1];