9824230fe3
Adds ADST/DCT hybrid transform coding for Intra4x4 mode. The ADST is applied to directions in which the boundary pixels are used for prediction, while DCT applied to directions without corresponding boundary prediction. Adds enum TX_TYPE in b_mode_infor to indicate the transform type used. Make coding style consistent with google style. Fixed the commented issues. Experimental results in terms of bit-rate reduction: derf: 0.731% yt: 0.982% std-hd: 0.459% hd: 0.725% Will be looking at 8x8 transforms next. Change-Id: I46dbd7b80dbb3e8856e9c34fbc58cb3764a12fcf
156 lines
4.2 KiB
C
156 lines
4.2 KiB
C
/*
|
|
* 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 "invtrans.h"
|
|
|
|
|
|
|
|
static void recon_dcblock(MACROBLOCKD *x) {
|
|
BLOCKD *b = &x->block[24];
|
|
int i;
|
|
|
|
for (i = 0; i < 16; i++) {
|
|
x->block[i].dqcoeff[0] = b->diff[i];
|
|
}
|
|
|
|
}
|
|
static void recon_dcblock_8x8(MACROBLOCKD *x) {
|
|
BLOCKD *b = &x->block[24]; // for coeff 0, 2, 8, 10
|
|
x->block[0].dqcoeff[0] = b->diff[0];
|
|
x->block[4].dqcoeff[0] = b->diff[1];
|
|
x->block[8].dqcoeff[0] = b->diff[4];
|
|
x->block[12].dqcoeff[0] = b->diff[8];
|
|
|
|
}
|
|
|
|
#if CONFIG_HYBRIDTRANSFORM
|
|
void vp8_inverse_htransform_b(const vp8_idct_rtcd_vtable_t *rtcd, BLOCKD *b, int pitch) {
|
|
vp8_iht4x4llm_c(b->dqcoeff, b->diff, pitch, b->bmi.as_mode.tx_type);
|
|
}
|
|
#endif
|
|
|
|
void vp8_inverse_transform_b(const vp8_idct_rtcd_vtable_t *rtcd, BLOCKD *b, int pitch) {
|
|
if (b->eob <= 1)
|
|
IDCT_INVOKE(rtcd, idct1)(b->dqcoeff, b->diff, pitch);
|
|
else
|
|
IDCT_INVOKE(rtcd, idct16)(b->dqcoeff, b->diff, pitch);
|
|
}
|
|
|
|
|
|
void vp8_inverse_transform_mby(const vp8_idct_rtcd_vtable_t *rtcd, MACROBLOCKD *x) {
|
|
int i;
|
|
|
|
/* do 2nd order transform on the dc block */
|
|
IDCT_INVOKE(rtcd, iwalsh16)(x->block[24].dqcoeff, x->block[24].diff);
|
|
|
|
recon_dcblock(x);
|
|
|
|
for (i = 0; i < 16; i++) {
|
|
vp8_inverse_transform_b(rtcd, &x->block[i], 32);
|
|
}
|
|
|
|
}
|
|
void vp8_inverse_transform_mbuv(const vp8_idct_rtcd_vtable_t *rtcd, MACROBLOCKD *x) {
|
|
int i;
|
|
|
|
for (i = 16; i < 24; i++) {
|
|
vp8_inverse_transform_b(rtcd, &x->block[i], 16);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void vp8_inverse_transform_mb(const vp8_idct_rtcd_vtable_t *rtcd, MACROBLOCKD *x) {
|
|
int i;
|
|
|
|
if (x->mode_info_context->mbmi.mode != B_PRED &&
|
|
x->mode_info_context->mbmi.mode != I8X8_PRED &&
|
|
x->mode_info_context->mbmi.mode != SPLITMV) {
|
|
/* do 2nd order transform on the dc block */
|
|
|
|
IDCT_INVOKE(rtcd, iwalsh16)(&x->block[24].dqcoeff[0], x->block[24].diff);
|
|
recon_dcblock(x);
|
|
}
|
|
|
|
for (i = 0; i < 16; i++) {
|
|
vp8_inverse_transform_b(rtcd, &x->block[i], 32);
|
|
}
|
|
|
|
|
|
for (i = 16; i < 24; i++) {
|
|
vp8_inverse_transform_b(rtcd, &x->block[i], 16);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void vp8_inverse_transform_b_8x8(const vp8_idct_rtcd_vtable_t *rtcd, short *input_dqcoeff, short *output_coeff, int pitch) { // pay attention to use when 8x8
|
|
// int b,i;
|
|
// if (b->eob > 1)
|
|
IDCT_INVOKE(rtcd, idct8)(input_dqcoeff, output_coeff, pitch);
|
|
// else
|
|
// IDCT_INVOKE(rtcd, idct8_1)(b->dqcoeff, b->diff, pitch);//pitch
|
|
|
|
}
|
|
|
|
|
|
void vp8_inverse_transform_mby_8x8(const vp8_idct_rtcd_vtable_t *rtcd, MACROBLOCKD *x) {
|
|
int i;
|
|
|
|
// do 2nd order transform on the dc block
|
|
IDCT_INVOKE(rtcd, ihaar2)(x->block[24].dqcoeff, x->block[24].diff, 8);
|
|
|
|
recon_dcblock_8x8(x); // need to change for 8x8
|
|
for (i = 0; i < 9; i += 8) {
|
|
vp8_inverse_transform_b_8x8(rtcd, &x->block[i].dqcoeff[0], &x->block[i].diff[0], 32);
|
|
}
|
|
for (i = 2; i < 11; i += 8) {
|
|
vp8_inverse_transform_b_8x8(rtcd, &x->block[i + 2].dqcoeff[0], &x->block[i].diff[0], 32);
|
|
}
|
|
|
|
}
|
|
void vp8_inverse_transform_mbuv_8x8(const vp8_idct_rtcd_vtable_t *rtcd, MACROBLOCKD *x) {
|
|
int i;
|
|
|
|
for (i = 16; i < 24; i += 4) {
|
|
vp8_inverse_transform_b_8x8(rtcd, &x->block[i].dqcoeff[0], &x->block[i].diff[0], 16);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void vp8_inverse_transform_mb_8x8(const vp8_idct_rtcd_vtable_t *rtcd, MACROBLOCKD *x) {
|
|
int i;
|
|
|
|
if (x->mode_info_context->mbmi.mode != B_PRED &&
|
|
x->mode_info_context->mbmi.mode != SPLITMV) {
|
|
// do 2nd order transform on the dc block
|
|
|
|
IDCT_INVOKE(rtcd, ihaar2)(&x->block[24].dqcoeff[0], x->block[24].diff, 8);// dqcoeff[0]
|
|
recon_dcblock_8x8(x); // need to change for 8x8
|
|
|
|
}
|
|
|
|
for (i = 0; i < 9; i += 8) {
|
|
vp8_inverse_transform_b_8x8(rtcd, &x->block[i].dqcoeff[0], &x->block[i].diff[0], 32);
|
|
}
|
|
for (i = 2; i < 11; i += 8) {
|
|
vp8_inverse_transform_b_8x8(rtcd, &x->block[i + 2].dqcoeff[0], &x->block[i].diff[0], 32);
|
|
}
|
|
|
|
|
|
for (i = 16; i < 24; i += 4) {
|
|
vp8_inverse_transform_b_8x8(rtcd, &x->block[i].dqcoeff[0], &x->block[i].diff[0], 16);
|
|
}
|
|
|
|
}
|
|
|