Non transform coding experiment

Non-transform option is enabled in both intra and inter modes.
In lossless case, the average coding gain on screen content
clips is 11.3% in my test.

Change-Id: I2e8de515fb39e74c61bb86ce0f682d5f79e15188
This commit is contained in:
hui su 2014-11-12 14:59:30 -08:00
parent e2a8e90874
commit d97fd3eef6
11 changed files with 767 additions and 5 deletions

1
configure vendored
View File

@ -285,6 +285,7 @@ EXPERIMENT_LIST="
tx64x64
filterintra
ext_tx
tx_skip
"
CONFIG_LIST="
external_build

View File

@ -133,6 +133,9 @@ typedef struct {
#if CONFIG_EXT_TX
EXT_TX_TYPE ext_txfrm;
#endif
#if CONFIG_TX_SKIP
int tx_skip[PLANE_TYPES];
#endif
} MB_MODE_INFO;
typedef struct MODE_INFO {

View File

@ -1457,6 +1457,18 @@ void vp9_iht16x16_add(TX_TYPE tx_type, const tran_low_t *input, uint8_t *dest,
}
}
#if CONFIG_TX_SKIP
void vp9_tx_identity_add(const tran_low_t *input, uint8_t *dest,
int stride, int bs) {
int r, c, temp;
for (r = 0; r < bs; r++)
for (c = 0; c < bs; c++) {
temp = dest[r * stride + c] + (input[r * bs + c] >> TX_SKIP_SHIFT);
dest[r * stride + c] = clip_pixel(temp);
}
}
#endif
#if CONFIG_TX64X64
#define DownshiftMultiplyBy2(x) x * 2
#define DownshiftMultiply(x) x

View File

