ref: 4e08fa96f32b30a9302a2de1b1d7d5c7f8ed8397
parent: 22d7f0703a105e7e7b80bb84514b66a52ea91d45
parent: 8ba92a0bed9f05b79851b364c4fafd97ac88e824
author: Paul Wilkins <paulwilkins@google.com>
date: Wed May 22 02:53:12 EDT 2013
Merge "changes intra coding to be based on txfm block" into experimental
--- a/vp9/common/vp9_blockd.h
+++ b/vp9/common/vp9_blockd.h
@@ -192,6 +192,7 @@
case BLOCK_SIZE_SB64X32:
case BLOCK_SIZE_SB64X64: return 4;
default: assert(0);
+ return -1;
}
}
@@ -215,6 +216,7 @@
case BLOCK_SIZE_SB32X64:
case BLOCK_SIZE_SB64X64: return 4;
default: assert(0);
+ return -1;
}
}
--- a/vp9/common/vp9_reconintra.c
+++ b/vp9/common/vp9_reconintra.c
@@ -138,15 +138,11 @@
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);
+ yleft_col[r], 2);
- ypred_ptr[(bh - 1) * y_stride] = ROUND_POWER_OF_TWO(yleft_col[bh - 2] +
- yleft_col[bh - 1] * 3,
- 2);
-
ypred_ptr += y_stride;
for (r = 1; r < bh; ++r) {
for (c = 1; c < bw; c++)
@@ -396,11 +392,11 @@
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 @@
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);
}
--- a/vp9/common/vp9_reconintra.h
+++ b/vp9/common/vp9_reconintra.h
@@ -23,7 +23,7 @@
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);
--- a/vp9/decoder/vp9_decodemv.c
+++ b/vp9/decoder/vp9_decodemv.c
@@ -154,11 +154,11 @@
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 @@
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
--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -239,6 +239,59 @@
}
}
+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 @@
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 @@
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
--- a/vp9/decoder/vp9_onyxd_if.c
+++ b/vp9/decoder/vp9_onyxd_if.c
@@ -352,6 +352,16 @@
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);
}
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -871,8 +871,9 @@
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 @@
!(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
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -1703,21 +1703,16 @@
#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);
-
+#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 if (mbmi->ref_frame == INTRA_FRAME) {
- vp9_build_intra_predictors_sby_s(xd, bsize);
- vp9_build_intra_predictors_sbuv_s(xd, bsize);
- if (output_enabled)
- sum_intra_stats(cpi, x);
} else {
int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, mbmi->ref_frame)];
YV12_BUFFER_CONFIG *ref_fb = &cm->yv12_fb[idx];
@@ -1741,10 +1736,10 @@
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 @@
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 @@
} 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++) {
--- 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_
--- a/vp9/encoder/vp9_encodemb.c
+++ b/vp9/encoder/vp9_encodemb.c
@@ -628,16 +628,23 @@
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 @@
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 @@
}
}
-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};
@@ -703,5 +709,13 @@
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);
}
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -3170,6 +3170,15 @@
// 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);
--
⑨