Newer
Older
} else if (single_count_zero == 0) {
cpi->common.comp_pred_mode = COMP_PREDICTION_ONLY;
}
if (cpi->common.txfm_mode == TX_MODE_SELECT) {
const int count4x4 = cpi->txfm_count_16x16p[TX_4X4] +
cpi->txfm_count_32x32p[TX_4X4] +
cpi->txfm_count_8x8p[TX_4X4];
const int count8x8_lp = cpi->txfm_count_32x32p[TX_8X8] +
cpi->txfm_count_16x16p[TX_8X8];
const int count8x8_8x8p = cpi->txfm_count_8x8p[TX_8X8];
const int count16x16_16x16p = cpi->txfm_count_16x16p[TX_16X16];
const int count16x16_lp = cpi->txfm_count_32x32p[TX_16X16];
const int count32x32 = cpi->txfm_count_32x32p[TX_32X32];
if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
count32x32 == 0) {
reset_skip_txfm_size(cpi, TX_8X8);
} else if (count8x8_8x8p == 0 && count16x16_16x16p == 0 &&
count8x8_lp == 0 && count16x16_lp == 0 && count32x32 == 0) {
reset_skip_txfm_size(cpi, TX_4X4);
} else if (count8x8_lp == 0 && count16x16_lp == 0 && count4x4 == 0) {
cpi->common.txfm_mode = ALLOW_32X32;
} else if (count32x32 == 0 && count8x8_lp == 0 && count4x4 == 0) {
cpi->common.txfm_mode = ALLOW_16X16;
reset_skip_txfm_size(cpi, TX_16X16);
// Update interpolation filter strategy for next frame.
if ((cpi->common.frame_type != KEY_FRAME) && (cpi->sf.search_best_filter))
void vp9_build_block_offsets(MACROBLOCK *x) {
static void sum_intra_stats(VP9_COMP *cpi, MACROBLOCK *x) {
const MB_PREDICTION_MODE m = xd->mode_info_context->mbmi.mode;
const MB_PREDICTION_MODE uvm = xd->mode_info_context->mbmi.uv_mode;
++ (is_key ? uv_modes : inter_uv_modes)[uvm];
++ uv_modes_y[m][uvm];
unsigned int *const bct = is_key ? b_modes : inter_b_modes;
} while (++b < (16 >> (CONFIG_SB8X8 * 2)));
if (m == I8X8_PRED) {
i8x8_modes[xd->block[0].bmi.as_mode.first]++;
i8x8_modes[xd->block[2].bmi.as_mode.first]++;
i8x8_modes[xd->block[8].bmi.as_mode.first]++;
i8x8_modes[xd->block[10].bmi.as_mode.first]++;
}
if (xd->mode_info_context->mbmi.sb_type > BLOCK_SIZE_MB16X16) {
cpi->i8x8_mode_count[xd->mode_info_context->bmi[0].as_mode.first]++;
cpi->i8x8_mode_count[xd->mode_info_context->bmi[2].as_mode.first]++;
cpi->i8x8_mode_count[xd->mode_info_context->bmi[8].as_mode.first]++;
cpi->i8x8_mode_count[xd->mode_info_context->bmi[10].as_mode.first]++;
int m = xd->mode_info_context->bmi[b].as_mode.first;
#if CONFIG_NEWBINTRAMODES
if (m == B_CONTEXT_PRED) m -= CONTEXT_PRED_REPLACEMENTS;
#endif
++cpi->bmode_count[m];
} while (++b < (16 >> (CONFIG_SB8X8 * 2)));
// Experimental stub function to create a per MB zbin adjustment based on
// some previously calculated measure of MB activity.
static void adjust_act_zbin(VP9_COMP *cpi, MACROBLOCK *x) {
int64_t a;
int64_t b;
int64_t act = *(x->mb_activity_ptr);
// Apply the masking to the RD multiplier.
a = act + 4 * cpi->activity_avg;
b = 4 * act + cpi->activity_avg;
if (act > cpi->activity_avg)
x->act_zbin_adj = (int)(((int64_t)b + (a >> 1)) / a) - 1;
else
x->act_zbin_adj = 1 - (int)(((int64_t)a + (b >> 1)) / b);
static void encode_macroblock(VP9_COMP *cpi, TOKENEXTRA **t,
int output_enabled,
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
MODE_INFO *mi = xd->mode_info_context;
MB_MODE_INFO *const mbmi = &mi->mbmi;
const int mis = cm->mode_info_stride;
#if CONFIG_SB8X8
int n;
#endif
assert(xd->mode_info_context->mbmi.sb_type == BLOCK_SIZE_MB16X16);
enc_debug = (cpi->common.current_video_frame == 11 && cm->show_frame &&
mb_row == 8 && mb_col == 0 && output_enabled);
if (enc_debug)
printf("Encode MB %d %d output %d\n", mb_row, mb_col, output_enabled);
#endif
if (cm->frame_type == KEY_FRAME) {
if (cpi->oxcf.tuning == VP8_TUNE_SSIM && output_enabled) {
// Adjust the zbin based on this MB rate.
adjust_act_zbin(cpi, x);
vp9_update_zbin_extra(cpi, x);
}
} else {
vp9_setup_interp_filters(xd, mbmi->interp_filter, cm);
if (cpi->oxcf.tuning == VP8_TUNE_SSIM) {
// Adjust the zbin based on this MB rate.
adjust_act_zbin(cpi, x);
}
// Experimental code. Special case for gf and arf zeromv modes.
// Increase zbin size to suppress noise
cpi->zbin_mode_boost = 0;
if (cpi->zbin_mode_boost_enabled) {
if (mbmi->ref_frame != INTRA_FRAME) {
if (mbmi->mode == ZEROMV) {
if (mbmi->ref_frame != LAST_FRAME)
cpi->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST;
else
cpi->zbin_mode_boost = LF_ZEROMV_ZBIN_BOOST;
} else {
cpi->zbin_mode_boost = INTRA_ZBIN_BOOST;
vp9_update_zbin_extra(cpi, x);
if (enc_debug) {
printf("Mode %d skip %d tx_size %d\n", mbmi->mode, x->skip,
mbmi->txfm_size);
}
#endif
vp9_encode_intra16x16mbuv(cm, x);
vp9_encode_intra4x4mby(x, BLOCK_SIZE_MB16X16);
vp9_encode_intra8x8mby(x);
vp9_encode_intra8x8mbuv(x);
vp9_encode_intra16x16mbuv(cm, x);
vp9_encode_intra16x16mby(cm, x);
if (output_enabled)
sum_intra_stats(cpi, x);
} else {
int ref_fb_idx, second_ref_fb_idx;
#ifdef ENC_DEBUG
if (enc_debug)
printf("Mode %d skip %d tx_size %d ref %d ref2 %d mv %d %d interp %d\n",
mbmi->mode, x->skip, mbmi->txfm_size,
mbmi->ref_frame, mbmi->second_ref_frame,
mbmi->mv[0].as_mv.row, mbmi->mv[0].as_mv.col,
mbmi->interp_filter);
assert(cm->frame_type != KEY_FRAME);
ref_fb_idx = cpi->common.ref_frame_map[cpi->lst_fb_idx];
ref_fb_idx = cpi->common.ref_frame_map[cpi->gld_fb_idx];
ref_fb_idx = cpi->common.ref_frame_map[cpi->alt_fb_idx];
second_ref_fb_idx = cpi->common.ref_frame_map[cpi->lst_fb_idx];
second_ref_fb_idx = cpi->common.ref_frame_map[cpi->gld_fb_idx];
second_ref_fb_idx = cpi->common.ref_frame_map[cpi->alt_fb_idx];
setup_pre_planes(xd,
&cpi->common.yv12_fb[ref_fb_idx],
mbmi->second_ref_frame > 0 ? &cpi->common.yv12_fb[second_ref_fb_idx]
: NULL,
mi_row, mi_col, xd->scale_factor, xd->scale_factor_uv);
vp9_encode_inter16x16(cm, x, mi_row, mi_col);
vp9_build_inter_predictors_sb(xd, mi_row, mi_col, BLOCK_SIZE_MB16X16);
#if CONFIG_COMP_INTERINTRA_PRED
if (xd->mode_info_context->mbmi.second_ref_frame == INTRA_FRAME) {
vp9_build_interintra_predictors(xd,
xd->plane[0].dst.buf,
xd->plane[1].dst.buf,
xd->plane[2].dst.buf,
xd->plane[0].dst.stride,
xd->plane[1].dst.stride,
BLOCK_SIZE_MB16X16);
int i, j;
printf("\n");
printf("qcoeff\n");
for (i = 0; i < 384; i++) {
printf("%3d ", xd->qcoeff[i]);
if (i % 16 == 15) printf("\n");
}
printf("\n");
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
printf("predictor\n");
for (i = 0; i < 384; i++) {
printf("%3d ", xd->predictor[i]);
if (i % 16 == 15) printf("\n");
}
printf("\n");
printf("src_diff\n");
for (i = 0; i < 384; i++) {
printf("%3d ", x->src_diff[i]);
if (i % 16 == 15) printf("\n");
}
printf("\n");
printf("diff\n");
for (i = 0; i < 384; i++) {
printf("%3d ", xd->block[0].diff[i]);
if (i % 16 == 15) printf("\n");
}
printf("\n");
printf("final y\n");
for (i = 0; i < 16; i++) {
for (j = 0; j < 16; j++)
printf("%3d ", xd->plane[0].dst.buf[i * xd->plane[0].dst.stride + j]);
printf("\n");
}
printf("\n");
printf("final u\n");
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++)
printf("%3d ", xd->plane[1].dst.buf[i * xd->plane[1].dst.stride + j]);
printf("\n");
}
printf("final v\n");
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++)
printf("%3d ", xd->plane[2].dst.buf[i * xd->plane[1].dst.stride + j]);
printf("\n");
}
vp9_tokenize_sb(cpi, xd, t, !output_enabled, BLOCK_SIZE_MB16X16);
// FIXME(rbultje): not tile-aware (mi - 1)
int mb_skip_context =
(mi - 1)->mbmi.mb_skip_coeff + (mi - mis)->mbmi.mb_skip_coeff;
mbmi->mb_skip_coeff = 1;
if (output_enabled)
cpi->skip_true_count[mb_skip_context]++;
vp9_reset_sb_tokens_context(xd, BLOCK_SIZE_MB16X16);
#if CONFIG_SB8X8
// copy skip flag on all mb_mode_info contexts in this SB
// if this was a skip at this txfm size
for (n = 1; n < 4; n++) {
const int x_idx = n & 1, y_idx = n >> 1;
if (mi_col + x_idx < cm->mi_cols && mi_row + y_idx < cm->mi_rows)
mi[x_idx + y_idx * mis].mbmi.mb_skip_coeff = mi->mbmi.mb_skip_coeff;
}
#endif
if (output_enabled) {
int segment_id = mbmi->segment_id;
if (cpi->common.txfm_mode == TX_MODE_SELECT &&
!(mbmi->mb_skip_coeff ||
vp9_segfeature_active(&x->e_mbd, segment_id, SEG_LVL_SKIP))) {
assert(mbmi->txfm_size <= TX_16X16);
if (mbmi->mode != I4X4_PRED && mbmi->mode != I8X8_PRED &&
cpi->txfm_count_16x16p[mbmi->txfm_size]++;
} else if (mbmi->mode == I8X8_PRED ||
(mbmi->mode == SPLITMV &&
mbmi->partitioning != PARTITIONING_4X4)) {
cpi->txfm_count_8x8p[mbmi->txfm_size]++;
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
#if CONFIG_SB8X8
int y, x;
#endif
if (mbmi->mode != I4X4_PRED && mbmi->mode != I8X8_PRED &&
mbmi->mode != SPLITMV && cpi->common.txfm_mode >= ALLOW_16X16) {
mbmi->txfm_size = TX_16X16;
} else if (mbmi->mode != I4X4_PRED &&
!(mbmi->mode == SPLITMV &&
mbmi->partitioning == PARTITIONING_4X4) &&
cpi->common.txfm_mode >= ALLOW_8X8) {
mbmi->txfm_size = TX_8X8;
} else {
mbmi->txfm_size = TX_4X4;
}
#if CONFIG_SB8X8
for (y = 0; y < 2; y++) {
for (x = !y; x < 2; x++) {
if (mi_col + x < cm->mi_cols && mi_row + y < cm->mi_rows) {
mi[mis * y + x].mbmi.txfm_size = mbmi->txfm_size;
}
}
}
#endif
static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t,
int output_enabled, int mi_row, int mi_col,
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
int n;
MODE_INFO *mi = x->e_mbd.mode_info_context;
unsigned int segment_id = mi->mbmi.segment_id;
const int mis = cm->mode_info_stride;
const int bwl = mi_width_log2(bsize);
const int bw = 1 << bwl, bh = 1 << mi_height_log2(bsize);
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
if (cm->frame_type == KEY_FRAME) {
if (cpi->oxcf.tuning == VP8_TUNE_SSIM) {
adjust_act_zbin(cpi, x);
vp9_update_zbin_extra(cpi, x);
}
} else {
vp9_setup_interp_filters(xd, xd->mode_info_context->mbmi.interp_filter, cm);
if (cpi->oxcf.tuning == VP8_TUNE_SSIM) {
// Adjust the zbin based on this MB rate.
adjust_act_zbin(cpi, x);
}
// Experimental code. Special case for gf and arf zeromv modes.
// Increase zbin size to suppress noise
cpi->zbin_mode_boost = 0;
if (cpi->zbin_mode_boost_enabled) {
if (xd->mode_info_context->mbmi.ref_frame != INTRA_FRAME) {
if (xd->mode_info_context->mbmi.mode == ZEROMV) {
if (xd->mode_info_context->mbmi.ref_frame != LAST_FRAME)
cpi->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST;
else
cpi->zbin_mode_boost = LF_ZEROMV_ZBIN_BOOST;
} else if (xd->mode_info_context->mbmi.mode == SPLITMV) {
} else {
cpi->zbin_mode_boost = MV_ZBIN_BOOST;
}
} else {
cpi->zbin_mode_boost = INTRA_ZBIN_BOOST;
}
}
vp9_update_zbin_extra(cpi, x);
}
#if CONFIG_SB8X8
if (xd->mode_info_context->mbmi.mode == I4X4_PRED) {
assert(bsize == BLOCK_SIZE_SB8X8 &&
xd->mode_info_context->mbmi.txfm_size == TX_4X4);
vp9_encode_intra4x4mby(x, bsize);
vp9_build_intra_predictors_sbuv_s(&x->e_mbd, bsize);
vp9_subtract_sbuv(x, bsize);
vp9_transform_sbuv_4x4(x, bsize);
vp9_quantize_sbuv_4x4(x, bsize);
if (x->optimize)
vp9_optimize_sbuv(cm, x, bsize);
vp9_inverse_transform_sbuv_4x4(xd, bsize);
vp9_recon_sbuv(xd, bsize);
if (output_enabled)
sum_intra_stats(cpi, x);
} else
#endif
if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
vp9_build_intra_predictors_sby_s(&x->e_mbd, bsize);
vp9_build_intra_predictors_sbuv_s(&x->e_mbd, bsize);
if (output_enabled)
sum_intra_stats(cpi, x);
int ref_fb_idx, second_ref_fb_idx;
assert(cm->frame_type != KEY_FRAME);
if (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME)
ref_fb_idx = cpi->common.ref_frame_map[cpi->lst_fb_idx];
else if (xd->mode_info_context->mbmi.ref_frame == GOLDEN_FRAME)
ref_fb_idx = cpi->common.ref_frame_map[cpi->gld_fb_idx];
ref_fb_idx = cpi->common.ref_frame_map[cpi->alt_fb_idx];
if (xd->mode_info_context->mbmi.second_ref_frame > 0) {
if (xd->mode_info_context->mbmi.second_ref_frame == LAST_FRAME)
second_ref_fb_idx = cpi->common.ref_frame_map[cpi->lst_fb_idx];
else if (xd->mode_info_context->mbmi.second_ref_frame == GOLDEN_FRAME)
second_ref_fb_idx = cpi->common.ref_frame_map[cpi->gld_fb_idx];
second_ref_fb_idx = cpi->common.ref_frame_map[cpi->alt_fb_idx];
setup_pre_planes(xd,
&cpi->common.yv12_fb[ref_fb_idx],
xd->mode_info_context->mbmi.second_ref_frame > 0
? &cpi->common.yv12_fb[second_ref_fb_idx] : NULL,
mi_row, mi_col, xd->scale_factor, xd->scale_factor_uv);
vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
#if CONFIG_SB8X8
if (xd->mode_info_context->mbmi.mode == I4X4_PRED) {
assert(bsize == BLOCK_SIZE_SB8X8);
vp9_tokenize_sb(cpi, &x->e_mbd, t, !output_enabled, bsize);
} else
#endif
if (!x->skip) {
switch (xd->mode_info_context->mbmi.txfm_size) {
case TX_32X32:
vp9_transform_sby_32x32(x, bsize);
vp9_quantize_sby_32x32(x, bsize);
if (bsize == BLOCK_SIZE_SB64X64) {
vp9_transform_sbuv_32x32(x, bsize);
vp9_quantize_sbuv_32x32(x, bsize);
} else {
vp9_transform_sbuv_16x16(x, bsize);
vp9_quantize_sbuv_16x16(x, bsize);
}
if (x->optimize) {
vp9_inverse_transform_sby_32x32(xd, bsize);
if (bsize == BLOCK_SIZE_SB64X64)
vp9_inverse_transform_sbuv_32x32(xd, bsize);
else
vp9_inverse_transform_sbuv_16x16(xd, bsize);
break;
case TX_16X16:
vp9_transform_sby_16x16(x, bsize);
vp9_quantize_sby_16x16(x, bsize);
if (bsize >= BLOCK_SIZE_SB32X32) {
vp9_transform_sbuv_16x16(x, bsize);
vp9_quantize_sbuv_16x16(x, bsize);
} else {
vp9_transform_sbuv_8x8(x, bsize);
vp9_quantize_sbuv_8x8(x, bsize);
}
if (x->optimize) {
vp9_inverse_transform_sby_16x16(xd, bsize);
if (bsize >= BLOCK_SIZE_SB32X32)
vp9_inverse_transform_sbuv_16x16(xd, bsize);
else
vp9_inverse_transform_sbuv_8x8(xd, bsize);
break;
case TX_8X8:
vp9_transform_sby_8x8(x, bsize);
vp9_quantize_sby_8x8(x, bsize);
vp9_inverse_transform_sby_8x8(xd, bsize);
if (bsize >= BLOCK_SIZE_MB16X16) {
vp9_transform_sbuv_8x8(x, bsize);
vp9_quantize_sbuv_8x8(x, bsize);
if (x->optimize)
vp9_inverse_transform_sbuv_8x8(xd, bsize);
} else {
vp9_transform_sbuv_4x4(x, bsize);
vp9_quantize_sbuv_4x4(x, bsize);
if (x->optimize)
vp9_inverse_transform_sbuv_4x4(xd, bsize);
}
break;
case TX_4X4:
vp9_transform_sby_4x4(x, bsize);
vp9_transform_sbuv_4x4(x, bsize);
vp9_quantize_sby_4x4(x, bsize);
vp9_quantize_sbuv_4x4(x, bsize);
if (x->optimize) {
vp9_optimize_sby(cm, x, bsize);
vp9_optimize_sbuv(cm, x, bsize);
vp9_inverse_transform_sby_4x4(xd, bsize);
vp9_inverse_transform_sbuv_4x4(xd, bsize);
break;
default: assert(0);
vp9_recon_sb_c(xd, bsize);
vp9_tokenize_sb(cpi, &x->e_mbd, t, !output_enabled, bsize);
// FIXME(rbultje): not tile-aware (mi - 1)
int mb_skip_context =
(mi - 1)->mbmi.mb_skip_coeff + (mi - mis)->mbmi.mb_skip_coeff;
xd->mode_info_context->mbmi.mb_skip_coeff = 1;
if (output_enabled)
cpi->skip_true_count[mb_skip_context]++;
vp9_reset_sb_tokens_context(xd, bsize);
// copy skip flag on all mb_mode_info contexts in this SB
// if this was a skip at this txfm size
for (n = 1; n < bw * bh; n++) {
const int x_idx = n & (bw - 1), y_idx = n >> bwl;
if (mi_col + x_idx < cm->mi_cols && mi_row + y_idx < cm->mi_rows)
mi[x_idx + y_idx * mis].mbmi.mb_skip_coeff = mi->mbmi.mb_skip_coeff;
}
if (output_enabled) {
if (cm->txfm_mode == TX_MODE_SELECT &&
!(mi->mbmi.mb_skip_coeff ||
vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))) {
if (bsize >= BLOCK_SIZE_SB32X32) {
cpi->txfm_count_32x32p[mi->mbmi.txfm_size]++;
} else if (bsize >= BLOCK_SIZE_MB16X16) {
cpi->txfm_count_16x16p[mi->mbmi.txfm_size]++;
} else {
cpi->txfm_count_8x8p[mi->mbmi.txfm_size]++;
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;
for (y = 0; y < bh; y++) {
for (x = 0; x < bw; x++) {
if (mi_col + x < cm->mi_cols && mi_row + y < cm->mi_rows) {
mi[mis * y + x].mbmi.txfm_size = sz;
}
}
}