diff --git a/vp8/common/onyxc_int.h b/vp8/common/onyxc_int.h index 9b253e94c1f77d330aecd837617a1a3b0f217d80..ec737dd46d7caa314a9942764e47c41c094f9fcb 100644 --- a/vp8/common/onyxc_int.h +++ b/vp8/common/onyxc_int.h @@ -55,10 +55,8 @@ typedef struct frame_contexts 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]; MV_CONTEXT mvc[2]; - MV_CONTEXT pre_mvc[2]; /* not to caculate the mvcost for the frame if mvc doesn't change. */ #if CONFIG_HIGH_PRECISION_MV MV_CONTEXT_HP mvc_hp[2]; - MV_CONTEXT_HP pre_mvc_hp[2]; /* not to caculate the mvcost for the frame if mvc doesn't change. */ #endif } FRAME_CONTEXT; diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index 065ea9f1b852ab88f865daa66bb4e8eeddd0b81f..8691ba356dc676bd8edeb0839133bfa74cbe4f85 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 e742809c8e2ff1d02715c681ea3021366b63cf48..5032cbdce24c5de6cb9c3a7001b4d4c7f2796a6f 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 b561ea3380e06b85466f2f5fb536cf678a9988a9..1e8594d7b4720aae30b6784d8977055c50ccf29c 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 a758b19274d99fae0674165556cb517518212952..e547c9ddfe0de88b42a05730b337fcabfb32dd77 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 e2788c0efedad6264fa8eb933e43db88fee20564..932e8ca7c5ed5fe0f278ce1c369d93db474f7379 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 a57996612db344944bb0c6214cef7f1d823158aa..1ff13754f540c24366dbcd0fb07573ec62f0262b 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) { diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c index 4f34569e02abf78c51d15d54465afb0306530502..96dcedca9061a9057741d57527d7f39a517d884c 100644 --- a/vp8/vp8_cx_iface.c +++ b/vp8/vp8_cx_iface.c @@ -144,7 +144,7 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx, RANGE_CHECK_HI(cfg, rc_max_quantizer, 63); RANGE_CHECK_HI(cfg, rc_min_quantizer, cfg->rc_max_quantizer); RANGE_CHECK_HI(cfg, g_threads, 64); - RANGE_CHECK_HI(cfg, g_lag_in_frames, 25); + RANGE_CHECK_HI(cfg, g_lag_in_frames, MAX_LAG_BUFFERS); RANGE_CHECK(cfg, rc_end_usage, VPX_VBR, VPX_CQ); RANGE_CHECK_HI(cfg, rc_undershoot_pct, 1000); RANGE_CHECK_HI(cfg, rc_overshoot_pct, 1000);