quantize.c 23.83 KiB
/*
 *  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 <math.h>
#include "vpx_mem/vpx_mem.h"
#include "onyx_int.h"
#include "quantize.h"
#include "vp8/common/quant_common.h"
#include "vp8/common/seg_common.h"
#ifdef ENC_DEBUG
extern int enc_debug;
#endif
void vp9_ht_quantize_b_4x4(BLOCK *b, BLOCKD *d, TX_TYPE tx_type) {
  int i, rc, eob;
  int zbin;
  int x, y, z, sz;
  short *zbin_boost_ptr  = b->zrun_zbin_boost;
  short *coeff_ptr       = b->coeff;
  short *zbin_ptr        = b->zbin;
  short *round_ptr       = b->round;
  short *quant_ptr       = b->quant;
  unsigned char *quant_shift_ptr = b->quant_shift;
  short *qcoeff_ptr      = d->qcoeff;
  short *dqcoeff_ptr     = d->dqcoeff;
  short *dequant_ptr     = d->dequant;
  short zbin_oq_value    = b->zbin_extra;
  int const *pt_scan ;
  switch (tx_type) {
    case ADST_DCT :
      pt_scan = vp8_row_scan;
      break;
    case DCT_ADST :
      pt_scan = vp8_col_scan;
      break;
    default :
      pt_scan = vp8_default_zig_zag1d;
      break;
  vpx_memset(qcoeff_ptr, 0, 32);
  vpx_memset(dqcoeff_ptr, 0, 32);
  eob = -1;
  for (i = 0; i < b->eob_max_offset; i++) {
    rc   = pt_scan[i];
    z    = coeff_ptr[rc];
    zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value;
    zbin_boost_ptr ++;
    sz = (z >> 31);                                 // sign of z
    x  = (z ^ sz) - sz;                             // x = abs(z)
    if (x >= zbin) {
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
x += round_ptr[rc]; y = (((x * quant_ptr[rc]) >> 16) + x) >> quant_shift_ptr[rc]; // quantize (x) x = (y ^ sz) - sz; // get the sign back qcoeff_ptr[rc] = x; // write to destination dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value if (y) { eob = i; // last nonzero coeffs zbin_boost_ptr = b->zrun_zbin_boost; // reset zero runlength } } } d->eob = eob + 1; } void vp9_regular_quantize_b_4x4(BLOCK *b, BLOCKD *d) { int i, rc, eob; int zbin; int x, y, z, sz; short *zbin_boost_ptr = b->zrun_zbin_boost; short *coeff_ptr = b->coeff; short *zbin_ptr = b->zbin; short *round_ptr = b->round; short *quant_ptr = b->quant; unsigned char *quant_shift_ptr = b->quant_shift; short *qcoeff_ptr = d->qcoeff; short *dqcoeff_ptr = d->dqcoeff; short *dequant_ptr = d->dequant; short zbin_oq_value = b->zbin_extra; vpx_memset(qcoeff_ptr, 0, 32); vpx_memset(dqcoeff_ptr, 0, 32); eob = -1; for (i = 0; i < b->eob_max_offset; i++) { rc = vp8_default_zig_zag1d[i]; z = coeff_ptr[rc]; zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value; zbin_boost_ptr ++; sz = (z >> 31); // sign of z x = (z ^ sz) - sz; // x = abs(z) if (x >= zbin) { x += round_ptr[rc]; y = (((x * quant_ptr[rc]) >> 16) + x) >> quant_shift_ptr[rc]; // quantize (x) x = (y ^ sz) - sz; // get the sign back qcoeff_ptr[rc] = x; // write to destination dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value if (y) { eob = i; // last nonzero coeffs zbin_boost_ptr = b->zrun_zbin_boost; // reset zero runlength } } } d->eob = eob + 1; } void vp9_quantize_mby_4x4_c(MACROBLOCK *x) { int i; int has_2nd_order = x->e_mbd.mode_info_context->mbmi.mode != SPLITMV;
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
for (i = 0; i < 16; i++) x->quantize_b_4x4(&x->block[i], &x->e_mbd.block[i]); if (has_2nd_order) x->quantize_b_4x4(&x->block[24], &x->e_mbd.block[24]); } void vp9_quantize_mbuv_4x4_c(MACROBLOCK *x) { int i; for (i = 16; i < 24; i++) x->quantize_b_4x4(&x->block[i], &x->e_mbd.block[i]); } void vp9_quantize_mb_4x4_c(MACROBLOCK *x) { vp9_quantize_mby_4x4_c(x); vp9_quantize_mbuv_4x4_c(x); } void vp9_regular_quantize_b_2x2(BLOCK *b, BLOCKD *d) { int i, rc, eob; int zbin; int x, y, z, sz; short *zbin_boost_ptr = b->zrun_zbin_boost; int zbin_zrun_index = 0; short *coeff_ptr = b->coeff; short *zbin_ptr = b->zbin; short *round_ptr = b->round; short *quant_ptr = b->quant; unsigned char *quant_shift_ptr = b->quant_shift; short *qcoeff_ptr = d->qcoeff; short *dqcoeff_ptr = d->dqcoeff; short *dequant_ptr = d->dequant; short zbin_oq_value = b->zbin_extra; // double q2nd = 4; vpx_memset(qcoeff_ptr, 0, 32); vpx_memset(dqcoeff_ptr, 0, 32); eob = -1; for (i = 0; i < b->eob_max_offset_8x8; i++) { rc = vp8_default_zig_zag1d[i]; z = coeff_ptr[rc]; zbin_boost_ptr = &b->zrun_zbin_boost[zbin_zrun_index]; zbin_zrun_index += 4; zbin = (zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value); sz = (z >> 31); // sign of z x = (z ^ sz) - sz; // x = abs(z) if (x >= zbin) { x += (round_ptr[rc]); y = ((int)((int)(x * quant_ptr[rc]) >> 16) + x) >> quant_shift_ptr[rc]; // quantize (x) x = (y ^ sz) - sz; // get the sign back qcoeff_ptr[rc] = x; // write to destination dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value if (y) { eob = i; // last nonzero coeffs zbin_zrun_index = 0; } } } d->eob = eob + 1; } void vp9_regular_quantize_b_8x8(BLOCK *b, BLOCKD *d) {
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
int i, rc, eob; int zbin; int x, y, z, sz; short *zbin_boost_ptr = b->zrun_zbin_boost_8x8; short *coeff_ptr = b->coeff; short *zbin_ptr = b->zbin_8x8; short *round_ptr = b->round; short *quant_ptr = b->quant; unsigned char *quant_shift_ptr = b->quant_shift; short *qcoeff_ptr = d->qcoeff; short *dqcoeff_ptr = d->dqcoeff; short *dequant_ptr = d->dequant; short zbin_oq_value = b->zbin_extra; vpx_memset(qcoeff_ptr, 0, 64 * sizeof(short)); vpx_memset(dqcoeff_ptr, 0, 64 * sizeof(short)); eob = -1; for (i = 0; i < b->eob_max_offset_8x8; i++) { rc = vp8_default_zig_zag1d_8x8[i]; z = coeff_ptr[rc]; zbin = (zbin_ptr[rc != 0] + *zbin_boost_ptr + zbin_oq_value); zbin_boost_ptr++; sz = (z >> 31); // sign of z x = (z ^ sz) - sz; // x = abs(z) if (x >= zbin) { x += (round_ptr[rc != 0]); y = ((int)(((int)(x * quant_ptr[rc != 0]) >> 16) + x)) >> quant_shift_ptr[rc != 0]; // quantize (x) x = (y ^ sz) - sz; // get the sign back qcoeff_ptr[rc] = x; // write to destination dqcoeff_ptr[rc] = x * dequant_ptr[rc != 0]; // dequantized value if (y) { eob = i; // last nonzero coeffs zbin_boost_ptr = b->zrun_zbin_boost_8x8; } } } d->eob = eob + 1; } void vp9_quantize_mby_8x8(MACROBLOCK *x) { int i; int has_2nd_order = x->e_mbd.mode_info_context->mbmi.mode != SPLITMV; for (i = 0; i < 16; i ++) { x->e_mbd.block[i].eob = 0; } x->e_mbd.block[24].eob = 0; for (i = 0; i < 16; i += 4) x->quantize_b_8x8(&x->block[i], &x->e_mbd.block[i]); if (has_2nd_order) x->quantize_b_2x2(&x->block[24], &x->e_mbd.block[24]); } void vp9_quantize_mbuv_8x8(MACROBLOCK *x) { int i; for (i = 16; i < 24; i ++) x->e_mbd.block[i].eob = 0; for (i = 16; i < 24; i += 4) x->quantize_b_8x8(&x->block[i], &x->e_mbd.block[i]); }