Commit 68033ca4 authored by Paul Wilkins's avatar Paul Wilkins
Browse files

Snapshot candidate

Pulled out super block code for the snapshot as this
is not quite ready and will need an extensive re-merge.

Change-Id: I436369b511257447a7b0ea064016cb63f5011849
parent 157f15e1
......@@ -219,7 +219,6 @@ EXPERIMENT_LIST="
uvintra
compred
enhanced_interp
superblocks
featureupdates
high_precision_mv
sixteenth_subpel_uv
......
......@@ -988,81 +988,6 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
}
#if CONFIG_SUPERBLOCKS
void vp8_decode_mode_mvs(VP8D_COMP *pbi)
{
int i;
VP8_COMMON *cm = &pbi->common;
int sb_row, sb_col;
int sb_rows = (cm->mb_rows + 1)>>1;
int sb_cols = (cm->mb_cols + 1)>>1;
MODE_INFO *mi = cm->mi;
int row_delta[4] = {-1, 0, +1, 0};
int col_delta[4] = {+1, +1, -1, +1};
MODE_INFO *prev_mi = cm->prev_mi;
mb_mode_mv_init(pbi);
#if CONFIG_QIMODE
if(cm->frame_type==KEY_FRAME && !cm->kf_ymode_probs_update)
{
cm->kf_ymode_probs_index = vp8_read_literal(&pbi->bc, 3);
}
#endif
for (sb_row=0; sb_row<sb_rows; sb_row++)
{
int mb_col = -col_delta[0];
int mb_row = (sb_row <<1)-row_delta[0];
for (sb_col=0; sb_col<sb_cols; sb_col++)
{
for ( i=0; i<4; i++ )
{
int mb_to_top_edge;
int mb_to_bottom_edge;
int offset_extended = row_delta[(i+1) & 0x3]
* cm->mode_info_stride + col_delta[(i+1) & 0x3];
int dy = row_delta[i];
int dx = col_delta[i];
mb_row += dy;
mb_col += dx;
if ((mb_row >= cm->mb_rows) || (mb_col >= cm->mb_cols))
{
prev_mi += offset_extended;
mi += offset_extended; /* next macroblock */
continue;
}
pbi->mb.mb_to_top_edge =
mb_to_top_edge = -((mb_row * 16)) << 3;
mb_to_top_edge -= LEFT_TOP_MARGIN;
pbi->mb.mb_to_bottom_edge =
mb_to_bottom_edge = ((pbi->common.mb_rows - 1 - mb_row) * 16) << 3;
mb_to_bottom_edge += RIGHT_BOTTOM_MARGIN;
/*read_mb_modes_mv(pbi, cm->mode_info_context, &cm->mode_info_context->mbmi, mb_row, mb_col);*/
if(pbi->common.frame_type == KEY_FRAME)
vp8_kfread_modes(pbi, mi, mb_row, mb_col);
else
read_mb_modes_mv(pbi, mi, &mi->mbmi,
prev_mi,
mb_row, mb_col);
prev_mi += offset_extended;
mi += offset_extended; /* next macroblock */
}
}
mi += cm->mode_info_stride + (1 - (cm->mb_cols & 0x1));
}
}
#else
void vp8_decode_mode_mvs(VP8D_COMP *pbi)
{
MODE_INFO *mi = pbi->common.mi;
......@@ -1148,4 +1073,3 @@ void vp8_decode_mode_mvs(VP8D_COMP *pbi)
}
#endif /* CONFIG_SUPERBLOCKS */
......@@ -244,10 +244,10 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
{
RECON_INVOKE(&pbi->common.rtcd.recon,
build_intra_predictors_mby)(xd);
} else {
#if !CONFIG_SUPERBLOCKS
}
else
{
vp8_intra_prediction_down_copy(xd);
#endif
}
}
}
......@@ -448,135 +448,6 @@ static int get_delta_q(vp8_reader *bc, int prev, int *q_update)
FILE *vpxlog = 0;
#endif
#if CONFIG_SUPERBLOCKS
static void
decode_sb_row(VP8D_COMP *pbi, VP8_COMMON *pc, int mbrow, MACROBLOCKD *xd)
{
int i;
int recon_yoffset, recon_uvoffset;
int mb_row, mb_col;
int ref_fb_idx = pc->lst_fb_idx;
int dst_fb_idx = pc->new_fb_idx;
int recon_y_stride = pc->yv12_fb[ref_fb_idx].y_stride;
int recon_uv_stride = pc->yv12_fb[ref_fb_idx].uv_stride;
int sb_col;
int row_delta[4] = { 0, +1, 0, -1};
int col_delta[4] = {+1, -1, +1, +1};
int sb_cols = (pc->mb_cols + 1)>>1;
ENTROPY_CONTEXT_PLANES left_context[2];
vpx_memset(left_context, 0, sizeof(left_context));
mb_row = mbrow;
mb_col = 0;
for (sb_col=0; sb_col<sb_cols; sb_col++)
{
for ( i=0; i<4; i++ )
{
int dy = row_delta[i];
int dx = col_delta[i];
int offset_extended = dy * xd->mode_info_stride + dx;
if ((mb_row >= pc->mb_rows) || (mb_col >= pc->mb_cols))
{
// Skip on to the next MB
mb_row += dy;
mb_col += dx;
xd->mode_info_context += offset_extended;
continue;
}
// Copy in the appropriate left context
vpx_memcpy (&pc->left_context,
&left_context[(i>>1) & 0x1],
sizeof(ENTROPY_CONTEXT_PLANES));
// reset above block coeffs
xd->above_context = pc->above_context + mb_col;
/* Distance of Mb to the various image edges.
* These are specified to 8th pel as they are always compared to
* values that are in 1/8th pel units
*/
xd->mb_to_top_edge = -((mb_row * 16)) << 3;
xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
xd->mb_to_left_edge = -((mb_col * 16) << 3);
xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
xd->up_available = (mb_row != 0);
xd->left_available = (mb_col != 0);
update_blockd_bmi(xd);
recon_yoffset = (mb_row * recon_y_stride * 16) + (mb_col * 16);
recon_uvoffset = (mb_row * recon_uv_stride * 8) + (mb_col * 8);
xd->dst.y_buffer = pc->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
xd->dst.u_buffer = pc->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
xd->dst.v_buffer = pc->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
/* Select the appropriate reference frame for this MB */
if (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME)
ref_fb_idx = pc->lst_fb_idx;
else if (xd->mode_info_context->mbmi.ref_frame == GOLDEN_FRAME)
ref_fb_idx = pc->gld_fb_idx;
else
ref_fb_idx = pc->alt_fb_idx;
xd->pre.y_buffer = pc->yv12_fb[ref_fb_idx].y_buffer +recon_yoffset;
xd->pre.u_buffer = pc->yv12_fb[ref_fb_idx].u_buffer +recon_uvoffset;
xd->pre.v_buffer = pc->yv12_fb[ref_fb_idx].v_buffer +recon_uvoffset;
if (xd->mode_info_context->mbmi.second_ref_frame)
{
int second_ref_fb_idx;
/* Select the appropriate reference frame for this MB */
if (xd->mode_info_context->mbmi.second_ref_frame == LAST_FRAME)
second_ref_fb_idx = pc->lst_fb_idx;
else if (xd->mode_info_context->mbmi.second_ref_frame ==
GOLDEN_FRAME)
second_ref_fb_idx = pc->gld_fb_idx;
else
second_ref_fb_idx = pc->alt_fb_idx;
xd->second_pre.y_buffer =
pc->yv12_fb[second_ref_fb_idx].y_buffer + recon_yoffset;
xd->second_pre.u_buffer =
pc->yv12_fb[second_ref_fb_idx].u_buffer + recon_uvoffset;
xd->second_pre.v_buffer =
pc->yv12_fb[second_ref_fb_idx].v_buffer + recon_uvoffset;
}
if (xd->mode_info_context->mbmi.ref_frame != INTRA_FRAME)
{
/* propagate errors from reference frames */
xd->corrupted |= pc->yv12_fb[ref_fb_idx].corrupted;
}
decode_macroblock(pbi, xd, mb_row * pc->mb_cols + mb_col);
/* check if the boolean decoder has suffered an error */
xd->corrupted |= vp8dx_bool_error(xd->current_bc);
// Copy in the appropriate left context
vpx_memcpy (&left_context[(i>>1) & 0x1],
&pc->left_context,
sizeof(ENTROPY_CONTEXT_PLANES));
// skip to next MB
xd->mode_info_context += offset_extended;
mb_row += dy;
mb_col += dx;
}
}
/* skip prediction column */
xd->mode_info_context += 1 - (pc->mb_cols & 0x1) + xd->mode_info_stride;
}
#else
static void
decode_mb_row(VP8D_COMP *pbi, VP8_COMMON *pc, int mb_row, MACROBLOCKD *xd)
{
......@@ -674,7 +545,6 @@ decode_mb_row(VP8D_COMP *pbi, VP8_COMMON *pc, int mb_row, MACROBLOCKD *xd)
++xd->mode_info_context; /* skip prediction column */
}
#endif // CONFIG_SUPERBLOCKS
static unsigned int read_partition_size(const unsigned char *cx_size)
{
......@@ -1278,19 +1148,11 @@ int vp8_decode_frame(VP8D_COMP *pbi)
// Resset the macroblock mode info context to the start of the list
xd->mode_info_context = pc->mi;
#if CONFIG_SUPERBLOCKS
/* Decode a row of super-blocks */
for (mb_row = 0; mb_row < pc->mb_rows; mb_row+=2)
{
decode_sb_row(pbi, pc, mb_row, xd);
}
#else
/* Decode a row of macro blocks */
for (mb_row = 0; mb_row < pc->mb_rows; mb_row++)
{
decode_mb_row(pbi, pc, mb_row, xd);
}
#endif /* CONFIG_SUPERBLOCKS */
corrupt_tokens |= xd->corrupted;
/* Collect information about decoder corruption. */
......
......@@ -561,397 +561,6 @@ static void update_ref_probs( VP8_COMP *const cpi )
compute_mod_refprobs( cm );
}
#if CONFIG_SUPERBLOCKS
static void pack_inter_mode_mvs(VP8_COMP *const cpi)
{
VP8_COMMON *const pc = & cpi->common;
vp8_writer *const w = & cpi->bc;
const MV_CONTEXT *mvc = pc->fc.mvc;
#if CONFIG_HIGH_PRECISION_MV
const MV_CONTEXT_HP *mvc_hp = pc->fc.mvc_hp;
#endif
MACROBLOCKD *xd = &cpi->mb.e_mbd;
int i;
int pred_context;
MODE_INFO *m = pc->mi;
MODE_INFO *prev_m = pc->prev_mi;
const int mis = pc->mode_info_stride;
int mb_row, mb_col;
int row, col;
int prob_skip_false = 0;
// Values used in prediction model coding
vp8_prob pred_prob;
unsigned char prediction_flag;
int row_delta[4] = { 0, +1, 0, -1};
int col_delta[4] = {+1, -1, +1, +1};
cpi->mb.partition_info = cpi->mb.pi;
// Update the probabilities used to encode reference frame data
update_ref_probs( cpi );
#ifdef ENTROPY_STATS
active_section = 1;
#endif
if (pc->mb_no_coeff_skip)
{
// Divide by 0 check. 0 case possible with segment features
if ( (cpi->skip_false_count + cpi->skip_true_count) )
{
prob_skip_false = cpi->skip_false_count * 256 /
(cpi->skip_false_count + cpi->skip_true_count);
if (prob_skip_false <= 1)
prob_skip_false = 1;
if (prob_skip_false > 255)
prob_skip_false = 255;
}
else
prob_skip_false = 255;
cpi->prob_skip_false = prob_skip_false;
vp8_write_literal(w, prob_skip_false, 8);
}
vp8_write_literal(w, pc->prob_intra_coded, 8);
vp8_write_literal(w, pc->prob_last_coded, 8);
vp8_write_literal(w, pc->prob_gf_coded, 8);
if (cpi->common.comp_pred_mode == HYBRID_PREDICTION)
{
vp8_write(w, 1, 128);
vp8_write(w, 1, 128);
for (i = 0; i < COMP_PRED_CONTEXTS; i++)
{
if (cpi->single_pred_count[i] + cpi->comp_pred_count[i])
{
pc->prob_comppred[i] = cpi->single_pred_count[i] * 255 /
(cpi->single_pred_count[i] + cpi->comp_pred_count[i]);
if (pc->prob_comppred[i] < 1)
pc->prob_comppred[i] = 1;
}
else
{
pc->prob_comppred[i] = 128;
}
vp8_write_literal(w, pc->prob_comppred[i], 8);
}
}
else if (cpi->common.comp_pred_mode == SINGLE_PREDICTION_ONLY)
{
vp8_write(w, 0, 128);
}
else /* compound prediction only */
{
vp8_write(w, 1, 128);
vp8_write(w, 0, 128);
}
update_mbintra_mode_probs(cpi);
#if CONFIG_HIGH_PRECISION_MV
if (xd->allow_high_precision_mv)
vp8_write_mvprobs_hp(cpi);
else
#endif
vp8_write_mvprobs(cpi);
mb_row = 0;
for (row=0; row < pc->mb_rows; row += 2)
{
m = pc->mi + row * mis;
mb_col = 0;
for (col=0; col < pc->mb_cols; col += 2)
{
int i;
for (i=0; i<4; i++)
{
const MB_MODE_INFO *const mi = & m->mbmi;
const MV_REFERENCE_FRAME rf = mi->ref_frame;
const MB_PREDICTION_MODE mode = mi->mode;
const int segment_id = mi->segment_id;
int dy = row_delta[i];
int dx = col_delta[i];
int offset_extended = dy * mis + dx;
if ((mb_row >= pc->mb_rows) || (mb_col >= pc->mb_cols))
{
mb_row += dy;
mb_col += dx;
m += offset_extended;
cpi->mb.partition_info += offset_extended;
continue;
}
// Distance of Mb to the various image edges.
// These specified to 8th pel as they are always compared to MV
// values that are in 1/8th pel units
xd->mb_to_left_edge = -((mb_col * 16) << 3);
xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
xd->mb_to_top_edge = -((mb_row * 16)) << 3;
xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
// Make sure the MacroBlockD mode info pointer is set correctly
xd->mode_info_context = m;
xd->prev_mode_info_context = prev_m;
#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)
{
prediction_flag =
get_pred_flag( xd, PRED_SEG_ID );
pred_prob =
get_pred_prob( pc, xd, PRED_SEG_ID);
// Code the segment id prediction flag for this mb
vp8_write( w, prediction_flag, pred_prob );
// If the mbs segment id was not predicted code explicitly
if (!prediction_flag)
write_mb_segid(w, mi, &cpi->mb.e_mbd);
}
else
{
// Normal undpredicted coding
write_mb_segid(w, mi, &cpi->mb.e_mbd);
}
}
if ( pc->mb_no_coeff_skip &&
( !segfeature_active( xd, segment_id, SEG_LVL_EOB ) ||
( get_segdata( xd, segment_id, SEG_LVL_EOB ) != 0 ) ) )
{
vp8_encode_bool(w, mi->mb_skip_coeff, prob_skip_false);
}
// Encode the reference frame.
encode_ref_frame( w, pc, xd,
segment_id, rf );
if (rf == INTRA_FRAME)
{
#ifdef ENTROPY_STATS
active_section = 6;
#endif
if ( !segfeature_active( xd, segment_id, SEG_LVL_MODE ) )
write_ymode(w, mode, pc->fc.ymode_prob);
if (mode == B_PRED)
{
int j = 0, uses_second = m->bmi[0].as_mode.second != (B_PREDICTION_MODE);
vp8_write(w, uses_second, 128);
do {
#if CONFIG_COMP_INTRA_PRED
int mode2 = m->bmi[j].as_mode.second;
#endif
write_bmode(w, m->bmi[j].as_mode.first, pc->fc.bmode_prob);
#if CONFIG_COMP_INTRA_PRED
if (uses_second)
{
write_bmode(w, mode2, pc->fc.bmode_prob);
}
#endif
} while (++j < 16);
}
if(mode == I8X8_PRED)
{
write_i8x8_mode(w, m->bmi[0].as_mode.first, pc->i8x8_mode_prob);
write_i8x8_mode(w, m->bmi[2].as_mode.first, pc->i8x8_mode_prob);
write_i8x8_mode(w, m->bmi[8].as_mode.first, pc->i8x8_mode_prob);
write_i8x8_mode(w, m->bmi[10].as_mode.first, pc->i8x8_mode_prob);
}
else
{
#if CONFIG_UVINTRA
write_uv_mode(w, mi->uv_mode, pc->fc.uv_mode_prob[mode]);
#ifdef MODE_STATS
if(mode!=B_PRED)
++cpi->y_uv_mode_count[mode][mi->uv_mode];
#endif
#else
write_uv_mode(w, mi->uv_mode, pc->fc.uv_mode_prob);
#endif /*CONFIG_UVINTRA*/
}
}
else
{
int_mv best_mv;
vp8_prob mv_ref_p [VP8_MVREFS-1];
{
int_mv n1, n2;
int ct[4];
vp8_find_near_mvs(xd, m,
prev_m,
&n1, &n2, &best_mv, ct, rf,
cpi->common.ref_frame_sign_bias);
vp8_mv_ref_probs(&cpi->common, mv_ref_p, ct);
#ifdef ENTROPY_STATS
accum_mv_refs(mode, ct);
#endif
}
#ifdef ENTROPY_STATS
active_section = 3;
#endif
// Is the segment coding of mode enabled
if ( !segfeature_active( xd, segment_id, SEG_LVL_MODE ) )
{
write_mv_ref(w, mode, mv_ref_p);
vp8_accum_mv_refs(&cpi->common, mode, ct);
}
{
switch (mode) /* new, split require MVs */
{
case NEWMV:
#ifdef ENTROPY_STATS
active_section = 5;
#endif
#if CONFIG_HIGH_PRECISION_MV
if (xd->allow_high_precision_mv)
write_mv_hp(w, &mi->mv.as_mv, &best_mv, mvc_hp);
else
#endif
write_mv(w, &mi->mv.as_mv, &best_mv, mvc);
if (cpi->common.comp_pred_mode == HYBRID_PREDICTION)
{
vp8_write(w,
mi->second_ref_frame != INTRA_FRAME,
get_pred_prob( pc, xd, PRED_COMP ) );
}
if (mi->second_ref_frame)
{
const int second_rf = mi->second_ref_frame;
int_mv n1, n2;
int ct[4];
vp8_find_near_mvs(xd, m,
prev_m,
&n1, &n2, &best_mv,
ct, second_rf,
cpi->common.ref_frame_sign_bias);
#if CONFIG_HIGH_PRECISION_MV
if (xd->allow_high_precision_mv)
write_mv_hp(w, &mi->second_mv.as_mv,
&best_mv, mvc_hp);
else
#endif
write_mv(w, &mi->second_mv.as_mv, &best_mv,
mvc);
}
break;
case SPLITMV:
{
int j = 0;
#ifdef MODE_STATS
++count_mb_seg [mi->partitioning];
#endif
write_split(w, mi->partitioning);
do
{
B_PREDICTION_MODE blockmode;
int_mv blockmv;
const int *const L = vp8_mbsplits [mi->partitioning];
int k = -1; /* first block in subset j */
int mv_contz;
int_mv leftmv, abovemv;
blockmode = cpi->mb.partition_info->bmi[j].mode;
blockmv = cpi->mb.partition_info->bmi[j].mv;
#if CONFIG_DEBUG
while (j != L[++k])
if (k >= 16)