summaryrefslogtreecommitdiff
path: root/vp8/encoder
diff options
context:
space:
mode:
authorPaul Wilkins <paulwilkins@google.com>2012-04-11 15:44:14 +0100
committerPaul Wilkins <paulwilkins@google.com>2012-04-11 15:44:14 +0100
commit13c6d1a8c80bea1eccf21bbd267afbb3825d2797 (patch)
tree2c2e9391df2f6e17525f55fc2ae42a27a5a596d4 /vp8/encoder
parentf2ec452fbc8779fc2230148d7b446cc84929ff70 (diff)
downloadlibvpx-13c6d1a8c80bea1eccf21bbd267afbb3825d2797.tar
libvpx-13c6d1a8c80bea1eccf21bbd267afbb3825d2797.tar.gz
libvpx-13c6d1a8c80bea1eccf21bbd267afbb3825d2797.tar.bz2
libvpx-13c6d1a8c80bea1eccf21bbd267afbb3825d2797.zip
Refactoring of encode loop and bitstream packing
Some code re-factored / moved to allow the main pack operation inside the recode loop so that the size estimate is accurate. Deletion of some redundant code relating to one pass. Aproximate improvement over March 27 code base: Derf 0.0%, YT 0.5%, YThd 0.3% Std_hd 0.25% Change-Id: Id2d071794ab44f0b52935f6fcdb5733d09a6bb86
Diffstat (limited to 'vp8/encoder')
-rw-r--r--vp8/encoder/bitstream.c296
-rw-r--r--vp8/encoder/encodeframe.c49
-rw-r--r--vp8/encoder/firstpass.c1
-rw-r--r--vp8/encoder/onyx_if.c419
-rw-r--r--vp8/encoder/onyx_int.h53
-rw-r--r--vp8/encoder/ratectrl.c88
6 files changed, 308 insertions, 598 deletions
diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c
index 065ea9f1b..8691ba356 100644
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -170,6 +170,106 @@ void update_skip_probs(VP8_COMP *cpi)
#endif
}
+// 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_pred_probs_update, 0,
+ sizeof(cpi->ref_pred_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++;
+ }
+
+ // 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_pred_probs_update[i] = 1;
+ cm->ref_pred_probs[i] = new_pred_probs[i];
+ }
+ else
+ cpi->ref_pred_probs_update[i] = 0;
+
+ }
+ }
+}
+
static void write_ymode(vp8_writer *bc, int m, const vp8_prob *p)
{
vp8_write_token(bc, vp8_ymode_tree, p, vp8_ymode_encodings + m);
@@ -1307,88 +1407,35 @@ static int default_coef_context_savings(VP8_COMP *cpi)
return savings;
}
-int vp8_estimate_entropy_savings(VP8_COMP *cpi)
+void build_coeff_contexts(VP8_COMP *cpi)
{
- int savings = 0;
- int i=0;
- 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];
- int new_intra, new_last, new_gf_alt, oldtotal, newtotal;
- int ref_frame_cost[MAX_REF_FRAMES];
-
- vp8_clear_system_state(); //__asm emms;
-
- // Estimate reference frame cost savings.
- // For now this is just based on projected overall frequency of
- // each reference frame coded using an unpredicted coding tree.
- if (cpi->common.frame_type != KEY_FRAME)
+ int i = 0;
+ do
{
- new_intra = (rf_intra + rf_inter)
- ? rf_intra * 255 / (rf_intra + rf_inter) : 1;
- new_intra += !new_intra;
-
- new_last = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
- new_last += !new_last;
-
- new_gf_alt = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
- ? (rfct[GOLDEN_FRAME] * 255) /
- (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]) : 128;
- new_gf_alt += !new_gf_alt;
-
- // new costs
- ref_frame_cost[INTRA_FRAME] = vp8_cost_zero(new_intra);
- ref_frame_cost[LAST_FRAME] = vp8_cost_one(new_intra)
- + vp8_cost_zero(new_last);
- ref_frame_cost[GOLDEN_FRAME] = vp8_cost_one(new_intra)
- + vp8_cost_one(new_last)
- + vp8_cost_zero(new_gf_alt);
- ref_frame_cost[ALTREF_FRAME] = vp8_cost_one(new_intra)
- + vp8_cost_one(new_last)
- + vp8_cost_one(new_gf_alt);
-
- newtotal =
- rfct[INTRA_FRAME] * ref_frame_cost[INTRA_FRAME] +
- rfct[LAST_FRAME] * ref_frame_cost[LAST_FRAME] +
- rfct[GOLDEN_FRAME] * ref_frame_cost[GOLDEN_FRAME] +
- rfct[ALTREF_FRAME] * ref_frame_cost[ALTREF_FRAME];
-
- // old costs
- ref_frame_cost[INTRA_FRAME] = vp8_cost_zero(cm->prob_intra_coded);
- ref_frame_cost[LAST_FRAME] = vp8_cost_one(cm->prob_intra_coded)
- + vp8_cost_zero(cm->prob_last_coded);
- ref_frame_cost[GOLDEN_FRAME] = vp8_cost_one(cm->prob_intra_coded)
- + vp8_cost_one(cm->prob_last_coded)
- + vp8_cost_zero(cm->prob_gf_coded);
- ref_frame_cost[ALTREF_FRAME] = vp8_cost_one(cm->prob_intra_coded)
- + vp8_cost_one(cm->prob_last_coded)
- + vp8_cost_one(cm->prob_gf_coded);
-
- oldtotal =
- rfct[INTRA_FRAME] * ref_frame_cost[INTRA_FRAME] +
- rfct[LAST_FRAME] * ref_frame_cost[LAST_FRAME] +
- rfct[GOLDEN_FRAME] * ref_frame_cost[GOLDEN_FRAME] +
- rfct[ALTREF_FRAME] * ref_frame_cost[ALTREF_FRAME];
-
- savings += (oldtotal - newtotal) / 256;
-
- // Update the reference frame probability numbers to reflect
- // the observed counts in this frame. Doing this here insures
- // that if there are multiple recode iterations the baseline
- // probabilities used are updated in each iteration.
- cm->prob_intra_coded = new_intra;
- cm->prob_last_coded = new_last;
- cm->prob_gf_coded = new_gf_alt;
+ int j = 0;
+ do
+ {
+ int k = 0;
+ do
+ {
+ vp8_tree_probs_from_distribution(
+ MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
+ cpi->frame_coef_probs [i][j][k],
+ cpi->frame_branch_ct [i][j][k],
+ cpi->coef_counts [i][j][k],
+ 256, 1
+ );
+ }
+ while (++k < PREV_COEF_CONTEXTS);
+ }
+ while (++j < COEF_BANDS);
}
-
- savings += default_coef_context_savings(cpi);
+ while (++i < BLOCK_TYPES);
- /* do not do this if not evena allowed */
+ i= 0;
if(cpi->common.txfm_mode == ALLOW_8X8)
{
- int savings8x8 = 0;
do
{
int j = 0;
@@ -1410,40 +1457,14 @@ int vp8_estimate_entropy_savings(VP8_COMP *cpi)
256, 1
);
- do
- {
- const unsigned int *ct = cpi->frame_branch_ct_8x8 [i][j][k][t];
- const vp8_prob newp = cpi->frame_coef_probs_8x8 [i][j][k][t];
-
- const vp8_prob old = cpi->common.fc.coef_probs_8x8 [i][j][k][t];
- const vp8_prob upd = vp8_coef_update_probs_8x8 [i][j][k][t];
-
- const int old_b = vp8_cost_branch(ct, old);
- const int new_b = vp8_cost_branch(ct, newp);
-
- const int update_b = 8 + vp8_cost_upd;
-
- const int s = old_b - new_b - update_b;
-
- if (s > 0)
- savings8x8 += s;
-
-
- }
- while (++t < MAX_ENTROPY_TOKENS - 1);
-
-
}
while (++k < PREV_COEF_CONTEXTS);
}
while (++j < COEF_BANDS);
}
while (++i < BLOCK_TYPES);
-
- savings += savings8x8 >> 8;
}
- return savings;
}
static void update_coef_probs(VP8_COMP *cpi)
@@ -1453,6 +1474,10 @@ static void update_coef_probs(VP8_COMP *cpi)
int update = 0;
vp8_clear_system_state(); //__asm emms;
+
+ // Build the cofficient contexts based on counts collected in encode loop
+ build_coeff_contexts(cpi);
+
/* dry run to see if there is any udpate at all needed */
do
{
@@ -1463,17 +1488,7 @@ static void update_coef_probs(VP8_COMP *cpi)
int prev_coef_savings[ENTROPY_NODES] = {0};
do
{
- //note: use result from vp8_estimate_entropy_savings, so no need to call vp8_tree_probs_from_distribution here.
- /* at every context */
- /* calc probs and branch cts for this frame only */
- //vp8_prob new_p [ENTROPY_NODES];
- //unsigned int branch_ct [ENTROPY_NODES] [2];
int t = 0; /* token/prob index */
- //vp8_tree_probs_from_distribution(
- // MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
- // new_p, branch_ct, (unsigned int *)cpi->coef_counts [i][j][k],
- // 256, 1
- // );
do
{
const vp8_prob newp = cpi->frame_coef_probs [i][j][k][t];
@@ -1492,7 +1507,6 @@ static void update_coef_probs(VP8_COMP *cpi)
update += u;
}
while (++t < ENTROPY_NODES);
- /* Accum token counts for generation of default statistics */
}
while (++k < PREV_COEF_CONTEXTS);
}
@@ -1518,18 +1532,8 @@ static void update_coef_probs(VP8_COMP *cpi)
do
{
- //note: use result from vp8_estimate_entropy_savings, so no need to call vp8_tree_probs_from_distribution here.
- /* at every context */
-
- /* calc probs and branch cts for this frame only */
- //vp8_prob new_p [ENTROPY_NODES];
- //unsigned int branch_ct [ENTROPY_NODES] [2];
+ // calc probs and branch cts for this frame only
int t = 0; /* token/prob index */
- //vp8_tree_probs_from_distribution(
- // MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
- // new_p, branch_ct, (unsigned int *)cpi->coef_counts [i][j][k],
- // 256, 1
- // );
do
{
const vp8_prob newp = cpi->frame_coef_probs [i][j][k][t];
@@ -1557,7 +1561,8 @@ static void update_coef_probs(VP8_COMP *cpi)
}
}
while (++t < ENTROPY_NODES);
- /* Accum token counts for generation of default statistics */
+
+ // Accum token counts for generation of default statistics
#ifdef ENTROPY_STATS
t = 0;
do
@@ -1589,17 +1594,8 @@ static void update_coef_probs(VP8_COMP *cpi)
int k = 0;
do
{
- //note: use result from vp8_estimate_entropy_savings, so no need to call vp8_tree_probs_from_distribution here.
- /* at every context */
- /* calc probs and branch cts for this frame only */
- //vp8_prob new_p [ENTROPY_NODES];
- //unsigned int branch_ct [ENTROPY_NODES] [2];
+ // calc probs and branch cts for this frame only
int t = 0; /* token/prob index */
- //vp8_tree_probs_from_distribution(
- // MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
- // new_p, branch_ct, (unsigned int *)cpi->coef_counts [i][j][k],
- // 256, 1
- // );
do
{
const unsigned int *ct = cpi->frame_branch_ct_8x8 [i][j][k][t];
@@ -1620,7 +1616,7 @@ static void update_coef_probs(VP8_COMP *cpi)
}
while (++t < MAX_ENTROPY_TOKENS - 1);
- /* Accum token counts for generation of default statistics */
+ // Accum token counts for generation of default statistics
#ifdef ENTROPY_STATS
t = 0;
@@ -1655,17 +1651,7 @@ static void update_coef_probs(VP8_COMP *cpi)
int k = 0;
do
{
- //note: use result from vp8_estimate_entropy_savings, so no need to call vp8_tree_probs_from_distribution here.
- /* at every context */
- /* calc probs and branch cts for this frame only */
- //vp8_prob new_p [ENTROPY_NODES];
- //unsigned int branch_ct [ENTROPY_NODES] [2];
int t = 0; /* token/prob index */
- //vp8_tree_probs_from_distribution(
- // MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
- // new_p, branch_ct, (unsigned int *)cpi->coef_counts [i][j][k],
- // 256, 1
- // );
do
{
const unsigned int *ct = cpi->frame_branch_ct_8x8 [i][j][k][t];
@@ -1690,7 +1676,7 @@ static void update_coef_probs(VP8_COMP *cpi)
}
}
while (++t < MAX_ENTROPY_TOKENS - 1);
- /* Accum token counts for generation of default statistics */
+ // Accum token counts for generation of default statistics
#ifdef ENTROPY_STATS
t = 0;
do
@@ -1851,7 +1837,18 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
// If it is, then indicate the method that will be used.
if ( xd->update_mb_segmentation_map )
+ {
+ // Select the coding strategy (temporal or spatial)
+ choose_segmap_coding_method( cpi );
+
+ // Take a copy of the segment map if it changed for
+ // future comparison
+ vpx_memcpy( pc->last_frame_seg_map,
+ cpi->segmentation_map, pc->MBs );
+
+ // Write out the chosen coding method.
vp8_write_bit(bc, (pc->temporal_update) ? 1:0);
+ }
vp8_write_bit(bc, (xd->update_mb_segmentation_data) ? 1 : 0);
@@ -2002,6 +1999,7 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
// Encode the common prediction model status flag probability updates for
// the reference frame
+ update_refpred_stats( cpi );
if ( pc->frame_type != KEY_FRAME )
{
for (i = 0; i < PREDICTION_PROBS; i++)
@@ -2112,6 +2110,12 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
vp8_write_bit(bc, pc->refresh_golden_frame);
vp8_write_bit(bc, pc->refresh_alt_ref_frame);
+ // For inter frames the current default behavior is that when
+ // cm->refresh_golden_frame is set we copy the old GF over to
+ // the ARF buffer. This is purely an encoder decision at present.
+ if (pc->refresh_golden_frame)
+ pc->copy_buffer_to_arf = 2;
+
// If not being updated from current frame should either GF or ARF be updated from another buffer
if (!pc->refresh_golden_frame)
vp8_write_literal(bc, pc->copy_buffer_to_gf, 2);
diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c
index e742809c8..5032cbdce 100644
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -1217,55 +1217,6 @@ static void encode_frame_internal(VP8_COMP *cpi)
// projected_frame_size in units of BYTES
cpi->projected_frame_size = totalrate >> 8;
- // Make a note of the percentage MBs coded Intra.
- if (cm->frame_type == KEY_FRAME)
- {
- cpi->this_frame_percent_intra = 100;
- }
- else
- {
- int tot_modes;
-
- tot_modes = cpi->count_mb_ref_frame_usage[INTRA_FRAME]
- + cpi->count_mb_ref_frame_usage[LAST_FRAME]
- + cpi->count_mb_ref_frame_usage[GOLDEN_FRAME]
- + cpi->count_mb_ref_frame_usage[ALTREF_FRAME];
-
- if (tot_modes)
- cpi->this_frame_percent_intra =
- cpi->count_mb_ref_frame_usage[INTRA_FRAME] * 100 / tot_modes;
-
- }
-
-#if 0
- {
- int cnt = 0;
- int flag[2] = {0, 0};
-
- for (cnt = 0; cnt < MVPcount; cnt++)
- {
- if (cm->fc.pre_mvc[0][cnt] != cm->fc.mvc[0][cnt])
- {
- flag[0] = 1;
- vpx_memcpy(cm->fc.pre_mvc[0], cm->fc.mvc[0], MVPcount);
- break;
- }
- }
-
- for (cnt = 0; cnt < MVPcount; cnt++)
- {
- if (cm->fc.pre_mvc[1][cnt] != cm->fc.mvc[1][cnt])
- {
- flag[1] = 1;
- vpx_memcpy(cm->fc.pre_mvc[1], cm->fc.mvc[1], MVPcount);
- break;
- }
- }
-
- if (flag[0] || flag[1])
- vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cm->fc.mvc, flag);
- }
-#endif
#if 0
// Keep record of the total distortion this time around for future use
diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c
index b561ea338..1e8594d7b 100644
--- a/vp8/encoder/firstpass.c
+++ b/vp8/encoder/firstpass.c
@@ -1845,6 +1845,7 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
// Should we use the alternate refernce frame
if (allow_alt_ref &&
+ (i < cpi->oxcf.lag_in_frames ) &&
(i >= MIN_GF_INTERVAL) &&
// dont use ARF very near next kf
(i <= (cpi->twopass.frames_to_key - MIN_GF_INTERVAL)) &&
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index a758b1927..e547c9ddf 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -70,7 +70,6 @@ extern void vp8_yv12_copy_frame_func_neon(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFF
extern void vp8_yv12_copy_src_frame_func_neon(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
#endif
-int vp8_estimate_entropy_savings(VP8_COMP *cpi);
int vp8_calc_ss_err(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *dest, const vp8_variance_rtcd_vtable_t *rtcd);
extern void vp8_temporal_filter_prepare_c(VP8_COMP *cpi, int distance);
@@ -413,6 +412,8 @@ static void dealloc_compressor_data(VP8_COMP *cpi)
cpi->segmentation_map = 0;
vpx_free(cpi->common.last_frame_seg_map);
cpi->common.last_frame_seg_map = 0;
+ vpx_free(cpi->coding_context.last_frame_seg_map_copy);
+ cpi->coding_context.last_frame_seg_map_copy = 0;
vpx_free(cpi->active_map);
cpi->active_map = 0;
@@ -1660,6 +1661,11 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf)
CHECK_MEM_ERROR(cm->last_frame_seg_map,
vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
+ // And a place holder structure is the coding context
+ // for use if we want to save and restore it
+ CHECK_MEM_ERROR(cpi->coding_context.last_frame_seg_map_copy,
+ vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
+
CHECK_MEM_ERROR(cpi->active_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1));
vpx_memset(cpi->active_map , 1, (cpi->common.mb_rows * cpi->common.mb_cols));
cpi->active_map_enabled = 0;
@@ -2480,47 +2486,6 @@ static void update_golden_frame_stats(VP8_COMP *cpi)
}
}
-// 1 = key, 0 = inter
-static int decide_key_frame(VP8_COMP *cpi)
-{
- VP8_COMMON *cm = &cpi->common;
-
- int code_key_frame = FALSE;
-
- cpi->kf_boost = 0;
-
- if (cpi->Speed > 11)
- return FALSE;
-
- // Clear down mmx registers
- vp8_clear_system_state(); //__asm emms;
-
- // If the following are true we might as well code a key frame
- if (((cpi->this_frame_percent_intra == 100) &&
- (cpi->this_frame_percent_intra > (cpi->last_frame_percent_intra + 2))) ||
- ((cpi->this_frame_percent_intra > 95) &&
- (cpi->this_frame_percent_intra >= (cpi->last_frame_percent_intra + 5))))
- {
- code_key_frame = TRUE;
- }
- // in addition if the following are true and this is not a golden frame then code a key frame
- // Note that on golden frames there often seems to be a pop in intra useage anyway hence this
- // restriction is designed to prevent spurious key frames. The Intra pop needs to be investigated.
- else if (((cpi->this_frame_percent_intra > 60) &&
- (cpi->this_frame_percent_intra > (cpi->last_frame_percent_intra * 2))) ||
- ((cpi->this_frame_percent_intra > 75) &&
- (cpi->this_frame_percent_intra > (cpi->last_frame_percent_intra * 3 / 2))) ||
- ((cpi->this_frame_percent_intra > 90) &&
- (cpi->this_frame_percent_intra > (cpi->last_frame_percent_intra + 10))))
- {
- if (!cm->refresh_golden_frame)
- code_key_frame = TRUE;
- }
-
- return code_key_frame;
-
-}
-
int find_fp_qindex()
{
int i;
@@ -2812,106 +2777,6 @@ void loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm)
}
-// 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_pred_probs_update, 0,
- sizeof(cpi->ref_pred_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++;
- }
-
- // 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_pred_probs_update[i] = 1;
- cm->ref_pred_probs[i] = new_pred_probs[i];
- }
- else
- cpi->ref_pred_probs_update[i] = 0;
-
- }
- }
-}
-
static void encode_frame_to_data_rate
(
VP8_COMP *cpi,
@@ -3028,12 +2893,7 @@ static void encode_frame_to_data_rate
init_seg_features( cpi );
// Decide how big to make the frame
- if (!vp8_pick_frame_size(cpi))
- {
- cm->current_video_frame++;
- cpi->frames_since_key++;
- return;
- }
+ vp8_pick_frame_size(cpi);
vp8_clear_system_state();
@@ -3156,7 +3016,6 @@ static void encode_frame_to_data_rate
q_low = cpi->active_best_quality;
q_high = cpi->active_worst_quality;
- vp8_save_coding_context(cpi);
loop_count = 0;
@@ -3235,97 +3094,100 @@ static void encode_frame_to_data_rate
vp8_set_quantizer(cpi, Q);
this_q = Q;
- // setup skip prob for costing in mode/mv decision
- if (cpi->common.mb_no_coeff_skip)
+ if ( loop_count == 0 )
{
+ // setup skip prob for costing in mode/mv decision
+ if (cpi->common.mb_no_coeff_skip)
+ {
#if CONFIG_NEWENTROPY
- int k;
- for (k=0; k<MBSKIP_CONTEXTS; k++)
- cm->mbskip_pred_probs[k] = cpi->base_skip_false_prob[Q][k];
+ int k;
+ for (k=0; k<MBSKIP_CONTEXTS; k++)
+ cm->mbskip_pred_probs[k] = cpi->base_skip_false_prob[Q][k];
#else
- cpi->prob_skip_false = cpi->base_skip_false_prob[Q];
+ cpi->prob_skip_false = cpi->base_skip_false_prob[Q];
#endif
- if (cm->frame_type != KEY_FRAME)
- {
- if (cpi->common.refresh_alt_ref_frame)
+ if (cm->frame_type != KEY_FRAME)
{
-#if CONFIG_NEWENTROPY
- for (k=0; k<MBSKIP_CONTEXTS; k++)
+ if (cpi->common.refresh_alt_ref_frame)
{
- if (cpi->last_skip_false_probs[2][k] != 0)
- cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[2][k];
- }
+#if CONFIG_NEWENTROPY
+ for (k=0; k<MBSKIP_CONTEXTS; k++)
+ {
+ if (cpi->last_skip_false_probs[2][k] != 0)
+ cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[2][k];
+ }
#else
- if (cpi->last_skip_false_probs[2] != 0)
- cpi->prob_skip_false = cpi->last_skip_false_probs[2];
+ if (cpi->last_skip_false_probs[2] != 0)
+ cpi->prob_skip_false = cpi->last_skip_false_probs[2];
#endif
- }
- else if (cpi->common.refresh_golden_frame)
- {
-#if CONFIG_NEWENTROPY
- for (k=0; k<MBSKIP_CONTEXTS; k++)
- {
- if (cpi->last_skip_false_probs[1][k] != 0)
- cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[1][k];
}
+ else if (cpi->common.refresh_golden_frame)
+ {
+#if CONFIG_NEWENTROPY
+ for (k=0; k<MBSKIP_CONTEXTS; k++)
+ {
+ if (cpi->last_skip_false_probs[1][k] != 0)
+ cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[1][k];
+ }
#else
- if (cpi->last_skip_false_probs[1] != 0)
- cpi->prob_skip_false = cpi->last_skip_false_probs[1];
+ if (cpi->last_skip_false_probs[1] != 0)
+ cpi->prob_skip_false = cpi->last_skip_false_probs[1];
#endif
- }
- else
- {
-#if CONFIG_NEWENTROPY
- int k;
- for (k=0; k<MBSKIP_CONTEXTS; k++)
- {
- if (cpi->last_skip_false_probs[0][k] != 0)
- cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[0][k];
}
+ else
+ {
+#if CONFIG_NEWENTROPY
+ int k;
+ for (k=0; k<MBSKIP_CONTEXTS; k++)
+ {
+ if (cpi->last_skip_false_probs[0][k] != 0)
+ cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[0][k];
+ }
#else
- if (cpi->last_skip_false_probs[0] != 0)
- cpi->prob_skip_false = cpi->last_skip_false_probs[0];
+ if (cpi->last_skip_false_probs[0] != 0)
+ cpi->prob_skip_false = cpi->last_skip_false_probs[0];
#endif
- }
+ }
- // as this is for cost estimate, let's make sure it does not
- // get extreme either way
+ // as this is for cost estimate, let's make sure it does not
+ // get extreme either way
#if CONFIG_NEWENTROPY
- {
- int k;
- for (k=0; k<MBSKIP_CONTEXTS; ++k)
{
- if (cm->mbskip_pred_probs[k] < 5)
- cm->mbskip_pred_probs[k] = 5;
-
- if (cm->mbskip_pred_probs[k] > 250)
- cm->mbskip_pred_probs[k] = 250;
-
- if (cpi->is_src_frame_alt_ref)
- cm->mbskip_pred_probs[k] = 1;
+ int k;
+ for (k=0; k<MBSKIP_CONTEXTS; ++k)
+ {
+ if (cm->mbskip_pred_probs[k] < 5)
+ cm->mbskip_pred_probs[k] = 5;
+
+ if (cm->mbskip_pred_probs[k] > 250)
+ cm->mbskip_pred_probs[k] = 250;
+
+ if (cpi->is_src_frame_alt_ref)
+ cm->mbskip_pred_probs[k] = 1;
+ }
}
- }
#else
- if (cpi->prob_skip_false < 5)
- cpi->prob_skip_false = 5;
+ if (cpi->prob_skip_false < 5)
+ cpi->prob_skip_false = 5;
- if (cpi->prob_skip_false > 250)
- cpi->prob_skip_false = 250;
+ if (cpi->prob_skip_false > 250)
+ cpi->prob_skip_false = 250;
- if (cpi->is_src_frame_alt_ref)
- cpi->prob_skip_false = 1;
+ if (cpi->is_src_frame_alt_ref)
+ cpi->prob_skip_false = 1;
#endif
+ }
}
- }
- // Set up entropy depending on frame type.
- if (cm->frame_type == KEY_FRAME)
- vp8_setup_key_frame(cpi);
- else
- vp8_setup_inter_frame(cpi);
+ // Set up entropy depending on frame type.
+ if (cm->frame_type == KEY_FRAME)
+ vp8_setup_key_frame(cpi);
+ else
+ vp8_setup_inter_frame(cpi);
+ }
// transform / motion compensation build reconstruction frame
vp8_encode_frame(cpi);
@@ -3334,9 +3196,6 @@ static void encode_frame_to_data_rate
// seen in the last encoder iteration.
update_base_skip_probs( cpi );
- cpi->projected_frame_size -= vp8_estimate_entropy_savings(cpi);
- cpi->projected_frame_size = (cpi->projected_frame_size > 0) ? cpi->projected_frame_size : 0;
-
vp8_clear_system_state(); //__asm emms;
if (frame_over_shoot_limit == 0)
@@ -3344,6 +3203,14 @@ static void encode_frame_to_data_rate
active_worst_qchanged = FALSE;
+ // Dummy pack of the bitstream using up to date stats to get an
+ // accurate estimate of output frame size to determine if we need
+ // to recode.
+ vp8_save_coding_context(cpi);
+ vp8_pack_bitstream(cpi, dest, size);
+ cpi->projected_frame_size = (*size) << 3;
+ vp8_restore_coding_context(cpi);
+
// Special case handling for forced key frames
if ( (cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced )
{
@@ -3353,7 +3220,7 @@ static void encode_frame_to_data_rate
IF_RTCD(&cpi->rtcd.variance));
int high_err_target = cpi->ambient_err;
- int low_err_target = ((cpi->ambient_err * 3) >> 2);
+ int low_err_target = (cpi->ambient_err >> 1);
// Prevent possible divide by zero error below for perfect KF
kf_err += (!kf_err);
@@ -3521,7 +3388,6 @@ static void encode_frame_to_data_rate
if (Loop == TRUE)
{
- vp8_restore_coding_context(cpi);
loop_count++;
#if CONFIG_INTERNAL_STATS
cpi->tot_recode_hits++;
@@ -3530,28 +3396,6 @@ static void encode_frame_to_data_rate
}
while (Loop == TRUE);
-#if 0
- // Experimental code for lagged and one pass
- // Update stats used for one pass GF selection
- {
- /*
- int frames_so_far;
- double frame_intra_error;
- double frame_coded_error;
- double frame_pcnt_inter;
- double frame_pcnt_motion;
- double frame_mvr;
- double frame_mvr_abs;
- double frame_mvc;
- double frame_mvc_abs;
- */
-
- cpi->one_pass_frame_stats[cpi->one_pass_frame_index].frame_coded_error = (double)cpi->prediction_error;
- cpi->one_pass_frame_stats[cpi->one_pass_frame_index].frame_intra_error = (double)cpi->intra_error;
- cpi->one_pass_frame_stats[cpi->one_pass_frame_index].frame_pcnt_inter = (double)(100 - cpi->this_frame_percent_intra) / 100.0;
- }
-#endif
-
// Special case code to reduce pulsing when key frames are forced at a
// fixed interval. Note the reconstruction error if it is the frame before
// the force key frame
@@ -3562,13 +3406,15 @@ static void encode_frame_to_data_rate
IF_RTCD(&cpi->rtcd.variance));
}
- // This frame's MVs are saved and will be used in next frame's MV prediction.
- // Last frame has one more line(add to bottom) and one more column(add to right) than cm->mip. The edge elements are initialized to 0.
+ // This frame's MVs are saved and will be used in next frame's MV
+ // prediction. Last frame has one more line(add to bottom) and one
+ // more column(add to right) than cm->mip. The edge elements are
+ // initialized to 0.
if(cm->show_frame) //do not save for altref frame
{
int mb_row;
int mb_col;
- MODE_INFO *tmp = cm->mip; //point to beginning of allocated MODE_INFO arrays.
+ MODE_INFO *tmp = cm->mip;
if(cm->frame_type != KEY_FRAME)
{
@@ -3588,8 +3434,8 @@ static void encode_frame_to_data_rate
}
// Update the GF useage maps.
- // This is done after completing the compression of a frame when all modes etc. are finalized but before loop filter
- // This is done after completing the compression of a frame when all modes etc. are finalized but before loop filter
+ // This is done after completing the compression of a frame when all modes
+ // etc. are finalized but before loop filter
vp8_update_gf_useage_maps(cpi, cm, &cpi->mb);
if (cm->frame_type == KEY_FRAME)
@@ -3603,12 +3449,6 @@ static void encode_frame_to_data_rate
}
#endif
- // For inter frames the current default behavior is that when
- // cm->refresh_golden_frame is set we copy the old GF over to the ARF buffer
- // This is purely an encoder decision at present.
- if (cm->refresh_golden_frame)
- cm->copy_buffer_to_arf = 2;
-
cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx];
#if WRITE_RECON_BUFFER
@@ -3620,34 +3460,13 @@ static void encode_frame_to_data_rate
cm->current_video_frame+1000);
#endif
- {
- loopfilter_frame(cpi, cm);
- }
-
- if(cm->show_frame)
- write_yuv_frame_to_file(cm->frame_to_show);
-
- update_reference_frames(cm);
-
- // Work out the segment probabilities if segmentation is enabled and
- // the map is due to be updated
- if (xd->segmentation_enabled && xd->update_mb_segmentation_map)
- {
- // Select the coding strategy for the segment map (temporal or spatial)
- choose_segmap_coding_method( cpi );
-
- // Take a copy of the segment map if it changed for future comparison
- vpx_memcpy( cm->last_frame_seg_map,
- cpi->segmentation_map, cm->MBs );
- }
-
- // Update the common prediction model probabilities to reflect
- // the what was seen in the current frame.
- update_refpred_stats( cpi );
+ // Pick the loop filter level for the frame.
+ loopfilter_frame(cpi, cm);
// build the bitstream
vp8_pack_bitstream(cpi, dest, size);
+ update_reference_frames(cm);
/* Move storing frame_type out of the above loop since it is also
* needed in motion search besides loopfilter */
@@ -3745,53 +3564,7 @@ static void encode_frame_to_data_rate
// Update the skip mb flag probabilities based on the distribution seen
// in this frame.
update_base_skip_probs( cpi );
-/*
- if (cm->frame_type != KEY_FRAME)
- {
- if (cpi->common.refresh_alt_ref_frame)
- {
-#if CONFIG_NEWENTROPY
- int k;
- for (k=0; k<MBSKIP_CONTEXTS; ++k)
- cpi->last_skip_false_probs[2][k] = cm->mbskip_pred_probs[k];
-#else
- cpi->last_skip_false_probs[2] = cpi->prob_skip_false;
-#endif
- cpi->last_skip_probs_q[2] = cm->base_qindex;
- }
- else if (cpi->common.refresh_golden_frame)
- {
-#if CONFIG_NEWENTROPY
- int k;
- for (k=0; k<MBSKIP_CONTEXTS; ++k)
- cpi->last_skip_false_probs[1][k] = cm->mbskip_pred_probs[k];
-#else
- cpi->last_skip_false_probs[1] = cpi->prob_skip_false;
-#endif
- cpi->last_skip_probs_q[1] = cm->base_qindex;
- }
- else
- {
-#if CONFIG_NEWENTROPY
- int k;
- for (k=0; k<MBSKIP_CONTEXTS; ++k)
- cpi->last_skip_false_probs[0][k] = cm->mbskip_pred_probs[k];
-#else
- cpi->last_skip_false_probs[0] = cpi->prob_skip_false;
-#endif
- cpi->last_skip_probs_q[0] = cm->base_qindex;
-
- //update the baseline
-#if CONFIG_NEWENTROPY
- for (k=0; k<MBSKIP_CONTEXTS; ++k)
- cpi->base_skip_false_prob[cm->base_qindex][k] = cm->mbskip_pred_probs[k];
-#else
- cpi->base_skip_false_prob[cm->base_qindex] = cpi->prob_skip_false;
-#endif
- }
- }
-*/
#if 0 && CONFIG_INTERNAL_STATS
{
FILE *f = fopen("tmp.stt", "a");
@@ -3942,14 +3715,10 @@ static void encode_frame_to_data_rate
// As this frame is a key frame the next defaults to an inter frame.
cm->frame_type = INTER_FRAME;
-
- cpi->last_frame_percent_intra = 100;
}
else
{
*frame_flags = cm->frame_flags&~FRAMEFLAGS_KEY;
-
- cpi->last_frame_percent_intra = cpi->this_frame_percent_intra;
}
// Clear the one shot update flags for segmentation map and mode/ref loop filter deltas.
diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h
index e2788c0ef..932e8ca7c 100644
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -55,13 +55,6 @@
typedef struct
{
- int kf_indicated;
- unsigned int frames_since_key;
- unsigned int frames_since_golden;
- int filter_level;
- int frames_till_gf_update_due;
- int recent_ref_frame_usage[MAX_REF_FRAMES];
-
MV_CONTEXT mvc[2];
int mvcosts[2][MVvals+1];
#if CONFIG_HIGH_PRECISION_MV
@@ -79,30 +72,28 @@ typedef struct
int inter_uv_modes[VP8_UV_MODES];
int inter_b_modes[B_MODE_COUNT];
#endif
- /* interframe intra mode probs */
- vp8_prob ymode_prob[VP8_YMODES-1];
- /* keyframe intra mode probs */
-#if CONFIG_QIMODE
- vp8_prob kf_ymode_prob[8][VP8_YMODES-1];
-#else
- vp8_prob kf_ymode_prob[VP8_YMODES-1];
-#endif
-#if CONFIG_UVINTRA
- vp8_prob kf_uv_mode_prob[VP8_YMODES][VP8_UV_MODES-1];
- vp8_prob uv_mode_prob[VP8_YMODES][VP8_UV_MODES-1];
-#else
- vp8_prob kf_uv_mode_prob[VP8_UV_MODES-1];
- vp8_prob uv_mode_prob[VP8_UV_MODES-1];
-#endif
- /* intra MB type cts this frame */
- int ymode_count[VP8_YMODES], uv_mode_count[VP8_UV_MODES];
+ vp8_prob segment_pred_probs[PREDICTION_PROBS];
+ unsigned char ref_pred_probs_update[PREDICTION_PROBS];
+ vp8_prob ref_pred_probs[PREDICTION_PROBS];
+ vp8_prob prob_comppred[COMP_PRED_CONTEXTS];
- int count_mb_ref_frame_usage[MAX_REF_FRAMES];
+ unsigned char * last_frame_seg_map_copy;
+
+ // 0 = Intra, Last, GF, ARF
+ signed char last_ref_lf_deltas[MAX_REF_LF_DELTAS];
+ // 0 = BPRED, ZERO_MV, MV, SPLIT
+ signed char last_mode_lf_deltas[MAX_MODE_LF_DELTAS];
- int this_frame_percent_intra;
- int last_frame_percent_intra;
+ vp8_prob coef_probs[BLOCK_TYPES]
+ [COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES];
+ vp8_prob coef_probs_8x8[BLOCK_TYPES]
+ [COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES];
+ int mv_ref_ct[6][4][2];
+ int mode_context[6][4];
+ int mv_ref_ct_a[6][4][2];
+ int mode_context_a[6][4];
} CODING_CONTEXT;
@@ -490,17 +481,15 @@ typedef struct VP8_COMP
int pass;
#if CONFIG_NEWENTROPY
- int last_skip_false_probs[3][MBSKIP_CONTEXTS];
+ vp8_prob last_skip_false_probs[3][MBSKIP_CONTEXTS];
#else
- int prob_skip_false;
- int last_skip_false_probs[3];
+ vp8_prob prob_skip_false;
+ vp8_prob last_skip_false_probs[3];
#endif
int last_skip_probs_q[3];
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_pred_probs_update[PREDICTION_PROBS];
diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c
index a57996612..1ff13754f 100644
--- a/vp8/encoder/ratectrl.c
+++ b/vp8/encoder/ratectrl.c
@@ -135,32 +135,25 @@ int vp8_bits_per_mb( FRAME_TYPE frame_type, int qindex )
void vp8_save_coding_context(VP8_COMP *cpi)
{
CODING_CONTEXT *const cc = & cpi->coding_context;
+ VP8_COMMON *cm = &cpi->common;
+ MACROBLOCKD *xd = &cpi->mb.e_mbd;
// Stores a snapshot of key state variables which can subsequently be
// restored with a call to vp8_restore_coding_context. These functions are
// intended for use in a re-code loop in vp8_compress_frame where the
// quantizer value is adjusted between loop iterations.
- cc->frames_since_key = cpi->frames_since_key;
- cc->filter_level = cpi->common.filter_level;
- cc->frames_till_gf_update_due = cpi->frames_till_gf_update_due;
- cc->frames_since_golden = cpi->common.frames_since_golden;
-
- vp8_copy(cc->mvc, cpi->common.fc.mvc);
+ vp8_copy(cc->mvc, cm->fc.mvc);
vp8_copy(cc->mvcosts, cpi->mb.mvcosts);
#if CONFIG_HIGH_PRECISION_MV
- vp8_copy(cc->mvc_hp, cpi->common.fc.mvc_hp);
+ vp8_copy(cc->mvc_hp, cm->fc.mvc_hp);
vp8_copy(cc->mvcosts_hp, cpi->mb.mvcosts_hp);
#endif
- vp8_copy(cc->kf_ymode_prob, cpi->common.kf_ymode_prob);
- vp8_copy(cc->ymode_prob, cpi->common.fc.ymode_prob);
- vp8_copy(cc->kf_uv_mode_prob, cpi->common.kf_uv_mode_prob);
- vp8_copy(cc->uv_mode_prob, cpi->common.fc.uv_mode_prob);
-
- vp8_copy(cc->ymode_count, cpi->ymode_count);
- vp8_copy(cc->uv_mode_count, cpi->uv_mode_count);
-
+ vp8_copy( cc->mv_ref_ct, cm->mv_ref_ct );
+ vp8_copy( cc->mode_context, cm->mode_context );
+ vp8_copy( cc->mv_ref_ct_a, cm->mv_ref_ct_a );
+ vp8_copy( cc->mode_context_a, cm->mode_context_a );
// Stats
#ifdef MODE_STATS
@@ -172,37 +165,41 @@ void vp8_save_coding_context(VP8_COMP *cpi)
vp8_copy(cc->inter_b_modes, inter_b_modes);
#endif
- cc->this_frame_percent_intra = cpi->this_frame_percent_intra;
-}
+ vp8_copy( cc->segment_pred_probs, cm->segment_pred_probs );
+ vp8_copy( cc->ref_pred_probs_update, cpi->ref_pred_probs_update );
+ vp8_copy( cc->ref_pred_probs, cm->ref_pred_probs );
+ vp8_copy( cc->prob_comppred, cm->prob_comppred );
+ vpx_memcpy( cpi->coding_context.last_frame_seg_map_copy,
+ cm->last_frame_seg_map, (cm->mb_rows * cm->mb_cols) );
+
+ vp8_copy( cc->last_ref_lf_deltas, xd->last_ref_lf_deltas );
+ vp8_copy( cc->last_mode_lf_deltas, xd->last_mode_lf_deltas );
+
+ vp8_copy( cc->coef_probs, cm->fc.coef_probs );
+ vp8_copy( cc->coef_probs_8x8, cm->fc.coef_probs_8x8 );
+}
void vp8_restore_coding_context(VP8_COMP *cpi)
{
CODING_CONTEXT *const cc = & cpi->coding_context;
+ VP8_COMMON *cm = &cpi->common;
+ MACROBLOCKD *xd = &cpi->mb.e_mbd;
// Restore key state variables to the snapshot state stored in the
// previous call to vp8_save_coding_context.
- cpi->frames_since_key = cc->frames_since_key;
- cpi->common.filter_level = cc->filter_level;
- cpi->frames_till_gf_update_due = cc->frames_till_gf_update_due;
- cpi->common.frames_since_golden = cc->frames_since_golden;
-
- vp8_copy(cpi->common.fc.mvc, cc->mvc);
-
+ vp8_copy(cm->fc.mvc, cc->mvc);
vp8_copy(cpi->mb.mvcosts, cc->mvcosts);
#if CONFIG_HIGH_PRECISION_MV
- vp8_copy(cpi->common.fc.mvc_hp, cc->mvc_hp);
-
+ vp8_copy(cm->fc.mvc_hp, cc->mvc_hp);
vp8_copy(cpi->mb.mvcosts_hp, cc->mvcosts_hp);
#endif
- vp8_copy(cpi->common.kf_ymode_prob, cc->kf_ymode_prob);
- vp8_copy(cpi->common.fc.ymode_prob, cc->ymode_prob);
- vp8_copy(cpi->common.kf_uv_mode_prob, cc->kf_uv_mode_prob);
- vp8_copy(cpi->common.fc.uv_mode_prob, cc->uv_mode_prob);
- vp8_copy(cpi->ymode_count, cc->ymode_count);
- vp8_copy(cpi->uv_mode_count, cc->uv_mode_count);
+ vp8_copy( cm->mv_ref_ct, cc->mv_ref_ct );
+ vp8_copy( cm->mode_context, cc->mode_context );
+ vp8_copy( cm->mv_ref_ct_a, cc->mv_ref_ct_a );
+ vp8_copy( cm->mode_context_a, cc->mode_context_a );
// Stats
#ifdef MODE_STATS
@@ -214,8 +211,20 @@ void vp8_restore_coding_context(VP8_COMP *cpi)
vp8_copy(inter_b_modes, cc->inter_b_modes);
#endif
+ vp8_copy( cm->segment_pred_probs, cc->segment_pred_probs );
+ vp8_copy( cpi->ref_pred_probs_update, cc->ref_pred_probs_update );
+ vp8_copy( cm->ref_pred_probs, cc->ref_pred_probs );
+ vp8_copy( cm->prob_comppred, cc->prob_comppred );
+
+ vpx_memcpy( cm->last_frame_seg_map,
+ cpi->coding_context.last_frame_seg_map_copy,
+ (cm->mb_rows * cm->mb_cols) );
- cpi->this_frame_percent_intra = cc->this_frame_percent_intra;
+ vp8_copy( xd->last_ref_lf_deltas, cc->last_ref_lf_deltas );
+ vp8_copy( xd->last_mode_lf_deltas, cc->last_mode_lf_deltas );
+
+ vp8_copy( cm->fc.coef_probs, cc->coef_probs );
+ vp8_copy( cm->fc.coef_probs_8x8, cc->coef_probs_8x8 );
}
@@ -231,14 +240,12 @@ void vp8_setup_key_frame(VP8_COMP *cpi)
int flag[2] = {1, 1};
vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cpi->common.fc.mvc, flag);
}
- vpx_memset(cpi->common.fc.pre_mvc, 0, sizeof(cpi->common.fc.pre_mvc)); //initialize pre_mvc to all zero.
#if CONFIG_HIGH_PRECISION_MV
vpx_memcpy(cpi->common.fc.mvc_hp, vp8_default_mv_context_hp, sizeof(vp8_default_mv_context_hp));
{
int flag[2] = {1, 1};
vp8_build_component_cost_table_hp(cpi->mb.mvcost_hp, (const MV_CONTEXT_HP *) cpi->common.fc.mvc_hp, flag);
}
- vpx_memset(cpi->common.fc.pre_mvc_hp, 0, sizeof(cpi->common.fc.pre_mvc_hp)); //initialize pre_mvc to all zero.
#endif
cpi->common.txfm_mode = ONLY_4X4;
@@ -270,17 +277,6 @@ void vp8_setup_key_frame(VP8_COMP *cpi)
default_vp8_mode_contexts,
sizeof(default_vp8_mode_contexts));
- /* make sure coding_context is correct in key frame recode */
- {
- CODING_CONTEXT *const cc = & cpi->coding_context;
-
- vp8_copy(cc->mvc, cpi->common.fc.mvc);
-#if CONFIG_HIGH_PRECISION_MV
- vp8_copy(cc->mvc_hp, cpi->common.fc.mvc_hp);
-#endif
- vp8_copy(cc->ymode_prob, cpi->common.fc.ymode_prob);
- vp8_copy(cc->uv_mode_prob, cpi->common.fc.uv_mode_prob);
- }
}
void vp8_setup_inter_frame(VP8_COMP *cpi)
{