diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h index 71d1dd9343b3edccee7aee2e9324546bc4736ee8..f1722fd72315312f78970517a641fa602adf0e25 100644 --- a/vp9/common/vp9_blockd.h +++ b/vp9/common/vp9_blockd.h @@ -192,6 +192,7 @@ static INLINE int b_width_log2(BLOCK_SIZE_TYPE sb_type) { case BLOCK_SIZE_SB64X32: case BLOCK_SIZE_SB64X64: return 4; default: assert(0); + return -1; } } @@ -215,6 +216,7 @@ static INLINE int b_height_log2(BLOCK_SIZE_TYPE sb_type) { case BLOCK_SIZE_SB32X64: case BLOCK_SIZE_SB64X64: return 4; default: assert(0); + return -1; } } diff --git a/vp9/common/vp9_reconintra.c b/vp9/common/vp9_reconintra.c index 1588f33cef17de052aba709c82bd0c4270ed05c0..dd60a76c7ac5cc358c87acd4835c12ffb2b7b3f6 100644 --- a/vp9/common/vp9_reconintra.c +++ b/vp9/common/vp9_reconintra.c @@ -138,14 +138,10 @@ static void d135_predictor(uint8_t *ypred_ptr, int y_stride, ypred_ptr[y_stride] = ROUND_POWER_OF_TWO(yabove_row[-1] + yleft_col[0] * 2 + yleft_col[1], 2); - for (r = 2; r < bh - 1; ++r) + for (r = 2; r < bh; ++r) ypred_ptr[r * y_stride] = ROUND_POWER_OF_TWO(yleft_col[r - 2] + yleft_col[r - 1] * 2 + - yleft_col[r + 1], 2); - - ypred_ptr[(bh - 1) * y_stride] = ROUND_POWER_OF_TWO(yleft_col[bh - 2] + - yleft_col[bh - 1] * 3, - 2); + yleft_col[r], 2); ypred_ptr += y_stride; for (r = 1; r < bh; ++r) { @@ -396,11 +392,11 @@ void vp9_build_intra_predictors_sbuv_s(MACROBLOCKD *xd, void vp9_predict_intra_block(MACROBLOCKD *xd, int block_idx, - BLOCK_SIZE_TYPE bsize, + int bwl_in, TX_SIZE tx_size, int mode, uint8_t *predictor, int pre_stride) { - const int bwl = b_width_log2(bsize) - tx_size; + const int bwl = bwl_in - tx_size; const int wmask = (1 << bwl) - 1; const int have_top = (block_idx >> bwl) || xd->up_available; @@ -424,6 +420,6 @@ void vp9_intra4x4_predict(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize, int mode, uint8_t *predictor, int pre_stride) { - vp9_predict_intra_block(xd, block_idx, bsize, TX_4X4, + vp9_predict_intra_block(xd, block_idx, b_width_log2(bsize), TX_4X4, mode, predictor, pre_stride); } diff --git a/vp9/common/vp9_reconintra.h b/vp9/common/vp9_reconintra.h index faecd6be73565165603c61a3e55848bbdc51314b..b88761b023fd9387f6b3bd353a38eb1dd940bdab 100644 --- a/vp9/common/vp9_reconintra.h +++ b/vp9/common/vp9_reconintra.h @@ -23,7 +23,7 @@ B_PREDICTION_MODE vp9_find_bpred_context(MACROBLOCKD *xd, int block, void vp9_predict_intra_block(MACROBLOCKD *xd, int block_idx, - BLOCK_SIZE_TYPE bsize, + int bwl_in, TX_SIZE tx_size, int mode, uint8_t *predictor, int pre_stride); diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c index ac66fb6442c4c88eb06104e2615afff199fb5fd3..1ddd21c120938a44238ca6de57f7427900aec3ea 100644 --- a/vp9/decoder/vp9_decodemv.c +++ b/vp9/decoder/vp9_decodemv.c @@ -154,11 +154,11 @@ static void kfread_modes(VP9D_COMP *pbi, MODE_INFO *m, m->mbmi.uv_mode = read_uv_mode(r, cm->kf_uv_mode_prob[m->mbmi.mode]); if (cm->txfm_mode == TX_MODE_SELECT && - !m->mbmi.mb_skip_coeff && + !(m->mbmi.mb_skip_coeff && m->mbmi.ref_frame != INTRA_FRAME) #if CONFIG_AB4X4 - m->mbmi.sb_type >= BLOCK_SIZE_SB8X8 + && m->mbmi.sb_type >= BLOCK_SIZE_SB8X8 #else - m->mbmi.mode != I4X4_PRED + && m->mbmi.mode != I4X4_PRED #endif ) { const int allow_16x16 = m->mbmi.sb_type >= BLOCK_SIZE_MB16X16; @@ -880,7 +880,8 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, if (cm->txfm_mode == TX_MODE_SELECT && mbmi->mb_skip_coeff == 0 && bsize >= BLOCK_SIZE_SB8X8) { #else - if (cm->txfm_mode == TX_MODE_SELECT && mbmi->mb_skip_coeff == 0 && + if (cm->txfm_mode == TX_MODE_SELECT && + (mbmi->mb_skip_coeff == 0 || mbmi->ref_frame == INTRA_FRAME) && ((mbmi->ref_frame == INTRA_FRAME && mbmi->mode != I4X4_PRED) || (mbmi->ref_frame != INTRA_FRAME && mbmi->mode != SPLITMV))) { #endif diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index 449e4269ef81e1e583f770f6b9b1d707ea1b4151..eea7658a88005db1335e13b15746cc662ffaa5e6 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c @@ -239,6 +239,59 @@ static void decode_block(int plane, int block, BLOCK_SIZE_TYPE bsize, } } +static void decode_block_intra(int plane, int block, BLOCK_SIZE_TYPE bsize, + int ss_txfrm_size, void *arg) { + MACROBLOCKD* const xd = arg; + int16_t* const qcoeff = BLOCK_OFFSET(xd->plane[plane].qcoeff, block, 16); + const int stride = xd->plane[plane].dst.stride; + const int raster_block = txfrm_block_to_raster_block(xd, bsize, plane, + block, ss_txfrm_size); + uint8_t* const dst = raster_block_offset_uint8(xd, bsize, plane, + raster_block, + xd->plane[plane].dst.buf, + stride); + const TX_SIZE tx_size = (TX_SIZE)(ss_txfrm_size / 2); + TX_TYPE tx_type; + int mode, b_mode; + int plane_b_size; + int tx_ib = raster_block >> tx_size; + mode = plane == 0? xd->mode_info_context->mbmi.mode: + xd->mode_info_context->mbmi.uv_mode; + + if (bsize <= BLOCK_SIZE_SB8X8 && mode == I4X4_PRED && plane == 0) + b_mode = xd->mode_info_context->bmi[raster_block].as_mode.first; + else + b_mode = mode; + + plane_b_size = b_width_log2(bsize) - xd->plane[plane].subsampling_x; + vp9_predict_intra_block(xd, tx_ib, plane_b_size, tx_size, + b_mode, dst, xd->plane[plane].dst.stride); + + switch (ss_txfrm_size / 2) { + case TX_4X4: + tx_type = plane == 0 ? get_tx_type_4x4(xd, raster_block) : DCT_DCT; + if (tx_type == DCT_DCT) + xd->itxm_add(qcoeff, dst, stride, xd->plane[plane].eobs[block]); + else + vp9_iht_add_c(tx_type, qcoeff, dst, stride, + xd->plane[plane].eobs[block]); + break; + case TX_8X8: + tx_type = plane == 0 ? get_tx_type_8x8(xd, raster_block) : DCT_DCT; + vp9_iht_add_8x8_c(tx_type, qcoeff, dst, stride, + xd->plane[plane].eobs[block]); + break; + case TX_16X16: + tx_type = plane == 0 ? get_tx_type_16x16(xd, raster_block) : DCT_DCT; + vp9_iht_add_16x16_c(tx_type, qcoeff, dst, stride, + xd->plane[plane].eobs[block]); + break; + case TX_32X32: + vp9_idct_add_32x32(qcoeff, dst, stride, xd->plane[plane].eobs[block]); + break; + } +} + static void decode_atom_intra(VP9D_COMP *pbi, MACROBLOCKD *xd, vp9_reader *r, BLOCK_SIZE_TYPE bsize) { @@ -295,6 +348,26 @@ static void decode_atom(VP9D_COMP *pbi, MACROBLOCKD *xd, foreach_transformed_block(xd, bsize, decode_block, xd); } +static void decode_sb_intra(VP9D_COMP *pbi, MACROBLOCKD *xd, + int mi_row, int mi_col, + vp9_reader *r, BLOCK_SIZE_TYPE bsize) { + MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi; + if (mbmi->mb_skip_coeff) { + vp9_reset_sb_tokens_context(xd, bsize); + } else { + // re-initialize macroblock dequantizer before detokenization + if (xd->segmentation_enabled) + mb_init_dequantizer(&pbi->common, xd); + + if (!vp9_reader_has_error(r)) { + vp9_decode_tokens(pbi, xd, r, bsize); + } + } + + foreach_transformed_block(xd, bsize, decode_block_intra, xd); +} + + static void decode_sb(VP9D_COMP *pbi, MACROBLOCKD *xd, int mi_row, int mi_col, vp9_reader *r, BLOCK_SIZE_TYPE bsize) { const int bwl = mi_width_log2(bsize), bhl = mi_height_log2(bsize); @@ -422,12 +495,13 @@ static void decode_modes_b(VP9D_COMP *pbi, int mi_row, int mi_col, vp9_decode_mb_mode_mv(pbi, xd, mi_row, mi_col, r); set_refs(pbi, mi_row, mi_col); + if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) + decode_sb_intra(pbi, xd, mi_row, mi_col, r, bsize); #if CONFIG_AB4X4 - if (bsize < BLOCK_SIZE_SB8X8) + else if (bsize < BLOCK_SIZE_SB8X8) #else - if (bsize == BLOCK_SIZE_SB8X8 && - (xd->mode_info_context->mbmi.mode == SPLITMV || - xd->mode_info_context->mbmi.mode == I4X4_PRED)) + else if (bsize == BLOCK_SIZE_SB8X8 && + xd->mode_info_context->mbmi.mode == SPLITMV) #endif decode_atom(pbi, xd, mi_row, mi_col, r, BLOCK_SIZE_SB8X8); else diff --git a/vp9/decoder/vp9_onyxd_if.c b/vp9/decoder/vp9_onyxd_if.c index 9761bd6f8d2066d3003ae5185be53df0e7aaabf4..5d5a543a3c4f8d88d5428b33e1ed649c39a0e3d2 100644 --- a/vp9/decoder/vp9_onyxd_if.c +++ b/vp9/decoder/vp9_onyxd_if.c @@ -352,6 +352,16 @@ int vp9_receive_compressed_data(VP9D_PTR ptr, vp9_loop_filter_frame(cm, &pbi->mb, cm->filter_level, 0, cm->dering_enabled); } + +#if WRITE_RECON_BUFFER == 2 + if (cm->show_frame) + write_dx_frame_to_file(cm->frame_to_show, + cm->current_video_frame + 2000); + else + write_dx_frame_to_file(cm->frame_to_show, + cm->current_video_frame + 3000); +#endif + vp9_extend_frame_borders(cm->frame_to_show, cm->subsampling_x, cm->subsampling_y); } diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index 88943330f390c88eb582a9386bdf6d0e675a1c5b..9f3268021fc3e3c6427ee237e6daccf19bacf8cf 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -871,8 +871,9 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m, if (((rf == INTRA_FRAME && mode != I4X4_PRED) || (rf != INTRA_FRAME && mode != SPLITMV)) && pc->txfm_mode == TX_MODE_SELECT && - !(skip_coeff || vp9_segfeature_active(xd, segment_id, - SEG_LVL_SKIP))) + !(rf != INTRA_FRAME && + (skip_coeff || vp9_segfeature_active(xd, segment_id, + SEG_LVL_SKIP)))) #endif { TX_SIZE sz = mi->txfm_size; @@ -941,7 +942,8 @@ static void write_mb_modes_kf(const VP9_COMP *cpi, !(skip_coeff || vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))) { #else if (ym != I4X4_PRED && c->txfm_mode == TX_MODE_SELECT && - !(skip_coeff || vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))) { + !(m->mbmi.ref_frame != INTRA_FRAME && (skip_coeff || + vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)))) { #endif TX_SIZE sz = m->mbmi.txfm_size; // FIXME(rbultje) code ternary symbol once all experiments are merged diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index 277f92ce7770996c0aa47882936023257ba71187..73eec565690e3299c900a53bb70f2b1a4ba4caaa 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -1703,19 +1703,14 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, #if CONFIG_AB4X4 if (mbmi->ref_frame == INTRA_FRAME && bsize < BLOCK_SIZE_SB8X8) { -#else - if (mbmi->mode == I4X4_PRED) { - assert(bsize == BLOCK_SIZE_SB8X8 && mbmi->txfm_size == TX_4X4); -#endif - vp9_encode_intra4x4mby(cm, x, BLOCK_SIZE_SB8X8); + vp9_encode_intra_block_y(cm, x, BLOCK_SIZE_SB8X8); vp9_build_intra_predictors_sbuv_s(xd, BLOCK_SIZE_SB8X8); vp9_encode_sbuv(cm, x, BLOCK_SIZE_SB8X8); - - if (output_enabled) - sum_intra_stats(cpi, x); - } else if (mbmi->ref_frame == INTRA_FRAME) { - vp9_build_intra_predictors_sby_s(xd, bsize); - vp9_build_intra_predictors_sbuv_s(xd, bsize); +#else + if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) { + vp9_encode_intra_block_y(cm, x, bsize); + vp9_encode_intra_block_uv(cm, x, bsize); +#endif if (output_enabled) sum_intra_stats(cpi, x); } else { @@ -1741,10 +1736,10 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, if (mbmi->ref_frame == INTRA_FRAME && bsize < BLOCK_SIZE_SB8X8) { #else - if (mbmi->mode == I4X4_PRED) { - assert(bsize == BLOCK_SIZE_SB8X8); + if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) { #endif - vp9_tokenize_sb(cpi, xd, t, !output_enabled, BLOCK_SIZE_SB8X8); + vp9_tokenize_sb(cpi, xd, t, !output_enabled, + (bsize < BLOCK_SIZE_SB8X8) ? BLOCK_SIZE_SB8X8 : bsize); } else if (!x->skip) { vp9_encode_sb(cm, x, (bsize < BLOCK_SIZE_SB8X8) ? BLOCK_SIZE_SB8X8 : bsize); vp9_tokenize_sb(cpi, xd, t, !output_enabled, @@ -1771,8 +1766,9 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, if (output_enabled) { if (cm->txfm_mode == TX_MODE_SELECT && + (mbmi->ref_frame == INTRA_FRAME || !(mbmi->mb_skip_coeff || - vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))) { + vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)))) { if (bsize >= BLOCK_SIZE_SB32X32) { cpi->txfm_count_32x32p[mbmi->txfm_size]++; } else if (bsize >= BLOCK_SIZE_MB16X16) { @@ -1783,18 +1779,23 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, } else { int x, y; TX_SIZE sz = (cm->txfm_mode == TX_MODE_SELECT) ? TX_32X32 : cm->txfm_mode; - - if (sz == TX_32X32 && bsize < BLOCK_SIZE_SB32X32) - sz = TX_16X16; - if (sz == TX_16X16 && bsize < BLOCK_SIZE_MB16X16) - sz = TX_8X8; + // The new intra coding scheme requires no change of transform size + if (mi->mbmi.ref_frame != INTRA_FRAME) { + if (sz == TX_32X32 && bsize < BLOCK_SIZE_SB32X32) + sz = TX_16X16; + if (sz == TX_16X16 && bsize < BLOCK_SIZE_MB16X16) + sz = TX_8X8; #if CONFIG_AB4X4 - if (sz == TX_8X8 && bsize < BLOCK_SIZE_SB8X8) + if (sz == TX_8X8 && bsize < BLOCK_SIZE_SB8X8) #else - if (sz == TX_8X8 && (mbmi->mode == SPLITMV || - mbmi->mode == I4X4_PRED)) + if (sz == TX_8X8 && mbmi->mode == SPLITMV) #endif + sz = TX_4X4; + } else if (mbmi->mode != I4X4_PRED) { + sz = mbmi->txfm_size; + } else { sz = TX_4X4; + } for (y = 0; y < bh; y++) { for (x = 0; x < bw; x++) { diff --git a/vp9/encoder/vp9_encodeintra.h b/vp9/encoder/vp9_encodeintra.h index 22a046e355a21679dc8021f5d13c5e588d9c1059..7da164c6a3da60cc73d8c4e789a0c00189d32d53 100644 --- a/vp9/encoder/vp9_encodeintra.h +++ b/vp9/encoder/vp9_encodeintra.h @@ -16,6 +16,9 @@ int vp9_encode_intra(VP9_COMP *cpi, MACROBLOCK *x, int use_16x16_pred); void vp9_encode_intra16x16mby(VP9_COMMON *const cm, MACROBLOCK *x); void vp9_encode_intra16x16mbuv(VP9_COMMON *const cm, MACROBLOCK *x); -void vp9_encode_intra4x4mby(VP9_COMMON *const cm, MACROBLOCK *mb, - BLOCK_SIZE_TYPE bs); +void vp9_encode_intra_block_y(VP9_COMMON *const cm, MACROBLOCK *mb, + BLOCK_SIZE_TYPE bs); +void vp9_encode_intra_block_uv(VP9_COMMON *const cm, MACROBLOCK *mb, + BLOCK_SIZE_TYPE bs); + #endif // VP9_ENCODER_VP9_ENCODEINTRA_H_ diff --git a/vp9/encoder/vp9_encodemb.c b/vp9/encoder/vp9_encodemb.c index d9cd091632fa001857b895c62e2a2fd5b6060476..a4991f21a9b6906c39d2f76577351e4d9d56e37b 100644 --- a/vp9/encoder/vp9_encodemb.c +++ b/vp9/encoder/vp9_encodemb.c @@ -628,16 +628,23 @@ static void encode_block_intra(int plane, int block, BLOCK_SIZE_TYPE bsize, const int txfm_b_size = 4 << tx_size; int ib = raster_block; + int tx_ib = ib >> tx_size; + int plane_b_size; TX_TYPE tx_type; + int mode, b_mode; - if (tx_size <= TX_16X16) - tx_type = txfm_map(xd->mode_info_context->bmi[ib].as_mode.first); + mode = plane == 0? xd->mode_info_context->mbmi.mode: + xd->mode_info_context->mbmi.uv_mode; + if (bsize <= BLOCK_SIZE_SB8X8 && mode == I4X4_PRED && plane == 0) + b_mode = xd->mode_info_context->bmi[ib].as_mode.first; else - tx_type = DCT_DCT; + b_mode = mode; - vp9_predict_intra_block(&x->e_mbd, ib, bsize, tx_size, - xd->mode_info_context->bmi[ib].as_mode.first, + assert(b_mode >= B_DC_PRED && b_mode <= B_TM_PRED); + + plane_b_size = b_width_log2(bsize) - xd->plane[plane].subsampling_x; + vp9_predict_intra_block(xd, tx_ib, plane_b_size, tx_size, b_mode, dst, xd->plane[plane].dst.stride); vp9_subtract_block(txfm_b_size, txfm_b_size, src_diff, bw, @@ -650,7 +657,6 @@ static void encode_block_intra(int plane, int block, BLOCK_SIZE_TYPE bsize, if (x->optimize) vp9_optimize_b(plane, block, bsize, ss_txfrm_size, args->cm, x, args->ctx); */ - switch (ss_txfrm_size / 2) { case TX_32X32: vp9_short_idct32x32_add(BLOCK_OFFSET(xd->plane[plane].dqcoeff, @@ -695,8 +701,8 @@ static void encode_block_intra(int plane, int block, BLOCK_SIZE_TYPE bsize, } } -void vp9_encode_intra4x4mby(VP9_COMMON *const cm, MACROBLOCK *x, - BLOCK_SIZE_TYPE bsize) { +void vp9_encode_intra_block_y(VP9_COMMON *const cm, MACROBLOCK *x, + BLOCK_SIZE_TYPE bsize) { MACROBLOCKD* const xd = &x->e_mbd; struct optimize_ctx ctx; struct encode_b_args arg = {cm, x, &ctx}; @@ -704,4 +710,12 @@ void vp9_encode_intra4x4mby(VP9_COMMON *const cm, MACROBLOCK *x, foreach_transformed_block_in_plane(xd, bsize, 0, encode_block_intra, &arg); } +void vp9_encode_intra_block_uv(VP9_COMMON *const cm, MACROBLOCK *x, + BLOCK_SIZE_TYPE bsize) { + MACROBLOCKD* const xd = &x->e_mbd; + struct optimize_ctx ctx; + struct encode_b_args arg = {cm, x, &ctx}; + + foreach_transformed_block_uv(xd, bsize, encode_block_intra, &arg); +} diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index a8e1a1727783ff89a9308544a5147e5567834b6d..e3c7930ab25c5bfae9cb9fd1858cbd282f062c0a 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -3170,6 +3170,15 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, // Pick the loop filter level for the frame. loopfilter_frame(cpi, cm); +#if WRITE_RECON_BUFFER + if (cm->show_frame) + write_cx_frame_to_file(cm->frame_to_show, + cm->current_video_frame + 2000); + else + write_cx_frame_to_file(cm->frame_to_show, + cm->current_video_frame + 3000); +#endif + // build the bitstream cpi->dummy_packing = 0; vp9_pack_bitstream(cpi, dest, size);