Segment coding of mode and reference frame.
Proof of concept test code that encodes mode and reference frame data at the segment level. Decode-able bit stream but some issues not yet resolved. As it this helps a little on a couple of clips but hurts on most as the basis for segmentation is unsound. To build and test, configure with --enable-experimental --enable-segfeatures Change-Id: I22a60774f69273523fb152db8c31f4b10b07c7f4
This commit is contained in:
parent
45e49e6e19
commit
156b221a7f
@ -200,6 +200,43 @@ static void read_mvcontexts(vp8_reader *bc, MV_CONTEXT *mvc)
|
||||
while (++i < 2);
|
||||
}
|
||||
|
||||
// Read the referncence frame
|
||||
static MV_REFERENCE_FRAME read_ref_frame( VP8D_COMP *pbi,
|
||||
unsigned char segment_id )
|
||||
{
|
||||
MV_REFERENCE_FRAME ref_frame;
|
||||
|
||||
#if CONFIG_SEGFEATURES
|
||||
MACROBLOCKD *const xd = &pbi->mb;
|
||||
|
||||
// Is the segment level refernce frame feature enabled for this segment
|
||||
if ( xd->segment_feature_mask[segment_id] & (0x01 << SEG_LVL_REF_FRAME) )
|
||||
{
|
||||
ref_frame =
|
||||
xd->segment_feature_data[segment_id][SEG_LVL_REF_FRAME];
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
// Per MB read of the reference frame
|
||||
{
|
||||
vp8_reader *const bc = &pbi->bc;
|
||||
|
||||
ref_frame =
|
||||
(MV_REFERENCE_FRAME) vp8_read(bc, pbi->prob_intra);
|
||||
|
||||
if (ref_frame)
|
||||
{
|
||||
if (vp8_read(bc, pbi->prob_last))
|
||||
{
|
||||
ref_frame = (MV_REFERENCE_FRAME)((int)ref_frame +
|
||||
(int)(1 + vp8_read(bc, pbi->prob_gf)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (MV_REFERENCE_FRAME)ref_frame;
|
||||
}
|
||||
|
||||
static MB_PREDICTION_MODE read_mv_ref(vp8_reader *bc, const vp8_prob *p)
|
||||
{
|
||||
@ -296,8 +333,9 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
|
||||
vp8_reader *const bc = & pbi->bc;
|
||||
MV_CONTEXT *const mvc = pbi->common.fc.mvc;
|
||||
const int mis = pbi->common.mode_info_stride;
|
||||
#if CONFIG_SEGMENTATION
|
||||
MACROBLOCKD *const xd = & pbi->mb;
|
||||
|
||||
#if CONFIG_SEGMENTATION
|
||||
int sum;
|
||||
int index = mb_row * pbi->common.mb_cols + mb_col;
|
||||
#endif
|
||||
@ -307,24 +345,24 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
|
||||
int mb_to_top_edge;
|
||||
int mb_to_bottom_edge;
|
||||
|
||||
mb_to_top_edge = pbi->mb.mb_to_top_edge;
|
||||
mb_to_bottom_edge = pbi->mb.mb_to_bottom_edge;
|
||||
mb_to_top_edge = xd->mb_to_top_edge;
|
||||
mb_to_bottom_edge = xd->mb_to_bottom_edge;
|
||||
mb_to_top_edge -= LEFT_TOP_MARGIN;
|
||||
mb_to_bottom_edge += RIGHT_BOTTOM_MARGIN;
|
||||
mbmi->need_to_clamp_mvs = 0;
|
||||
/* 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
|
||||
*/
|
||||
pbi->mb.mb_to_left_edge =
|
||||
xd->mb_to_left_edge =
|
||||
mb_to_left_edge = -((mb_col * 16) << 3);
|
||||
mb_to_left_edge -= LEFT_TOP_MARGIN;
|
||||
|
||||
pbi->mb.mb_to_right_edge =
|
||||
xd->mb_to_right_edge =
|
||||
mb_to_right_edge = ((pbi->common.mb_cols - 1 - mb_col) * 16) << 3;
|
||||
mb_to_right_edge += RIGHT_BOTTOM_MARGIN;
|
||||
|
||||
/* If required read in new segmentation data for this MB */
|
||||
if (pbi->mb.update_mb_segmentation_map)
|
||||
if (xd->update_mb_segmentation_map)
|
||||
{
|
||||
#if CONFIG_SEGMENTATION
|
||||
if (xd->temporal_update)
|
||||
@ -343,7 +381,7 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
|
||||
}
|
||||
else
|
||||
{
|
||||
vp8_read_mb_features(bc, &mi->mbmi, &pbi->mb);
|
||||
vp8_read_mb_features(bc, &mi->mbmi, xd);
|
||||
mbmi->segment_flag = 1;
|
||||
pbi->segmentation_map[index] = mbmi->segment_id;
|
||||
}
|
||||
@ -351,12 +389,12 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
|
||||
}
|
||||
else
|
||||
{
|
||||
vp8_read_mb_features(bc, &mi->mbmi, &pbi->mb);
|
||||
vp8_read_mb_features(bc, &mi->mbmi, xd);
|
||||
pbi->segmentation_map[index] = mbmi->segment_id;
|
||||
}
|
||||
index++;
|
||||
#else
|
||||
vp8_read_mb_features(bc, &mi->mbmi, &pbi->mb);
|
||||
vp8_read_mb_features(bc, &mi->mbmi, xd);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -367,23 +405,38 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
|
||||
else
|
||||
mbmi->mb_skip_coeff = 0;
|
||||
|
||||
if ((mbmi->ref_frame = (MV_REFERENCE_FRAME) vp8_read(bc, pbi->prob_intra))) /* inter MB */
|
||||
// Read the reference frame
|
||||
mbmi->ref_frame = read_ref_frame( pbi, mbmi->segment_id );
|
||||
|
||||
// If reference frame is an Inter frame
|
||||
if (mbmi->ref_frame)
|
||||
{
|
||||
int rct[4];
|
||||
vp8_prob mv_ref_p [VP8_MVREFS-1];
|
||||
int_mv nearest, nearby, best_mv;
|
||||
vp8_prob mv_ref_p [VP8_MVREFS-1];
|
||||
|
||||
if (vp8_read(bc, pbi->prob_last))
|
||||
{
|
||||
mbmi->ref_frame = (MV_REFERENCE_FRAME)((int)mbmi->ref_frame + (int)(1 + vp8_read(bc, pbi->prob_gf)));
|
||||
}
|
||||
|
||||
vp8_find_near_mvs(&pbi->mb, mi, &nearest, &nearby, &best_mv, rct, mbmi->ref_frame, pbi->common.ref_frame_sign_bias);
|
||||
|
||||
vp8_find_near_mvs(xd, mi, &nearest, &nearby, &best_mv, rct,
|
||||
mbmi->ref_frame, pbi->common.ref_frame_sign_bias);
|
||||
vp8_mv_ref_probs(mv_ref_p, rct);
|
||||
|
||||
#if CONFIG_SEGFEATURES
|
||||
// Is the segment level mode feature enabled for this segment
|
||||
if ( xd->segment_feature_mask[mbmi->segment_id] &
|
||||
(0x01 << SEG_LVL_MODE) )
|
||||
{
|
||||
mbmi->mode =
|
||||
xd->segment_feature_data[mbmi->segment_id][SEG_LVL_MODE];
|
||||
}
|
||||
else
|
||||
{
|
||||
mbmi->mode = read_mv_ref(bc, mv_ref_p);
|
||||
}
|
||||
#else
|
||||
mbmi->mode = read_mv_ref(bc, mv_ref_p);
|
||||
#endif
|
||||
|
||||
mbmi->uv_mode = DC_PRED;
|
||||
switch (mbmi->mode = read_mv_ref(bc, mv_ref_p))
|
||||
switch (mbmi->mode)
|
||||
{
|
||||
case SPLITMV:
|
||||
{
|
||||
@ -530,6 +583,10 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
|
||||
}
|
||||
else
|
||||
{
|
||||
#if CONFIG_SEGFEATURES
|
||||
// TBD HANDLE INTRA MODE CASE
|
||||
#endif
|
||||
|
||||
/* required for left and above block mv */
|
||||
mbmi->mv.as_int = 0;
|
||||
|
||||
@ -554,6 +611,14 @@ void vp8_decode_mode_mvs(VP8D_COMP *pbi)
|
||||
MODE_INFO *mi = pbi->common.mi;
|
||||
int mb_row = -1;
|
||||
|
||||
#if CONFIG_SEGFEATURES
|
||||
#if 0
|
||||
FILE *statsfile;
|
||||
statsfile = fopen("decsegmap.stt", "a");
|
||||
fprintf(statsfile, "\n" );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
mb_mode_mv_init(pbi);
|
||||
|
||||
#if CONFIG_QIMODE
|
||||
@ -577,6 +642,12 @@ void vp8_decode_mode_mvs(VP8D_COMP *pbi)
|
||||
mb_to_bottom_edge = ((pbi->common.mb_rows - 1 - mb_row) * 16) << 3;
|
||||
mb_to_bottom_edge += RIGHT_BOTTOM_MARGIN;
|
||||
|
||||
#if CONFIG_SEGFEATURES
|
||||
#if 0
|
||||
fprintf(statsfile, "\n" );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
while (++mb_col < pbi->common.mb_cols)
|
||||
{
|
||||
#if CONFIG_ERROR_CONCEALMENT
|
||||
@ -617,9 +688,23 @@ void vp8_decode_mode_mvs(VP8D_COMP *pbi)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_SEGFEATURES
|
||||
#if 0
|
||||
fprintf(statsfile, "%2d%2d%2d ",
|
||||
mi->mbmi.segment_id, mi->mbmi.ref_frame, mi->mbmi.mode );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
mi++; /* next macroblock */
|
||||
}
|
||||
// printf("\n");
|
||||
mi++; /* skip left predictor each row */
|
||||
}
|
||||
|
||||
#if CONFIG_SEGFEATURES
|
||||
#if 0
|
||||
fclose(statsfile);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -896,7 +896,13 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
|
||||
cpi->mb.partition_info = cpi->mb.pi;
|
||||
|
||||
// Calculate the probabilities to be used to code the reference frame based on actual useage this frame
|
||||
if (!(cpi->prob_intra_coded = rf_intra * 255 / (rf_intra + rf_inter)))
|
||||
#if CONFIG_SEGFEATURES
|
||||
cpi->prob_intra_coded = (rf_intra + rf_inter)
|
||||
? rf_intra * 255 / (rf_intra + rf_inter) : 1;
|
||||
#else
|
||||
cpi->prob_intra_coded = rf_intra * 255 / (rf_intra + rf_inter);
|
||||
#endif
|
||||
if (!cpi->prob_intra_coded)
|
||||
cpi->prob_intra_coded = 1;
|
||||
|
||||
prob_last_coded = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
|
||||
@ -1010,7 +1016,15 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
|
||||
|
||||
if (rf == INTRA_FRAME)
|
||||
{
|
||||
vp8_write(w, 0, cpi->prob_intra_coded);
|
||||
#if CONFIG_SEGFEATURES
|
||||
// Is the segment coding of reference frame enabled
|
||||
if ( !( xd->segment_feature_mask[mi->segment_id] &
|
||||
(0x01 << SEG_LVL_REF_FRAME) ) )
|
||||
#endif
|
||||
{
|
||||
vp8_write(w, 0, cpi->prob_intra_coded);
|
||||
}
|
||||
|
||||
#ifdef ENTROPY_STATS
|
||||
active_section = 6;
|
||||
#endif
|
||||
@ -1032,14 +1046,22 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
|
||||
int_mv best_mv;
|
||||
vp8_prob mv_ref_p [VP8_MVREFS-1];
|
||||
|
||||
vp8_write(w, 1, cpi->prob_intra_coded);
|
||||
|
||||
if (rf == LAST_FRAME)
|
||||
vp8_write(w, 0, prob_last_coded);
|
||||
else
|
||||
#if CONFIG_SEGFEATURES
|
||||
// Is the segment coding of reference frame enabled
|
||||
if ( !( xd->segment_feature_mask[mi->segment_id] &
|
||||
(0x01 << SEG_LVL_REF_FRAME) ) )
|
||||
#endif
|
||||
{
|
||||
vp8_write(w, 1, prob_last_coded);
|
||||
vp8_write(w, (rf == GOLDEN_FRAME) ? 0 : 1, prob_gf_coded);
|
||||
vp8_write(w, 1, cpi->prob_intra_coded);
|
||||
|
||||
if (rf == LAST_FRAME)
|
||||
vp8_write(w, 0, prob_last_coded);
|
||||
else
|
||||
{
|
||||
vp8_write(w, 1, prob_last_coded);
|
||||
vp8_write(w, (rf == GOLDEN_FRAME)
|
||||
? 0 : 1, prob_gf_coded);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
@ -1052,73 +1074,79 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
|
||||
#ifdef ENTROPY_STATS
|
||||
accum_mv_refs(mode, ct);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#ifdef ENTROPY_STATS
|
||||
active_section = 3;
|
||||
#endif
|
||||
|
||||
write_mv_ref(w, mode, mv_ref_p);
|
||||
|
||||
switch (mode) /* new, split require MVs */
|
||||
{
|
||||
case NEWMV:
|
||||
|
||||
#ifdef ENTROPY_STATS
|
||||
active_section = 5;
|
||||
#if CONFIG_SEGFEATURES
|
||||
// Is the segment coding of reference frame enabled
|
||||
if ( !( xd->segment_feature_mask[mi->segment_id] &
|
||||
(0x01 << SEG_LVL_MODE) ) )
|
||||
#endif
|
||||
|
||||
write_mv(w, &mi->mv.as_mv, &best_mv, mvc);
|
||||
break;
|
||||
|
||||
case SPLITMV:
|
||||
{
|
||||
int j = 0;
|
||||
write_mv_ref(w, mode, mv_ref_p);
|
||||
|
||||
#ifdef MODE_STATS
|
||||
++count_mb_seg [mi->partitioning];
|
||||
#endif
|
||||
|
||||
write_split(w, mi->partitioning);
|
||||
|
||||
do
|
||||
switch (mode) /* new, split require MVs */
|
||||
{
|
||||
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;
|
||||
case NEWMV:
|
||||
|
||||
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)
|
||||
assert(0);
|
||||
#else
|
||||
while (j != L[++k]);
|
||||
#endif
|
||||
leftmv.as_int = left_block_mv(m, k);
|
||||
abovemv.as_int = above_block_mv(m, k, mis);
|
||||
mv_contz = vp8_mv_cont(&leftmv, &abovemv);
|
||||
#ifdef ENTROPY_STATS
|
||||
active_section = 5;
|
||||
#endif
|
||||
|
||||
write_sub_mv_ref(w, blockmode, vp8_sub_mv_ref_prob2 [mv_contz]);
|
||||
write_mv(w, &mi->mv.as_mv, &best_mv, mvc);
|
||||
break;
|
||||
|
||||
if (blockmode == NEW4X4)
|
||||
case SPLITMV:
|
||||
{
|
||||
int j = 0;
|
||||
|
||||
#ifdef MODE_STATS
|
||||
++count_mb_seg [mi->partitioning];
|
||||
#endif
|
||||
|
||||
write_split(w, mi->partitioning);
|
||||
|
||||
do
|
||||
{
|
||||
#ifdef ENTROPY_STATS
|
||||
active_section = 11;
|
||||
#endif
|
||||
write_mv(w, &blockmv.as_mv, &best_mv, (const MV_CONTEXT *) mvc);
|
||||
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)
|
||||
assert(0);
|
||||
#else
|
||||
while (j != L[++k]);
|
||||
#endif
|
||||
leftmv.as_int = left_block_mv(m, k);
|
||||
abovemv.as_int = above_block_mv(m, k, mis);
|
||||
mv_contz = vp8_mv_cont(&leftmv, &abovemv);
|
||||
|
||||
write_sub_mv_ref(w, blockmode, vp8_sub_mv_ref_prob2 [mv_contz]);
|
||||
|
||||
if (blockmode == NEW4X4)
|
||||
{
|
||||
#ifdef ENTROPY_STATS
|
||||
active_section = 11;
|
||||
#endif
|
||||
write_mv(w, &blockmv.as_mv, &best_mv, (const MV_CONTEXT *) mvc);
|
||||
}
|
||||
}
|
||||
while (++j < cpi->mb.partition_info->count);
|
||||
}
|
||||
while (++j < cpi->mb.partition_info->count);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1448,7 +1476,13 @@ int vp8_estimate_entropy_savings(VP8_COMP *cpi)
|
||||
|
||||
if (cpi->common.frame_type != KEY_FRAME)
|
||||
{
|
||||
if (!(new_intra = rf_intra * 255 / (rf_intra + rf_inter)))
|
||||
#if CONFIG_SEGFEATURES
|
||||
new_intra = (rf_intra + rf_inter)
|
||||
? rf_intra * 255 / (rf_intra + rf_inter) : 1;
|
||||
#else
|
||||
new_intra = rf_intra * 255 / (rf_intra + rf_inter);
|
||||
#endif
|
||||
if (!new_intra)
|
||||
new_intra = 1;
|
||||
|
||||
new_last = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
|
||||
|
@ -717,27 +717,51 @@ void encode_mb_row(VP8_COMP *cpi,
|
||||
if ((xd->mode_info_context->mbmi.mode == ZEROMV) && (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME))
|
||||
cpi->inter_zz_count ++;
|
||||
|
||||
// Special case code for cyclic refresh
|
||||
// If cyclic update enabled then copy xd->mbmi.segment_id; (which may have been updated based on mode
|
||||
// during vp8cx_encode_inter_macroblock()) back into the global sgmentation map
|
||||
if (cpi->cyclic_refresh_mode_enabled && xd->segmentation_enabled)
|
||||
// Actions required if segmentation enabled
|
||||
if ( xd->segmentation_enabled )
|
||||
{
|
||||
cpi->segmentation_map[map_index+mb_col] = xd->mode_info_context->mbmi.segment_id;
|
||||
|
||||
// If the block has been refreshed mark it as clean (the magnitude of the -ve influences how long it will be before we consider another refresh):
|
||||
// Else if it was coded (last frame 0,0) and has not already been refreshed then mark it as a candidate for cleanup next time (marked 0)
|
||||
// else mark it as dirty (1).
|
||||
if (xd->mode_info_context->mbmi.segment_id)
|
||||
cpi->cyclic_refresh_map[map_index+mb_col] = -1;
|
||||
else if ((xd->mode_info_context->mbmi.mode == ZEROMV) && (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME))
|
||||
// Special case code for cyclic refresh
|
||||
// If cyclic update enabled then copy xd->mbmi.segment_id;
|
||||
// (which may have been updated based on mode during
|
||||
// vp8cx_encode_inter_macroblock()) back into the global
|
||||
// segmentation map
|
||||
if (cpi->cyclic_refresh_mode_enabled)
|
||||
{
|
||||
if (cpi->cyclic_refresh_map[map_index+mb_col] == 1)
|
||||
cpi->cyclic_refresh_map[map_index+mb_col] = 0;
|
||||
}
|
||||
else
|
||||
cpi->cyclic_refresh_map[map_index+mb_col] = 1;
|
||||
cpi->segmentation_map[map_index+mb_col] =
|
||||
xd->mode_info_context->mbmi.segment_id;
|
||||
|
||||
// If the block has been refreshed mark it as clean (the
|
||||
// magnitude of the -ve influences how long it will be
|
||||
// before we consider another refresh):
|
||||
// Else if it was coded (last frame 0,0) and has not
|
||||
// already been refreshed then mark it as a candidate
|
||||
// for cleanup next time (marked 0)
|
||||
// else mark it as dirty (1).
|
||||
if (xd->mode_info_context->mbmi.segment_id)
|
||||
cpi->cyclic_refresh_map[map_index+mb_col] = -1;
|
||||
|
||||
else if ((xd->mode_info_context->mbmi.mode == ZEROMV) &&
|
||||
(xd->mode_info_context->mbmi.ref_frame ==
|
||||
LAST_FRAME))
|
||||
{
|
||||
if (cpi->cyclic_refresh_map[map_index+mb_col] == 1)
|
||||
cpi->cyclic_refresh_map[map_index+mb_col] = 0;
|
||||
}
|
||||
else
|
||||
cpi->cyclic_refresh_map[map_index+mb_col] = 1;
|
||||
}
|
||||
#if CONFIG_SEGFEATURES
|
||||
else if ( cm->refresh_alt_ref_frame &&
|
||||
(cm->frame_type != KEY_FRAME) )
|
||||
{
|
||||
// Update the global segmentation map to reflect
|
||||
// the segment choice made for this MB.
|
||||
cpi->segmentation_map[map_index+mb_col] =
|
||||
xd->mode_info_context->mbmi.segment_id;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cpi->tplist[mb_row].stop = *tp;
|
||||
@ -828,8 +852,45 @@ void encode_mb_row(VP8_COMP *cpi,
|
||||
sem_post(&cpi->h_event_end_encoding); /* signal frame encoding end */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if CONFIG_SEGFEATURES
|
||||
// debug output
|
||||
#if 0
|
||||
{
|
||||
FILE *statsfile;
|
||||
statsfile = fopen("segmap2.stt", "a");
|
||||
fprintf(statsfile, "\n" );
|
||||
fclose(statsfile);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_SEGFEATURES
|
||||
// Funtion to test out new segment features
|
||||
void segfeature_test_function(VP8_COMP *cpi, MACROBLOCKD * xd)
|
||||
{
|
||||
VP8_COMMON *const cm = & cpi->common;
|
||||
|
||||
// Only update segment map for a frame that is an arf but not a kf.
|
||||
if ( cm->refresh_alt_ref_frame && (cm->frame_type != KEY_FRAME) )
|
||||
{
|
||||
// Test code to code features at the segment level
|
||||
if ( (xd->mode_info_context->mbmi.mode ==
|
||||
cpi->segment_feature_data[1][SEG_LVL_MODE]) &&
|
||||
(xd->mode_info_context->mbmi.ref_frame ==
|
||||
cpi->segment_feature_data[1][SEG_LVL_REF_FRAME]) )
|
||||
{
|
||||
xd->mode_info_context->mbmi.segment_id = 1;
|
||||
}
|
||||
else
|
||||
xd->mode_info_context->mbmi.segment_id = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void init_encode_frame_mb_context(VP8_COMP *cpi)
|
||||
{
|
||||
MACROBLOCK *const x = & cpi->mb;
|
||||
@ -927,6 +988,7 @@ void vp8_encode_frame(VP8_COMP *cpi)
|
||||
MACROBLOCKD *const xd = & x->e_mbd;
|
||||
|
||||
TOKENEXTRA *tp = cpi->tok;
|
||||
|
||||
#if CONFIG_SEGMENTATION
|
||||
int segment_counts[MAX_MB_SEGMENTS + SEEK_SEGID];
|
||||
int prob[3];
|
||||
@ -936,6 +998,19 @@ void vp8_encode_frame(VP8_COMP *cpi)
|
||||
#endif
|
||||
int totalrate;
|
||||
|
||||
|
||||
#if CONFIG_SEGFEATURES
|
||||
// debug output
|
||||
#if 0
|
||||
{
|
||||
FILE *statsfile;
|
||||
statsfile = fopen("segmap2.stt", "a");
|
||||
fprintf(statsfile, "\n" );
|
||||
fclose(statsfile);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
vpx_memset(segment_counts, 0, sizeof(segment_counts));
|
||||
totalrate = 0;
|
||||
|
||||
@ -1307,8 +1382,16 @@ void vp8_encode_frame(VP8_COMP *cpi)
|
||||
cpi->prob_gf_coded = 1;
|
||||
}
|
||||
}
|
||||
#if CONFIG_SEGFEATURES
|
||||
else
|
||||
{
|
||||
// Trap case where cpi->count_mb_ref_frame_usage[] blank.
|
||||
cpi->prob_intra_coded = 63;
|
||||
cpi->prob_last_coded = 128;
|
||||
cpi->prob_gf_coded = 128;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Keep record of the total distortion this time around for future use
|
||||
cpi->last_frame_distortion = cpi->frame_distortion;
|
||||
@ -1599,8 +1682,9 @@ int vp8cx_encode_inter_macroblock
|
||||
if (cpi->cyclic_refresh_mode_enabled)
|
||||
{
|
||||
// Clear segment_id back to 0 if not coded (last frame 0,0)
|
||||
if ((xd->mode_info_context->mbmi.segment_id == 1) &&
|
||||
((xd->mode_info_context->mbmi.ref_frame != LAST_FRAME) || (xd->mode_info_context->mbmi.mode != ZEROMV)))
|
||||
if ( (xd->mode_info_context->mbmi.segment_id == 1) &&
|
||||
( (xd->mode_info_context->mbmi.ref_frame != LAST_FRAME) ||
|
||||
(xd->mode_info_context->mbmi.mode != ZEROMV) ) )
|
||||
{
|
||||
xd->mode_info_context->mbmi.segment_id = 0;
|
||||
|
||||
@ -1608,6 +1692,26 @@ int vp8cx_encode_inter_macroblock
|
||||
vp8cx_mb_init_quantizer(cpi, x);
|
||||
}
|
||||
}
|
||||
#if CONFIG_SEGFEATURES
|
||||
else
|
||||
{
|
||||
segfeature_test_function(cpi, xd);
|
||||
#if 0
|
||||
// Debug output
|
||||
{
|
||||
FILE *statsfile;
|
||||
statsfile = fopen("segmap2.stt", "a");
|
||||
|
||||
fprintf(statsfile, "%2d%2d%2d ",
|
||||
xd->mode_info_context->mbmi.segment_id,
|
||||
xd->mode_info_context->mbmi.ref_frame,
|
||||
xd->mode_info_context->mbmi.mode );
|
||||
|
||||
fclose(statsfile);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
@ -1638,7 +1742,15 @@ int vp8cx_encode_inter_macroblock
|
||||
vp8_update_zbin_extra(cpi, x);
|
||||
}
|
||||
|
||||
#if 0
|
||||
//#if CONFIG_SEGFEATURES
|
||||
// Test code using segment 1 only.
|
||||
// Dont increment count if ref frame coded at segment level
|
||||
if ( (xd->mode_info_context->mbmi.segment_id != 1) )
|
||||
cpi->count_mb_ref_frame_usage[xd->mode_info_context->mbmi.ref_frame]++;
|
||||
#else
|
||||
cpi->count_mb_ref_frame_usage[xd->mode_info_context->mbmi.ref_frame] ++;
|
||||
#endif
|
||||
|
||||
#if CONFIG_T8X8
|
||||
if (xd->segmentation_enabled)
|
||||
|
@ -434,14 +434,6 @@ static void set_segmentation_map(VP8_PTR ptr, unsigned char *segmentation_map)
|
||||
cpi->mb.e_mbd.update_mb_segmentation_data = 1;
|
||||
}
|
||||
|
||||
// The values given for each segment can be either deltas (from the default value chosen for the frame) or absolute values.
|
||||
//
|
||||
// Valid range for abs values is (0-127 for SEG_LVL_ALT_Q) , (0-63 for SEGMENT_ALT_LF)
|
||||
// Valid range for delta values are (+/-127 for SEG_LVL_ALT_Q) , (+/-63 for SEGMENT_ALT_LF)
|
||||
//
|
||||
// abs_delta = SEGMENT_DELTADATA (deltas) abs_delta = SEGMENT_ABSDATA (use the absolute values given).
|
||||
//
|
||||
//
|
||||
static void set_segment_data(VP8_PTR ptr, signed char *feature_data, unsigned char abs_delta)
|
||||
{
|
||||
VP8_COMP *cpi = (VP8_COMP *)(ptr);
|
||||
@ -514,6 +506,99 @@ static void segmentation_test_function(VP8_PTR ptr)
|
||||
|
||||
}
|
||||
|
||||
#if CONFIG_SEGFEATURES
|
||||
static void init_seg_features(VP8_COMP *cpi)
|
||||
{
|
||||
VP8_COMMON *cm = &cpi->common;
|
||||
MACROBLOCKD *mbd = &cpi->mb.e_mbd;
|
||||
|
||||
// For now at least dont enable seg features alongside cyclic refresh.
|
||||
if (cpi->cyclic_refresh_mode_enabled)
|
||||
return;
|
||||
|
||||
// No updates for key frames
|
||||
if ( cm->frame_type == KEY_FRAME )
|
||||
{
|
||||
cpi->mb.e_mbd.update_mb_segmentation_map = 0;
|
||||
cpi->mb.e_mbd.update_mb_segmentation_data = 0;
|
||||
}
|
||||
// Arf but not a key frame.
|
||||
else if ( cm->refresh_alt_ref_frame )
|
||||
{
|
||||
// Clear down the global segmentation map
|
||||
vpx_memset( cpi->segmentation_map, 0, (cm->mb_rows * cm->mb_cols));
|
||||
|
||||
// Activate segmentation.
|
||||
enable_segmentation((VP8_PTR)cpi);
|
||||
|
||||
// For now set GF, (0,0) MV in segment 1
|
||||
cpi->segment_feature_data[1][SEG_LVL_REF_FRAME] = LAST_FRAME;
|
||||
cpi->segment_feature_data[1][SEG_LVL_MODE] = ZEROMV;
|
||||
|
||||
mbd->segment_feature_data[1][SEG_LVL_REF_FRAME] = LAST_FRAME;
|
||||
mbd->segment_feature_data[1][SEG_LVL_MODE] = ZEROMV;
|
||||
|
||||
// Enable target features is the segment feature mask
|
||||
mbd->segment_feature_mask[1] |= (0x01 << SEG_LVL_REF_FRAME);
|
||||
mbd->segment_feature_mask[1] |= (0x01 << SEG_LVL_MODE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Special case where we are coding over the top of a previous
|
||||
// alt ref frame
|
||||
if ( cpi->is_src_frame_alt_ref )
|
||||
{
|
||||
if ( cpi->source_alt_ref_pending )
|
||||
{
|
||||
cpi->mb.e_mbd.update_mb_segmentation_data = 1;
|
||||
cpi->segment_feature_data[1][SEG_LVL_REF_FRAME] = ALTREF_FRAME;
|
||||
mbd->segment_feature_data[1][SEG_LVL_REF_FRAME] = ALTREF_FRAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
vpx_memset( cpi->segmentation_map, 0,
|
||||
(cm->mb_rows * cm->mb_cols));
|
||||
cpi->mb.e_mbd.update_mb_segmentation_map = 1;
|
||||
cpi->mb.e_mbd.update_mb_segmentation_data = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cpi->mb.e_mbd.update_mb_segmentation_data = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DEBUG: Print out the segment id of each MB in the current frame.
|
||||
static void print_seg_map(VP8_COMP *cpi)
|
||||
{
|
||||
VP8_COMMON *cm = & cpi->common;
|
||||
int row,col;
|
||||
int map_index = 0;
|
||||
FILE *statsfile;
|
||||
|
||||
statsfile = fopen("segmap.stt", "a");
|
||||
|
||||
fprintf(statsfile, "%10d\n",
|
||||
cm->current_video_frame );
|
||||
|
||||
for ( row = 0; row < cpi->common.mb_rows; row++ )
|
||||
{
|
||||
for ( col = 0; col < cpi->common.mb_cols; col++ )
|
||||
{
|
||||
fprintf(statsfile, "%10d",
|
||||
cpi->segmentation_map[map_index]);
|
||||
map_index++;
|
||||
}
|
||||
fprintf(statsfile, "\n");
|
||||
}
|
||||
fprintf(statsfile, "\n");
|
||||
|
||||
fclose(statsfile);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// A simple function to cyclically refresh the background at a lower Q
|
||||
static void cyclic_background_refresh(VP8_COMP *cpi, int Q, int lf_adjustment)
|
||||
{
|
||||
@ -3401,13 +3486,6 @@ static void encode_frame_to_data_rate
|
||||
// Clear down mmx registers to allow floating point in what follows
|
||||
vp8_clear_system_state();
|
||||
|
||||
// Test code for segmentation of gf/arf (0,0)
|
||||
//segmentation_test_function((VP8_PTR) cpi);
|
||||
#if CONFIG_SEGMENTATION
|
||||
cpi->mb.e_mbd.segmentation_enabled = 1;
|
||||
cpi->mb.e_mbd.update_mb_segmentation_map = 1;
|
||||
#endif
|
||||
|
||||
if (cpi->compressor_speed == 2)
|
||||
{
|
||||
if(cpi->oxcf.auto_key && cm->frame_type != KEY_FRAME)
|
||||
@ -3472,9 +3550,23 @@ static void encode_frame_to_data_rate
|
||||
cm->frame_type = KEY_FRAME;
|
||||
}
|
||||
|
||||
// Set default state for segment and mode based loop filter update flags
|
||||
cpi->mb.e_mbd.update_mb_segmentation_map = 0;
|
||||
cpi->mb.e_mbd.update_mb_segmentation_data = 0;
|
||||
// Test code for segmentation of gf/arf (0,0)
|
||||
//segmentation_test_function((VP8_PTR) cpi);
|
||||
#if CONFIG_SEGMENTATION
|
||||
cpi->mb.e_mbd.segmentation_enabled = 1;
|
||||
cpi->mb.e_mbd.update_mb_segmentation_map = 1;
|
||||
#else
|
||||
#if CONFIG_SEGFEATURES
|
||||
// Test code for new segment features
|
||||
init_seg_features( cpi );
|
||||
#else
|
||||
// Set default state for segment update flags
|
||||
cpi->mb.e_mbd.update_mb_segmentation_map = 0;
|
||||
cpi->mb.e_mbd.update_mb_segmentation_data = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Set default state for segment based loop filter update flags
|
||||
cpi->mb.e_mbd.mode_ref_lf_delta_update = 0;
|
||||
|
||||
// Set various flags etc to special state if it is a key frame
|
||||
@ -4533,6 +4625,13 @@ static void encode_frame_to_data_rate
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if CONFIG_SEGFEATURES
|
||||
#if 0
|
||||
// Debug stats for segment feature experiments.
|
||||
print_seg_map(cpi);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// If this was a kf or Gf note the Q
|
||||
|
@ -409,6 +409,7 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
|
||||
BLOCKD *d = &x->e_mbd.block[0];
|
||||
MACROBLOCKD *xd = &x->e_mbd;
|
||||
MB_MODE_INFO best_mbmode;
|
||||
VP8_COMMON *cm = & cpi->common;
|
||||
|
||||
int_mv best_ref_mv;
|
||||
int_mv mode_mv[MB_MODE_COUNT];
|
||||
@ -514,6 +515,38 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
|
||||
if (skip_mode[x->e_mbd.mode_info_context->mbmi.ref_frame])
|
||||
continue;
|
||||
|
||||
#if CONFIG_SEGFEATURES
|
||||
// Experimental use of Segment features.
|
||||
if ( !cm->refresh_alt_ref_frame )
|
||||
{
|
||||
unsigned char segment_id = xd->mode_info_context->mbmi.segment_id;
|
||||
int feature_mask = xd->segment_feature_mask[segment_id];
|
||||
|
||||
if ( (feature_mask & (0x01 << SEG_LVL_REF_FRAME)) &&
|
||||
( x->e_mbd.mode_info_context->mbmi.ref_frame !=
|
||||
cpi->segment_feature_data[segment_id][SEG_LVL_REF_FRAME]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( (feature_mask & (0x01 << SEG_LVL_MODE)) &&
|
||||
( this_mode !=
|
||||
cpi->segment_feature_data[segment_id][SEG_LVL_MODE]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
|
||||
// unless ARNR filtering is enabled in which case we want
|
||||
// an unfiltered alternative
|
||||
if (cpi->is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
|
||||
{
|
||||
if (this_mode != ZEROMV ||
|
||||
x->e_mbd.mode_info_context->mbmi.ref_frame != ALTREF_FRAME)
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check to see if the testing frequency for this mode is at its max
|
||||
// If so then prevent it from being tested and increase the threshold for its testing
|
||||
if (cpi->mode_test_hit_counts[mode_index] && (cpi->mode_check_freq[mode_index] > 1))
|
||||
@ -532,6 +565,7 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// We have now reached the point where we are going to test the current mode so increment the counter for the number of times it has been tested
|
||||
cpi->mode_test_hit_counts[mode_index] ++;
|
||||
@ -564,6 +598,7 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
|
||||
memcpy(mdcounts, MDCounts[x->e_mbd.mode_info_context->mbmi.ref_frame], sizeof(mdcounts));
|
||||
}
|
||||
|
||||
#if !CONFIG_SEGFEATURES
|
||||
// Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
|
||||
// unless ARNR filtering is enabled in which case we want
|
||||
// an unfiltered alternative
|
||||
@ -572,6 +607,7 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
|
||||
if (this_mode != ZEROMV || x->e_mbd.mode_info_context->mbmi.ref_frame != ALTREF_FRAME)
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (this_mode)
|
||||
{
|
||||
|
@ -1993,6 +1993,7 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
|
||||
BLOCK *b = &x->block[0];
|
||||
BLOCKD *d = &x->e_mbd.block[0];
|
||||
MACROBLOCKD *xd = &x->e_mbd;
|
||||
VP8_COMMON *cm = &cpi->common;
|
||||
union b_mode_info best_bmodes[16];
|
||||
MB_MODE_INFO best_mbmode;
|
||||
PARTITION_INFO best_partition;
|
||||
@ -2119,14 +2120,38 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
|
||||
x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED;
|
||||
x->e_mbd.mode_info_context->mbmi.ref_frame = vp8_ref_frame_order[mode_index];
|
||||
|
||||
#if CONFIG_SEGFEATURES
|
||||
// Experimental use of Segment features.
|
||||
if ( !cm->refresh_alt_ref_frame )
|
||||
{
|
||||
unsigned char segment_id = xd->mode_info_context->mbmi.segment_id;
|
||||
int feature_mask = xd->segment_feature_mask[segment_id];
|
||||
|
||||
if ( (feature_mask & (0x01 << SEG_LVL_REF_FRAME)) &&
|
||||
( x->e_mbd.mode_info_context->mbmi.ref_frame !=
|
||||
cpi->segment_feature_data[segment_id][SEG_LVL_REF_FRAME]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( (feature_mask & (0x01 << SEG_LVL_MODE)) &&
|
||||
( this_mode !=
|
||||
cpi->segment_feature_data[segment_id][SEG_LVL_MODE]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
|
||||
// unless ARNR filtering is enabled in which case we want
|
||||
// an unfiltered alternative
|
||||
if (cpi->is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
|
||||
{
|
||||
if (this_mode != ZEROMV || x->e_mbd.mode_info_context->mbmi.ref_frame != ALTREF_FRAME)
|
||||
if (this_mode != ZEROMV ||
|
||||
x->e_mbd.mode_info_context->mbmi.ref_frame != ALTREF_FRAME)
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* everything but intra */
|
||||
if (x->e_mbd.mode_info_context->mbmi.ref_frame)
|
||||
@ -2141,6 +2166,7 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
|
||||
lf_or_gf = frame_lf_or_gf[x->e_mbd.mode_info_context->mbmi.ref_frame];
|
||||
}
|
||||
|
||||
#if !CONFIG_SEGFEATURES
|
||||
// Check to see if the testing frequency for this mode is at its max
|
||||
// If so then prevent it from being tested and increase the threshold for its testing
|
||||
if (cpi->mode_test_hit_counts[mode_index] && (cpi->mode_check_freq[mode_index] > 1))
|
||||
@ -2161,6 +2187,7 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
|
||||
|
||||
// We have now reached the point where we are going to test the current mode so increment the counter for the number of times it has been tested
|
||||
cpi->mode_test_hit_counts[mode_index] ++;
|
||||
#endif
|
||||
|
||||
// Experimental code. Special case for gf and arf zeromv modes. Increase zbin size to supress noise
|
||||
if (cpi->zbin_mode_boost_enabled)
|
||||
|
Loading…
Reference in New Issue
Block a user