decodframe.c 54.9 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
 *
 *  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.
John Koleszar's avatar
John Koleszar committed
 */


#include "onyxd_int.h"
#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"
John Koleszar's avatar
John Koleszar committed
#include "dequantize.h"
#include "detokenize.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 "vp8/common/setupintrarecon.h"
John Koleszar's avatar
John Koleszar committed
#include "decodemv.h"
#include "vp8/common/extend.h"
Yaowu Xu's avatar
Yaowu Xu committed
#include "vp8/common/modecont.h"
John Koleszar's avatar
John Koleszar committed
#include "vpx_mem/vpx_mem.h"
#include "vp8/common/idct.h"
John Koleszar's avatar
John Koleszar committed
#include "dequantize.h"
#include "dboolhuff.h"

#include "vp8/common/seg_common.h"
#include "vp8/common/entropy.h"
John Koleszar's avatar
John Koleszar committed
#include <assert.h>
#include <stdio.h>

#ifdef DEC_DEBUG
int dec_debug = 0;
#endif

#define COEFCOUNT_TESTING

#if CONFIG_NEWUPDATE

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);
}
John Koleszar's avatar
John Koleszar committed
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);
John Koleszar's avatar
John Koleszar committed

        /* all the ac values = ; */
John Koleszar's avatar
John Koleszar committed
        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)
John Koleszar's avatar
John Koleszar committed
{
    int i;
    int QIndex;
    VP8_COMMON *const pc = & pbi->common;
Paul Wilkins's avatar
Paul Wilkins committed
    int segment_id = xd->mode_info_context->mbmi.segment_id;
Paul Wilkins's avatar
Paul Wilkins committed
    // Set the Q baseline allowing for any segment level adjustment
    if ( segfeature_active( xd, segment_id, SEG_LVL_ALT_Q ) )
John Koleszar's avatar
John Koleszar committed
    {
        /* Abs Value */
Paul Wilkins's avatar
Paul Wilkins committed
        if (xd->mb_segment_abs_delta == SEGMENT_ABSDATA)
            QIndex = get_segdata( xd, segment_id, SEG_LVL_ALT_Q );
        /* Delta Value */
John Koleszar's avatar
John Koleszar committed
        else
        {
            QIndex = pc->base_qindex +
                     get_segdata( xd, segment_id, SEG_LVL_ALT_Q );
            QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ) : 0;    /* Clamp to valid range */
John Koleszar's avatar
John Koleszar committed
        }
    }
    else
        QIndex = pc->base_qindex;

    /* Set up the block level dequant pointers */
John Koleszar's avatar
John Koleszar committed
    for (i = 0; i < 16; i++)
    {
        xd->block[i].dequant = pc->Y1dequant[QIndex];
    }

Hui Su's avatar
Hui Su committed
#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

John Koleszar's avatar
John Koleszar committed
    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.
 */
John Koleszar's avatar
John Koleszar committed
static void skip_recon_mb(VP8D_COMP *pbi, MACROBLOCKD *xd)
{
    if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME)
John Koleszar's avatar
John Koleszar committed
    {
        RECON_INVOKE(&pbi->common.rtcd.recon, build_intra_predictors_mbuv_s)(xd);
        RECON_INVOKE(&pbi->common.rtcd.recon,
                     build_intra_predictors_mby_s)(xd);
John Koleszar's avatar
John Koleszar committed
    }
    else
    {
        vp8_build_inter16x16_predictors_mb(xd, xd->dst.y_buffer,
Loading full blame...