From d97fd3eef6d73aabd357c43484d65b00ed06b6cf Mon Sep 17 00:00:00 2001 From: hui su Date: Wed, 12 Nov 2014 14:59:30 -0800 Subject: [PATCH] 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 --- configure | 1 + vp9/common/vp9_blockd.h | 3 + vp9/common/vp9_idct.c | 12 ++ vp9/common/vp9_idct.h | 8 + vp9/decoder/vp9_decodeframe.c | 146 ++++++++++++++- vp9/decoder/vp9_decodemv.c | 8 + vp9/encoder/vp9_bitstream.c | 8 + vp9/encoder/vp9_dct.c | 10 ++ vp9/encoder/vp9_encodemb.c | 327 ++++++++++++++++++++++++++++++++++ vp9/encoder/vp9_firstpass.c | 4 + vp9/encoder/vp9_rdopt.c | 245 +++++++++++++++++++++++++ 11 files changed, 767 insertions(+), 5 deletions(-) diff --git a/configure b/configure index 7a7946a7f..52b9f5b00 100755 --- a/configure +++ b/configure @@ -285,6 +285,7 @@ EXPERIMENT_LIST=" tx64x64 filterintra ext_tx + tx_skip " CONFIG_LIST=" external_build diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h index 5512476c5..9772228df 100644 --- a/vp9/common/vp9_blockd.h +++ b/vp9/common/vp9_blockd.h @@ -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 { diff --git a/vp9/common/vp9_idct.c b/vp9/common/vp9_idct.c index 8938fa484..6b2acb59e 100644 --- a/vp9/common/vp9_idct.c +++ b/vp9/common/vp9_idct.c @@ -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 diff --git a/vp9/common/vp9_idct.h b/vp9/common/vp9_idct.h index 122aa291d..5a86c96ef 100644 --- a/vp9/common/vp9_idct.h +++ b/vp9/common/vp9_idct.h @@ -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 diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c index dce5ff35a..5d64d160c 100644 --- a/vp9/decoder/vp9_decodeframe.c +++ b/vp9/decoder/vp9_decodeframe.c @@ -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; diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c index cd3fc889c..52ed635d7 100644 --- a/vp9/decoder/vp9_decodemv.c +++ b/vp9/decoder/vp9_decodemv.c @@ -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); diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index 56b61e271..019c68b3a 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -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); diff --git a/vp9/encoder/vp9_dct.c b/vp9/encoder/vp9_dct.c index 5c322a2b3..dde9bd9b6 100644 --- a/vp9/encoder/vp9_dct.c +++ b/vp9/encoder/vp9_dct.c @@ -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. diff --git a/vp9/encoder/vp9_encodemb.c b/vp9/encoder/vp9_encodemb.c index 7488afd74..2327fe2e7 100644 --- a/vp9/encoder/vp9_encodemb.c +++ b/vp9/encoder/vp9_encodemb.c @@ -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) { diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index f1baf8323..731caf084 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -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 diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index b4a8fcfa6..70efa104d 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -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;