2010-05-18 17:58:33 +02:00
|
|
|
/*
|
2010-09-09 14:16:39 +02:00
|
|
|
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
|
2010-05-18 17:58:33 +02:00
|
|
|
*
|
2010-06-18 18:39:21 +02:00
|
|
|
* Use of this source code is governed by a BSD-style license
|
2010-06-04 22:19:40 +02:00
|
|
|
* that can be found in the LICENSE file in the root of the source
|
|
|
|
* tree. An additional intellectual property rights grant can be found
|
2010-06-18 18:39:21 +02:00
|
|
|
* in the file PATENTS. All contributing project authors may
|
2010-06-04 22:19:40 +02:00
|
|
|
* be found in the AUTHORS file in the root of the source tree.
|
2010-05-18 17:58:33 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
#include "vpx_mem/vpx_mem.h"
|
|
|
|
|
2012-11-28 19:41:40 +01:00
|
|
|
#include "vp9/encoder/vp9_onyx_int.h"
|
|
|
|
#include "vp9/encoder/vp9_quantize.h"
|
2012-11-27 22:59:17 +01:00
|
|
|
#include "vp9/common/vp9_quant_common.h"
|
2010-05-18 17:58:33 +02:00
|
|
|
|
2012-11-27 22:59:17 +01:00
|
|
|
#include "vp9/common/vp9_seg_common.h"
|
2011-10-05 12:26:00 +02:00
|
|
|
|
2011-02-14 23:18:18 +01:00
|
|
|
#ifdef ENC_DEBUG
|
|
|
|
extern int enc_debug;
|
|
|
|
#endif
|
|
|
|
|
2013-04-04 21:03:27 +02:00
|
|
|
static INLINE int plane_idx(int plane) {
|
|
|
|
return plane == 0 ? 0 :
|
|
|
|
plane == 1 ? 16 : 20;
|
2013-03-06 00:18:06 +01:00
|
|
|
}
|
|
|
|
|
2013-02-27 19:00:24 +01:00
|
|
|
void vp9_ht_quantize_b_4x4(MACROBLOCK *mb, int b_idx, TX_TYPE tx_type) {
|
|
|
|
MACROBLOCKD *const xd = &mb->e_mbd;
|
2013-03-06 00:18:06 +01:00
|
|
|
BLOCK *const b = &mb->block[0];
|
|
|
|
BLOCKD *const d = &xd->block[0];
|
2012-06-25 21:26:09 +02:00
|
|
|
int i, rc, eob;
|
|
|
|
int zbin;
|
|
|
|
int x, y, z, sz;
|
2013-03-06 00:18:06 +01:00
|
|
|
int16_t *coeff_ptr = mb->coeff + b_idx * 16;
|
2013-04-02 23:50:40 +02:00
|
|
|
// ht is luma-only
|
|
|
|
int16_t *qcoeff_ptr = BLOCK_OFFSET(xd->plane[0].qcoeff, b_idx, 16);
|
|
|
|
int16_t *dqcoeff_ptr = BLOCK_OFFSET(xd->plane[0].dqcoeff, b_idx, 16);
|
2012-12-19 00:31:19 +01:00
|
|
|
int16_t *zbin_boost_ptr = b->zrun_zbin_boost;
|
|
|
|
int16_t *zbin_ptr = b->zbin;
|
|
|
|
int16_t *round_ptr = b->round;
|
|
|
|
int16_t *quant_ptr = b->quant;
|
|
|
|
uint8_t *quant_shift_ptr = b->quant_shift;
|
|
|
|
int16_t *dequant_ptr = d->dequant;
|
|
|
|
int zbin_oq_value = b->zbin_extra;
|
2013-03-06 00:18:06 +01:00
|
|
|
const int *pt_scan;
|
2013-02-20 19:16:24 +01:00
|
|
|
#if CONFIG_CODE_NONZEROCOUNT
|
|
|
|
int nzc = 0;
|
|
|
|
#endif
|
2012-06-25 21:26:09 +02:00
|
|
|
|
2012-10-16 01:41:41 +02:00
|
|
|
switch (tx_type) {
|
2012-12-19 00:31:19 +01:00
|
|
|
case ADST_DCT:
|
2012-12-18 19:49:10 +01:00
|
|
|
pt_scan = vp9_row_scan_4x4;
|
2012-06-25 21:26:09 +02:00
|
|
|
break;
|
2012-12-19 00:31:19 +01:00
|
|
|
case DCT_ADST:
|
2012-12-18 19:49:10 +01:00
|
|
|
pt_scan = vp9_col_scan_4x4;
|
2012-06-25 21:26:09 +02:00
|
|
|
break;
|
2012-12-19 00:31:19 +01:00
|
|
|
default:
|
2012-12-18 19:49:10 +01:00
|
|
|
pt_scan = vp9_default_zig_zag1d_4x4;
|
2012-06-25 21:26:09 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
vpx_memset(qcoeff_ptr, 0, 32);
|
|
|
|
vpx_memset(dqcoeff_ptr, 0, 32);
|
|
|
|
|
|
|
|
eob = -1;
|
|
|
|
|
2013-01-29 14:33:17 +01:00
|
|
|
if (!b->skip_block) {
|
|
|
|
for (i = 0; i < 16; 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) {
|
|
|
|
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
|
2013-02-20 19:16:24 +01:00
|
|
|
#if CONFIG_CODE_NONZEROCOUNT
|
|
|
|
++nzc; // number of nonzero coeffs
|
|
|
|
#endif
|
2013-01-29 14:33:17 +01:00
|
|
|
zbin_boost_ptr = b->zrun_zbin_boost; // reset zero runlength
|
|
|
|
}
|
2012-06-25 21:26:09 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-04 21:03:27 +02:00
|
|
|
xd->plane[0].eobs[b_idx] = eob + 1;
|
2013-02-20 19:16:24 +01:00
|
|
|
#if CONFIG_CODE_NONZEROCOUNT
|
|
|
|
xd->nzcs[b_idx] = nzc;
|
|
|
|
#endif
|
2012-06-25 21:26:09 +02:00
|
|
|
}
|
|
|
|
|
2013-04-04 21:03:27 +02:00
|
|
|
void vp9_regular_quantize_b_4x4(MACROBLOCK *mb, int b_idx, int y_blocks) {
|
2013-02-27 19:00:24 +01:00
|
|
|
MACROBLOCKD *const xd = &mb->e_mbd;
|
2013-04-04 21:03:27 +02:00
|
|
|
const struct plane_block_idx pb_idx = plane_block_idx(y_blocks, b_idx);
|
|
|
|
const int c_idx = plane_idx(pb_idx.plane);
|
2013-03-06 00:18:06 +01:00
|
|
|
BLOCK *const b = &mb->block[c_idx];
|
|
|
|
BLOCKD *const d = &xd->block[c_idx];
|
2012-07-14 00:21:29 +02:00
|
|
|
int i, rc, eob;
|
|
|
|
int zbin;
|
|
|
|
int x, y, z, sz;
|
2013-03-06 00:18:06 +01:00
|
|
|
int16_t *coeff_ptr = mb->coeff + b_idx * 16;
|
2013-04-02 23:50:40 +02:00
|
|
|
int16_t *qcoeff_ptr = BLOCK_OFFSET(xd->plane[pb_idx.plane].qcoeff,
|
|
|
|
pb_idx.block, 16);
|
|
|
|
int16_t *dqcoeff_ptr = BLOCK_OFFSET(xd->plane[pb_idx.plane].dqcoeff,
|
|
|
|
pb_idx.block, 16);
|
2012-12-19 00:31:19 +01:00
|
|
|
int16_t *zbin_boost_ptr = b->zrun_zbin_boost;
|
|
|
|
int16_t *zbin_ptr = b->zbin;
|
|
|
|
int16_t *round_ptr = b->round;
|
|
|
|
int16_t *quant_ptr = b->quant;
|
|
|
|
uint8_t *quant_shift_ptr = b->quant_shift;
|
|
|
|
int16_t *dequant_ptr = d->dequant;
|
|
|
|
int zbin_oq_value = b->zbin_extra;
|
2013-02-20 19:16:24 +01:00
|
|
|
#if CONFIG_CODE_NONZEROCOUNT
|
|
|
|
int nzc = 0;
|
|
|
|
#endif
|
2012-07-14 00:21:29 +02:00
|
|
|
|
2013-04-04 21:03:27 +02:00
|
|
|
if (c_idx == 0) assert(pb_idx.plane == 0);
|
|
|
|
if (c_idx == 16) assert(pb_idx.plane == 1);
|
|
|
|
if (c_idx == 20) assert(pb_idx.plane == 2);
|
2012-07-14 00:21:29 +02:00
|
|
|
vpx_memset(qcoeff_ptr, 0, 32);
|
|
|
|
vpx_memset(dqcoeff_ptr, 0, 32);
|
|
|
|
|
|
|
|
eob = -1;
|
|
|
|
|
2013-01-29 14:33:17 +01:00
|
|
|
if (!b->skip_block) {
|
|
|
|
for (i = 0; i < 16; i++) {
|
|
|
|
rc = vp9_default_zig_zag1d_4x4[i];
|
|
|
|
z = coeff_ptr[rc];
|
2012-07-14 00:21:29 +02:00
|
|
|
|
2013-01-29 14:33:17 +01:00
|
|
|
zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value;
|
|
|
|
zbin_boost_ptr++;
|
2012-07-14 00:21:29 +02:00
|
|
|
|
2013-01-29 14:33:17 +01:00
|
|
|
sz = (z >> 31); // sign of z
|
|
|
|
x = (z ^ sz) - sz; // x = abs(z)
|
2012-07-14 00:21:29 +02:00
|
|
|
|
2013-01-29 14:33:17 +01:00
|
|
|
if (x >= zbin) {
|
|
|
|
x += round_ptr[rc];
|
2012-06-25 21:26:09 +02:00
|
|
|
|
2013-01-29 14:33:17 +01:00
|
|
|
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
|
2012-07-14 00:21:29 +02:00
|
|
|
|
2013-01-29 14:33:17 +01:00
|
|
|
if (y) {
|
|
|
|
eob = i; // last nonzero coeffs
|
2013-02-20 19:16:24 +01:00
|
|
|
#if CONFIG_CODE_NONZEROCOUNT
|
|
|
|
++nzc; // number of nonzero coeffs
|
|
|
|
#endif
|
2013-01-29 14:33:17 +01:00
|
|
|
zbin_boost_ptr = b->zrun_zbin_boost; // reset zero runlength
|
|
|
|
}
|
2012-07-14 00:21:29 +02:00
|
|
|
}
|
2010-05-18 17:58:33 +02:00
|
|
|
}
|
2012-07-14 00:21:29 +02:00
|
|
|
}
|
2010-05-18 17:58:33 +02:00
|
|
|
|
2013-04-04 21:03:27 +02:00
|
|
|
xd->plane[pb_idx.plane].eobs[pb_idx.block] = eob + 1;
|
2013-02-20 19:16:24 +01:00
|
|
|
#if CONFIG_CODE_NONZEROCOUNT
|
|
|
|
xd->nzcs[b_idx] = nzc;
|
|
|
|
#endif
|
2010-05-18 17:58:33 +02:00
|
|
|
}
|
2010-10-11 22:49:52 +02:00
|
|
|
|
2013-03-06 00:18:06 +01:00
|
|
|
void vp9_quantize_mby_4x4(MACROBLOCK *x) {
|
2012-07-14 00:21:29 +02:00
|
|
|
int i;
|
2012-11-16 00:14:38 +01:00
|
|
|
|
|
|
|
for (i = 0; i < 16; i++) {
|
2013-03-06 00:18:06 +01:00
|
|
|
TX_TYPE tx_type = get_tx_type_4x4(&x->e_mbd, i);
|
2012-11-16 00:14:38 +01:00
|
|
|
if (tx_type != DCT_DCT) {
|
2013-02-27 19:00:24 +01:00
|
|
|
vp9_ht_quantize_b_4x4(x, i, tx_type);
|
2012-11-16 00:14:38 +01:00
|
|
|
} else {
|
2013-04-04 21:03:27 +02:00
|
|
|
x->quantize_b_4x4(x, i, 16);
|
2012-11-16 00:14:38 +01:00
|
|
|
}
|
|
|
|
}
|
2010-05-18 17:58:33 +02:00
|
|
|
}
|
|
|
|
|
2013-03-06 00:18:06 +01:00
|
|
|
void vp9_quantize_mbuv_4x4(MACROBLOCK *x) {
|
2012-07-14 00:21:29 +02:00
|
|
|
int i;
|
2013-04-02 23:50:40 +02:00
|
|
|
const MACROBLOCKD * const xd = &x->e_mbd;
|
|
|
|
const BLOCK_SIZE_TYPE real_sb_type = xd->mode_info_context->mbmi.sb_type;
|
|
|
|
xd->mode_info_context->mbmi.sb_type = BLOCK_SIZE_MB16X16;
|
2010-05-18 17:58:33 +02:00
|
|
|
|
2012-07-14 00:21:29 +02:00
|
|
|
for (i = 16; i < 24; i++)
|
2013-04-04 21:03:27 +02:00
|
|
|
x->quantize_b_4x4(x, i, 16);
|
2013-04-02 23:50:40 +02:00
|
|
|
xd->mode_info_context->mbmi.sb_type = real_sb_type;
|
2010-05-18 17:58:33 +02:00
|
|
|
}
|
2011-05-19 17:04:03 +02:00
|
|
|
|
2013-03-06 00:18:06 +01:00
|
|
|
void vp9_quantize_mb_4x4(MACROBLOCK *x) {
|
|
|
|
vp9_quantize_mby_4x4(x);
|
|
|
|
vp9_quantize_mbuv_4x4(x);
|
2012-10-13 07:42:06 +02:00
|
|
|
}
|
2012-02-29 02:11:12 +01:00
|
|
|
|
2013-04-04 21:03:27 +02:00
|
|
|
void vp9_regular_quantize_b_8x8(MACROBLOCK *mb, int b_idx, TX_TYPE tx_type,
|
|
|
|
int y_blocks) {
|
2013-02-27 19:00:24 +01:00
|
|
|
MACROBLOCKD *const xd = &mb->e_mbd;
|
2013-04-04 21:03:27 +02:00
|
|
|
const struct plane_block_idx pb_idx = plane_block_idx(y_blocks, b_idx);
|
|
|
|
const int c_idx = plane_idx(pb_idx.plane);
|
2013-04-02 23:50:40 +02:00
|
|
|
int16_t *qcoeff_ptr = BLOCK_OFFSET(xd->plane[pb_idx.plane].qcoeff,
|
|
|
|
pb_idx.block, 16);
|
|
|
|
int16_t *dqcoeff_ptr = BLOCK_OFFSET(xd->plane[pb_idx.plane].dqcoeff,
|
|
|
|
pb_idx.block, 16);
|
2013-03-06 00:18:06 +01:00
|
|
|
BLOCK *const b = &mb->block[c_idx];
|
|
|
|
BLOCKD *const d = &xd->block[c_idx];
|
2013-03-25 20:30:00 +01:00
|
|
|
const int *pt_scan;
|
|
|
|
|
|
|
|
switch (tx_type) {
|
|
|
|
case ADST_DCT:
|
|
|
|
pt_scan = vp9_row_scan_8x8;
|
|
|
|
break;
|
|
|
|
case DCT_ADST:
|
|
|
|
pt_scan = vp9_col_scan_8x8;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
pt_scan = vp9_default_zig_zag1d_8x8;
|
|
|
|
break;
|
|
|
|
}
|
2013-02-13 19:49:55 +01:00
|
|
|
|
2013-04-04 21:03:27 +02:00
|
|
|
if (c_idx == 0) assert(pb_idx.plane == 0);
|
|
|
|
if (c_idx == 16) assert(pb_idx.plane == 1);
|
|
|
|
if (c_idx == 20) assert(pb_idx.plane == 2);
|
2013-02-13 19:49:55 +01:00
|
|
|
vpx_memset(qcoeff_ptr, 0, 64 * sizeof(int16_t));
|
|
|
|
vpx_memset(dqcoeff_ptr, 0, 64 * sizeof(int16_t));
|
|
|
|
|
2013-02-12 02:43:27 +01:00
|
|
|
if (!b->skip_block) {
|
|
|
|
int i, rc, eob;
|
|
|
|
int zbin;
|
|
|
|
int x, y, z, sz;
|
|
|
|
int zero_run;
|
|
|
|
int16_t *zbin_boost_ptr = b->zrun_zbin_boost;
|
2013-03-06 00:18:06 +01:00
|
|
|
int16_t *coeff_ptr = mb->coeff + 16 * b_idx;
|
2013-02-12 02:43:27 +01:00
|
|
|
int16_t *zbin_ptr = b->zbin;
|
|
|
|
int16_t *round_ptr = b->round;
|
|
|
|
int16_t *quant_ptr = b->quant;
|
|
|
|
uint8_t *quant_shift_ptr = b->quant_shift;
|
|
|
|
int16_t *dequant_ptr = d->dequant;
|
|
|
|
int zbin_oq_value = b->zbin_extra;
|
2013-02-20 19:16:24 +01:00
|
|
|
#if CONFIG_CODE_NONZEROCOUNT
|
|
|
|
int nzc = 0;
|
|
|
|
#endif
|
2013-02-12 02:43:27 +01:00
|
|
|
|
|
|
|
eob = -1;
|
|
|
|
|
|
|
|
// Special case for DC as it is the one triggering access in various
|
|
|
|
// tables: {zbin, quant, quant_shift, dequant}_ptr[rc != 0]
|
|
|
|
{
|
|
|
|
z = coeff_ptr[0];
|
|
|
|
zbin = (zbin_ptr[0] + zbin_boost_ptr[0] + zbin_oq_value);
|
|
|
|
zero_run = 1;
|
2012-12-19 00:31:19 +01:00
|
|
|
|
2013-02-12 02:43:27 +01:00
|
|
|
sz = (z >> 31); // sign of z
|
|
|
|
x = (z ^ sz) - sz; // x = abs(z)
|
2011-02-14 23:18:18 +01:00
|
|
|
|
2013-02-12 02:43:27 +01:00
|
|
|
if (x >= zbin) {
|
|
|
|
x += (round_ptr[0]);
|
|
|
|
y = ((int)(((int)(x * quant_ptr[0]) >> 16) + x))
|
|
|
|
>> quant_shift_ptr[0]; // quantize (x)
|
|
|
|
x = (y ^ sz) - sz; // get the sign back
|
|
|
|
qcoeff_ptr[0] = x; // write to destination
|
|
|
|
dqcoeff_ptr[0] = x * dequant_ptr[0]; // dequantized value
|
2011-02-14 23:18:18 +01:00
|
|
|
|
2013-02-12 02:43:27 +01:00
|
|
|
if (y) {
|
|
|
|
eob = 0; // last nonzero coeffs
|
2013-02-20 19:16:24 +01:00
|
|
|
#if CONFIG_CODE_NONZEROCOUNT
|
|
|
|
++nzc; // number of nonzero coeffs
|
|
|
|
#endif
|
2013-02-12 02:43:27 +01:00
|
|
|
zero_run = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (i = 1; i < 64; i++) {
|
2013-03-25 20:30:00 +01:00
|
|
|
rc = pt_scan[i];
|
2013-01-29 14:33:17 +01:00
|
|
|
z = coeff_ptr[rc];
|
2013-02-12 02:43:27 +01:00
|
|
|
zbin = (zbin_ptr[1] + zbin_boost_ptr[zero_run] + zbin_oq_value);
|
|
|
|
// The original code was incrementing zero_run while keeping it at
|
|
|
|
// maximum 15 by adding "(zero_run < 15)". The same is achieved by
|
|
|
|
// removing the opposite of the sign mask of "(zero_run - 15)".
|
|
|
|
zero_run -= (zero_run - 15) >> 31;
|
2013-01-29 14:33:17 +01:00
|
|
|
|
|
|
|
sz = (z >> 31); // sign of z
|
|
|
|
x = (z ^ sz) - sz; // x = abs(z)
|
|
|
|
|
|
|
|
if (x >= zbin) {
|
|
|
|
x += (round_ptr[rc != 0]);
|
2013-02-12 02:43:27 +01:00
|
|
|
y = ((int)(((int)(x * quant_ptr[1]) >> 16) + x))
|
|
|
|
>> quant_shift_ptr[1]; // quantize (x)
|
2013-01-29 14:33:17 +01:00
|
|
|
x = (y ^ sz) - sz; // get the sign back
|
|
|
|
qcoeff_ptr[rc] = x; // write to destination
|
2013-02-12 02:43:27 +01:00
|
|
|
dqcoeff_ptr[rc] = x * dequant_ptr[1]; // dequantized value
|
2013-01-29 14:33:17 +01:00
|
|
|
|
|
|
|
if (y) {
|
|
|
|
eob = i; // last nonzero coeffs
|
2013-02-20 19:16:24 +01:00
|
|
|
#if CONFIG_CODE_NONZEROCOUNT
|
|
|
|
++nzc; // number of nonzero coeffs
|
|
|
|
#endif
|
2013-01-29 14:33:17 +01:00
|
|
|
zero_run = 0;
|
|
|
|
}
|
2011-02-14 23:18:18 +01:00
|
|
|
}
|
|
|
|
}
|
2013-04-04 21:03:27 +02:00
|
|
|
xd->plane[pb_idx.plane].eobs[pb_idx.block] = eob + 1;
|
2013-02-20 19:16:24 +01:00
|
|
|
#if CONFIG_CODE_NONZEROCOUNT
|
|
|
|
xd->nzcs[b_idx] = nzc;
|
|
|
|
#endif
|
2013-02-12 02:43:27 +01:00
|
|
|
} else {
|
2013-04-04 21:03:27 +02:00
|
|
|
xd->plane[pb_idx.plane].eobs[pb_idx.block] = 0;
|
2013-02-20 19:16:24 +01:00
|
|
|
#if CONFIG_CODE_NONZEROCOUNT
|
|
|
|
xd->nzcs[b_idx] = 0;
|
|
|
|
#endif
|
2011-02-14 23:18:18 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-30 20:58:42 +01:00
|
|
|
void vp9_quantize_mby_8x8(MACROBLOCK *x) {
|
2011-02-14 23:18:18 +01:00
|
|
|
int i;
|
2012-10-13 07:42:06 +02:00
|
|
|
|
2013-02-20 19:16:24 +01:00
|
|
|
#if CONFIG_CODE_NONZEROCOUNT
|
|
|
|
for (i = 0; i < 16; i ++) {
|
|
|
|
x->e_mbd.nzcs[i] = 0;
|
|
|
|
}
|
|
|
|
#endif
|
2012-11-16 00:14:38 +01:00
|
|
|
for (i = 0; i < 16; i += 4) {
|
2013-03-25 20:30:00 +01:00
|
|
|
TX_TYPE tx_type = get_tx_type_8x8(&x->e_mbd, (i & 8) + ((i & 4) >> 1));
|
2013-04-04 21:03:27 +02:00
|
|
|
x->quantize_b_8x8(x, i, tx_type, 16);
|
2012-11-16 00:14:38 +01:00
|
|
|
}
|
2011-02-14 23:18:18 +01:00
|
|
|
}
|
|
|
|
|
2012-10-30 20:58:42 +01:00
|
|
|
void vp9_quantize_mbuv_8x8(MACROBLOCK *x) {
|
2011-02-14 23:18:18 +01:00
|
|
|
int i;
|
2013-04-02 23:50:40 +02:00
|
|
|
const MACROBLOCKD * const xd = &x->e_mbd;
|
|
|
|
const BLOCK_SIZE_TYPE real_sb_type = xd->mode_info_context->mbmi.sb_type;
|
|
|
|
xd->mode_info_context->mbmi.sb_type = BLOCK_SIZE_MB16X16;
|
2011-02-14 23:18:18 +01:00
|
|
|
|
2013-02-20 19:16:24 +01:00
|
|
|
#if CONFIG_CODE_NONZEROCOUNT
|
|
|
|
for (i = 16; i < 24; i ++) {
|
|
|
|
x->e_mbd.nzcs[i] = 0;
|
|
|
|
}
|
|
|
|
#endif
|
2012-07-14 00:21:29 +02:00
|
|
|
for (i = 16; i < 24; i += 4)
|
2013-04-04 21:03:27 +02:00
|
|
|
x->quantize_b_8x8(x, i, DCT_DCT, 16);
|
2013-04-02 23:50:40 +02:00
|
|
|
xd->mode_info_context->mbmi.sb_type = real_sb_type;
|
2011-02-14 23:18:18 +01:00
|
|
|
}
|
|
|
|
|
2012-10-30 20:58:42 +01:00
|
|
|
void vp9_quantize_mb_8x8(MACROBLOCK *x) {
|
|
|
|
vp9_quantize_mby_8x8(x);
|
|
|
|
vp9_quantize_mbuv_8x8(x);
|
2012-10-13 07:42:06 +02:00
|
|
|
}
|
2012-08-03 02:03:14 +02:00
|
|
|
|
2012-10-30 20:58:42 +01:00
|
|
|
void vp9_quantize_mby_16x16(MACROBLOCK *x) {
|
2013-03-25 20:30:00 +01:00
|
|
|
TX_TYPE tx_type = get_tx_type_16x16(&x->e_mbd, 0);
|
2013-02-20 19:16:24 +01:00
|
|
|
#if CONFIG_CODE_NONZEROCOUNT
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < 16; i++) {
|
|
|
|
x->e_mbd.nzcs[i] = 0;
|
|
|
|
}
|
|
|
|
#endif
|
2013-04-04 21:03:27 +02:00
|
|
|
x->quantize_b_16x16(x, 0, tx_type, 16);
|
2012-08-03 02:03:14 +02:00
|
|
|
}
|
|
|
|
|
2012-10-30 20:58:42 +01:00
|
|
|
void vp9_quantize_mb_16x16(MACROBLOCK *x) {
|
|
|
|
vp9_quantize_mby_16x16(x);
|
|
|
|
vp9_quantize_mbuv_8x8(x);
|
2012-08-03 02:03:14 +02:00
|
|
|
}
|
|
|
|
|
2012-12-19 00:31:19 +01:00
|
|
|
static void quantize(int16_t *zbin_boost_orig_ptr,
|
2013-01-29 14:33:17 +01:00
|
|
|
int16_t *coeff_ptr, int n_coeffs, int skip_block,
|
2012-12-19 00:31:19 +01:00
|
|
|
int16_t *zbin_ptr, int16_t *round_ptr, int16_t *quant_ptr,
|
|
|
|
uint8_t *quant_shift_ptr,
|
|
|
|
int16_t *qcoeff_ptr, int16_t *dqcoeff_ptr,
|
|
|
|
int16_t *dequant_ptr, int zbin_oq_value,
|
2013-02-20 19:16:24 +01:00
|
|
|
uint16_t *eob_ptr,
|
|
|
|
#if CONFIG_CODE_NONZEROCOUNT
|
|
|
|
uint16_t *nzc_ptr,
|
|
|
|
#endif
|
|
|
|
const int *scan, int mul) {
|
2012-08-03 02:03:14 +02:00
|
|
|
int i, rc, eob;
|
|
|
|
int zbin;
|
|
|
|
int x, y, z, sz;
|
2013-01-24 19:28:33 +01:00
|
|
|
int zero_run = 0;
|
2012-12-19 00:31:19 +01:00
|
|
|
int16_t *zbin_boost_ptr = zbin_boost_orig_ptr;
|
2013-02-20 19:16:24 +01:00
|
|
|
#if CONFIG_CODE_NONZEROCOUNT
|
|
|
|
int nzc = 0;
|
|
|
|
#endif
|
2012-08-03 02:03:14 +02:00
|
|
|
|
2012-12-19 00:31:19 +01:00
|
|
|
vpx_memset(qcoeff_ptr, 0, n_coeffs*sizeof(int16_t));
|
|
|
|
vpx_memset(dqcoeff_ptr, 0, n_coeffs*sizeof(int16_t));
|
2012-08-03 02:03:14 +02:00
|
|
|
|
|
|
|
eob = -1;
|
2013-01-29 14:33:17 +01:00
|
|
|
|
|
|
|
if (!skip_block) {
|
|
|
|
for (i = 0; i < n_coeffs; i++) {
|
|
|
|
rc = scan[i];
|
|
|
|
z = coeff_ptr[rc] * mul;
|
|
|
|
|
|
|
|
zbin = (zbin_ptr[rc != 0] + zbin_boost_ptr[zero_run] + zbin_oq_value);
|
|
|
|
zero_run += (zero_run < 15);
|
|
|
|
|
|
|
|
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] / mul; // dequantized value
|
|
|
|
|
|
|
|
if (y) {
|
|
|
|
eob = i; // last nonzero coeffs
|
|
|
|
zero_run = 0;
|
2013-02-20 19:16:24 +01:00
|
|
|
#if CONFIG_CODE_NONZEROCOUNT
|
|
|
|
++nzc; // number of nonzero coeffs
|
|
|
|
#endif
|
2013-01-29 14:33:17 +01:00
|
|
|
}
|
2012-08-03 02:03:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
32x32 transform for superblocks.
This adds Debargha's DCT/DWT hybrid and a regular 32x32 DCT, and adds
code all over the place to wrap that in the bitstream/encoder/decoder/RD.
Some implementation notes (these probably need careful review):
- token range is extended by 1 bit, since the value range out of this
transform is [-16384,16383].
- the coefficients coming out of the FDCT are manually scaled back by
1 bit, or else they won't fit in int16_t (they are 17 bits). Because
of this, the RD error scoring does not right-shift the MSE score by
two (unlike for 4x4/8x8/16x16).
- to compensate for this loss in precision, the quantizer is halved
also. This is currently a little hacky.
- FDCT and IDCT is double-only right now. Needs a fixed-point impl.
- There are no default probabilities for the 32x32 transform yet; I'm
simply using the 16x16 luma ones. A future commit will add newly
generated probabilities for all transforms.
- No ADST version. I don't think we'll add one for this level; if an
ADST is desired, transform-size selection can scale back to 16x16
or lower, and use an ADST at that level.
Additional notes specific to Debargha's DWT/DCT hybrid:
- coefficient scale is different for the top/left 16x16 (DCT-over-DWT)
block than for the rest (DWT pixel differences) of the block. Therefore,
RD error scoring isn't easily scalable between coefficient and pixel
domain. Thus, unfortunately, we need to compute the RD distortion in
the pixel domain until we figure out how to scale these appropriately.
Change-Id: I00386f20f35d7fabb19aba94c8162f8aee64ef2b
2012-12-07 23:45:05 +01:00
|
|
|
*eob_ptr = eob + 1;
|
2013-02-20 19:16:24 +01:00
|
|
|
#if CONFIG_CODE_NONZEROCOUNT
|
|
|
|
*nzc_ptr = nzc;
|
|
|
|
#endif
|
2012-08-03 02:03:14 +02:00
|
|
|
}
|
|
|
|
|
2013-04-04 21:03:27 +02:00
|
|
|
void vp9_regular_quantize_b_16x16(MACROBLOCK *mb, int b_idx, TX_TYPE tx_type,
|
|
|
|
int y_blocks) {
|
2013-02-27 19:00:24 +01:00
|
|
|
MACROBLOCKD *const xd = &mb->e_mbd;
|
2013-04-04 21:03:27 +02:00
|
|
|
const struct plane_block_idx pb_idx = plane_block_idx(y_blocks, b_idx);
|
|
|
|
const int c_idx = plane_idx(pb_idx.plane);
|
2013-03-06 00:18:06 +01:00
|
|
|
BLOCK *const b = &mb->block[c_idx];
|
|
|
|
BLOCKD *const d = &xd->block[c_idx];
|
2013-03-25 20:30:00 +01:00
|
|
|
const int *pt_scan;
|
|
|
|
|
|
|
|
switch (tx_type) {
|
|
|
|
case ADST_DCT:
|
|
|
|
pt_scan = vp9_row_scan_16x16;
|
|
|
|
break;
|
|
|
|
case DCT_ADST:
|
|
|
|
pt_scan = vp9_col_scan_16x16;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
pt_scan = vp9_default_zig_zag1d_16x16;
|
|
|
|
break;
|
|
|
|
}
|
2013-03-06 00:18:06 +01:00
|
|
|
|
2013-04-04 21:03:27 +02:00
|
|
|
if (c_idx == 0) assert(pb_idx.plane == 0);
|
|
|
|
if (c_idx == 16) assert(pb_idx.plane == 1);
|
|
|
|
if (c_idx == 20) assert(pb_idx.plane == 2);
|
2013-01-24 19:28:33 +01:00
|
|
|
quantize(b->zrun_zbin_boost,
|
2013-03-06 00:18:06 +01:00
|
|
|
mb->coeff + 16 * b_idx,
|
2013-01-29 14:33:17 +01:00
|
|
|
256, b->skip_block,
|
2013-01-24 19:28:33 +01:00
|
|
|
b->zbin, b->round, b->quant, b->quant_shift,
|
2013-04-02 23:50:40 +02:00
|
|
|
BLOCK_OFFSET(xd->plane[pb_idx.plane].qcoeff, pb_idx.block, 16),
|
|
|
|
BLOCK_OFFSET(xd->plane[pb_idx.plane].dqcoeff, pb_idx.block, 16),
|
32x32 transform for superblocks.
This adds Debargha's DCT/DWT hybrid and a regular 32x32 DCT, and adds
code all over the place to wrap that in the bitstream/encoder/decoder/RD.
Some implementation notes (these probably need careful review):
- token range is extended by 1 bit, since the value range out of this
transform is [-16384,16383].
- the coefficients coming out of the FDCT are manually scaled back by
1 bit, or else they won't fit in int16_t (they are 17 bits). Because
of this, the RD error scoring does not right-shift the MSE score by
two (unlike for 4x4/8x8/16x16).
- to compensate for this loss in precision, the quantizer is halved
also. This is currently a little hacky.
- FDCT and IDCT is double-only right now. Needs a fixed-point impl.
- There are no default probabilities for the 32x32 transform yet; I'm
simply using the 16x16 luma ones. A future commit will add newly
generated probabilities for all transforms.
- No ADST version. I don't think we'll add one for this level; if an
ADST is desired, transform-size selection can scale back to 16x16
or lower, and use an ADST at that level.
Additional notes specific to Debargha's DWT/DCT hybrid:
- coefficient scale is different for the top/left 16x16 (DCT-over-DWT)
block than for the rest (DWT pixel differences) of the block. Therefore,
RD error scoring isn't easily scalable between coefficient and pixel
domain. Thus, unfortunately, we need to compute the RD distortion in
the pixel domain until we figure out how to scale these appropriately.
Change-Id: I00386f20f35d7fabb19aba94c8162f8aee64ef2b
2012-12-07 23:45:05 +01:00
|
|
|
d->dequant,
|
|
|
|
b->zbin_extra,
|
2013-04-04 21:03:27 +02:00
|
|
|
&xd->plane[pb_idx.plane].eobs[pb_idx.block],
|
2013-02-20 19:16:24 +01:00
|
|
|
#if CONFIG_CODE_NONZEROCOUNT
|
|
|
|
&xd->nzcs[b_idx],
|
|
|
|
#endif
|
2013-03-25 20:30:00 +01:00
|
|
|
pt_scan, 1);
|
32x32 transform for superblocks.
This adds Debargha's DCT/DWT hybrid and a regular 32x32 DCT, and adds
code all over the place to wrap that in the bitstream/encoder/decoder/RD.
Some implementation notes (these probably need careful review):
- token range is extended by 1 bit, since the value range out of this
transform is [-16384,16383].
- the coefficients coming out of the FDCT are manually scaled back by
1 bit, or else they won't fit in int16_t (they are 17 bits). Because
of this, the RD error scoring does not right-shift the MSE score by
two (unlike for 4x4/8x8/16x16).
- to compensate for this loss in precision, the quantizer is halved
also. This is currently a little hacky.
- FDCT and IDCT is double-only right now. Needs a fixed-point impl.
- There are no default probabilities for the 32x32 transform yet; I'm
simply using the 16x16 luma ones. A future commit will add newly
generated probabilities for all transforms.
- No ADST version. I don't think we'll add one for this level; if an
ADST is desired, transform-size selection can scale back to 16x16
or lower, and use an ADST at that level.
Additional notes specific to Debargha's DWT/DCT hybrid:
- coefficient scale is different for the top/left 16x16 (DCT-over-DWT)
block than for the rest (DWT pixel differences) of the block. Therefore,
RD error scoring isn't easily scalable between coefficient and pixel
domain. Thus, unfortunately, we need to compute the RD distortion in
the pixel domain until we figure out how to scale these appropriately.
Change-Id: I00386f20f35d7fabb19aba94c8162f8aee64ef2b
2012-12-07 23:45:05 +01:00
|
|
|
}
|
|
|
|
|
2013-04-04 21:03:27 +02:00
|
|
|
void vp9_regular_quantize_b_32x32(MACROBLOCK *mb, int b_idx, int y_blocks) {
|
2013-03-06 00:18:06 +01:00
|
|
|
MACROBLOCKD *const xd = &mb->e_mbd;
|
2013-04-04 21:03:27 +02:00
|
|
|
const struct plane_block_idx pb_idx = plane_block_idx(y_blocks, b_idx);
|
|
|
|
const int c_idx = plane_idx(pb_idx.plane);
|
2013-03-06 00:18:06 +01:00
|
|
|
BLOCK *const b = &mb->block[c_idx];
|
|
|
|
BLOCKD *const d = &xd->block[c_idx];
|
2013-01-29 14:33:17 +01:00
|
|
|
|
2013-04-04 21:03:27 +02:00
|
|
|
if (c_idx == 0) assert(pb_idx.plane == 0);
|
|
|
|
if (c_idx == 16) assert(pb_idx.plane == 1);
|
|
|
|
if (c_idx == 20) assert(pb_idx.plane == 2);
|
2013-01-29 14:33:17 +01:00
|
|
|
quantize(b->zrun_zbin_boost,
|
2013-03-06 00:18:06 +01:00
|
|
|
mb->coeff + b_idx * 16,
|
2013-01-29 14:33:17 +01:00
|
|
|
1024, b->skip_block,
|
|
|
|
b->zbin,
|
|
|
|
b->round, b->quant, b->quant_shift,
|
2013-04-02 23:50:40 +02:00
|
|
|
BLOCK_OFFSET(xd->plane[pb_idx.plane].qcoeff, pb_idx.block, 16),
|
|
|
|
BLOCK_OFFSET(xd->plane[pb_idx.plane].dqcoeff, pb_idx.block, 16),
|
2013-01-29 14:33:17 +01:00
|
|
|
d->dequant,
|
|
|
|
b->zbin_extra,
|
2013-04-04 21:03:27 +02:00
|
|
|
&xd->plane[pb_idx.plane].eobs[pb_idx.block],
|
2013-02-20 19:16:24 +01:00
|
|
|
#if CONFIG_CODE_NONZEROCOUNT
|
2013-03-06 00:18:06 +01:00
|
|
|
&xd->nzcs[b_idx],
|
2013-02-20 19:16:24 +01:00
|
|
|
#endif
|
32x32 transform for superblocks.
This adds Debargha's DCT/DWT hybrid and a regular 32x32 DCT, and adds
code all over the place to wrap that in the bitstream/encoder/decoder/RD.
Some implementation notes (these probably need careful review):
- token range is extended by 1 bit, since the value range out of this
transform is [-16384,16383].
- the coefficients coming out of the FDCT are manually scaled back by
1 bit, or else they won't fit in int16_t (they are 17 bits). Because
of this, the RD error scoring does not right-shift the MSE score by
two (unlike for 4x4/8x8/16x16).
- to compensate for this loss in precision, the quantizer is halved
also. This is currently a little hacky.
- FDCT and IDCT is double-only right now. Needs a fixed-point impl.
- There are no default probabilities for the 32x32 transform yet; I'm
simply using the 16x16 luma ones. A future commit will add newly
generated probabilities for all transforms.
- No ADST version. I don't think we'll add one for this level; if an
ADST is desired, transform-size selection can scale back to 16x16
or lower, and use an ADST at that level.
Additional notes specific to Debargha's DWT/DCT hybrid:
- coefficient scale is different for the top/left 16x16 (DCT-over-DWT)
block than for the rest (DWT pixel differences) of the block. Therefore,
RD error scoring isn't easily scalable between coefficient and pixel
domain. Thus, unfortunately, we need to compute the RD distortion in
the pixel domain until we figure out how to scale these appropriately.
Change-Id: I00386f20f35d7fabb19aba94c8162f8aee64ef2b
2012-12-07 23:45:05 +01:00
|
|
|
vp9_default_zig_zag1d_32x32, 2);
|
|
|
|
}
|
|
|
|
|
2013-04-10 06:28:27 +02:00
|
|
|
void vp9_quantize_sby_32x32(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize) {
|
|
|
|
const int bw = 1 << (mb_width_log2(bsize) - 1);
|
|
|
|
const int bh = 1 << (mb_height_log2(bsize) - 1);
|
2013-03-04 23:12:17 +01:00
|
|
|
int n;
|
|
|
|
|
2013-04-10 06:28:27 +02:00
|
|
|
for (n = 0; n < bw * bh; n++)
|
|
|
|
vp9_regular_quantize_b_32x32(x, n * 64, bw * bh * 64);
|
2013-03-04 23:12:17 +01:00
|
|
|
}
|
|
|
|
|
2013-04-10 06:28:27 +02:00
|
|
|
void vp9_quantize_sby_16x16(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize) {
|
|
|
|
const int bwl = mb_width_log2(bsize), bw = 1 << bwl;
|
|
|
|
const int bh = 1 << mb_height_log2(bsize);
|
|
|
|
const int bstride = 16 << bwl;
|
2013-03-04 23:12:17 +01:00
|
|
|
int n;
|
|
|
|
|
2013-04-10 06:28:27 +02:00
|
|
|
for (n = 0; n < bw * bh; n++) {
|
|
|
|
const int x_idx = n & (bw - 1), y_idx = n >> bwl;
|
2013-03-25 20:30:00 +01:00
|
|
|
TX_TYPE tx_type = get_tx_type_16x16(&x->e_mbd,
|
2013-04-10 06:28:27 +02:00
|
|
|
4 * x_idx + y_idx * bstride);
|
|
|
|
x->quantize_b_16x16(x, n * 16, tx_type, 16 * bw * bh);
|
2013-03-25 20:30:00 +01:00
|
|
|
}
|
2013-03-04 23:12:17 +01:00
|
|
|
}
|
|
|
|
|
2013-04-10 06:28:27 +02:00
|
|
|
void vp9_quantize_sby_8x8(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize) {
|
|
|
|
const int bwl = mb_width_log2(bsize) + 1, bw = 1 << bwl;
|
|
|
|
const int bh = 1 << (mb_height_log2(bsize) + 1);
|
|
|
|
const int bstride = 4 << bwl;
|
2013-03-04 23:12:17 +01:00
|
|
|
int n;
|
|
|
|
|
2013-04-10 06:28:27 +02:00
|
|
|
for (n = 0; n < bw * bh; n++) {
|
|
|
|
const int x_idx = n & (bw - 1), y_idx = n >> bwl;
|
2013-03-25 20:30:00 +01:00
|
|
|
TX_TYPE tx_type = get_tx_type_8x8(&x->e_mbd,
|
2013-04-10 06:28:27 +02:00
|
|
|
2 * x_idx + y_idx * bstride);
|
|
|
|
x->quantize_b_8x8(x, n * 4, tx_type, 4 * bw * bh);
|
2013-03-25 20:30:00 +01:00
|
|
|
}
|
2013-03-04 23:12:17 +01:00
|
|
|
}
|
|
|
|
|
2013-04-10 06:28:27 +02:00
|
|
|
void vp9_quantize_sby_4x4(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize) {
|
|
|
|
const int bwl = mb_width_log2(bsize) + 2, bw = 1 << bwl;
|
|
|
|
const int bh = 1 << (mb_height_log2(bsize) + 2);
|
2013-03-04 23:12:17 +01:00
|
|
|
MACROBLOCKD *const xd = &x->e_mbd;
|
|
|
|
int n;
|
|
|
|
|
2013-04-10 06:28:27 +02:00
|
|
|
for (n = 0; n < bw * bh; n++) {
|
2013-03-06 00:18:06 +01:00
|
|
|
const TX_TYPE tx_type = get_tx_type_4x4(xd, n);
|
|
|
|
if (tx_type != DCT_DCT) {
|
|
|
|
vp9_ht_quantize_b_4x4(x, n, tx_type);
|
|
|
|
} else {
|
2013-04-10 06:28:27 +02:00
|
|
|
x->quantize_b_4x4(x, n, bw * bh);
|
2013-03-06 00:18:06 +01:00
|
|
|
}
|
|
|
|
}
|
2013-03-04 23:12:17 +01:00
|
|
|
}
|
|
|
|
|
2013-04-10 06:28:27 +02:00
|
|
|
void vp9_quantize_sbuv_32x32(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize) {
|
|
|
|
assert(bsize == BLOCK_SIZE_SB64X64);
|
2013-04-04 21:03:27 +02:00
|
|
|
vp9_regular_quantize_b_32x32(x, 256, 256);
|
|
|
|
vp9_regular_quantize_b_32x32(x, 320, 256);
|
2013-03-04 23:12:17 +01:00
|
|
|
}
|
|
|
|
|
2013-04-10 06:28:27 +02:00
|
|
|
void vp9_quantize_sbuv_16x16(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize) {
|
|
|
|
const int bwl = mb_width_log2(bsize);
|
|
|
|
const int bhl = mb_width_log2(bsize);
|
|
|
|
const int uoff = 16 << (bhl + bwl);
|
2013-03-04 23:12:17 +01:00
|
|
|
int i;
|
|
|
|
|
2013-04-10 06:28:27 +02:00
|
|
|
for (i = uoff; i < ((uoff * 3) >> 1); i += 16)
|
|
|
|
x->quantize_b_16x16(x, i, DCT_DCT, uoff);
|
2013-03-04 23:12:17 +01:00
|
|
|
}
|
|
|
|
|
2013-04-10 06:28:27 +02:00
|
|
|
void vp9_quantize_sbuv_8x8(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize) {
|
|
|
|
const int bwl = mb_width_log2(bsize);
|
|
|
|
const int bhl = mb_width_log2(bsize);
|
|
|
|
const int uoff = 16 << (bhl + bwl);
|
2013-03-04 23:12:17 +01:00
|
|
|
int i;
|
|
|
|
|
2013-04-10 06:28:27 +02:00
|
|
|
for (i = uoff; i < ((uoff * 3) >> 1); i += 4)
|
|
|
|
x->quantize_b_8x8(x, i, DCT_DCT, uoff);
|
2013-03-04 23:12:17 +01:00
|
|
|
}
|
|
|
|
|
2013-04-10 06:28:27 +02:00
|
|
|
void vp9_quantize_sbuv_4x4(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize) {
|
|
|
|
const int bwl = mb_width_log2(bsize);
|
|
|
|
const int bhl = mb_width_log2(bsize);
|
|
|
|
const int uoff = 16 << (bhl + bwl);
|
2013-03-04 23:12:17 +01:00
|
|
|
int i;
|
|
|
|
|
2013-04-10 06:28:27 +02:00
|
|
|
for (i = uoff; i < ((uoff * 3) >> 1); i++)
|
|
|
|
x->quantize_b_4x4(x, i, uoff);
|
32x32 transform for superblocks.
This adds Debargha's DCT/DWT hybrid and a regular 32x32 DCT, and adds
code all over the place to wrap that in the bitstream/encoder/decoder/RD.
Some implementation notes (these probably need careful review):
- token range is extended by 1 bit, since the value range out of this
transform is [-16384,16383].
- the coefficients coming out of the FDCT are manually scaled back by
1 bit, or else they won't fit in int16_t (they are 17 bits). Because
of this, the RD error scoring does not right-shift the MSE score by
two (unlike for 4x4/8x8/16x16).
- to compensate for this loss in precision, the quantizer is halved
also. This is currently a little hacky.
- FDCT and IDCT is double-only right now. Needs a fixed-point impl.
- There are no default probabilities for the 32x32 transform yet; I'm
simply using the 16x16 luma ones. A future commit will add newly
generated probabilities for all transforms.
- No ADST version. I don't think we'll add one for this level; if an
ADST is desired, transform-size selection can scale back to 16x16
or lower, and use an ADST at that level.
Additional notes specific to Debargha's DWT/DCT hybrid:
- coefficient scale is different for the top/left 16x16 (DCT-over-DWT)
block than for the rest (DWT pixel differences) of the block. Therefore,
RD error scoring isn't easily scalable between coefficient and pixel
domain. Thus, unfortunately, we need to compute the RD distortion in
the pixel domain until we figure out how to scale these appropriately.
Change-Id: I00386f20f35d7fabb19aba94c8162f8aee64ef2b
2012-12-07 23:45:05 +01:00
|
|
|
}
|
|
|
|
|
2011-05-09 09:09:41 +02:00
|
|
|
/* quantize_b_pair function pointer in MACROBLOCK structure is set to one of
|
|
|
|
* these two C functions if corresponding optimized routine is not available.
|
|
|
|
* NEON optimized version implements currently the fast quantization for pair
|
|
|
|
* of blocks. */
|
2013-04-04 21:03:27 +02:00
|
|
|
void vp9_regular_quantize_b_4x4_pair(MACROBLOCK *x, int b_idx1, int b_idx2,
|
|
|
|
int y_blocks) {
|
|
|
|
vp9_regular_quantize_b_4x4(x, b_idx1, y_blocks);
|
|
|
|
vp9_regular_quantize_b_4x4(x, b_idx2, y_blocks);
|
2011-05-09 09:09:41 +02:00
|
|
|
}
|
|
|
|
|
2013-03-07 21:24:35 +01:00
|
|
|
static void invert_quant(int16_t *quant, uint8_t *shift, int d) {
|
2012-07-14 00:21:29 +02:00
|
|
|
unsigned t;
|
|
|
|
int l;
|
|
|
|
t = d;
|
|
|
|
for (l = 0; t > 1; l++)
|
|
|
|
t >>= 1;
|
|
|
|
t = 1 + (1 << (16 + l)) / d;
|
2012-12-19 00:31:19 +01:00
|
|
|
*quant = (int16_t)(t - (1 << 16));
|
2012-07-14 00:21:29 +02:00
|
|
|
*shift = l;
|
2011-05-19 17:04:03 +02:00
|
|
|
}
|
|
|
|
|
2012-10-31 01:53:32 +01:00
|
|
|
void vp9_init_quantizer(VP9_COMP *cpi) {
|
2012-07-14 00:21:29 +02:00
|
|
|
int i;
|
|
|
|
int quant_val;
|
2013-03-07 21:24:35 +01:00
|
|
|
int q;
|
2011-12-02 15:57:21 +01:00
|
|
|
|
2013-01-24 19:28:33 +01:00
|
|
|
static const int zbin_boost[16] = { 0, 0, 0, 8, 8, 8, 10, 12,
|
|
|
|
14, 16, 20, 24, 28, 32, 36, 40 };
|
|
|
|
|
2013-03-07 21:24:35 +01:00
|
|
|
for (q = 0; q < QINDEX_RANGE; q++) {
|
|
|
|
int qzbin_factor = (vp9_dc_quant(q, 0) < 148) ? 84 : 80;
|
2013-02-12 06:14:46 +01:00
|
|
|
int qrounding_factor = 48;
|
2013-03-07 21:24:35 +01:00
|
|
|
if (q == 0) {
|
2013-02-12 06:14:46 +01:00
|
|
|
qzbin_factor = 64;
|
|
|
|
qrounding_factor = 64;
|
2012-07-14 00:21:29 +02:00
|
|
|
}
|
|
|
|
// dc values
|
2013-03-07 21:24:35 +01:00
|
|
|
quant_val = vp9_dc_quant(q, cpi->common.y1dc_delta_q);
|
|
|
|
invert_quant(cpi->Y1quant[q] + 0, cpi->Y1quant_shift[q] + 0, quant_val);
|
|
|
|
cpi->Y1zbin[q][0] = ROUND_POWER_OF_TWO(qzbin_factor * quant_val, 7);
|
|
|
|
cpi->Y1round[q][0] = (qrounding_factor * quant_val) >> 7;
|
2013-04-09 19:46:57 +02:00
|
|
|
cpi->common.y_dequant[q][0] = quant_val;
|
2013-03-07 21:24:35 +01:00
|
|
|
cpi->zrun_zbin_boost_y1[q][0] = (quant_val * zbin_boost[0]) >> 7;
|
|
|
|
|
|
|
|
quant_val = vp9_dc_uv_quant(q, cpi->common.uvdc_delta_q);
|
|
|
|
invert_quant(cpi->UVquant[q] + 0, cpi->UVquant_shift[q] + 0, quant_val);
|
|
|
|
cpi->UVzbin[q][0] = ROUND_POWER_OF_TWO(qzbin_factor * quant_val, 7);
|
|
|
|
cpi->UVround[q][0] = (qrounding_factor * quant_val) >> 7;
|
2013-04-09 19:46:57 +02:00
|
|
|
cpi->common.uv_dequant[q][0] = quant_val;
|
2013-03-07 21:24:35 +01:00
|
|
|
cpi->zrun_zbin_boost_uv[q][0] = (quant_val * zbin_boost[0]) >> 7;
|
2012-07-14 00:21:29 +02:00
|
|
|
|
|
|
|
// all the 4x4 ac values =;
|
|
|
|
for (i = 1; i < 16; i++) {
|
2012-12-18 19:49:10 +01:00
|
|
|
int rc = vp9_default_zig_zag1d_4x4[i];
|
2012-07-14 00:21:29 +02:00
|
|
|
|
2013-03-07 21:24:35 +01:00
|
|
|
quant_val = vp9_ac_yquant(q);
|
|
|
|
invert_quant(cpi->Y1quant[q] + rc, cpi->Y1quant_shift[q] + rc, quant_val);
|
|
|
|
cpi->Y1zbin[q][rc] = ROUND_POWER_OF_TWO(qzbin_factor * quant_val, 7);
|
|
|
|
cpi->Y1round[q][rc] = (qrounding_factor * quant_val) >> 7;
|
2013-04-09 19:46:57 +02:00
|
|
|
cpi->common.y_dequant[q][rc] = quant_val;
|
2013-03-07 21:24:35 +01:00
|
|
|
cpi->zrun_zbin_boost_y1[q][i] =
|
|
|
|
ROUND_POWER_OF_TWO(quant_val * zbin_boost[i], 7);
|
|
|
|
|
|
|
|
quant_val = vp9_ac_uv_quant(q, cpi->common.uvac_delta_q);
|
|
|
|
invert_quant(cpi->UVquant[q] + rc, cpi->UVquant_shift[q] + rc, quant_val);
|
|
|
|
cpi->UVzbin[q][rc] = ROUND_POWER_OF_TWO(qzbin_factor * quant_val, 7);
|
|
|
|
cpi->UVround[q][rc] = (qrounding_factor * quant_val) >> 7;
|
2013-04-09 19:46:57 +02:00
|
|
|
cpi->common.uv_dequant[q][rc] = quant_val;
|
2013-03-07 21:24:35 +01:00
|
|
|
cpi->zrun_zbin_boost_uv[q][i] =
|
|
|
|
ROUND_POWER_OF_TWO(quant_val * zbin_boost[i], 7);
|
2011-05-19 17:04:03 +02:00
|
|
|
}
|
2012-07-14 00:21:29 +02:00
|
|
|
}
|
|
|
|
}
|
2011-05-19 17:04:03 +02:00
|
|
|
|
2012-10-31 01:53:32 +01:00
|
|
|
void vp9_mb_init_quantizer(VP9_COMP *cpi, MACROBLOCK *x) {
|
2012-07-14 00:21:29 +02:00
|
|
|
int i;
|
2013-04-09 19:46:57 +02:00
|
|
|
int qindex;
|
2012-07-14 00:21:29 +02:00
|
|
|
MACROBLOCKD *xd = &x->e_mbd;
|
|
|
|
int zbin_extra;
|
|
|
|
int segment_id = xd->mode_info_context->mbmi.segment_id;
|
|
|
|
|
|
|
|
// Select the baseline MB Q index allowing for any segment level change.
|
2012-10-30 06:15:27 +01:00
|
|
|
if (vp9_segfeature_active(xd, segment_id, SEG_LVL_ALT_Q)) {
|
2013-04-09 19:46:57 +02:00
|
|
|
if (xd->mb_segment_abs_delta == SEGMENT_ABSDATA) {
|
|
|
|
// Abs Value
|
|
|
|
qindex = vp9_get_segdata(xd, segment_id, SEG_LVL_ALT_Q);
|
|
|
|
} else {
|
|
|
|
// Delta Value
|
|
|
|
qindex = cpi->common.base_qindex +
|
|
|
|
vp9_get_segdata(xd, segment_id, SEG_LVL_ALT_Q);
|
2012-07-14 00:21:29 +02:00
|
|
|
|
|
|
|
// Clamp to valid range
|
2013-04-09 19:46:57 +02:00
|
|
|
qindex = clamp(qindex, 0, MAXQ);
|
2011-05-19 17:04:03 +02:00
|
|
|
}
|
2013-04-09 19:46:57 +02:00
|
|
|
} else {
|
|
|
|
qindex = cpi->common.base_qindex;
|
|
|
|
}
|
2012-07-14 00:21:29 +02:00
|
|
|
|
|
|
|
// Y
|
2013-04-09 19:46:57 +02:00
|
|
|
zbin_extra = (cpi->common.y_dequant[qindex][1] *
|
|
|
|
(cpi->zbin_mode_boost + x->act_zbin_adj)) >> 7;
|
2012-07-14 00:21:29 +02:00
|
|
|
|
|
|
|
for (i = 0; i < 16; i++) {
|
2013-04-09 19:46:57 +02:00
|
|
|
x->block[i].quant = cpi->Y1quant[qindex];
|
|
|
|
x->block[i].quant_shift = cpi->Y1quant_shift[qindex];
|
|
|
|
x->block[i].zbin = cpi->Y1zbin[qindex];
|
|
|
|
x->block[i].round = cpi->Y1round[qindex];
|
|
|
|
x->e_mbd.block[i].dequant = cpi->common.y_dequant[qindex];
|
|
|
|
x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_y1[qindex];
|
2012-12-19 00:31:19 +01:00
|
|
|
x->block[i].zbin_extra = (int16_t)zbin_extra;
|
2011-05-19 17:04:03 +02:00
|
|
|
|
2013-01-28 16:22:53 +01:00
|
|
|
// Segment skip feature.
|
2013-01-29 14:33:17 +01:00
|
|
|
x->block[i].skip_block =
|
|
|
|
vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP);
|
2012-07-14 00:21:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// UV
|
2013-04-09 19:46:57 +02:00
|
|
|
zbin_extra = (cpi->common.uv_dequant[qindex][1] *
|
|
|
|
(cpi->zbin_mode_boost + x->act_zbin_adj)) >> 7;
|
2012-07-14 00:21:29 +02:00
|
|
|
|
|
|
|
for (i = 16; i < 24; i++) {
|
2013-04-09 19:46:57 +02:00
|
|
|
x->block[i].quant = cpi->UVquant[qindex];
|
|
|
|
x->block[i].quant_shift = cpi->UVquant_shift[qindex];
|
|
|
|
x->block[i].zbin = cpi->UVzbin[qindex];
|
|
|
|
x->block[i].round = cpi->UVround[qindex];
|
|
|
|
x->e_mbd.block[i].dequant = cpi->common.uv_dequant[qindex];
|
|
|
|
x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_uv[qindex];
|
2012-12-19 00:31:19 +01:00
|
|
|
x->block[i].zbin_extra = (int16_t)zbin_extra;
|
2012-07-14 00:21:29 +02:00
|
|
|
|
2013-01-28 16:22:53 +01:00
|
|
|
// Segment skip feature.
|
2013-01-29 14:33:17 +01:00
|
|
|
x->block[i].skip_block =
|
2013-04-09 19:46:57 +02:00
|
|
|
vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP);
|
2012-07-14 00:21:29 +02:00
|
|
|
}
|
|
|
|
|
2012-10-30 20:58:42 +01:00
|
|
|
/* save this macroblock QIndex for vp9_update_zbin_extra() */
|
2013-04-09 19:46:57 +02:00
|
|
|
x->e_mbd.q_index = qindex;
|
2011-05-19 17:04:03 +02:00
|
|
|
}
|
|
|
|
|
2012-10-31 01:53:32 +01:00
|
|
|
void vp9_update_zbin_extra(VP9_COMP *cpi, MACROBLOCK *x) {
|
2012-07-14 00:21:29 +02:00
|
|
|
int i;
|
2013-04-09 19:46:57 +02:00
|
|
|
const int qindex = x->e_mbd.q_index;
|
|
|
|
const int y_zbin_extra = (cpi->common.y_dequant[qindex][1] *
|
|
|
|
(cpi->zbin_mode_boost + x->act_zbin_adj)) >> 7;
|
|
|
|
const int uv_zbin_extra = (cpi->common.uv_dequant[qindex][1] *
|
|
|
|
(cpi->zbin_mode_boost + x->act_zbin_adj)) >> 7;
|
2011-05-19 17:04:03 +02:00
|
|
|
|
2013-04-09 19:46:57 +02:00
|
|
|
for (i = 0; i < 16; i++)
|
|
|
|
x->block[i].zbin_extra = (int16_t)y_zbin_extra;
|
2011-05-19 17:04:03 +02:00
|
|
|
|
2013-04-09 19:46:57 +02:00
|
|
|
for (i = 16; i < 24; i++)
|
|
|
|
x->block[i].zbin_extra = (int16_t)uv_zbin_extra;
|
2011-05-19 17:04:03 +02:00
|
|
|
}
|
|
|
|
|
2012-10-31 01:53:32 +01:00
|
|
|
void vp9_frame_init_quantizer(VP9_COMP *cpi) {
|
2012-07-14 00:21:29 +02:00
|
|
|
// Clear Zbin mode boost for default case
|
|
|
|
cpi->zbin_mode_boost = 0;
|
2011-05-19 17:04:03 +02:00
|
|
|
|
2012-07-14 00:21:29 +02:00
|
|
|
// MB level quantizer setup
|
2012-10-30 22:25:33 +01:00
|
|
|
vp9_mb_init_quantizer(cpi, &cpi->mb);
|
2011-05-19 17:04:03 +02:00
|
|
|
}
|
|
|
|
|
2012-10-31 01:53:32 +01:00
|
|
|
void vp9_set_quantizer(struct VP9_COMP *cpi, int Q) {
|
|
|
|
VP9_COMMON *cm = &cpi->common;
|
2011-05-19 17:04:03 +02:00
|
|
|
|
2012-07-14 00:21:29 +02:00
|
|
|
cm->base_qindex = Q;
|
2012-01-20 01:56:46 +01:00
|
|
|
|
2013-03-13 19:03:17 +01:00
|
|
|
// Set lossless mode
|
|
|
|
if (cm->base_qindex <= 4)
|
|
|
|
cm->base_qindex = 0;
|
|
|
|
|
2012-07-14 00:21:29 +02:00
|
|
|
// if any of the delta_q values are changing update flag will
|
|
|
|
// have to be set.
|
|
|
|
cm->y1dc_delta_q = 0;
|
|
|
|
cm->uvdc_delta_q = 0;
|
|
|
|
cm->uvac_delta_q = 0;
|
2011-05-19 17:04:03 +02:00
|
|
|
|
2012-07-14 00:21:29 +02:00
|
|
|
// quantizer has to be reinitialized if any delta_q changes.
|
|
|
|
// As there are not any here for now this is inactive code.
|
|
|
|
// if(update)
|
2012-10-30 22:25:33 +01:00
|
|
|
// vp9_init_quantizer(cpi);
|
2011-05-19 17:04:03 +02:00
|
|
|
}
|