Implementation of new prediction model for reference frame coding.
This check in uses the common prediction interface functions to code reference frame. Some updates made regarding the impact of the new code in rd loop but there remain TODOs in this regard. Change-Id: I9da3ed5dfdaa489e0903ab33258b0767a585567f
This commit is contained in:
Родитель
56904be19d
Коммит
1335ac3071
|
@ -248,6 +248,65 @@ static MV_REFERENCE_FRAME read_ref_frame( VP8D_COMP *pbi,
|
|||
// Segment reference frame features not available
|
||||
if ( !seg_ref_active )
|
||||
{
|
||||
#if CONFIG_COMPRED
|
||||
// Values used in prediction model coding
|
||||
unsigned char prediction_flag;
|
||||
vp8_prob pred_prob;
|
||||
MV_REFERENCE_FRAME pred_ref;
|
||||
|
||||
// Get the context probability the prediction flag
|
||||
pred_prob = get_pred_prob( cm, xd, PRED_REF );
|
||||
|
||||
// Read the prediction status flag
|
||||
prediction_flag = (unsigned char)vp8_read( bc, pred_prob );
|
||||
|
||||
// Store the prediction flag.
|
||||
set_pred_flag( xd, PRED_REF, prediction_flag );
|
||||
|
||||
// Get the predicted reference frame.
|
||||
pred_ref = get_pred_ref( cm, xd );
|
||||
|
||||
// If correctly predicted then use the predicted value
|
||||
if ( prediction_flag )
|
||||
{
|
||||
ref_frame = pred_ref;
|
||||
}
|
||||
// else decode the explicitly coded value
|
||||
else
|
||||
{
|
||||
vp8_prob * mod_refprobs = cm->mod_refprobs[pred_ref];
|
||||
|
||||
// Default to INTRA_FRAME (value 0)
|
||||
ref_frame = INTRA_FRAME;
|
||||
|
||||
// Do we need to decode the Intra/Inter branch
|
||||
if ( mod_refprobs[0] )
|
||||
ref_frame = (MV_REFERENCE_FRAME) vp8_read(bc, mod_refprobs[0]);
|
||||
else
|
||||
ref_frame ++;
|
||||
|
||||
if (ref_frame)
|
||||
{
|
||||
// Do we need to decode the Last/Gf_Arf branch
|
||||
if ( mod_refprobs[1] )
|
||||
ref_frame += vp8_read(bc, mod_refprobs[1]);
|
||||
else
|
||||
ref_frame++;
|
||||
|
||||
if ( ref_frame > 1 )
|
||||
{
|
||||
// Do we need to decode the GF/Arf branch
|
||||
if ( mod_refprobs[2] )
|
||||
ref_frame += vp8_read(bc, mod_refprobs[2]);
|
||||
else
|
||||
{
|
||||
ref_frame = (pred_ref == GOLDEN_FRAME)
|
||||
? ALTREF_FRAME : GOLDEN_FRAME;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
ref_frame =
|
||||
(MV_REFERENCE_FRAME) vp8_read(bc, cm->prob_intra_coded);
|
||||
|
||||
|
@ -259,12 +318,20 @@ static MV_REFERENCE_FRAME read_ref_frame( VP8D_COMP *pbi,
|
|||
(int)(1 + vp8_read(bc, cm->prob_gf_coded)));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//#if CONFIG_SEGFEATURES
|
||||
// Segment reference frame features are enabled
|
||||
else
|
||||
{
|
||||
#if CONFIG_COMPRED
|
||||
// The reference frame for the mb is considered as correclty predicted
|
||||
// if it is signaled at the segment level for the purposes of the
|
||||
// common prediction model
|
||||
set_pred_flag( xd, PRED_REF, 1 );
|
||||
#endif
|
||||
|
||||
// If there are no inter reference frames enabled we can set INTRA
|
||||
if ( !check_segref_inter(xd, segment_id) )
|
||||
{
|
||||
|
@ -397,6 +464,11 @@ static void mb_mode_mv_init(VP8D_COMP *pbi)
|
|||
cm->prob_last_coded = (vp8_prob)vp8_read_literal(bc, 8);
|
||||
cm->prob_gf_coded = (vp8_prob)vp8_read_literal(bc, 8);
|
||||
|
||||
#if CONFIG_COMPRED
|
||||
// Computes a modified set of probabilities for use when reference
|
||||
// frame prediction fails.
|
||||
compute_mod_refprobs( cm );
|
||||
#endif
|
||||
|
||||
#if CONFIG_DUALPRED
|
||||
pbi->common.dual_pred_mode = vp8_read(bc, 128);
|
||||
|
|
|
@ -1146,6 +1146,26 @@ int vp8_decode_frame(VP8D_COMP *pbi)
|
|||
}
|
||||
}
|
||||
|
||||
#if CONFIG_COMPRED
|
||||
// Read common prediction model status flag probability updates for the
|
||||
// reference frame
|
||||
if ( pc->frame_type == KEY_FRAME )
|
||||
{
|
||||
// Set the prediction probabilities to defaults
|
||||
pc->ref_pred_probs[0] = 120;
|
||||
pc->ref_pred_probs[1] = 80;
|
||||
pc->ref_pred_probs[2] = 40;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < PREDICTION_PROBS; i++)
|
||||
{
|
||||
if ( vp8_read_bit(bc) )
|
||||
pc->ref_pred_probs[i] = (vp8_prob)vp8_read_literal(bc, 8);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Read the loop filter level and type */
|
||||
pc->filter_type = (LOOPFILTERTYPE) vp8_read_bit(bc);
|
||||
pc->filter_level = vp8_read_literal(bc, 6);
|
||||
|
|
|
@ -851,6 +851,49 @@ static void encode_ref_frame( vp8_writer *const w,
|
|||
// If segment level coding of this signal is disabled...
|
||||
if ( !seg_ref_active )
|
||||
{
|
||||
#if CONFIG_COMPRED
|
||||
// Values used in prediction model coding
|
||||
unsigned char prediction_flag;
|
||||
vp8_prob pred_prob;
|
||||
|
||||
// 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 );
|
||||
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];
|
||||
|
||||
if ( mod_refprobs[0] )
|
||||
{
|
||||
vp8_write(w, (rf != INTRA_FRAME), mod_refprobs[0] );
|
||||
}
|
||||
|
||||
// Inter coded
|
||||
if (rf != INTRA_FRAME)
|
||||
{
|
||||
if ( mod_refprobs[1] )
|
||||
{
|
||||
vp8_write(w, (rf != LAST_FRAME), mod_refprobs[1] );
|
||||
}
|
||||
|
||||
if (rf != LAST_FRAME)
|
||||
{
|
||||
if ( mod_refprobs[2] )
|
||||
{
|
||||
vp8_write(w, (rf != GOLDEN_FRAME), mod_refprobs[2] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (rf == INTRA_FRAME)
|
||||
{
|
||||
vp8_write(w, 0, cm->prob_intra_coded);
|
||||
|
@ -870,6 +913,7 @@ static void encode_ref_frame( vp8_writer *const w,
|
|||
vp8_write(w, (rf == GOLDEN_FRAME) ? 0 : 1, cm->prob_gf_coded);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
//#if CONFIG_SEGFEATURES
|
||||
// Else use the segment
|
||||
|
@ -971,6 +1015,11 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
|
|||
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
|
||||
|
||||
#ifdef ENTROPY_STATS
|
||||
active_section = 1;
|
||||
|
@ -1598,6 +1647,9 @@ static int default_coef_context_savings(VP8_COMP *cpi)
|
|||
return savings;
|
||||
}
|
||||
|
||||
#if CONFIG_COMPRED
|
||||
// TODO... this will all need changing for new reference frame coding model
|
||||
#endif
|
||||
int vp8_estimate_entropy_savings(VP8_COMP *cpi)
|
||||
{
|
||||
int savings = 0;
|
||||
|
@ -2179,6 +2231,24 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
|
|||
}
|
||||
}
|
||||
|
||||
#if CONFIG_COMPRED
|
||||
// Encode the common prediction model status flag probability updates for
|
||||
// the reference frame
|
||||
if ( pc->frame_type != KEY_FRAME )
|
||||
{
|
||||
for (i = 0; i < PREDICTION_PROBS; i++)
|
||||
{
|
||||
if ( cpi->ref_probs_update[i] )
|
||||
{
|
||||
vp8_write_bit(bc, 1);
|
||||
vp8_write_literal(bc, pc->ref_pred_probs[i], 8);
|
||||
}
|
||||
else
|
||||
vp8_write_bit(bc, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Encode the loop filter level and type
|
||||
vp8_write_bit(bc, pc->filter_type);
|
||||
vp8_write_literal(bc, pc->filter_level, 6);
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <limits.h>
|
||||
#include "vp8/common/subpixel.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
#include "vp8/common/pred_common.h"
|
||||
|
||||
//#if CONFIG_SEGFEATURES
|
||||
//#define DBG_PRNT_SEGMAP 1
|
||||
|
@ -880,6 +881,13 @@ void init_encode_frame_mb_context(VP8_COMP *cpi)
|
|||
vpx_memset(cm->above_context, 0,
|
||||
sizeof(ENTROPY_CONTEXT_PLANES) * cm->mb_cols);
|
||||
|
||||
|
||||
//#if CONFIG_COMPRED
|
||||
// TODO... this will all need changing for new reference frame coding model
|
||||
// in addition... ref_frame_cost should not be in the MACROBLOCKD structure as
|
||||
// it is only referenced in the encoder.
|
||||
//#endif
|
||||
|
||||
xd->ref_frame_cost[INTRA_FRAME] = vp8_cost_zero(cm->prob_intra_coded);
|
||||
|
||||
// Special case treatment when GF and ARF are not sensible options for reference
|
||||
|
@ -921,6 +929,12 @@ static void encode_frame_internal(VP8_COMP *cpi)
|
|||
TOKENEXTRA *tp = cpi->tok;
|
||||
int totalrate;
|
||||
|
||||
#if CONFIG_COMPRED
|
||||
// Compute a modified set of reference frame probabilities to use when
|
||||
// prediction fails. These are based on the current genreal estimates for
|
||||
// this frame which may be updated with each itteration of the recode loop.
|
||||
compute_mod_refprobs( cm );
|
||||
#endif
|
||||
|
||||
//#if CONFIG_SEGFEATURES
|
||||
// debug output
|
||||
|
@ -1529,11 +1543,16 @@ int vp8cx_encode_inter_macroblock
|
|||
int recon_yoffset, int recon_uvoffset
|
||||
)
|
||||
{
|
||||
VP8_COMMON *cm = &cpi->common;
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
int intra_error = 0;
|
||||
int rate;
|
||||
int distortion;
|
||||
unsigned char *segment_id = &xd->mode_info_context->mbmi.segment_id;
|
||||
int seg_ref_active;
|
||||
#if CONFIG_COMPRED
|
||||
unsigned char ref_pred_flag;
|
||||
#endif
|
||||
|
||||
x->skip = 0;
|
||||
|
||||
|
@ -1677,18 +1696,42 @@ int vp8cx_encode_inter_macroblock
|
|||
}
|
||||
|
||||
//#if CONFIG_SEGFEATURES
|
||||
seg_ref_active = segfeature_active( xd, *segment_id, SEG_LVL_REF_FRAME );
|
||||
|
||||
#if CONFIG_COMPRED
|
||||
// SET VARIOUS PREDICTION FLAGS
|
||||
|
||||
// Did the chosen reference frame match its predicted value.
|
||||
// If the reference frame is predicted at the segment level we
|
||||
// mark it as correctly predicted
|
||||
ref_pred_flag = ( (xd->mode_info_context->mbmi.ref_frame ==
|
||||
get_pred_ref( cm, xd )) ||
|
||||
seg_ref_active );
|
||||
set_pred_flag( xd, PRED_REF, ref_pred_flag );
|
||||
#endif
|
||||
|
||||
// If we have just a single reference frame coded for a segment then
|
||||
// exclude from the reference frame counts used to work out
|
||||
// probabilities. NOTE: At the moment we dont support custom trees
|
||||
// for the reference frame coding for each segment but this is a
|
||||
// possible future action.
|
||||
if ( !segfeature_active( xd, *segment_id, SEG_LVL_REF_FRAME ) ||
|
||||
if ( !seg_ref_active ||
|
||||
( ( check_segref( xd, *segment_id, INTRA_FRAME ) +
|
||||
check_segref( xd, *segment_id, LAST_FRAME ) +
|
||||
check_segref( xd, *segment_id, GOLDEN_FRAME ) +
|
||||
check_segref( xd, *segment_id, ALTREF_FRAME ) ) > 1 ) )
|
||||
{
|
||||
cpi->count_mb_ref_frame_usage[xd->mode_info_context->mbmi.ref_frame]++;
|
||||
// TODO this may not be a good idea as it makes sample size small and means
|
||||
// the predictor functions cannot use data about most likely value only most
|
||||
// likely unpredicted value.
|
||||
//#if CONFIG_COMPRED
|
||||
// // Only update count for incorrectly predicted cases
|
||||
// if ( !ref_pred_flag )
|
||||
//#endif
|
||||
{
|
||||
cpi->count_mb_ref_frame_usage
|
||||
[xd->mode_info_context->mbmi.ref_frame]++;
|
||||
}
|
||||
}
|
||||
|
||||
if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME)
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
//#if CONFIG_SEGFEATURES
|
||||
#include "vp8/common/seg_common.h"
|
||||
#include "mbgraph.h"
|
||||
#include "vp8/common/pred_common.h"
|
||||
|
||||
#if ARCH_ARM
|
||||
#include "vpx_ports/arm.h"
|
||||
|
@ -268,7 +269,6 @@ void vp8_initialize()
|
|||
{
|
||||
static int init_done = 0;
|
||||
|
||||
|
||||
if (!init_done)
|
||||
{
|
||||
vp8_scale_machine_specific_config();
|
||||
|
@ -574,7 +574,14 @@ static void init_seg_features(VP8_COMP *cpi)
|
|||
set_segdata( xd, 1, SEG_LVL_ALT_LF, -2 );
|
||||
enable_segfeature(xd, 1, SEG_LVL_ALT_LF);
|
||||
|
||||
#if CONFIG_COMPRED
|
||||
// Segment coding disabled for compred testing
|
||||
if ( high_q || (cpi->static_mb_pct == 100) )
|
||||
//if ( 0 )
|
||||
#else
|
||||
if ( high_q || (cpi->static_mb_pct == 100) )
|
||||
//if ( 0 )
|
||||
#endif
|
||||
{
|
||||
set_segref(xd, 1, ALTREF_FRAME);
|
||||
enable_segfeature(xd, 1, SEG_LVL_REF_FRAME);
|
||||
|
@ -610,11 +617,20 @@ static void init_seg_features(VP8_COMP *cpi)
|
|||
|
||||
// Special case where we are coding over the top of a previous
|
||||
// alt ref frame
|
||||
#if CONFIG_COMPRED
|
||||
// Segment coding disabled for compred testing
|
||||
else if ( cpi->is_src_frame_alt_ref )
|
||||
//else if ( 0 )
|
||||
#else
|
||||
else if ( cpi->is_src_frame_alt_ref )
|
||||
//else if ( 0 )
|
||||
#endif
|
||||
{
|
||||
// Enable mode and ref frame features for segment 0 as well
|
||||
enable_segfeature(xd, 0, SEG_LVL_REF_FRAME);
|
||||
enable_segfeature(xd, 0, SEG_LVL_MODE);
|
||||
enable_segfeature(xd, 1, SEG_LVL_REF_FRAME);
|
||||
enable_segfeature(xd, 1, SEG_LVL_MODE);
|
||||
|
||||
// All mbs should use ALTREF_FRAME, ZEROMV exclusively
|
||||
clear_segref(xd, 0);
|
||||
|
@ -2379,7 +2395,7 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf)
|
|||
// Create the encoder segmentation map and set all entries to 0
|
||||
CHECK_MEM_ERROR(cpi->segmentation_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
|
||||
|
||||
// And a copy "last_segmentation_map" for temporal coding
|
||||
// And a copy in common for temporal coding
|
||||
CHECK_MEM_ERROR(cm->last_frame_seg_map,
|
||||
vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
|
||||
|
||||
|
@ -3411,6 +3427,7 @@ static void update_golden_frame_stats(VP8_COMP *cpi)
|
|||
}
|
||||
}
|
||||
|
||||
#if !CONFIG_COMPRED
|
||||
// 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)
|
||||
|
@ -3525,7 +3542,7 @@ static void update_rd_ref_frame_probs(VP8_COMP *cpi)
|
|||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// 1 = key, 0 = inter
|
||||
static int decide_key_frame(VP8_COMP *cpi)
|
||||
|
@ -3865,6 +3882,133 @@ void loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm)
|
|||
|
||||
}
|
||||
|
||||
#if CONFIG_COMPRED
|
||||
// This function updates the reference frame prediction stats
|
||||
static void update_refpred_stats( VP8_COMP *cpi )
|
||||
{
|
||||
VP8_COMMON *const cm = & cpi->common;
|
||||
MACROBLOCKD *const xd = & cpi->mb.e_mbd;
|
||||
|
||||
int mb_row, mb_col;
|
||||
int i;
|
||||
int tot_count;
|
||||
int ref_pred_count[PREDICTION_PROBS][2];
|
||||
vp8_prob new_pred_probs[PREDICTION_PROBS];
|
||||
unsigned char pred_context;
|
||||
unsigned char pred_flag;
|
||||
|
||||
int old_cost, new_cost;
|
||||
|
||||
// Clear the prediction hit counters
|
||||
vpx_memset(ref_pred_count, 0, sizeof(ref_pred_count));
|
||||
|
||||
// Set the prediction probability structures to defaults
|
||||
if ( cm->frame_type == KEY_FRAME )
|
||||
{
|
||||
// Set the prediction probabilities to defaults
|
||||
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) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// For non-key frames.......
|
||||
|
||||
// Scan through the macroblocks and collate prediction counts.
|
||||
xd->mode_info_context = cm->mi;
|
||||
for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
|
||||
{
|
||||
for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
|
||||
{
|
||||
// Get the prediction context and status
|
||||
pred_flag = get_pred_flag( xd, PRED_REF );
|
||||
pred_context = get_pred_context( cm, xd, PRED_REF );
|
||||
|
||||
// Count prediction success
|
||||
ref_pred_count[pred_context][pred_flag]++;
|
||||
|
||||
// Step on to the next mb
|
||||
xd->mode_info_context++;
|
||||
}
|
||||
|
||||
// this is to account for the border in mode_info_context
|
||||
xd->mode_info_context++;
|
||||
}
|
||||
|
||||
// TEMP / Print out prediction quality numbers
|
||||
if (0)
|
||||
{
|
||||
FILE *f = fopen("predquality.stt", "a");
|
||||
int pred0, pred1, pred2;
|
||||
|
||||
|
||||
pred0 = ref_pred_count[0][0] + ref_pred_count[0][1];
|
||||
if ( pred0 )
|
||||
pred0 = (ref_pred_count[0][1] * 255) / pred0;
|
||||
|
||||
pred1 = ref_pred_count[1][0] + ref_pred_count[1][1];
|
||||
if ( pred1 )
|
||||
pred1 = (ref_pred_count[1][1] * 255) / pred1;
|
||||
|
||||
pred2 = ref_pred_count[2][0] + ref_pred_count[2][1];
|
||||
if ( pred2 )
|
||||
pred2 = (ref_pred_count[2][1] * 255) / pred2;
|
||||
|
||||
fprintf(f, "%8d: %8d %8d: %8d %8d: %8d %8d\n",
|
||||
cm->current_video_frame,
|
||||
pred0, ref_pred_count[0][1],
|
||||
pred1, ref_pred_count[1][1],
|
||||
pred2, ref_pred_count[2][1] );
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
// From the prediction counts set the probabilities for each context
|
||||
for ( i = 0; i < PREDICTION_PROBS; i++ )
|
||||
{
|
||||
// MB reference frame not relevent to key frame encoding
|
||||
if ( cm->frame_type != KEY_FRAME )
|
||||
{
|
||||
// Work out the probabilities for the reference frame predictor
|
||||
tot_count = ref_pred_count[i][0] + ref_pred_count[i][1];
|
||||
if ( tot_count )
|
||||
{
|
||||
new_pred_probs[i] =
|
||||
( ref_pred_count[i][0] * 255 ) / tot_count;
|
||||
|
||||
// Clamp to minimum allowed value
|
||||
new_pred_probs[i] += !new_pred_probs[i];
|
||||
}
|
||||
else
|
||||
new_pred_probs[i] = 128;
|
||||
}
|
||||
else
|
||||
new_pred_probs[i] = 128;
|
||||
|
||||
// Decide whether or not to update the reference frame probs.
|
||||
// Returned costs are in 1/256 bit units.
|
||||
old_cost =
|
||||
(ref_pred_count[i][0] * vp8_cost_zero(cm->ref_pred_probs[i])) +
|
||||
(ref_pred_count[i][1] * vp8_cost_one(cm->ref_pred_probs[i]));
|
||||
|
||||
new_cost =
|
||||
(ref_pred_count[i][0] * vp8_cost_zero(new_pred_probs[i])) +
|
||||
(ref_pred_count[i][1] * vp8_cost_one(new_pred_probs[i]));
|
||||
|
||||
// Cost saving must be >= 8 bits (2048 in these units)
|
||||
if ( (old_cost - new_cost) >= 2048 )
|
||||
{
|
||||
cpi->ref_probs_update[i] = 1;
|
||||
cm->ref_pred_probs[i] = new_pred_probs[i];
|
||||
}
|
||||
else
|
||||
cpi->ref_probs_update[i] = 0;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void encode_frame_to_data_rate
|
||||
(
|
||||
VP8_COMP *cpi,
|
||||
|
@ -4021,7 +4165,9 @@ static void encode_frame_to_data_rate
|
|||
}
|
||||
#endif
|
||||
|
||||
#if !CONFIG_COMPRED
|
||||
update_rd_ref_frame_probs(cpi);
|
||||
#endif
|
||||
|
||||
// Test code for new segment features
|
||||
init_seg_features( cpi );
|
||||
|
@ -4872,6 +5018,12 @@ static void encode_frame_to_data_rate
|
|||
cpi->segmentation_map, cm->MBs );
|
||||
}
|
||||
|
||||
#if CONFIG_COMPRED
|
||||
// Update the common prediction model probabilities to reflect
|
||||
// the what was seen in the current frame.
|
||||
update_refpred_stats( cpi );
|
||||
#endif
|
||||
|
||||
// build the bitstream
|
||||
vp8_pack_bitstream(cpi, dest, size);
|
||||
|
||||
|
|
|
@ -512,14 +512,15 @@ typedef struct VP8_COMP
|
|||
#if CONFIG_DUALPRED
|
||||
int prob_dualpred[3];
|
||||
#endif /* CONFIG_DUALPRED */
|
||||
int recent_ref_frame_usage[MAX_REF_FRAMES];
|
||||
|
||||
int recent_ref_frame_usage[MAX_REF_FRAMES];
|
||||
int count_mb_ref_frame_usage[MAX_REF_FRAMES];
|
||||
int this_frame_percent_intra;
|
||||
int last_frame_percent_intra;
|
||||
|
||||
int ref_frame_flags;
|
||||
|
||||
unsigned char ref_probs_update[PREDICTION_PROBS];
|
||||
|
||||
SPEED_FEATURES sf;
|
||||
int error_bins[1024];
|
||||
|
||||
|
|
|
@ -597,6 +597,10 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
|
|||
x->e_mbd.mode_info_context->mbmi.mode = this_mode;
|
||||
x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED;
|
||||
|
||||
|
||||
// #if CONFIG_COMPRED
|
||||
// TODO... this will all need changing for new reference frame coding model
|
||||
// #endif
|
||||
// Work out the cost assosciated with selecting the reference frame
|
||||
frame_cost =
|
||||
x->e_mbd.ref_frame_cost[x->e_mbd.mode_info_context->mbmi.ref_frame];
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
|
||||
//#if CONFIG_SEGFEATURES
|
||||
#include "vp8/common/seg_common.h"
|
||||
#include "vp8/common/pred_common.h"
|
||||
|
||||
#if CONFIG_RUNTIME_CPU_DETECT
|
||||
#define IF_RTCD(x) (x)
|
||||
|
@ -47,7 +48,6 @@
|
|||
#define IF_RTCD(x) NULL
|
||||
#endif
|
||||
|
||||
|
||||
extern void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x);
|
||||
extern void vp8_update_zbin_extra(VP8_COMP *cpi, MACROBLOCK *x);
|
||||
|
||||
|
@ -2030,6 +2030,66 @@ static void set_i8x8_block_modes(MACROBLOCK *x, int *modes)
|
|||
}
|
||||
}
|
||||
|
||||
#if CONFIG_COMPRED
|
||||
void vp8_estimate_ref_frame_costs(VP8_COMP *cpi, unsigned int * ref_costs )
|
||||
{
|
||||
VP8_COMMON *cm = &cpi->common;
|
||||
MACROBLOCKD *xd = &cpi->mb.e_mbd;
|
||||
vp8_prob * mod_refprobs;
|
||||
|
||||
unsigned int cost;
|
||||
int pred_ref ;
|
||||
int pred_flag;
|
||||
int i;
|
||||
|
||||
vp8_prob pred_prob;
|
||||
|
||||
// Get the predicted reference for this mb
|
||||
pred_ref = get_pred_ref( cm, xd );
|
||||
|
||||
// Get the context probability for the prediction flag
|
||||
pred_prob = get_pred_prob( cm, xd, PRED_REF );
|
||||
|
||||
// Get the set of probailities to use if prediction fails
|
||||
mod_refprobs = cm->mod_refprobs[pred_ref];
|
||||
|
||||
// For each possible selected reference frame work out a cost.
|
||||
// TODO: correct handling of costs if segment indicates only a subset of
|
||||
// reference frames are allowed... though mostly this should come out
|
||||
// in the wash.
|
||||
for ( i = 0; i < MAX_REF_FRAMES; i++ )
|
||||
{
|
||||
pred_flag = (i == pred_ref);
|
||||
|
||||
// Get the prediction for the current mb
|
||||
cost = vp8_cost_bit( pred_prob, pred_flag );
|
||||
|
||||
// for incorectly predicted cases
|
||||
if ( ! pred_flag )
|
||||
{
|
||||
if ( mod_refprobs[0] )
|
||||
cost += vp8_cost_bit( (i != INTRA_FRAME), mod_refprobs[0] );
|
||||
|
||||
// Inter coded
|
||||
if (i != INTRA_FRAME)
|
||||
{
|
||||
if ( mod_refprobs[1] )
|
||||
cost += vp8_cost_bit( (i != LAST_FRAME), mod_refprobs[1] );
|
||||
|
||||
if (i != LAST_FRAME)
|
||||
{
|
||||
if ( mod_refprobs[2] )
|
||||
cost += vp8_cost_bit( (i != GOLDEN_FRAME),
|
||||
mod_refprobs[2] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ref_costs[i] = cost;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int recon_uvoffset,
|
||||
int *returnrate, int *returndistortion, int *returnintra,
|
||||
int *best_single_rd_diff, int *best_dual_rd_diff,
|
||||
|
@ -2089,8 +2149,13 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
|
|||
unsigned char *u_buffer[4];
|
||||
unsigned char *v_buffer[4];
|
||||
|
||||
#if CONFIG_COMPRED
|
||||
unsigned int ref_costs[MAX_REF_FRAMES];
|
||||
#endif
|
||||
|
||||
vpx_memset(&best_mbmode, 0, sizeof(best_mbmode));
|
||||
vpx_memset(&best_bmodes, 0, sizeof(best_bmodes));
|
||||
|
||||
#if CONFIG_DUALPRED
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
|
@ -2158,6 +2223,12 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
|
|||
rd_pick_intra_mbuv_mode(cpi, x, &uv_intra_rate, &uv_intra_rate_tokenonly, &uv_intra_distortion);
|
||||
uv_intra_mode = x->e_mbd.mode_info_context->mbmi.uv_mode;
|
||||
|
||||
#if CONFIG_COMPRED
|
||||
// Get estimates of reference frame costs for each reference frame
|
||||
// that depend on the current prediction etc.
|
||||
vp8_estimate_ref_frame_costs( cpi, ref_costs );
|
||||
#endif
|
||||
|
||||
for (mode_index = 0; mode_index < MAX_MODES; mode_index++)
|
||||
{
|
||||
int this_rd = INT_MAX;
|
||||
|
@ -2733,11 +2804,15 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
|
|||
}
|
||||
#endif /* CONFIG_DUALPRED */
|
||||
|
||||
/* Estimate the reference frame signaling cost and add it
|
||||
* to the rolling cost variable.
|
||||
*/
|
||||
|
||||
// Estimate the reference frame signaling cost and add it
|
||||
// to the rolling cost variable.
|
||||
#if CONFIG_COMPRED
|
||||
rate2 += ref_costs[x->e_mbd.mode_info_context->mbmi.ref_frame];
|
||||
#else
|
||||
rate2 +=
|
||||
x->e_mbd.ref_frame_cost[x->e_mbd.mode_info_context->mbmi.ref_frame];
|
||||
#endif
|
||||
|
||||
if (!disable_skip)
|
||||
{
|
||||
|
@ -2818,8 +2893,12 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
|
|||
x->e_mbd.mode_info_context->mbmi.mv.as_int = 0;
|
||||
}
|
||||
|
||||
#if CONFIG_COMPRED
|
||||
other_cost += ref_costs[x->e_mbd.mode_info_context->mbmi.ref_frame];
|
||||
#else
|
||||
other_cost +=
|
||||
x->e_mbd.ref_frame_cost[x->e_mbd.mode_info_context->mbmi.ref_frame];
|
||||
x->e_mbd.ref_frame_cost[x->e_mbd.mode_info_context->mbmi.ref_frame];
|
||||
#endif
|
||||
|
||||
/* Calculate the final y RD estimate for this mode */
|
||||
best_yrd = RDCOST(x->rdmult, x->rddiv, (rate2-rate_uv-other_cost),
|
||||
|
|
Загрузка…
Ссылка в новой задаче