@ -34,6 +34,10 @@ extern "C" {
#define dual_set_epi16(a, b) \
_mm_set_epi16(b, b, b, b, a, a, a, a)
#if CONFIG_TX_SKIP
#define TX_SKIP_SHIFT 2
#endif
// Constants:
// for (int i = 1; i< 32; ++i)
// printf("static const int cospi_%d_64 = %.0f;\n", i,
@ -164,3 +168,7 @@ void vp9_highbd_iht16x16_add(TX_TYPE tx_type, const tran_low_t *input,
#endif
#endif // VP9_COMMON_VP9_IDCT_H_
#if CONFIG_TX_SKIP
void vp9_tx_identity_add(const tran_low_t *input, uint8_t *dest,
int stride, int bs);
#endif

View File

@ -206,12 +206,19 @@ static void inverse_transform_block(MACROBLOCKD* xd, int plane, int block,
TX_SIZE tx_size, uint8_t *dst, int stride,
int eob) {
struct macroblockd_plane *const pd = &xd->plane[plane];
#if CONFIG_TX_SKIP
MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
#endif
if (eob > 0) {
TX_TYPE tx_type = DCT_DCT;
tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
#if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
#if CONFIG_TX_SKIP
if (xd->lossless && !mbmi->tx_skip[plane != 0]) {
#else
if (xd->lossless) {
#endif // CONFIG_TX_SKIP
tx_type = DCT_DCT;
vp9_highbd_iwht4x4_add(dqcoeff, dst, stride, eob, xd->bd);
} else {
@ -219,32 +226,77 @@ static void inverse_transform_block(MACROBLOCKD* xd, int plane, int block,
switch (tx_size) {
case TX_4X4:
tx_type = get_tx_type_4x4(plane_type, xd, block);
#if CONFIG_TX_SKIP
if (mbmi->tx_skip[plane != 0]) {
vp9_tx_identity_add(dqcoeff, dst, stride, 4);
} else {
vp9_highbd_iht4x4_add(tx_type, dqcoeff, dst, stride, eob, xd->bd);
}
#else
vp9_highbd_iht4x4_add(tx_type, dqcoeff, dst, stride, eob, xd->bd);
#endif
break;
case TX_8X8:
tx_type = get_tx_type(plane_type, xd);
#if CONFIG_TX_SKIP
if (mbmi->tx_skip[plane != 0]) {
vp9_tx_identity_add(dqcoeff, dst, stride, 8);
} else {
vp9_highbd_iht8x8_add(tx_type, dqcoeff, dst, stride, eob, xd->bd);
}
#else
vp9_highbd_iht8x8_add(tx_type, dqcoeff, dst, stride, eob, xd->bd);
#endif
break;
case TX_16X16:
tx_type = get_tx_type(plane_type, xd);
#if CONFIG_TX_SKIP
if (mbmi->tx_skip[plane != 0]) {
vp9_tx_identity_add(dqcoeff, dst, stride, 16);
} else {
vp9_highbd_iht16x16_add(tx_type, dqcoeff, dst, stride, eob,
xd->bd);
}
#else
vp9_highbd_iht16x16_add(tx_type, dqcoeff, dst, stride, eob, xd->bd);
#endif
break;
case TX_32X32:
tx_type = DCT_DCT;
#if CONFIG_TX_SKIP
if (mbmi->tx_skip[plane != 0]) {
vp9_tx_identity_add(dqcoeff, dst, stride, 32);
} else {
vp9_highbd_idct32x32_add(dqcoeff, dst, stride, eob, xd->bd);
}
#else
vp9_highbd_idct32x32_add(dqcoeff, dst, stride, eob, xd->bd);
#endif
break;
#if CONFIG_TX64X64
case TX_64X64:
tx_type = DCT_DCT;
#if CONFIG_TX_SKIP
if (mbmi->tx_skip[plane != 0]) {
vp9_tx_identity_add(dqcoeff, dst, stride, 64);
} else {
vp9_highbd_idct64x64_add(dqcoeff, dst, stride, eob, xd->bd);
}
#else
vp9_highbd_idct64x64_add(dqcoeff, dst, stride, eob, xd->bd);
#endif // CONFIG_TX_SKIP
break;
#endif
#endif // CONFIG_TX64X64
default:
assert(0 && "Invalid transform size");
}
}
} else {
#if CONFIG_TX_SKIP
if (xd->lossless && !mbmi->tx_skip[plane != 0]) {
#else
if (xd->lossless) {
#endif
tx_type = DCT_DCT;
vp9_iwht4x4_add(dqcoeff, dst, stride, eob);
} else {
@ -252,34 +304,78 @@ static void inverse_transform_block(MACROBLOCKD* xd, int plane, int block,
switch (tx_size) {
case TX_4X4:
tx_type = get_tx_type_4x4(plane_type, xd, block);
#if CONFIG_TX_SKIP
if (mbmi->tx_skip[plane != 0]) {
vp9_tx_identity_add(dqcoeff, dst, stride, 4);
} else {
vp9_iht4x4_add(tx_type, dqcoeff, dst, stride, eob);
}
#else
vp9_iht4x4_add(tx_type, dqcoeff, dst, stride, eob);
#endif
break;
case TX_8X8:
tx_type = get_tx_type(plane_type, xd);
#if CONFIG_TX_SKIP
if (mbmi->tx_skip[plane != 0]) {
vp9_tx_identity_add(dqcoeff, dst, stride, 8);
} else {
vp9_iht8x8_add(tx_type, dqcoeff, dst, stride, eob);
}
#else
vp9_iht8x8_add(tx_type, dqcoeff, dst, stride, eob);
#endif
break;
case TX_16X16:
tx_type = get_tx_type(plane_type, xd);
#if CONFIG_TX_SKIP
if (mbmi->tx_skip[plane != 0]) {
vp9_tx_identity_add(dqcoeff, dst, stride, 16);
} else {
vp9_iht16x16_add(tx_type, dqcoeff, dst, stride, eob);
}
#else
vp9_iht16x16_add(tx_type, dqcoeff, dst, stride, eob);
#endif
break;
case TX_32X32:
tx_type = DCT_DCT;
#if CONFIG_TX_SKIP
if (mbmi->tx_skip[plane != 0]) {
vp9_tx_identity_add(dqcoeff, dst, stride, 32);
} else {
vp9_idct32x32_add(dqcoeff, dst, stride, eob);
}
#else
vp9_idct32x32_add(dqcoeff, dst, stride, eob);
#endif
break;
#if CONFIG_TX64X64
case TX_64X64:
tx_type = DCT_DCT;
vp9_idct64x64_add(dqcoeff, dst, stride, eob);
#if CONFIG_TX_SKIP
if (mbmi->tx_skip[plane != 0]) {
vp9_tx_identity_add(dqcoeff, dst, stride, 64);
} else {
vp9_idct64x64_add(dqcoeff, dst, stride, eob);
}
#else
vp9_idct64x64_add(dqcoeff, dst, stride, eob);
#endif // CONFIG_TX_SKIP
break;
#endif
#endif // CONFIG_TX64X64
default:
assert(0 && "Invalid transform size");
return;
}
}
}
#else
#if CONFIG_TX_SKIP
if (xd->lossless && !mbmi->tx_skip[plane != 0]) {
#else
if (xd->lossless) {
#endif
tx_type = DCT_DCT;
vp9_iwht4x4_add(dqcoeff, dst, stride, eob);
} else {
@ -287,26 +383,66 @@ static void inverse_transform_block(MACROBLOCKD* xd, int plane, int block,
switch (tx_size) {
case TX_4X4:
tx_type = get_tx_type_4x4(plane_type, xd, block);
#if CONFIG_TX_SKIP
if (mbmi->tx_skip[plane != 0]) {
vp9_tx_identity_add(dqcoeff, dst, stride, 4);
} else {
vp9_iht4x4_add(tx_type, dqcoeff, dst, stride, eob);
}
#else
vp9_iht4x4_add(tx_type, dqcoeff, dst, stride, eob);
#endif
break;
case TX_8X8:
tx_type = get_tx_type(plane_type, xd);
#if CONFIG_TX_SKIP
if (mbmi->tx_skip[plane != 0]) {
vp9_tx_identity_add(dqcoeff, dst, stride, 8);
} else {
vp9_iht8x8_add(tx_type, dqcoeff, dst, stride, eob);
}
#else
vp9_iht8x8_add(tx_type, dqcoeff, dst, stride, eob);
#endif
break;
case TX_16X16:
tx_type = get_tx_type(plane_type, xd);
#if CONFIG_TX_SKIP
if (mbmi->tx_skip[plane != 0]) {
vp9_tx_identity_add(dqcoeff, dst, stride, 16);
} else {
vp9_iht16x16_add(tx_type, dqcoeff, dst, stride, eob);
}
#else
vp9_iht16x16_add(tx_type, dqcoeff, dst, stride, eob);
break;
#endif
break;
case TX_32X32:
tx_type = DCT_DCT;
#if CONFIG_TX_SKIP
if (mbmi->tx_skip[plane != 0]) {
vp9_tx_identity_add(dqcoeff, dst, stride, 32);
} else {
vp9_idct32x32_add(dqcoeff, dst, stride, eob);;
}
#else
vp9_idct32x32_add(dqcoeff, dst, stride, eob);
#endif
break;
#if CONFIG_TX64X64
case TX_64X64:
tx_type = DCT_DCT;
#if CONFIG_TX_SKIP
if (mbmi->tx_skip[plane != 0]) {
vp9_tx_identity_add(dqcoeff, dst, stride, 64);
} else {
vp9_idct64x64_add(dqcoeff, dst, stride, eob);;
}
#else
vp9_idct64x64_add(dqcoeff, dst, stride, eob);
#endif // CONFIG_TX_SKIP
break;
#endif
#endif // CONFIG_TX64X64
default:
assert(0 && "Invalid transform size");
return;

View File

@ -175,6 +175,10 @@ static void read_intra_frame_mode_info(VP9_COMMON *const cm,
mbmi->segment_id = read_intra_segment_id(cm, xd, mi_row, mi_col, r);
mbmi->skip = read_skip(cm, xd, mbmi->segment_id, r);
#if CONFIG_TX_SKIP
mbmi->tx_skip[0] = vp9_read_bit(r);
mbmi->tx_skip[1] = vp9_read_bit(r);
#endif
mbmi->tx_size = read_tx_size(cm, xd, cm->tx_mode, bsize, 1, r);
mbmi->ref_frame[0] = INTRA_FRAME;
mbmi->ref_frame[1] = NONE;
@ -669,6 +673,10 @@ static void read_inter_frame_mode_info(VP9_COMMON *const cm,
mbmi->segment_id = read_inter_segment_id(cm, xd, mi_row, mi_col, r);
mbmi->skip = read_skip(cm, xd, mbmi->segment_id, r);
#if CONFIG_TX_SKIP
mbmi->tx_skip[0] = vp9_read_bit(r);
mbmi->tx_skip[1] = vp9_read_bit(r);
#endif
inter_block = read_is_inter_block(cm, xd, mbmi->segment_id, r);
mbmi->tx_size = read_tx_size(cm, xd, cm->tx_mode, mbmi->sb_type,
!mbmi->skip || !inter_block, r);

View File

@ -268,6 +268,10 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
}
skip = write_skip(cm, xd, segment_id, mi, w);
#if CONFIG_TX_SKIP
vp9_write_bit(w, mbmi->tx_skip[0]);
vp9_write_bit(w, mbmi->tx_skip[1]);
#endif
if (!vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
vp9_write(w, is_inter, vp9_get_intra_inter_prob(cm, xd));
@ -388,6 +392,10 @@ static void write_mb_modes_kf(const VP9_COMMON *cm, const MACROBLOCKD *xd,
write_segment_id(w, seg, mbmi->segment_id);
write_skip(cm, xd, mbmi->segment_id, mi, w);
#if CONFIG_TX_SKIP
vp9_write_bit(w, mbmi->tx_skip[0]);
vp9_write_bit(w, mbmi->tx_skip[1]);
#endif
if (bsize >= BLOCK_8X8 && cm->tx_mode == TX_MODE_SELECT)
write_selected_tx_size(cm, xd, mbmi->tx_size, bsize, w);

View File

@ -1439,6 +1439,16 @@ void vp9_fdct32x32_rd_c(const int16_t *input, tran_low_t *out, int stride) {
}
}
#if CONFIG_TX_SKIP
void vp9_tx_identity(const int16_t *input, tran_low_t *out, int stride,
int bs) {
int r, c;
for (r = 0; r < bs; r++)
for (c = 0; c < bs; c++)
out[bs * r + c] = input[stride * r + c] << TX_SKIP_SHIFT;
}
#endif
#if CONFIG_TX64X64
// TODO(debargha): Using a floating point implementation for now.
// Should re-use the 32x32 integer dct we already have.

View File

@ -389,10 +389,61 @@ void vp9_xform_quant_fp(MACROBLOCK *x, int plane, int block,
#if CONFIG_EXT_TX
TX_TYPE tx_type;
#endif
#if CONFIG_TX_SKIP
MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
#endif
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &i, &j);
src_diff = &p->src_diff[4 * (j * diff_stride + i)];
#if CONFIG_TX_SKIP
if (mbmi->tx_skip[plane != 0]) {
switch (tx_size) {
#if CONFIG_TX64X64
case TX_64X64:
vp9_tx_identity(src_diff, coeff, diff_stride, 64);
vp9_quantize_fp_64x64(coeff, 4096, x->skip_block, p->zbin, p->round_fp,
p->quant_fp, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob, scan_order->scan,
scan_order->iscan);
break;
#endif // CONFIG_TX64X64
case TX_32X32:
vp9_tx_identity(src_diff, coeff, diff_stride, 32);
vp9_quantize_fp_32x32(coeff, 1024, x->skip_block, p->zbin, p->round_fp,
p->quant_fp, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob, scan_order->scan,
scan_order->iscan);
break;
case TX_16X16:
vp9_tx_identity(src_diff, coeff, diff_stride, 16);
vp9_quantize_fp(coeff, 256, x->skip_block, p->zbin, p->round_fp,
p->quant_fp, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob,
scan_order->scan, scan_order->iscan);
break;
case TX_8X8:
vp9_tx_identity(src_diff, coeff, diff_stride, 8);
vp9_quantize_fp(coeff, 64, x->skip_block, p->zbin, p->round_fp,
p->quant_fp, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob,
scan_order->scan, scan_order->iscan);
break;
case TX_4X4:
vp9_tx_identity(src_diff, coeff, diff_stride, 4);
vp9_quantize_fp(coeff, 16, x->skip_block, p->zbin, p->round_fp,
p->quant_fp, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob,
scan_order->scan, scan_order->iscan);
break;
default:
assert(0);
break;
}
return;
}
#endif // CONFIG_TX_SKIP
#if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
switch (tx_size) {
@ -555,10 +606,56 @@ void vp9_xform_quant_dc(MACROBLOCK *x, int plane, int block,
#if CONFIG_EXT_TX
TX_TYPE tx_type;
#endif
#if CONFIG_TX_SKIP
MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
#endif
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &i, &j);
src_diff = &p->src_diff[4 * (j * diff_stride + i)];
#if CONFIG_TX_SKIP
if (mbmi->tx_skip[plane != 0]) {
switch (tx_size) {
#if CONFIG_TX64X64
case TX_64X64:
vp9_tx_identity(src_diff, coeff, diff_stride, 64);
vp9_quantize_dc_64x64(coeff, x->skip_block, p->round,
p->quant_fp[0], qcoeff, dqcoeff,
pd->dequant[0], eob);
break;
#endif // CONFIG_TX64X64
case TX_32X32:
vp9_tx_identity(src_diff, coeff, diff_stride, 32);
vp9_quantize_dc_32x32(coeff, x->skip_block, p->round,
p->quant_fp[0], qcoeff, dqcoeff,
pd->dequant[0], eob);
break;
case TX_16X16:
vp9_tx_identity(src_diff, coeff, diff_stride, 16);
vp9_quantize_dc(coeff, x->skip_block, p->round,
p->quant_fp[0], qcoeff, dqcoeff,
pd->dequant[0], eob);
break;
case TX_8X8:
vp9_tx_identity(src_diff, coeff, diff_stride, 8);
vp9_quantize_dc(coeff, x->skip_block, p->round,
p->quant_fp[0], qcoeff, dqcoeff,
pd->dequant[0], eob);
break;
case TX_4X4:
vp9_tx_identity(src_diff, coeff, diff_stride, 4);
vp9_quantize_dc(coeff, x->skip_block, p->round,
p->quant_fp[0], qcoeff, dqcoeff,
pd->dequant[0], eob);
break;
default:
assert(0);
break;
}
return;
}
#endif // CONFIG_TX_SKIP
#if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
switch (tx_size) {
@ -709,10 +806,61 @@ void vp9_xform_quant(MACROBLOCK *x, int plane, int block,
const int16_t *src_diff;
#if CONFIG_EXT_TX
TX_TYPE tx_type;
#endif
#if CONFIG_TX_SKIP
MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
#endif
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &i, &j);
src_diff = &p->src_diff[4 * (j * diff_stride + i)];
#if CONFIG_TX_SKIP
if (mbmi->tx_skip[plane != 0]) {
switch (tx_size) {
#if CONFIG_TX64X64
case TX_64X64:
vp9_tx_identity(src_diff, coeff, diff_stride, 64);
vp9_quantize_b_64x64(coeff, 4096, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob, scan_order->scan,
scan_order->iscan);
break;
#endif // CONFIG_TX64X64
case TX_32X32:
vp9_tx_identity(src_diff, coeff, diff_stride, 32);
vp9_quantize_b_32x32(coeff, 1024, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob, scan_order->scan,
scan_order->iscan);
break;
case TX_16X16:
vp9_tx_identity(src_diff, coeff, diff_stride, 16);
vp9_quantize_b(coeff, 256, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob,
scan_order->scan, scan_order->iscan);
break;
case TX_8X8:
vp9_tx_identity(src_diff, coeff, diff_stride, 8);
vp9_quantize_b(coeff, 64, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob,
scan_order->scan, scan_order->iscan);
break;
case TX_4X4:
vp9_tx_identity(src_diff, coeff, diff_stride, 4);
vp9_quantize_b(coeff, 16, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob,
scan_order->scan, scan_order->iscan);
break;
default:
assert(0);
break;
}
return;
}
#endif // CONFIG_TX_SKIP
#if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
switch (tx_size) {
@ -873,6 +1021,8 @@ static void encode_block(int plane, int block, BLOCK_SIZE plane_bsize,
#if CONFIG_EXT_TX
MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
TX_TYPE tx_type;
#elif CONFIG_TX_SKIP
MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
#endif
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &i, &j);
dst = &pd->dst.buf[4 * j * pd->dst.stride + 4 * i];
@ -924,6 +1074,35 @@ static void encode_block(int plane, int block, BLOCK_SIZE plane_bsize,
if (x->skip_encode || p->eobs[block] == 0)
return;
#if CONFIG_TX_SKIP
if (mbmi->tx_skip[plane != 0]) {
switch (tx_size) {
#if CONFIG_TX64X64
case TX_64X64:
vp9_tx_identity_add(dqcoeff, dst, pd->dst.stride, 64);
break;
#endif // CONFIG_TX64X64
case TX_32X32:
vp9_tx_identity_add(dqcoeff, dst, pd->dst.stride, 32);
break;
case TX_16X16:
vp9_tx_identity_add(dqcoeff, dst, pd->dst.stride, 16);
break;
case TX_8X8:
vp9_tx_identity_add(dqcoeff, dst, pd->dst.stride, 8);
break;
case TX_4X4:
vp9_tx_identity_add(dqcoeff, dst, pd->dst.stride, 4);
break;
default:
assert(0 && "Invalid transform size");
break;
}
return;
}
#endif // CONFIG_TX_SKIP
#if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
switch (tx_size) {
@ -1067,6 +1246,10 @@ static void encode_block_pass1(int plane, int block, BLOCK_SIZE plane_bsize,
#if CONFIG_EXT_TX
MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
mbmi->ext_txfrm = NORM;
#endif
#if CONFIG_TX_SKIP
xd->mi[0].src_mi->mbmi.tx_skip[0] = 0;
xd->mi[0].src_mi->mbmi.tx_skip[1] = 0;
#endif
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &i, &j);
dst = &pd->dst.buf[4 * j * pd->dst.stride + 4 * i];
@ -1148,6 +1331,150 @@ static void encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
src = &p->src.buf[4 * (j * src_stride + i)];
src_diff = &p->src_diff[4 * (j * diff_stride + i)];
#if CONFIG_TX_SKIP
if (mbmi->tx_skip[plane != 0]) {
#if CONFIG_FILTERINTRA
if (mbmi->sb_type < BLOCK_8X8 && plane == 0)
fbit = xd->mi[0].b_filter_info[block];
else
fbit = plane == 0 ? mbmi->filterbit : mbmi->uv_filterbit;
#endif // CONFIG_FILTERINTRA
switch (tx_size) {
#if CONFIG_TX64X64
case TX_64X64:
assert(plane == 0);
scan_order = &vp9_default_scan_orders[TX_64X64];
mode = plane == 0 ? mbmi->mode : mbmi->uv_mode;
vp9_predict_intra_block(xd, block >> 8, bwl, TX_64X64, mode,
#if CONFIG_FILTERINTRA
fbit,
#endif
x->skip_encode ? src : dst,
x->skip_encode ? src_stride : dst_stride,
dst, dst_stride, i, j, plane);
if (!x->skip_recode) {
vp9_subtract_block(64, 64, src_diff, diff_stride,
src, src_stride, dst, dst_stride);
vp9_tx_identity(src_diff, coeff, diff_stride, 64);
vp9_quantize_b_64x64(coeff, 4096, x->skip_block, p->zbin,
p->round, p->quant, p->quant_shift, qcoeff,
dqcoeff, pd->dequant, p->zbin_extra, eob,
scan_order->scan, scan_order->iscan);
}
if (!x->skip_encode && *eob)
vp9_tx_identity_add(dqcoeff, dst, dst_stride, 64);
break;
#endif // CONFIG_TX64X64
case TX_32X32:
scan_order = &vp9_default_scan_orders[TX_32X32];
mode = plane == 0 ? mbmi->mode : mbmi->uv_mode;
vp9_predict_intra_block(xd, block >> 6, bwl, TX_32X32, mode,
#if CONFIG_FILTERINTRA
fbit,
#endif
x->skip_encode ? src : dst,
x->skip_encode ? src_stride : dst_stride,
dst, dst_stride, i, j, plane);
if (!x->skip_recode) {
vp9_subtract_block(32, 32, src_diff, diff_stride,
src, src_stride, dst, dst_stride);
vp9_tx_identity(src_diff, coeff, diff_stride, 32);
vp9_quantize_b_32x32(coeff, 1024, x->skip_block, p->zbin,
p->round, p->quant, p->quant_shift, qcoeff,
dqcoeff, pd->dequant, p->zbin_extra, eob,
scan_order->scan, scan_order->iscan);
}
if (!x->skip_encode && *eob) {
vp9_tx_identity_add(dqcoeff, dst, dst_stride, 32);
}
break;
case TX_16X16:
tx_type = get_tx_type(pd->plane_type, xd);
scan_order = &vp9_scan_orders[TX_16X16][tx_type];
mode = plane == 0 ? mbmi->mode : mbmi->uv_mode;
vp9_predict_intra_block(xd, block >> 4, bwl, TX_16X16, mode,
#if CONFIG_FILTERINTRA
fbit,
#endif
x->skip_encode ? src : dst,
x->skip_encode ? src_stride : dst_stride,
dst, dst_stride, i, j, plane);
if (!x->skip_recode) {
vp9_subtract_block(16, 16, src_diff, diff_stride,
src, src_stride, dst, dst_stride);
vp9_tx_identity(src_diff, coeff, diff_stride, 16);
vp9_quantize_b(coeff, 256, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob, scan_order->scan,
scan_order->iscan);
}
if (!x->skip_encode && *eob) {
vp9_tx_identity_add(dqcoeff, dst, dst_stride, 16);
}
break;
case TX_8X8:
tx_type = get_tx_type(pd->plane_type, xd);
scan_order = &vp9_scan_orders[TX_8X8][tx_type];
mode = plane == 0 ? mbmi->mode : mbmi->uv_mode;
vp9_predict_intra_block(xd, block >> 2, bwl, TX_8X8, mode,
#if CONFIG_FILTERINTRA
fbit,
#endif
x->skip_encode ? src : dst,
x->skip_encode ? src_stride : dst_stride,
dst, dst_stride, i, j, plane);
if (!x->skip_recode) {
vp9_subtract_block(8, 8, src_diff, diff_stride,
src, src_stride, dst, dst_stride);
vp9_tx_identity(src_diff, coeff, diff_stride, 8);
vp9_quantize_b(coeff, 64, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob, scan_order->scan,
scan_order->iscan);
}
if (!x->skip_encode && *eob) {
vp9_tx_identity_add(dqcoeff, dst, dst_stride, 8);
}
break;
case TX_4X4:
tx_type = get_tx_type_4x4(pd->plane_type, xd, block);
scan_order = &vp9_scan_orders[TX_4X4][tx_type];
mode = plane == 0 ?
get_y_mode(xd->mi[0].src_mi, block) : mbmi->uv_mode;
vp9_predict_intra_block(xd, block, bwl, TX_4X4, mode,
#if CONFIG_FILTERINTRA
fbit,
#endif
x->skip_encode ? src : dst,
x->skip_encode ? src_stride : dst_stride,
dst, dst_stride, i, j, plane);
if (!x->skip_recode) {
vp9_subtract_block(4, 4, src_diff, diff_stride,
src, src_stride, dst, dst_stride);
vp9_tx_identity(src_diff, coeff, diff_stride, 4);
vp9_quantize_b(coeff, 16, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob, scan_order->scan,
scan_order->iscan);
}
if (!x->skip_encode && *eob) {
vp9_tx_identity_add(dqcoeff, dst, dst_stride, 4);
}
break;
default:
assert(0);
break;
}
if (*eob)
*(args->skip) = 0;
return;
}
#endif // CONFIG_TX_SKIP
#if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
switch (tx_size) {

View File

@ -614,6 +614,10 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
xd->mi[0].src_mi->mbmi.mode = DC_PRED;
xd->mi[0].src_mi->mbmi.tx_size = use_dc_pred ?
(bsize >= BLOCK_16X16 ? TX_16X16 : TX_8X8) : TX_4X4;
#if CONFIG_TX_SKIP
xd->mi[0].src_mi->mbmi.tx_skip[0] = 0;
xd->mi[0].src_mi->mbmi.tx_skip[1] = 0;
#endif
vp9_encode_intra_block_plane(x, bsize, 0);
this_error = vp9_get_mb_ss(x->plane[0].src_diff);
#if CONFIG_VP9_HIGHBITDEPTH

View File

@ -960,6 +960,10 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
vpx_memcpy(tempa, ta, sizeof(ta));
vpx_memcpy(templ, tl, sizeof(tl));
#if CONFIG_TX_SKIP
xd->mi[0].src_mi->mbmi.tx_skip[0] = 0;
xd->mi[0].src_mi->mbmi.tx_skip[1] = 0;
#endif
for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
const int block = ib + idy * 2 + idx;
@ -1151,6 +1155,9 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
const MODE_INFO *left_mi = xd->left_available ? xd->mi[-1].src_mi : NULL;
const PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, 0);
const PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, 0);
#if CONFIG_TX_SKIP
int tx_skipped = 0;
#endif
bmode_costs = cpi->y_mode_costs[A][L];
if (cpi->sf.tx_size_search_method == USE_FULL_RD)
@ -1173,6 +1180,9 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
int64_t local_tx_cache[TX_MODES];
mic->mbmi.mode = mode;
#endif
#if CONFIG_TX_SKIP
mic->mbmi.tx_skip[0] = 0;
#endif
super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
&s, NULL, bsize, local_tx_cache, best_rd);
@ -1212,6 +1222,57 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
}
}
#if CONFIG_TX_SKIP
#if CONFIG_FILTERINTRA
for (mode_ext = 2 * DC_PRED; mode_ext <= 2 * TM_PRED + 1; mode_ext++) {
int64_t local_tx_cache[TX_MODES];
fbit = mode_ext & 1;
mode = mode_ext >> 1;
if (fbit && !is_filter_allowed(mode))
continue;
mic->mbmi.filterbit = fbit;
mic->mbmi.mode = mode;
#else
for (mode = DC_PRED; mode <= TM_PRED; mode++) {
int64_t local_tx_cache[TX_MODES];
mic->mbmi.mode = mode;
#endif
mic->mbmi.tx_skip[0] = 1;
super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
&s, NULL, bsize, local_tx_cache, best_rd);
if (this_rate_tokenonly == INT_MAX) {
continue;
}
if (mic->mbmi.tx_size < TX_32X32)
this_distortion = this_distortion << 2;
this_rate = this_rate_tokenonly + bmode_costs[mode];
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mode) && is_filter_enabled(mic->mbmi.tx_size))
this_rate += vp9_cost_bit(cpi->common.fc.filterintra_prob
[mic->mbmi.tx_size][mode], fbit);
#endif
this_rd = (RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion));
if (this_rd < best_rd) {
mode_selected = mode;
#if CONFIG_FILTERINTRA
fbit_selected = fbit;
#endif
best_rd = this_rd;
best_tx = mic->mbmi.tx_size;
*rate = this_rate;
*rate_tokenonly = this_rate_tokenonly;
*distortion = this_distortion;
*skippable = s;
tx_skipped = 1;
}
}
#endif
mic->mbmi.mode = mode_selected;
#if CONFIG_FILTERINTRA
if (is_filter_enabled(best_tx))
@ -1220,6 +1281,9 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
mic->mbmi.filterbit = 0;
#endif
mic->mbmi.tx_size = best_tx;
#if CONFIG_TX_SKIP
mic->mbmi.tx_skip[0] = tx_skipped;
#endif
return best_rd;
}
@ -1292,6 +1356,9 @@ static int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x,
int mode_ext, fbit = 0, fbit_selected = 0;
(void)max_tx_size;
#endif
#if CONFIG_TX_SKIP
int tx_skipped = 0;
#endif
vpx_memset(x->skip_txfm, 0, sizeof(x->skip_txfm));
#if CONFIG_FILTERINTRA
@ -1313,6 +1380,9 @@ static int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x,
#endif
xd->mi[0].src_mi->mbmi.uv_mode = mode;
#if CONFIG_TX_SKIP
xd->mi[0].src_mi->mbmi.tx_skip[1] = 0;
#endif
if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
&this_distortion, &s, &this_sse, bsize, best_rd))
@ -1341,10 +1411,73 @@ static int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x,
swap_block_ptr(x, ctx, 2, 0, 1, MAX_MB_PLANE);
}
}
#if CONFIG_TX_SKIP
#if CONFIG_FILTERINTRA
for (mode_ext = 2 * DC_PRED; mode_ext <= 2 * TM_PRED + 1; mode_ext++) {
mode = mode_ext >> 1;
fbit = mode_ext & 1;
if (fbit && !is_filter_allowed(mode))
continue;
if (fbit &&
!is_filter_enabled(get_uv_tx_size(&(x->e_mbd.mi[0].mbmi),
&xd->plane[1])))
continue;
x->e_mbd.mi[0].mbmi.uv_filterbit = fbit;
#else
for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
if (!(cpi->sf.intra_uv_mode_mask[max_tx_size] & (1 << mode)))
continue;
#endif // CONFIG_FILTERINTRA
if (xd->mi[0].src_mi->mbmi.sb_type < BLOCK_8X8)
break;
xd->mi[0].src_mi->mbmi.uv_mode = mode;
xd->mi[0].src_mi->mbmi.tx_skip[1] = 1;
if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
&this_distortion, &s, &this_sse, bsize, best_rd))
continue;
if (get_uv_tx_size(&xd->mi[0].src_mi->mbmi, &xd->plane[1]) < TX_32X32)
this_distortion = this_distortion << 2;
this_rate = this_rate_tokenonly +
cpi->intra_uv_mode_cost[cpi->common.frame_type][mode];
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mode) &&
is_filter_enabled(get_uv_tx_size(&(x->e_mbd.mi[0].mbmi),
&xd->plane[1])))
this_rate += vp9_cost_bit(cpi->common.fc.filterintra_prob
[get_uv_tx_size(&(x->e_mbd.mi[0].mbmi),
&xd->plane[1])][mode], fbit);
#endif
this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
if (this_rd < best_rd) {
mode_selected = mode;
#if CONFIG_FILTERINTRA
fbit_selected = fbit;
#endif
best_rd = this_rd;
*rate = this_rate;
*rate_tokenonly = this_rate_tokenonly;
*distortion = this_distortion;
*skippable = s;
tx_skipped = 1;
if (!x->select_tx_size)
swap_block_ptr(x, ctx, 2, 0, 1, MAX_MB_PLANE);
}
}
#endif
xd->mi[0].src_mi->mbmi.uv_mode = mode_selected;
#if CONFIG_FILTERINTRA
xd->mi[0].mbmi.uv_filterbit = fbit_selected;
#endif
#if CONFIG_TX_SKIP
xd->mi[0].src_mi->mbmi.tx_skip[1] = tx_skipped;
#endif
return best_rd;
}
@ -2807,6 +2940,12 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
int skippable_y, skippable_uv;
int64_t sseuv = INT64_MAX;
int64_t rdcosty = INT64_MAX;
#if CONFIG_TX_SKIP
int rate_s, skippable_s;
int64_t distortion_s, psse_s;
MB_MODE_INFO mbmi_temp;
int64_t tx_cache_s[TX_MODES];
#endif
vp9_subtract_plane(x, bsize, 0);
#if CONFIG_EXT_TX
@ -2847,6 +2986,32 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
// Y cost and distortion
super_block_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
bsize, txfm_cache, ref_best_rd);
#if CONFIG_TX_SKIP
mbmi_temp = *(mbmi);
mbmi->tx_skip[0] = 1;
super_block_yrd(cpi, x, &rate_s, &distortion_s, &skippable_s, &psse_s,
bsize, tx_cache_s, ref_best_rd);
if (mbmi->tx_size < TX_32X32)
distortion_s = distortion_s << 2;
if (rate_s != INT_MAX) {
if (*rate_y == INT_MAX ||
RDCOST(x->rdmult, x->rddiv, *rate_y, distortion_y) >
RDCOST(x->rdmult, x->rddiv, rate_s, distortion_s)) {
*rate_y = rate_s;
distortion_y = distortion_s;
*skippable = skippable_s;
*psse = psse_s;
} else {
*(mbmi) = mbmi_temp;
mbmi->tx_skip[0] = 0;
}
} else {
*(mbmi) = mbmi_temp;
mbmi->tx_skip[0] = 0;
}
#endif
if (*rate_y == INT_MAX) {
*rate2 = INT_MAX;
@ -2865,6 +3030,41 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
rdcosty = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
rdcosty = MIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, *psse));
#if CONFIG_TX_SKIP
super_block_uvrd(cpi, x, rate_uv, &distortion_uv, &skippable_uv,
&sseuv, bsize, ref_best_rd - rdcosty);
mbmi->tx_skip[1] = 1;
mbmi_temp = *(mbmi);
super_block_uvrd(cpi, x, &rate_s, &distortion_s, &skippable_s,
&psse_s, bsize, ref_best_rd - rdcosty);
if (rate_s != INT_MAX) {
if (get_uv_tx_size(mbmi, &xd->plane[1]) < TX_32X32)
distortion_s = distortion_s << 2;
if (*rate_uv == INT_MAX ||
RDCOST(x->rdmult, x->rddiv, *rate_uv, distortion_uv) >
RDCOST(x->rdmult, x->rddiv, rate_s, distortion_s)) {
*rate_uv = rate_s;
distortion_uv = distortion_s;
skippable_uv = skippable_s;
sseuv = psse_s;
} else {
*(mbmi) = mbmi_temp;
mbmi->tx_skip[1] = 0;
}
} else {
*(mbmi) = mbmi_temp;
mbmi->tx_skip[1] = 0;
}
if (*rate_uv == INT_MAX) {
*rate2 = INT_MAX;
*distortion = INT64_MAX;
restore_dst_buf(xd, orig_dst, orig_dst_stride);
return INT64_MAX;
}
#else
if (!super_block_uvrd(cpi, x, rate_uv, &distortion_uv, &skippable_uv,
&sseuv, bsize, ref_best_rd - rdcosty)) {
*rate2 = INT_MAX;
@ -2872,6 +3072,7 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
restore_dst_buf(xd, orig_dst, orig_dst_stride);
return INT64_MAX;
}
#endif
*psse += sseuv;
*rate2 += *rate_uv;
@ -3031,6 +3232,9 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
int64_t mode_threshold[MAX_MODES];
int *mode_map = rd_opt->mode_map[bsize];
const int mode_search_skip_flags = sf->mode_search_skip_flags;
#if CONFIG_TX_SKIP
int tx_skipped_uv[TX_SIZES];
#endif
vp9_zero(best_mbmode);
x->skip_encode = sf->skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
@ -3322,6 +3526,10 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
mbmi->uv_mode = DC_PRED;
mbmi->ref_frame[0] = ref_frame;
mbmi->ref_frame[1] = second_ref_frame;
#if CONFIG_TX_SKIP
mbmi->tx_skip[0] = 0;
mbmi->tx_skip[1] = 0;
#endif
// Evaluate all sub-pel filters irrespective of whether we can use
// them for this frame.
mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP
@ -3344,6 +3552,12 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
if (ref_frame == INTRA_FRAME) {
TX_SIZE uv_tx;
struct macroblockd_plane *const pd = &xd->plane[1];
#if CONFIG_TX_SKIP
int rate_y_s, skippable_s;
int64_t distortion_y_s;
MB_MODE_INFO mbmi_temp;
int64_t tx_cache_s[TX_MODES];
#endif
#if CONFIG_FILTERINTRA
mbmi->filterbit = 0;
#endif
@ -3385,6 +3599,27 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
}
}
#endif
#if CONFIG_TX_SKIP
mbmi_temp = *(mbmi);
mbmi->tx_skip[0] = 1;
super_block_yrd(cpi, x, &rate_y_s, &distortion_y_s, &skippable_s,
NULL, bsize, tx_cache_s, best_rd);
if (mbmi->tx_size < TX_32X32)
distortion_y_s = distortion_y_s << 2;
if (rate_y == INT_MAX && rate_y_s == INT_MAX)
continue;
else if (rate_y == INT_MAX ||
RDCOST(x->rdmult, x->rddiv, rate_y, distortion_y) >
RDCOST(x->rdmult, x->rddiv, rate_y_s, distortion_y_s)) {
rate_y = rate_y_s;
distortion_y = distortion_y_s;
skippable = skippable_s;
} else {
*(mbmi) = mbmi_temp;
mbmi->tx_skip[0] = 0;
}
#endif
if (rate_y == INT_MAX)
continue;
@ -3399,6 +3634,9 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
&fbit_uv[uv_tx],
#endif
&mode_uv[uv_tx]);
#if CONFIG_TX_SKIP
tx_skipped_uv[uv_tx] = mbmi->tx_skip[1];
#endif
}
@ -3409,6 +3647,9 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
#if CONFIG_FILTERINTRA
mbmi->uv_filterbit = fbit_uv[uv_tx];
#endif
#if CONFIG_TX_SKIP
mbmi->tx_skip[1] = tx_skipped_uv[uv_tx];
#endif
rate2 = rate_y + cpi->mbmode_cost[mbmi->mode] + rate_uv_intra[uv_tx];
#if CONFIG_FILTERINTRA
@ -3915,6 +4156,10 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
frame_mv[ZEROMV][ref_frame].as_int = 0;
}
#if CONFIG_TX_SKIP
mbmi->tx_skip[0] = 0;
mbmi->tx_skip[1] = 0;
#endif
for (ref_index = 0; ref_index < MAX_REFS; ++ref_index) {
int mode_excluded = 0;
int64_t this_rd = INT64_MAX;