Commit fe6eff7c authored by Paul Wilkins's avatar Paul Wilkins Committed by Gerrit Code Review
Browse files

Merge "Fix superblock experiment." into experimental

parents 412c5983 7944b4f2
......@@ -219,14 +219,22 @@ unsigned char vp9_get_pred_flag(const MACROBLOCKD *const xd,
void vp9_set_pred_flag(MACROBLOCKD *const xd,
PRED_ID pred_id,
unsigned char pred_flag) {
#if CONFIG_SUPERBLOCKS
const int mis = xd->mode_info_stride;
#endif
switch (pred_id) {
case PRED_SEG_ID:
xd->mode_info_context->mbmi.seg_id_predicted = pred_flag;
#if CONFIG_SUPERBLOCKS
if (xd->mode_info_context->mbmi.encoded_as_sb) {
xd->mode_info_context[1].mbmi.seg_id_predicted = pred_flag;
xd->mode_info_context[xd->mode_info_stride].mbmi.seg_id_predicted = pred_flag;
xd->mode_info_context[xd->mode_info_stride+1].mbmi.seg_id_predicted = pred_flag;
if (xd->mb_to_right_edge > 0)
xd->mode_info_context[1].mbmi.seg_id_predicted = pred_flag;
if (xd->mb_to_bottom_edge > 0) {
xd->mode_info_context[mis].mbmi.seg_id_predicted = pred_flag;
if (xd->mb_to_right_edge > 0)
xd->mode_info_context[mis + 1].mbmi.seg_id_predicted = pred_flag;
}
}
#endif
break;
......@@ -235,15 +243,30 @@ void vp9_set_pred_flag(MACROBLOCKD *const xd,
xd->mode_info_context->mbmi.ref_predicted = pred_flag;
#if CONFIG_SUPERBLOCKS
if (xd->mode_info_context->mbmi.encoded_as_sb) {
xd->mode_info_context[1].mbmi.ref_predicted = pred_flag;
xd->mode_info_context[xd->mode_info_stride].mbmi.ref_predicted = pred_flag;
xd->mode_info_context[xd->mode_info_stride+1].mbmi.ref_predicted = pred_flag;
if (xd->mb_to_right_edge > 0)
xd->mode_info_context[1].mbmi.ref_predicted = pred_flag;
if (xd->mb_to_bottom_edge > 0) {
xd->mode_info_context[mis].mbmi.ref_predicted = pred_flag;
if (xd->mb_to_right_edge > 0)
xd->mode_info_context[mis + 1].mbmi.ref_predicted = pred_flag;
}
}
#endif
break;
case PRED_MBSKIP:
xd->mode_info_context->mbmi.mb_skip_coeff = pred_flag;
#if CONFIG_SUPERBLOCKS
if (xd->mode_info_context->mbmi.encoded_as_sb) {
if (xd->mb_to_right_edge > 0)
xd->mode_info_context[1].mbmi.mb_skip_coeff = pred_flag;
if (xd->mb_to_bottom_edge > 0) {
xd->mode_info_context[mis].mbmi.mb_skip_coeff = pred_flag;
if (xd->mb_to_right_edge > 0)
xd->mode_info_context[mis + 1].mbmi.mb_skip_coeff = pred_flag;
}
}
#endif
break;
default:
......@@ -257,10 +280,29 @@ void vp9_set_pred_flag(MACROBLOCKD *const xd,
// peredict various bitstream signals.
// Macroblock segment id prediction function
unsigned char vp9_get_pred_mb_segid(const VP8_COMMON *const cm, int MbIndex) {
unsigned char vp9_get_pred_mb_segid(const VP8_COMMON *const cm,
const MACROBLOCKD *const xd, int MbIndex) {
// Currently the prediction for the macroblock segment ID is
// the value stored for this macroblock in the previous frame.
return cm->last_frame_seg_map[MbIndex];
#if CONFIG_SUPERBLOCKS
if (!xd->mode_info_context->mbmi.encoded_as_sb) {
#endif
return cm->last_frame_seg_map[MbIndex];
#if CONFIG_SUPERBLOCKS
} else {
int seg_id = cm->last_frame_seg_map[MbIndex];
int mb_col = MbIndex % cm->mb_cols;
int mb_row = MbIndex / cm->mb_cols;
if (mb_col + 1 < cm->mb_cols)
seg_id = seg_id && cm->last_frame_seg_map[MbIndex + 1];
if (mb_row + 1 < cm->mb_rows) {
seg_id = seg_id && cm->last_frame_seg_map[MbIndex + cm->mb_cols];
if (mb_col + 1 < cm->mb_cols)
seg_id = seg_id && cm->last_frame_seg_map[MbIndex + cm->mb_cols + 1];
}
return seg_id;
}
#endif
}
MV_REFERENCE_FRAME vp9_get_pred_ref(const VP8_COMMON *const cm,
......
......@@ -46,6 +46,7 @@ extern void vp9_set_pred_flag(MACROBLOCKD *const xd,
extern unsigned char vp9_get_pred_mb_segid(const VP8_COMMON *const cm,
const MACROBLOCKD *const xd,
int MbIndex);
extern MV_REFERENCE_FRAME vp9_get_pred_ref(const VP8_COMMON *const cm,
......
......@@ -188,6 +188,11 @@ static void kfread_modes(VP8D_COMP *pbi,
m->mbmi.second_uv_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
#endif
#if CONFIG_SUPERBLOCKS
if (m->mbmi.encoded_as_sb)
m->mbmi.txfm_size = TX_8X8;
else
#endif
if (cm->txfm_mode == TX_MODE_SELECT && m->mbmi.mb_skip_coeff == 0 &&
m->mbmi.mode <= I8X8_PRED) {
// FIXME(rbultje) code ternary symbol once all experiments are merged
......@@ -589,7 +594,7 @@ static void read_mb_segment_id(VP8D_COMP *pbi,
// If the value is flagged as correctly predicted
// then use the predicted value
if (seg_pred_flag) {
mbmi->segment_id = vp9_get_pred_mb_segid(cm, index);
mbmi->segment_id = vp9_get_pred_mb_segid(cm, xd, index);
}
// Else .... decode it explicitly
else {
......@@ -602,10 +607,14 @@ static void read_mb_segment_id(VP8D_COMP *pbi,
}
#if CONFIG_SUPERBLOCKS
if (mbmi->encoded_as_sb) {
cm->last_frame_seg_map[index] =
cm->last_frame_seg_map[index + 1] =
cm->last_frame_seg_map[index + cm->mb_cols] =
cm->last_frame_seg_map[index + cm->mb_cols + 1] = mbmi->segment_id;
cm->last_frame_seg_map[index] = mbmi->segment_id;
if (mb_col + 1 < cm->mb_cols)
cm->last_frame_seg_map[index + 1] = mbmi->segment_id;
if (mb_row + 1 < cm->mb_rows) {
cm->last_frame_seg_map[index + cm->mb_cols] = mbmi->segment_id;
if (mb_col + 1 < cm->mb_cols)
cm->last_frame_seg_map[index + cm->mb_cols + 1] = mbmi->segment_id;
}
} else
#endif
{
......@@ -614,11 +623,17 @@ static void read_mb_segment_id(VP8D_COMP *pbi,
} else {
#if CONFIG_SUPERBLOCKS
if (mbmi->encoded_as_sb) {
mbmi->segment_id =
cm->last_frame_seg_map[index] &&
cm->last_frame_seg_map[index + 1] &&
cm->last_frame_seg_map[index + cm->mb_cols] &&
cm->last_frame_seg_map[index + cm->mb_cols + 1];
mbmi->segment_id = cm->last_frame_seg_map[index];
if (mb_col < cm->mb_cols - 1)
mbmi->segment_id = mbmi->segment_id &&
cm->last_frame_seg_map[index + 1];
if (mb_row < cm->mb_rows - 1) {
mbmi->segment_id = mbmi->segment_id &&
cm->last_frame_seg_map[index + cm->mb_cols];
if (mb_col < cm->mb_cols - 1)
mbmi->segment_id = mbmi->segment_id &&
cm->last_frame_seg_map[index + cm->mb_cols + 1];
}
} else
#endif
{
......@@ -1131,6 +1146,11 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
#endif
}
#if CONFIG_SUPERBLOCKS
if (mbmi->encoded_as_sb)
mbmi->txfm_size = TX_8X8;
else
#endif
if (cm->txfm_mode == TX_MODE_SELECT && mbmi->mb_skip_coeff == 0 &&
((mbmi->ref_frame == INTRA_FRAME && mbmi->mode <= I8X8_PRED) ||
(mbmi->ref_frame != INTRA_FRAME && !(mbmi->mode == SPLITMV &&
......
......@@ -202,7 +202,7 @@ static void skip_recon_mb(VP8D_COMP *pbi, MACROBLOCKD *xd) {
}
static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
unsigned int mb_col,
int mb_row, unsigned int mb_col,
BOOL_DECODER* const bc) {
int eobtotal = 0;
MB_PREDICTION_MODE mode;
......@@ -218,24 +218,23 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
if (xd->segmentation_enabled)
mb_init_dequantizer(pbi, xd);
#if CONFIG_SUPERBLOCKS
if (xd->mode_info_context->mbmi.encoded_as_sb) {
xd->mode_info_context->mbmi.txfm_size = TX_8X8;
}
#endif
tx_size = xd->mode_info_context->mbmi.txfm_size;
mode = xd->mode_info_context->mbmi.mode;
if (xd->mode_info_context->mbmi.mb_skip_coeff) {
vp8_reset_mb_tokens_context(xd);
#if CONFIG_SUPERBLOCKS
if (xd->mode_info_context->mbmi.encoded_as_sb) {
xd->above_context++;
xd->left_context++;
if (xd->mode_info_context->mbmi.encoded_as_sb &&
(mb_col < pc->mb_cols - 1 || mb_row < pc->mb_rows - 1)) {
if (mb_col < pc->mb_cols - 1)
xd->above_context++;
if (mb_row < pc->mb_rows - 1)
xd->left_context++;
vp8_reset_mb_tokens_context(xd);
xd->above_context--;
xd->left_context--;
if (mb_col < pc->mb_cols - 1)
xd->above_context--;
if (mb_row < pc->mb_rows - 1)
xd->left_context--;
}
#endif
} else if (!vp8dx_bool_error(bc)) {
......@@ -411,6 +410,11 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
void *orig = xd->mode_info_context;
int n, num = xd->mode_info_context->mbmi.encoded_as_sb ? 4 : 1;
for (n = 0; n < num; n++) {
int x_idx = n & 1, y_idx = n >> 1;
if (num == 4 && (mb_col + x_idx >= pc->mb_cols ||
mb_row + y_idx >= pc->mb_rows))
continue;
if (n != 0) {
for (i = 0; i < 25; i++) {
xd->block[i].eob = 0;
......@@ -653,20 +657,17 @@ decode_sb_row(VP8D_COMP *pbi, VP8_COMMON *pc, int mbrow, MACROBLOCKD *xd,
#if CONFIG_SUPERBLOCKS
if (xd->mode_info_context->mbmi.encoded_as_sb) {
mi[1] = mi[0];
mi[pc->mode_info_stride] = mi[0];
mi[pc->mode_info_stride + 1] = mi[0];
if (mb_col < pc->mb_cols - 1)
mi[1] = mi[0];
if (mb_row < pc->mb_rows - 1) {
mi[pc->mode_info_stride] = mi[0];
if (mb_col < pc->mb_cols - 1)
mi[pc->mode_info_stride + 1] = mi[0];
}
}
#endif
vp8_intra_prediction_down_copy(xd);
decode_macroblock(pbi, xd, mb_col, bc);
#if CONFIG_SUPERBLOCKS
if (xd->mode_info_context->mbmi.encoded_as_sb) {
mi[1].mbmi.txfm_size = mi[0].mbmi.txfm_size;
mi[pc->mode_info_stride].mbmi.txfm_size = mi[0].mbmi.txfm_size;
mi[pc->mode_info_stride + 1].mbmi.txfm_size = mi[0].mbmi.txfm_size;
}
#endif
decode_macroblock(pbi, xd, mb_row, mb_col, bc);
/* check if the boolean decoder has suffered an error */
xd->corrupted |= vp8dx_bool_error(bc);
......
......@@ -744,8 +744,22 @@ static unsigned int pick_best_mv_ref(MACROBLOCK *x,
static void write_mb_segid(vp8_writer *bc,
const MB_MODE_INFO *mi, const MACROBLOCKD *xd) {
// Encode the MB segment id.
int seg_id = mi->segment_id;
#if CONFIG_SUPERBLOCKS
if (mi->encoded_as_sb) {
if (xd->mb_to_right_edge > 0)
seg_id = seg_id && xd->mode_info_context[1].mbmi.segment_id;
if (xd->mb_to_bottom_edge > 0) {
seg_id = seg_id &&
xd->mode_info_context[xd->mode_info_stride].mbmi.segment_id;
if (xd->mb_to_right_edge > 0)
seg_id = seg_id &&
xd->mode_info_context[xd->mode_info_stride + 1].mbmi.segment_id;
}
}
#endif
if (xd->segmentation_enabled && xd->update_mb_segmentation_map) {
switch (mi->segment_id) {
switch (seg_id) {
case 0:
vp8_write(bc, 0, xd->mb_segment_tree_probs[0]);
vp8_write(bc, 0, xd->mb_segment_tree_probs[1]);
......@@ -952,7 +966,6 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi, vp8_writer *const bc) {
#ifdef ENTROPY_STATS
active_section = 9;
#endif
if (cpi->mb.e_mbd.update_mb_segmentation_map) {
// Is temporal coding of the segment map enabled
if (pc->temporal_update) {
......@@ -1245,7 +1258,11 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi, vp8_writer *const bc) {
}
}
if (((rf == INTRA_FRAME && mode <= I8X8_PRED) ||
if (
#if CONFIG_SUPERBLOCKS
!mi->encoded_as_sb &&
#endif
((rf == INTRA_FRAME && mode <= I8X8_PRED) ||
(rf != INTRA_FRAME && !(mode == SPLITMV &&
mi->partitioning == PARTITIONING_4X4))) &&
pc->txfm_mode == TX_MODE_SELECT &&
......@@ -1386,7 +1403,11 @@ static void write_mb_modes_kf(const VP8_COMMON *c,
} else
write_uv_mode(bc, m->mbmi.uv_mode, c->kf_uv_mode_prob[ym]);
if (ym <= I8X8_PRED && c->txfm_mode == TX_MODE_SELECT &&
if (
#if CONFIG_SUPERBLOCKS
!m->mbmi.encoded_as_sb &&
#endif
ym <= I8X8_PRED && c->txfm_mode == TX_MODE_SELECT &&
!((c->mb_no_coeff_skip && m->mbmi.mb_skip_coeff) ||
(segfeature_active(xd, segment_id, SEG_LVL_EOB) &&
get_segdata(xd, segment_id, SEG_LVL_EOB) == 0))) {
......
......@@ -389,9 +389,14 @@ static void update_state(VP8_COMP *cpi, MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
vpx_memcpy(xd->mode_info_context, mi, sizeof(MODE_INFO));
#if CONFIG_SUPERBLOCKS
if (mi->mbmi.encoded_as_sb) {
vpx_memcpy(xd->mode_info_context + 1, mi, sizeof(MODE_INFO));
vpx_memcpy(xd->mode_info_context + cpi->common.mode_info_stride, mi, sizeof(MODE_INFO));
vpx_memcpy(xd->mode_info_context + cpi->common.mode_info_stride + 1, mi, sizeof(MODE_INFO));
const int mis = cpi->common.mode_info_stride;
if (xd->mb_to_right_edge > 0)
vpx_memcpy(xd->mode_info_context + 1, mi, sizeof(MODE_INFO));
if (xd->mb_to_bottom_edge > 0) {
vpx_memcpy(xd->mode_info_context + mis, mi, sizeof(MODE_INFO));
if (xd->mb_to_right_edge > 0)
vpx_memcpy(xd->mode_info_context + mis + 1, mi, sizeof(MODE_INFO));
}
}
#endif
......@@ -1442,25 +1447,47 @@ static int check_dual_ref_flags(VP8_COMP *cpi) {
static void reset_skip_txfm_size(VP8_COMP *cpi, TX_SIZE txfm_max) {
VP8_COMMON *cm = &cpi->common;
int mb_row, mb_col, mis = cm->mode_info_stride;
int mb_row, mb_col, mis = cm->mode_info_stride, segment_id;
MODE_INFO *mi, *mi_ptr = cm->mi;
#if CONFIG_SUPERBLOCKS
MODE_INFO *sb_mi_ptr = cm->mi, *sb_mi;
MB_MODE_INFO *sb_mbmi;
#endif
MB_MODE_INFO *mbmi;
MACROBLOCK *x = &cpi->mb;
MACROBLOCKD *xd = &x->e_mbd;
for (mb_row = 0; mb_row < cm->mb_rows; mb_row++, mi_ptr += mis) {
mi = mi_ptr;
#if CONFIG_SUPERBLOCKS
sb_mi = sb_mi_ptr;
#endif
for (mb_col = 0; mb_col < cm->mb_cols; mb_col++, mi++) {
mbmi = &mi->mbmi;
if (mbmi->txfm_size > txfm_max) {
int segment_id = mbmi->segment_id;
#if CONFIG_SUPERBLOCKS
sb_mbmi = &sb_mi->mbmi;
#endif
if (
#if CONFIG_SUPERBLOCKS
!sb_mbmi->encoded_as_sb &&
#endif
mbmi->txfm_size > txfm_max) {
segment_id = mbmi->segment_id;
xd->mode_info_context = mi;
assert((segfeature_active(xd, segment_id, SEG_LVL_EOB) &&
get_segdata(xd, segment_id, SEG_LVL_EOB) == 0) ||
(cm->mb_no_coeff_skip && mbmi->mb_skip_coeff));
mbmi->txfm_size = txfm_max;
}
#if CONFIG_SUPERBLOCKS
if (mb_col & 1)
sb_mi += 2;
#endif
}
#if CONFIG_SUPERBLOCKS
if (mb_row & 1)
sb_mi_ptr += 2 * mis;
#endif
}
}
......@@ -1854,8 +1881,7 @@ void vp8cx_encode_intra_super_block(VP8_COMP *cpi,
vp8_build_intra_predictors_sbuv_s(&x->e_mbd);
assert(x->e_mbd.mode_info_context->mbmi.txfm_size == TX_8X8);
for (n = 0; n < 4; n++)
{
for (n = 0; n < 4; n++) {
int x_idx = n & 1, y_idx = n >> 1;
xd->above_context = cm->above_context + mb_col + (n & 1);
......@@ -2249,8 +2275,7 @@ void vp8cx_encode_inter_superblock(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
}
assert(x->e_mbd.mode_info_context->mbmi.txfm_size == TX_8X8);
for (n = 0; n < 4; n++)
{
for (n = 0; n < 4; n++) {
int x_idx = n & 1, y_idx = n >> 1;
vp8_subtract_mby_s_c(x->src_diff,
......@@ -2281,7 +2306,7 @@ void vp8cx_encode_inter_superblock(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
if (!x->skip) {
if (output_enabled) {
xd->left_context = cm->left_context + (n >> 1);
xd->above_context = cm->above_context + mb_col + (n >> 1);
xd->above_context = cm->above_context + mb_col + (n & 1);
memcpy(&ta[n], xd->above_context, sizeof(ta[n]));
memcpy(&tl[n], xd->left_context, sizeof(tl[n]));
tp[n] = *t;
......@@ -2298,7 +2323,7 @@ void vp8cx_encode_inter_superblock(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
if (cpi->common.mb_no_coeff_skip) {
skip[n] = xd->mode_info_context->mbmi.mb_skip_coeff = 1;
xd->left_context = cm->left_context + (n >> 1);
xd->above_context = cm->above_context + mb_col + (n >> 1);
xd->above_context = cm->above_context + mb_col + (n & 1);
memcpy(&ta[n], xd->above_context, sizeof(ta[n]));
memcpy(&tl[n], xd->left_context, sizeof(tl[n]));
tp[n] = *t;
......
......@@ -629,8 +629,14 @@ static void update_reference_segmentation_map(VP8_COMP *cpi) {
uint8_t *cache = segcache + col * 2;
#if CONFIG_SUPERBLOCKS
if (miptr->mbmi.encoded_as_sb) {
cache[0] = cache[1] = cache[cm->mb_cols] = cache[cm->mb_cols + 1] =
miptr->mbmi.segment_id;
cache[0] = miptr->mbmi.segment_id;
if (!(cm->mb_cols & 1) || col < sb_cols - 1)
cache[1] = miptr->mbmi.segment_id;
if (!(cm->mb_rows & 1) || row < sb_rows - 1) {
cache[cm->mb_cols] = miptr->mbmi.segment_id;
if (!(cm->mb_cols & 1) || col < sb_cols - 1)
cache[cm->mb_cols + 1] = miptr->mbmi.segment_id;
}
} else
#endif
{
......
......@@ -353,7 +353,7 @@ typedef struct VP8_ENCODER_RTCD {
vp8_temporal_rtcd_vtable_t temporal;
} VP8_ENCODER_RTCD;
enum {
enum BlockSize {
BLOCK_16X8 = PARTITIONING_16X8,
BLOCK_8X16 = PARTITIONING_8X16,
BLOCK_8X8 = PARTITIONING_8X8,
......
This diff is collapsed.
......@@ -32,7 +32,6 @@ extern void vp8_mv_pred
int *sr,
int near_sadidx[]
);
extern void vp8_cal_sad(VP8_COMP *cpi, MACROBLOCKD *xd, MACROBLOCK *x, int recon_yoffset, int near_sadidx[]);
extern void vp8_init_me_luts();
extern void vp8_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv);
#endif
......@@ -164,6 +164,7 @@ void choose_segmap_coding_method(VP8_COMP *cpi) {
VP8_COMMON *const cm = &cpi->common;
MACROBLOCKD *const xd = &cpi->mb.e_mbd;
const int mis = cm->mode_info_stride;
int i;
int tot_count;
int no_pred_cost;
......@@ -212,8 +213,27 @@ void choose_segmap_coding_method(VP8_COMP *cpi) {
goto end;
}
xd->mb_to_top_edge = -((mb_row * 16) << 3);
xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3;
xd->mb_to_left_edge = -((mb_col * 16) << 3);
xd->mb_to_right_edge = ((cm->mb_cols - 1 - mb_row) * 16) << 3;
segmap_index = (mb_row + y_idx) * cm->mb_cols + mb_col + x_idx;
segment_id = xd->mode_info_context->mbmi.segment_id;
#if CONFIG_SUPERBLOCKS
if (xd->mode_info_context->mbmi.encoded_as_sb) {
if (mb_col + 1 < cm->mb_cols)
segment_id = segment_id &&
xd->mode_info_context[1].mbmi.segment_id;
if (mb_row + 1 < cm->mb_rows) {
segment_id = segment_id &&
xd->mode_info_context[mis].mbmi.segment_id;
if (mb_col + 1 < cm->mb_cols)
segment_id = segment_id &&
xd->mode_info_context[mis + 1].mbmi.segment_id;
}
}
#endif
// Count the number of hits on each segment with no prediction
no_pred_segcounts[segment_id]++;
......@@ -222,7 +242,7 @@ void choose_segmap_coding_method(VP8_COMP *cpi) {
if (cm->frame_type != KEY_FRAME) {
// Test to see if the segment id matches the predicted value.
int seg_predicted =
(segment_id == vp9_get_pred_mb_segid(cm, segmap_index));
(segment_id == vp9_get_pred_mb_segid(cm, xd, segmap_index));
// Get the segment id prediction context
pred_context =
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment