This patch allows use of 8x8 and 4x4 ADST correctly for Intra 16x16 modes and Intra 8x8 modes when the block size selected is smaller than the prediction mode. Also includes some cleanups and refactoring. Rebase. Change-Id: Ie3257bdf07bdb9c6e9476915e3a80183c8fa005a
285 lines
7.7 KiB
C
285 lines
7.7 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 "vpx_ports/config.h"
|
|
#include "vp9_rtcd.h"
|
|
#include "vp9/encoder/vp9_quantize.h"
|
|
#include "vp9/common/vp9_reconintra.h"
|
|
#include "vp9/common/vp9_reconintra4x4.h"
|
|
#include "vp9/encoder/vp9_encodemb.h"
|
|
#include "vp9/common/vp9_invtrans.h"
|
|
#include "vp9/encoder/vp9_encodeintra.h"
|
|
|
|
#if CONFIG_RUNTIME_CPU_DETECT
|
|
#define IF_RTCD(x) (x)
|
|
#else
|
|
#define IF_RTCD(x) NULL
|
|
#endif
|
|
|
|
int vp9_encode_intra(VP9_COMP *cpi, MACROBLOCK *x, int use_16x16_pred) {
|
|
int i;
|
|
int intra_pred_var = 0;
|
|
MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
|
|
(void) cpi;
|
|
|
|
if (use_16x16_pred) {
|
|
mbmi->mode = DC_PRED;
|
|
#if CONFIG_COMP_INTRA_PRED
|
|
mbmi->second_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
|
|
#endif
|
|
mbmi->uv_mode = DC_PRED;
|
|
mbmi->ref_frame = INTRA_FRAME;
|
|
|
|
vp9_encode_intra16x16mby(x);
|
|
} else {
|
|
for (i = 0; i < 16; i++) {
|
|
x->e_mbd.block[i].bmi.as_mode.first = B_DC_PRED;
|
|
vp9_encode_intra4x4block(x, i);
|
|
}
|
|
}
|
|
|
|
intra_pred_var = vp9_get_mb_ss(x->src_diff);
|
|
|
|
return intra_pred_var;
|
|
}
|
|
|
|
void vp9_encode_intra4x4block(MACROBLOCK *x, int ib) {
|
|
BLOCKD *b = &x->e_mbd.block[ib];
|
|
BLOCK *be = &x->block[ib];
|
|
TX_TYPE tx_type;
|
|
|
|
#if CONFIG_NEWBINTRAMODES
|
|
b->bmi.as_mode.context = vp9_find_bpred_context(b);
|
|
#endif
|
|
|
|
#if CONFIG_COMP_INTRA_PRED
|
|
if (b->bmi.as_mode.second == (B_PREDICTION_MODE)(B_DC_PRED - 1)) {
|
|
#endif
|
|
vp9_intra4x4_predict(b, b->bmi.as_mode.first, b->predictor);
|
|
#if CONFIG_COMP_INTRA_PRED
|
|
} else {
|
|
vp9_comp_intra4x4_predict(b, b->bmi.as_mode.first, b->bmi.as_mode.second,
|
|
b->predictor);
|
|
}
|
|
#endif
|
|
|
|
vp9_subtract_b(be, b, 16);
|
|
|
|
tx_type = get_tx_type_4x4(&x->e_mbd, b);
|
|
if (tx_type != DCT_DCT) {
|
|
vp9_fht(be->src_diff, 32, be->coeff, tx_type, 4);
|
|
vp9_ht_quantize_b_4x4(be, b, tx_type);
|
|
vp9_ihtllm_c(b->dqcoeff, b->diff, 32, tx_type, 4);
|
|
} else {
|
|
x->vp9_short_fdct4x4(be->src_diff, be->coeff, 32);
|
|
x->quantize_b_4x4(be, b) ;
|
|
vp9_inverse_transform_b_4x4(&x->e_mbd, ib, 32);
|
|
}
|
|
|
|
vp9_recon_b(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
|
|
}
|
|
|
|
void vp9_encode_intra4x4mby(MACROBLOCK *mb) {
|
|
int i;
|
|
|
|
for (i = 0; i < 16; i++)
|
|
vp9_encode_intra4x4block(mb, i);
|
|
return;
|
|
}
|
|
|
|
void vp9_encode_intra16x16mby(MACROBLOCK *x) {
|
|
MACROBLOCKD *xd = &x->e_mbd;
|
|
BLOCK *b = &x->block[0];
|
|
TX_SIZE tx_size = xd->mode_info_context->mbmi.txfm_size;
|
|
TX_TYPE tx_type;
|
|
|
|
#if CONFIG_COMP_INTRA_PRED
|
|
if (xd->mode_info_context->mbmi.second_mode == (MB_PREDICTION_MODE)(DC_PRED - 1))
|
|
#endif
|
|
vp9_build_intra_predictors_mby(xd);
|
|
#if CONFIG_COMP_INTRA_PRED
|
|
else
|
|
vp9_build_comp_intra_predictors_mby(xd);
|
|
#endif
|
|
|
|
vp9_subtract_mby(x->src_diff, *(b->base_src), xd->predictor, b->src_stride);
|
|
|
|
if (tx_size == TX_16X16) {
|
|
vp9_transform_mby_16x16(x);
|
|
vp9_quantize_mby_16x16(x);
|
|
if (x->optimize)
|
|
vp9_optimize_mby_16x16(x);
|
|
vp9_inverse_transform_mby_16x16(xd);
|
|
} else if (tx_size == TX_8X8) {
|
|
vp9_transform_mby_8x8(x);
|
|
vp9_quantize_mby_8x8(x);
|
|
if (x->optimize)
|
|
vp9_optimize_mby_8x8(x);
|
|
vp9_inverse_transform_mby_8x8(xd);
|
|
} else {
|
|
vp9_transform_mby_4x4(x);
|
|
vp9_quantize_mby_4x4(x);
|
|
if (x->optimize)
|
|
vp9_optimize_mby_4x4(x);
|
|
vp9_inverse_transform_mby_4x4(xd);
|
|
}
|
|
|
|
vp9_recon_mby(xd);
|
|
}
|
|
|
|
void vp9_encode_intra16x16mbuv(MACROBLOCK *x) {
|
|
MACROBLOCKD *xd = &x->e_mbd;
|
|
TX_SIZE tx_size = xd->mode_info_context->mbmi.txfm_size;
|
|
|
|
#if CONFIG_COMP_INTRA_PRED
|
|
if (xd->mode_info_context->mbmi.second_uv_mode == (MB_PREDICTION_MODE)(DC_PRED - 1)) {
|
|
#endif
|
|
vp9_build_intra_predictors_mbuv(xd);
|
|
#if CONFIG_COMP_INTRA_PRED
|
|
} else {
|
|
vp9_build_comp_intra_predictors_mbuv(xd);
|
|
}
|
|
#endif
|
|
|
|
vp9_subtract_mbuv(x->src_diff, x->src.u_buffer, x->src.v_buffer,
|
|
xd->predictor, x->src.uv_stride);
|
|
|
|
if (tx_size == TX_4X4) {
|
|
vp9_transform_mbuv_4x4(x);
|
|
vp9_quantize_mbuv_4x4(x);
|
|
if (x->optimize)
|
|
vp9_optimize_mbuv_4x4(x);
|
|
vp9_inverse_transform_mbuv_4x4(xd);
|
|
} else /* 16x16 or 8x8 */ {
|
|
vp9_transform_mbuv_8x8(x);
|
|
vp9_quantize_mbuv_8x8(x);
|
|
if (x->optimize)
|
|
vp9_optimize_mbuv_8x8(x);
|
|
vp9_inverse_transform_mbuv_8x8(xd);
|
|
}
|
|
|
|
vp9_recon_intra_mbuv(xd);
|
|
}
|
|
|
|
void vp9_encode_intra8x8(MACROBLOCK *x, int ib) {
|
|
MACROBLOCKD *xd = &x->e_mbd;
|
|
BLOCKD *b = &xd->block[ib];
|
|
BLOCK *be = &x->block[ib];
|
|
const int iblock[4] = {0, 1, 4, 5};
|
|
int i;
|
|
TX_TYPE tx_type;
|
|
|
|
#if CONFIG_COMP_INTRA_PRED
|
|
if (b->bmi.as_mode.second == (MB_PREDICTION_MODE)(DC_PRED - 1)) {
|
|
#endif
|
|
vp9_intra8x8_predict(b, b->bmi.as_mode.first, b->predictor);
|
|
#if CONFIG_COMP_INTRA_PRED
|
|
} else {
|
|
vp9_comp_intra8x8_predict(b, b->bmi.as_mode.first, b->bmi.as_mode.second,
|
|
b->predictor);
|
|
}
|
|
#endif
|
|
// generate residual blocks
|
|
vp9_subtract_4b_c(be, b, 16);
|
|
|
|
if (xd->mode_info_context->mbmi.txfm_size == TX_8X8) {
|
|
int idx = (ib & 0x02) ? (ib + 2) : ib;
|
|
|
|
tx_type = get_tx_type_8x8(xd, &xd->block[ib]);
|
|
if (tx_type != DCT_DCT) {
|
|
vp9_fht(be->src_diff, 32, (x->block + idx)->coeff,
|
|
tx_type, 8);
|
|
x->quantize_b_8x8(x->block + idx, xd->block + idx);
|
|
vp9_ihtllm_c(xd->block[idx].dqcoeff, xd->block[ib].diff, 32,
|
|
tx_type, 8);
|
|
} else {
|
|
x->vp9_short_fdct8x8(be->src_diff, (x->block + idx)->coeff, 32);
|
|
x->quantize_b_8x8(x->block + idx, xd->block + idx);
|
|
vp9_short_idct8x8(xd->block[idx].dqcoeff, xd->block[ib].diff, 32);
|
|
}
|
|
} else {
|
|
for (i = 0; i < 4; i++) {
|
|
b = &xd->block[ib + iblock[i]];
|
|
be = &x->block[ib + iblock[i]];
|
|
tx_type = get_tx_type_4x4(xd, b);
|
|
if (tx_type != DCT_DCT) {
|
|
vp9_fht_c(be->src_diff, 32, be->coeff, tx_type, 4);
|
|
vp9_ht_quantize_b_4x4(be, b, tx_type);
|
|
vp9_ihtllm_c(b->dqcoeff, b->diff, 32, tx_type, 4);
|
|
} else {
|
|
x->vp9_short_fdct4x4(be->src_diff, be->coeff, 32);
|
|
x->quantize_b_4x4(be, b);
|
|
vp9_inverse_transform_b_4x4(xd, ib + iblock[i], 32);
|
|
}
|
|
}
|
|
}
|
|
|
|
// reconstruct submacroblock
|
|
for (i = 0; i < 4; i++) {
|
|
b = &xd->block[ib + iblock[i]];
|
|
vp9_recon_b_c(b->predictor, b->diff, *(b->base_dst) + b->dst,
|
|
b->dst_stride);
|
|
}
|
|
}
|
|
|
|
void vp9_encode_intra8x8mby(MACROBLOCK *x) {
|
|
int i, ib;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
ib = vp9_i8x8_block[i];
|
|
vp9_encode_intra8x8(x, ib);
|
|
}
|
|
}
|
|
|
|
void vp9_encode_intra_uv4x4(MACROBLOCK *x, int ib,
|
|
int mode, int second) {
|
|
BLOCKD *b = &x->e_mbd.block[ib];
|
|
BLOCK *be = &x->block[ib];
|
|
|
|
#if CONFIG_COMP_INTRA_PRED
|
|
if (second == -1) {
|
|
#endif
|
|
vp9_intra_uv4x4_predict(b, mode, b->predictor);
|
|
#if CONFIG_COMP_INTRA_PRED
|
|
} else {
|
|
vp9_comp_intra_uv4x4_predict(b, mode, second, b->predictor);
|
|
}
|
|
#endif
|
|
|
|
vp9_subtract_b(be, b, 8);
|
|
|
|
x->vp9_short_fdct4x4(be->src_diff, be->coeff, 16);
|
|
x->quantize_b_4x4(be, b);
|
|
vp9_inverse_transform_b_4x4(&x->e_mbd, ib, 16);
|
|
|
|
vp9_recon_uv_b_c(b->predictor, b->diff, *(b->base_dst) + b->dst,
|
|
b->dst_stride);
|
|
}
|
|
|
|
void vp9_encode_intra8x8mbuv(MACROBLOCK *x) {
|
|
int i, ib, mode, second;
|
|
BLOCKD *b;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
ib = vp9_i8x8_block[i];
|
|
b = &x->e_mbd.block[ib];
|
|
mode = b->bmi.as_mode.first;
|
|
#if CONFIG_COMP_INTRA_PRED
|
|
second = b->bmi.as_mode.second;
|
|
#else
|
|
second = -1;
|
|
#endif
|
|
/*u */
|
|
vp9_encode_intra_uv4x4(x, i + 16, mode, second);
|
|
/*v */
|
|
vp9_encode_intra_uv4x4(x, i + 20, mode, second);
|
|
}
|
|
}
|