Newer
Older
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
#include "vp8/common/header.h"
#include "vp8/common/reconintra.h"
#include "vp8/common/reconintra4x4.h"
#include "vp8/common/recon.h"
#include "vp8/common/reconinter.h"
#include "vp8/common/invtrans.h"
#include "vp8/common/alloccommon.h"
#include "vp8/common/entropymode.h"
#include "vp8/common/quant_common.h"
#include "vpx_scale/vpxscale.h"
#include "vpx_scale/yv12extend.h"
#include "dequantize.h"
#include "dboolhuff.h"
#include "vp8/common/entropy.h"
#ifdef DEC_DEBUG
int dec_debug = 0;
#endif
#define COEFCOUNT_TESTING
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;
}
static int inv_remap_prob(int v, int m)
{
const int n = 256;
const int modulus = MODULUS_PARAM;
int i, w;
v = merge_index(v, n-1, modulus);
if ((m<<1)<=n) {
i = inv_recenter_nonneg(v+1, m);
} else {
i = n-1-inv_recenter_nonneg(v+1, n-1-m);
}
return i;
}
static vp8_prob read_prob_diff_update(vp8_reader *const bc, int oldp)
{
int delp = vp8_decode_term_subexp(bc, SUBEXP_PARAM, 255);
return (vp8_prob)inv_remap_prob(delp, oldp);
}
void vp8cx_init_de_quantizer(VP8D_COMP *pbi)
{
int i;
int Q;
VP8_COMMON *const pc = & pbi->common;
for (Q = 0; Q < QINDEX_RANGE; Q++)
{
pc->Y1dequant[Q][0] = (short)vp8_dc_quant(Q, pc->y1dc_delta_q);
pc->Y2dequant[Q][0] = (short)vp8_dc2quant(Q, pc->y2dc_delta_q);
pc->UVdequant[Q][0] = (short)vp8_dc_uv_quant(Q, pc->uvdc_delta_q);
for (i = 1; i < 16; i++)
{
int rc = vp8_default_zig_zag1d[i];
pc->Y1dequant[Q][rc] = (short)vp8_ac_yquant(Q);
pc->Y2dequant[Q][rc] = (short)vp8_ac2quant(Q, pc->y2ac_delta_q);
pc->UVdequant[Q][rc] = (short)vp8_ac_uv_quant(Q, pc->uvac_delta_q);
void mb_init_dequantizer(VP8D_COMP *pbi, MACROBLOCKD *xd)
{
int i;
int QIndex;
VP8_COMMON *const pc = & pbi->common;
int segment_id = xd->mode_info_context->mbmi.segment_id;
// Set the Q baseline allowing for any segment level adjustment
if ( segfeature_active( xd, segment_id, SEG_LVL_ALT_Q ) )
QIndex = get_segdata( xd, segment_id, SEG_LVL_ALT_Q );
get_segdata( xd, segment_id, SEG_LVL_ALT_Q );
QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ) : 0; /* Clamp to valid range */
/* Set up the block level dequant pointers */
for (i = 0; i < 16; i++)
{
xd->block[i].dequant = pc->Y1dequant[QIndex];
}
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#if CONFIG_LOSSLESS
if(!QIndex)
{
pbi->common.rtcd.idct.idct1 = vp8_short_inv_walsh4x4_1_x8_c;
pbi->common.rtcd.idct.idct16 = vp8_short_inv_walsh4x4_x8_c;
pbi->common.rtcd.idct.idct1_scalar_add = vp8_dc_only_inv_walsh_add_c;
pbi->common.rtcd.idct.iwalsh1 = vp8_short_inv_walsh4x4_1_lossless_c;
pbi->common.rtcd.idct.iwalsh16 = vp8_short_inv_walsh4x4_lossless_c;
pbi->dequant.idct_add = vp8_dequant_idct_add_lossless_c;
pbi->dequant.dc_idct_add = vp8_dequant_dc_idct_add_lossless_c;
pbi->dequant.dc_idct_add_y_block = vp8_dequant_dc_idct_add_y_block_lossless_c;
pbi->dequant.idct_add_y_block = vp8_dequant_idct_add_y_block_lossless_c;
pbi->dequant.idct_add_uv_block = vp8_dequant_idct_add_uv_block_lossless_c;
}
else
{
pbi->common.rtcd.idct.idct1 = vp8_short_idct4x4llm_1_c;
pbi->common.rtcd.idct.idct16 = vp8_short_idct4x4llm_c;
pbi->common.rtcd.idct.idct1_scalar_add = vp8_dc_only_idct_add_c;
pbi->common.rtcd.idct.iwalsh1 = vp8_short_inv_walsh4x4_1_c;
pbi->common.rtcd.idct.iwalsh16 = vp8_short_inv_walsh4x4_c;
pbi->dequant.idct_add = vp8_dequant_idct_add_c;
pbi->dequant.dc_idct_add = vp8_dequant_dc_idct_add_c;
pbi->dequant.dc_idct_add_y_block = vp8_dequant_dc_idct_add_y_block_c;
pbi->dequant.idct_add_y_block = vp8_dequant_idct_add_y_block_c;
pbi->dequant.idct_add_uv_block = vp8_dequant_idct_add_uv_block_c;
}
#endif
for (i = 16; i < 24; i++)
{
xd->block[i].dequant = pc->UVdequant[QIndex];
}
xd->block[24].dequant = pc->Y2dequant[QIndex];
}
#if CONFIG_RUNTIME_CPU_DETECT
#define RTCD_VTABLE(x) (&(pbi)->common.rtcd.x)
#else
#define RTCD_VTABLE(x) NULL
#endif
/* 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.
*/
static void skip_recon_mb(VP8D_COMP *pbi, MACROBLOCKD *xd)
{
if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME)
RECON_INVOKE(&pbi->common.rtcd.recon, build_intra_predictors_mbuv_s)(xd);
RECON_INVOKE(&pbi->common.rtcd.recon,
build_intra_predictors_mby_s)(xd);
vp8_build_inter16x16_predictors_mb(xd, xd->dst.y_buffer,
Loading full blame...