summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vp8/common/onyxc_int.h1
-rw-r--r--vp8/common/pred_common.c135
-rw-r--r--vp8/decoder/decodemv.c1
-rw-r--r--vp8/encoder/bitstream.c113
-rw-r--r--vp8/encoder/encodeframe.c1
-rw-r--r--vp8/encoder/onyx_if.c10
-rw-r--r--vp8/encoder/onyx_int.h2
7 files changed, 110 insertions, 153 deletions
diff --git a/vp8/common/onyxc_int.h b/vp8/common/onyxc_int.h
index fd6a55801..a86635a7c 100644
--- a/vp8/common/onyxc_int.h
+++ b/vp8/common/onyxc_int.h
@@ -236,6 +236,7 @@ typedef struct VP8Common
#if CONFIG_COMPRED
// Context probabilities for reference frame prediction
+ unsigned char ref_scores[MAX_REF_FRAMES];
vp8_prob ref_pred_probs[PREDICTION_PROBS];
vp8_prob mod_refprobs[MAX_REF_FRAMES][PREDICTION_PROBS];
#endif
diff --git a/vp8/common/pred_common.c b/vp8/common/pred_common.c
index e4cd037e8..bda140058 100644
--- a/vp8/common/pred_common.c
+++ b/vp8/common/pred_common.c
@@ -155,10 +155,6 @@ MV_REFERENCE_FRAME get_pred_ref( VP8_COMMON *const cm,
{
MODE_INFO *m = xd->mode_info_context;
- unsigned char left_pred;
- unsigned char above_pred;
- unsigned char frame_allowed[MAX_REF_FRAMES];
-
MV_REFERENCE_FRAME left;
MV_REFERENCE_FRAME above;
MV_REFERENCE_FRAME above_left;
@@ -166,107 +162,68 @@ MV_REFERENCE_FRAME get_pred_ref( VP8_COMMON *const cm,
int segment_id = xd->mode_info_context->mbmi.segment_id;
int seg_ref_active;
+ int i;
+
+ unsigned char frame_allowed[MAX_REF_FRAMES] = {1,1,1,1};
+ unsigned char ref_score[MAX_REF_FRAMES];
+ unsigned char best_score = 0;
+ unsigned char left_in_image;
+ unsigned char above_in_image;
+ unsigned char above_left_in_image;
// Is segment coding ennabled
seg_ref_active = segfeature_active( xd, segment_id, SEG_LVL_REF_FRAME );
- // Reference frame used by neighbours
- left = (m - 1)->mbmi.ref_frame;
- above = (m - cm->mode_info_stride)->mbmi.ref_frame;
- above_left = (m - 1 - cm->mode_info_stride)->mbmi.ref_frame;
-
- // Reference frame prediction status of immediate neigbours.
- // This can only be set if the mb is "in image"
- left_pred = (m - 1)->mbmi.ref_predicted;
- above_pred = (m - cm->mode_info_stride)->mbmi.ref_predicted;
-
// Special case treatment if segment coding is enabled.
// Dont allow prediction of a reference frame that the segment
// does not allow
if ( seg_ref_active )
{
- frame_allowed[INTRA_FRAME] =
- check_segref( xd, segment_id, INTRA_FRAME );
- frame_allowed[LAST_FRAME] =
- check_segref( xd, segment_id, LAST_FRAME );
- frame_allowed[GOLDEN_FRAME] =
- check_segref( xd, segment_id, GOLDEN_FRAME );
- frame_allowed[ALTREF_FRAME] =
- check_segref( xd, segment_id, ALTREF_FRAME );
+ for ( i = 0; i < MAX_REF_FRAMES; i++ )
+ {
+ frame_allowed[i] =
+ check_segref( xd, segment_id, i );
+
+ // Score set to 0 if ref frame not allowed
+ ref_score[i] = cm->ref_scores[i] * frame_allowed[i];
+ }
}
else
- {
- frame_allowed[INTRA_FRAME] = 1;
- frame_allowed[LAST_FRAME] = 1;
- frame_allowed[GOLDEN_FRAME] = 1;
- frame_allowed[ALTREF_FRAME] = 1;
- }
+ vpx_memcpy( ref_score, cm->ref_scores, sizeof(ref_score) );
- // Dont predict if not allowed
- left_pred = left_pred * frame_allowed[left];
- above_pred = above_pred * frame_allowed[above];
-
- // Boost prediction scores of above / left if they are predicted and match
- // the above left.
- if ( left_pred )
- left_pred += (left == above_left);
- if ( above_pred )
- above_pred += (above == above_left);
-
- // Only consider "in image" mbs as giving valid prediction.
- if ( (left == above) && frame_allowed[left] &&
- ((m - 1)->mbmi.mb_in_image ||
- (m - cm->mode_info_stride)->mbmi.mb_in_image) )
- {
- pred_ref = left;
- }
- else if ( left_pred > above_pred )
+ // Reference frames used by neighbours
+ left = (m - 1)->mbmi.ref_frame;
+ above = (m - cm->mode_info_stride)->mbmi.ref_frame;
+ above_left = (m - 1 - cm->mode_info_stride)->mbmi.ref_frame;
+
+ // Are neighbours in image
+ left_in_image = (m - 1)->mbmi.mb_in_image;
+ above_in_image = (m - cm->mode_info_stride)->mbmi.mb_in_image;
+ above_left_in_image = (m - 1 - cm->mode_info_stride)->mbmi.mb_in_image;
+
+ // Adjust scores for candidate reference frames based on neigbours
+ if ( frame_allowed[left] && left_in_image )
{
- pred_ref = left;
+ ref_score[left] += 16;
+ if ( above_left_in_image && (left == above_left) )
+ ref_score[left] += 4;
}
- else if ( above_pred > left_pred )
+ if ( frame_allowed[above] && above_in_image )
{
- pred_ref = above;
+ ref_score[above] += 16;
+ if ( above_left_in_image && (above == above_left) )
+ ref_score[above] += 4;
}
- // If we reach this clause left_pred and above_pred must be the same
- else if ( left_pred > 0 )
+
+ // Now choose the candidate with the highest score
+ for ( i = 0; i < MAX_REF_FRAMES; i++ )
{
- // Choose from above or left.
- // For now this is based on a fixed preference order.
- // Last,Altref,Golden
- if ( frame_allowed[LAST_FRAME] &&
- ((left == LAST_FRAME) || (above == LAST_FRAME)) )
- {
- pred_ref = LAST_FRAME;
- }
- else if ( frame_allowed[ALTREF_FRAME] &&
- ((left == ALTREF_FRAME) || (above == ALTREF_FRAME)) )
+ if ( ref_score[i] > best_score )
{
- pred_ref = ALTREF_FRAME;
- }
- else if ( frame_allowed[GOLDEN_FRAME] &&
- ((left == GOLDEN_FRAME) || (above == GOLDEN_FRAME)) )
- {
- pred_ref = GOLDEN_FRAME;
- }
- else
- {
- pred_ref = INTRA_FRAME;
+ pred_ref = i;
+ best_score = ref_score[i];
}
}
- // No prediction case.. choose in fixed order from allowed options
- // TBD could order based onf frequency.
- else
- {
- if ( frame_allowed[LAST_FRAME] )
- pred_ref = LAST_FRAME;
- else if ( frame_allowed[ALTREF_FRAME] )
- pred_ref = ALTREF_FRAME;
- else if ( frame_allowed[GOLDEN_FRAME] )
- pred_ref = GOLDEN_FRAME;
- else
- pred_ref = INTRA_FRAME;
- }
return pred_ref;
}
@@ -357,5 +314,13 @@ void compute_mod_refprobs( VP8_COMMON *const cm )
norm_cnt[3] = 0;
calc_ref_probs( norm_cnt, cm->mod_refprobs[ALTREF_FRAME] );
cm->mod_refprobs[ALTREF_FRAME][2] = 0; // This branch implicit
+
+ // Score the reference frames based on overal frequency.
+ // These scores contribute to the prediction choices.
+ // Max score 17 min 1
+ cm->ref_scores[INTRA_FRAME] = 1 + (intra_count * 16 / 255);
+ cm->ref_scores[LAST_FRAME] = 1 + (last_count * 16 / 255);
+ cm->ref_scores[GOLDEN_FRAME] = 1 + (gf_count * 16 / 255);
+ cm->ref_scores[ALTREF_FRAME] = 1 + (arf_count * 16 / 255);
}
#endif
diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c
index 432b339b1..4238e4d18 100644
--- a/vp8/decoder/decodemv.c
+++ b/vp8/decoder/decodemv.c
@@ -292,7 +292,6 @@ static MV_REFERENCE_FRAME read_ref_frame( VP8D_COMP *pbi,
// else decode the explicitly coded value
else
{
- //vp8_prob * mod_refprobs = cm->mod_refprobs[pred_ref];
vp8_prob mod_refprobs[PREDICTION_PROBS];
vpx_memcpy( mod_refprobs,
cm->mod_refprobs[pred_ref], sizeof(mod_refprobs) );
diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c
index 26f1cb487..3c0ea4c2b 100644
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -869,21 +869,24 @@ static void encode_ref_frame( vp8_writer *const w,
// Values used in prediction model coding
unsigned char prediction_flag;
vp8_prob pred_prob;
+ MV_REFERENCE_FRAME pred_rf;
// Get the context probability the prediction flag
pred_prob = get_pred_prob( cm, xd, PRED_REF );
- // Code the prediction flag
- prediction_flag = get_pred_flag( xd, PRED_REF );
+ // Get the predicted value.
+ pred_rf = get_pred_ref( cm, xd );
+
+ // Did the chosen reference frame match its predicted value.
+ prediction_flag =
+ ( xd->mode_info_context->mbmi.ref_frame == pred_rf );
+
+ set_pred_flag( xd, PRED_REF, prediction_flag );
vp8_write( w, prediction_flag, pred_prob );
// If not predicted correctly then code value explicitly
if ( !prediction_flag )
{
- // Get the predicted value so that it can be excluded.
- MV_REFERENCE_FRAME pred_rf = get_pred_ref( cm, xd );
-
- //vp8_prob * mod_refprobs = cm->mod_refprobs[pred_rf];
vp8_prob mod_refprobs[PREDICTION_PROBS];
vpx_memcpy( mod_refprobs,
@@ -997,6 +1000,42 @@ static void encode_ref_frame( vp8_writer *const w,
#endif
}
+// Update the probabilities used to encode reference frame data
+static void update_ref_probs( VP8_COMP *const cpi )
+{
+ VP8_COMMON *const cm = & cpi->common;
+
+ const int *const rfct = cpi->count_mb_ref_frame_usage;
+ const int rf_intra = rfct[INTRA_FRAME];
+ const int rf_inter = rfct[LAST_FRAME] +
+ rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];
+
+//#if CONFIG_SEGFEATURES
+ cm->prob_intra_coded = (rf_intra + rf_inter)
+ ? rf_intra * 255 / (rf_intra + rf_inter) : 1;
+
+ if (!cm->prob_intra_coded)
+ cm->prob_intra_coded = 1;
+
+ cm->prob_last_coded = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
+
+ if (!cm->prob_last_coded)
+ cm->prob_last_coded = 1;
+
+ cm->prob_gf_coded = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
+ ? (rfct[GOLDEN_FRAME] * 255) /
+ (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]) : 128;
+
+ if (!cm->prob_gf_coded)
+ cm->prob_gf_coded = 1;
+
+#if CONFIG_COMPRED
+ // Compute a modified set of probabilities to use when prediction of the
+ // reference frame fails
+ compute_mod_refprobs( cm );
+#endif
+}
+
#if CONFIG_SUPERBLOCKS
static void pack_inter_mode_mvs(VP8_COMP *const cpi)
{
@@ -1010,9 +1049,6 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
#endif
int pred_context;
- const int *const rfct = cpi->count_mb_ref_frame_usage;
- const int rf_intra = rfct[INTRA_FRAME];
- const int rf_inter = rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];
MODE_INFO *m = pc->mi;
#if CONFIG_NEWNEAR
MODE_INFO *prev_m = pc->prev_mi;
@@ -1036,31 +1072,8 @@ 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 CONFIG_SEGFEATURES
- pc->prob_intra_coded = (rf_intra + rf_inter)
- ? rf_intra * 255 / (rf_intra + rf_inter) : 1;
-
- if (!pc->prob_intra_coded)
- pc->prob_intra_coded = 1;
-
- pc->prob_last_coded = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
-
- if (!pc->prob_last_coded)
- pc->prob_last_coded = 1;
-
- pc->prob_gf_coded = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
- ? (rfct[GOLDEN_FRAME] * 255) / (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]) : 128;
-
- if (!pc->prob_gf_coded)
- pc->prob_gf_coded = 1;
-
-#if CONFIG_COMPRED
- // Compute a modified set of probabilities to use when prediction of the
- // reference frame fails
- compute_mod_refprobs( pc );
-#endif
+ // Update the probabilities used to encode reference frame data
+ update_ref_probs( cpi );
#ifdef ENTROPY_STATS
active_section = 1;
@@ -1425,9 +1438,6 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
#endif
int pred_context;
- const int *const rfct = cpi->count_mb_ref_frame_usage;
- const int rf_intra = rfct[INTRA_FRAME];
- const int rf_inter = rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];
MODE_INFO *m = pc->mi;
#if CONFIG_NEWNEAR
@@ -1448,31 +1458,8 @@ 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 CONFIG_SEGFEATURES
- pc->prob_intra_coded = (rf_intra + rf_inter)
- ? rf_intra * 255 / (rf_intra + rf_inter) : 1;
-
- if (!pc->prob_intra_coded)
- pc->prob_intra_coded = 1;
-
- pc->prob_last_coded = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
-
- if (!pc->prob_last_coded)
- pc->prob_last_coded = 1;
-
- pc->prob_gf_coded = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
- ? (rfct[GOLDEN_FRAME] * 255) / (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]) : 128;
-
- if (!pc->prob_gf_coded)
- pc->prob_gf_coded = 1;
-
-#if CONFIG_COMPRED
- // Compute a modified set of probabilities to use when prediction of the
- // reference frame fails
- compute_mod_refprobs( pc );
-#endif
+ // Update the probabilities used to encode reference frame data
+ update_ref_probs( cpi );
#ifdef ENTROPY_STATS
active_section = 1;
@@ -2825,7 +2812,7 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
{
for (i = 0; i < PREDICTION_PROBS; i++)
{
- if ( cpi->ref_probs_update[i] )
+ if ( cpi->ref_pred_probs_update[i] )
{
vp8_write_bit(bc, 1);
vp8_write_literal(bc, pc->ref_pred_probs[i], 8);
diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c
index 30352d719..2e5bd20c8 100644
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -1982,6 +1982,7 @@ int vp8cx_encode_inter_macroblock
ref_pred_flag = ( (xd->mode_info_context->mbmi.ref_frame ==
get_pred_ref( cm, xd )) );
set_pred_flag( xd, PRED_REF, ref_pred_flag );
+
#endif
// If we have just a single reference frame coded for a segment then
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 2ea41ab35..e3656e2d8 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -3418,6 +3418,7 @@ static void update_golden_frame_stats(VP8_COMP *cpi)
}
#if !CONFIG_COMPRED
+//#if 1
// This function updates the reference frame probability estimates that
// will be used during mode selection
static void update_rd_ref_frame_probs(VP8_COMP *cpi)
@@ -3899,7 +3900,9 @@ static void update_refpred_stats( VP8_COMP *cpi )
cm->ref_pred_probs[0] = 120;
cm->ref_pred_probs[1] = 80;
cm->ref_pred_probs[2] = 40;
- vpx_memset(cpi->ref_probs_update, 0, sizeof(cpi->ref_probs_update) );
+
+ vpx_memset(cpi->ref_pred_probs_update, 0,
+ sizeof(cpi->ref_pred_probs_update) );
}
else
{
@@ -3988,11 +3991,11 @@ static void update_refpred_stats( VP8_COMP *cpi )
// Cost saving must be >= 8 bits (2048 in these units)
if ( (old_cost - new_cost) >= 2048 )
{
- cpi->ref_probs_update[i] = 1;
+ cpi->ref_pred_probs_update[i] = 1;
cm->ref_pred_probs[i] = new_pred_probs[i];
}
else
- cpi->ref_probs_update[i] = 0;
+ cpi->ref_pred_probs_update[i] = 0;
}
}
@@ -4156,6 +4159,7 @@ static void encode_frame_to_data_rate
#endif
#if !CONFIG_COMPRED
+//#if 1
update_rd_ref_frame_probs(cpi);
#endif
diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h
index 214006cfd..cd2f25eaa 100644
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -519,7 +519,7 @@ typedef struct VP8_COMP
int last_frame_percent_intra;
int ref_frame_flags;
- unsigned char ref_probs_update[PREDICTION_PROBS];
+ unsigned char ref_pred_probs_update[PREDICTION_PROBS];
SPEED_FEATURES sf;
int error_bins[1024];