diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c index ea8c0642e53eeef5b5a59bc75b4844c2c111dc3e..bf88cdb6a12f8c4474114ee890f71447c49101f6 100644 --- a/vp8/encoder/encodeframe.c +++ b/vp8/encoder/encodeframe.c @@ -733,41 +733,6 @@ void encode_sb_row (VP8_COMP *cpi, if ((xd->mode_info_context->mbmi.mode == ZEROMV) && (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME)) cpi->inter_zz_count ++; - - // Actions required if segmentation enabled - if ( xd->segmentation_enabled ) - { - // Special case code for cyclic refresh - // If cyclic update enabled then copy xd->mbmi.segment_id; - // (which may have been updated based on mode during - // vp8cx_encode_inter_macroblock()) back into the global - // segmentation map - if (cpi->cyclic_refresh_mode_enabled) - { - cpi->segmentation_map[map_index] = - xd->mode_info_context->mbmi.segment_id; - - // If the block has been refreshed mark it as clean (the - // magnitude of the -ve influences how long it will be - // before we consider another refresh): - // Else if it was coded (last frame 0,0) and has not - // already been refreshed then mark it as a candidate - // for cleanup next time (marked 0) - // else mark it as dirty (1). - if (xd->mode_info_context->mbmi.segment_id) - cpi->cyclic_refresh_map[map_index] = -1; - - else if ((xd->mode_info_context->mbmi.mode == ZEROMV) && - (xd->mode_info_context->mbmi.ref_frame == - LAST_FRAME)) - { - if (cpi->cyclic_refresh_map[map_index] == 1) - cpi->cyclic_refresh_map[map_index] = 0; - } - else - cpi->cyclic_refresh_map[map_index] = 1; - } - } } // TODO Make sure partitioning works with this new scheme @@ -948,41 +913,6 @@ void encode_mb_row(VP8_COMP *cpi, // Count of last ref frame 0,0 usage if ((xd->mode_info_context->mbmi.mode == ZEROMV) && (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME)) cpi->inter_zz_count ++; - - // Actions required if segmentation enabled - if ( xd->segmentation_enabled ) - { - // Special case code for cyclic refresh - // If cyclic update enabled then copy xd->mbmi.segment_id; - // (which may have been updated based on mode during - // vp8cx_encode_inter_macroblock()) back into the global - // segmentation map - if (cpi->cyclic_refresh_mode_enabled) - { - cpi->segmentation_map[map_index+mb_col] = - xd->mode_info_context->mbmi.segment_id; - - // If the block has been refreshed mark it as clean (the - // magnitude of the -ve influences how long it will be - // before we consider another refresh): - // Else if it was coded (last frame 0,0) and has not - // already been refreshed then mark it as a candidate - // for cleanup next time (marked 0) - // else mark it as dirty (1). - if (xd->mode_info_context->mbmi.segment_id) - cpi->cyclic_refresh_map[map_index+mb_col] = -1; - - else if ((xd->mode_info_context->mbmi.mode == ZEROMV) && - (xd->mode_info_context->mbmi.ref_frame == - LAST_FRAME)) - { - if (cpi->cyclic_refresh_map[map_index+mb_col] == 1) - cpi->cyclic_refresh_map[map_index+mb_col] = 0; - } - else - cpi->cyclic_refresh_map[map_index+mb_col] = 1; - } - } } cpi->tplist[mb_row].stop = *tp; @@ -1722,49 +1652,6 @@ int vp8cx_encode_inter_macroblock adjust_act_zbin( cpi, x ); } -#if 0 - // Experimental RD code - cpi->frame_distortion += distortion; - cpi->last_mb_distortion = distortion; -#endif - - // MB level adjutment to quantizer setup - if (xd->segmentation_enabled) - { - // If cyclic update enabled - if (cpi->cyclic_refresh_mode_enabled) - { - // Clear segment_id back to 0 if not coded (last frame 0,0) - if ( (*segment_id == 1) && - ( (xd->mode_info_context->mbmi.ref_frame != LAST_FRAME) || - (xd->mode_info_context->mbmi.mode != ZEROMV) ) ) - { - *segment_id = 0; - - /* segment_id changed, so update */ - vp8cx_mb_init_quantizer(cpi, x); - } - } - else - { - //segfeature_test_function(cpi, xd); -#if DBG_PRNT_SEGMAP - // Debug output - { - FILE *statsfile; - statsfile = fopen("segmap2.stt", "a"); - - fprintf(statsfile, "%2d%2d%2d ", - *segment_id, - xd->mode_info_context->mbmi.ref_frame, - xd->mode_info_context->mbmi.mode ); - - fclose(statsfile); - } -#endif - } - } - { // Experimental code. Special case for gf and arf zeromv modes. // Increase zbin size to supress noise diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 76112d01f6f2cc27d5bb551bd4683cca91c5dd08..8a2fb8448c2a65acdac5aacc41be88db1c0dbcaa 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -369,68 +369,6 @@ static void dealloc_compressor_data(VP8_COMP *cpi) cpi->twopass.this_frame_stats = 0; } -static void segmentation_test_function(VP8_PTR ptr) -{ - VP8_COMP *cpi = (VP8_COMP *)(ptr); - unsigned char *seg_map; - signed char feature_data[SEG_LVL_MAX][MAX_MB_SEGMENTS]; - MACROBLOCKD *xd = &cpi->mb.e_mbd; - - CHECK_MEM_ERROR(seg_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1)); - - // Create a temporary map for segmentation data. - - // MB loop to set local segmentation map - /*for ( i = 0; i < cpi->common.mb_rows; i++ ) - { - for ( j = 0; j < cpi->common.mb_cols; j++ ) - { - //seg_map[(i*cpi->common.mb_cols) + j] = (j % 2) + ((i%2)* 2); - //if ( j < cpi->common.mb_cols/2 ) - - // Segment 1 around the edge else 0 - if ( (i == 0) || (j == 0) || (i == (cpi->common.mb_rows-1)) || (j == (cpi->common.mb_cols-1)) ) - seg_map[(i*cpi->common.mb_cols) + j] = 1; - //else if ( (i < 2) || (j < 2) || (i > (cpi->common.mb_rows-3)) || (j > (cpi->common.mb_cols-3)) ) - // seg_map[(i*cpi->common.mb_cols) + j] = 2; - //else if ( (i < 5) || (j < 5) || (i > (cpi->common.mb_rows-6)) || (j > (cpi->common.mb_cols-6)) ) - // seg_map[(i*cpi->common.mb_cols) + j] = 3; - else - seg_map[(i*cpi->common.mb_cols) + j] = 0; - } - }*/ - - // Set the segmentation Map - vp8_set_segmentation_map(ptr, seg_map); - - // Activate segmentation. - vp8_enable_segmentation(ptr); - - // Set up the quant segment data - feature_data[SEG_LVL_ALT_Q][0] = 0; - feature_data[SEG_LVL_ALT_Q][1] = 4; - feature_data[SEG_LVL_ALT_Q][2] = 0; - feature_data[SEG_LVL_ALT_Q][3] = 0; - // Set up the loop segment data - feature_data[SEG_LVL_ALT_LF][0] = 0; - feature_data[SEG_LVL_ALT_LF][1] = 0; - feature_data[SEG_LVL_ALT_LF][2] = 0; - feature_data[SEG_LVL_ALT_LF][3] = 0; - - // Enable features as required - enable_segfeature(xd, 1, SEG_LVL_ALT_Q); - - // Initialise the feature data structure - // SEGMENT_DELTADATA 0, SEGMENT_ABSDATA 1 - vp8_set_segment_data(ptr, &feature_data[0][0], SEGMENT_DELTADATA); - - // Delete sementation map - vpx_free(seg_map); - - seg_map = 0; - -} - // Computes a q delta (in "q index" terms) to get from a starting q value // to a target value // target q value @@ -468,15 +406,6 @@ static void init_seg_features(VP8_COMP *cpi) int high_q = (int)(cpi->avg_q > 48.0); int qi_delta; - // For now at least dont enable seg features alongside cyclic refresh. - if ( cpi->cyclic_refresh_mode_enabled || - (cpi->pass != 2) ) - { - vp8_disable_segmentation((VP8_PTR)cpi); - vpx_memset( cpi->segmentation_map, 0, (cm->mb_rows * cm->mb_cols)); - return; - } - // Disable and clear down for KF if ( cm->frame_type == KEY_FRAME ) { @@ -665,104 +594,6 @@ static void print_seg_map(VP8_COMP *cpi) fclose(statsfile); } -// A simple function to cyclically refresh the background at a lower Q -static void cyclic_background_refresh(VP8_COMP *cpi, int Q, int lf_adjustment) -{ - unsigned char *seg_map; - signed char feature_data[SEG_LVL_MAX][MAX_MB_SEGMENTS]; - int i; - int block_count = cpi->cyclic_refresh_mode_max_mbs_perframe; - int mbs_in_frame = cpi->common.mb_rows * cpi->common.mb_cols; - MACROBLOCKD *xd = &cpi->mb.e_mbd; - - // Create a temporary map for segmentation data. - CHECK_MEM_ERROR(seg_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1)); - - cpi->cyclic_refresh_q = Q; - - for (i = Q; i > 0; i--) - { - if ( vp8_bits_per_mb(cpi->common.frame_type, i) >= - ((vp8_bits_per_mb(cpi->common.frame_type, Q)*(Q + 128)) / 64)) - { - break; - } - } - - cpi->cyclic_refresh_q = i; - - // Only update for inter frames - if (cpi->common.frame_type != KEY_FRAME) - { - // Cycle through the macro_block rows - // MB loop to set local segmentation map - for (i = cpi->cyclic_refresh_mode_index; i < mbs_in_frame; i++) - { - // If the MB is as a candidate for clean up then mark it for possible boost/refresh (segment 1) - // The segment id may get reset to 0 later if the MB gets coded anything other than last frame 0,0 - // as only (last frame 0,0) MBs are eligable for refresh : that is to say Mbs likely to be background blocks. - if (cpi->cyclic_refresh_map[i] == 0) - { - seg_map[i] = 1; - } - else - { - seg_map[i] = 0; - - // Skip blocks that have been refreshed recently anyway. - if (cpi->cyclic_refresh_map[i] < 0) - //cpi->cyclic_refresh_map[i] = cpi->cyclic_refresh_map[i] / 16; - cpi->cyclic_refresh_map[i]++; - } - - - if (block_count > 0) - block_count--; - else - break; - - } - - // If we have gone through the frame reset to the start - cpi->cyclic_refresh_mode_index = i; - - if (cpi->cyclic_refresh_mode_index >= mbs_in_frame) - cpi->cyclic_refresh_mode_index = 0; - } - - // Set the segmentation Map - vp8_set_segmentation_map((VP8_PTR)cpi, seg_map); - - // Activate segmentation. - vp8_enable_segmentation((VP8_PTR)cpi); - - // Set up the quant segment data - feature_data[SEG_LVL_ALT_Q][0] = 0; - feature_data[SEG_LVL_ALT_Q][1] = (cpi->cyclic_refresh_q - Q); - feature_data[SEG_LVL_ALT_Q][2] = 0; - feature_data[SEG_LVL_ALT_Q][3] = 0; - - // Set up the loop segment data - feature_data[SEG_LVL_ALT_LF][0] = 0; - feature_data[SEG_LVL_ALT_LF][1] = lf_adjustment; - feature_data[SEG_LVL_ALT_LF][2] = 0; - feature_data[SEG_LVL_ALT_LF][3] = 0; - - // Enable the loop and quant changes in the feature mask - enable_segfeature(xd, 1, SEG_LVL_ALT_Q); - enable_segfeature(xd, 1, SEG_LVL_ALT_LF); - - // Initialise the feature data structure - // SEGMENT_DELTADATA 0, SEGMENT_ABSDATA 1 - vp8_set_segment_data((VP8_PTR)cpi, &feature_data[0][0], SEGMENT_DELTADATA); - - // Delete sementation map - vpx_free(seg_map); - - seg_map = 0; - -} - static void set_default_lf_deltas(VP8_COMP *cpi) { cpi->mb.e_mbd.mode_ref_lf_delta_enabled = 1; @@ -1489,8 +1320,6 @@ void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf) break; } - if (cpi->pass == 0) - cpi->auto_worst_q = 1; cpi->oxcf.worst_allowed_q = q_trans[oxcf->worst_allowed_q]; cpi->oxcf.best_allowed_q = q_trans[oxcf->best_allowed_q]; @@ -1790,29 +1619,6 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf) vpx_memset(cpi->active_map , 1, (cpi->common.mb_rows * cpi->common.mb_cols)); cpi->active_map_enabled = 0; -#if 0 - // Experimental code for lagged and one pass - // Initialise one_pass GF frames stats - // Update stats used for GF selection - if (cpi->pass == 0) - { - cpi->one_pass_frame_index = 0; - - for (i = 0; i < MAX_LAG_BUFFERS; i++) - { - cpi->one_pass_frame_stats[i].frames_so_far = 0; - cpi->one_pass_frame_stats[i].frame_intra_error = 0.0; - cpi->one_pass_frame_stats[i].frame_coded_error = 0.0; - cpi->one_pass_frame_stats[i].frame_pcnt_inter = 0.0; - cpi->one_pass_frame_stats[i].frame_pcnt_motion = 0.0; - cpi->one_pass_frame_stats[i].frame_mvr = 0.0; - cpi->one_pass_frame_stats[i].frame_mvr_abs = 0.0; - cpi->one_pass_frame_stats[i].frame_mvc = 0.0; - cpi->one_pass_frame_stats[i].frame_mvc_abs = 0.0; - } - } -#endif - for (i = 0; i < ( sizeof(cpi->mbgraph_stats) / sizeof(cpi->mbgraph_stats[0]) ); i++) { @@ -1822,22 +1628,6 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf) 1)); } - // Should we use the cyclic refresh method. - // Currently this is tied to error resilliant mode - cpi->cyclic_refresh_mode_enabled = cpi->oxcf.error_resilient_mode; - cpi->cyclic_refresh_mode_max_mbs_perframe = (cpi->common.mb_rows * cpi->common.mb_cols) / 40; - cpi->cyclic_refresh_mode_index = 0; - cpi->cyclic_refresh_q = 32; - - if (cpi->cyclic_refresh_mode_enabled) - CHECK_MEM_ERROR(cpi->cyclic_refresh_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1)); - else - cpi->cyclic_refresh_map = (signed char *) NULL; - - // Test function for segmentation - - //segmentation_test_function((VP8_PTR) cpi); - #ifdef ENTROPY_STATS init_context_counters(); #endif @@ -2116,12 +1906,6 @@ void vp8_remove_compressor(VP8_PTR *ptr) } fclose(f); -#if 0 - f = fopen("qskip.stt", "a"); - fprintf(f, "minq:%d -maxq:%d skipture:skipfalse = %d:%d\n", cpi->oxcf.best_allowed_q, cpi->oxcf.worst_allowed_q, skiptruecount, skipfalsecount); - fclose(f); -#endif - } #endif @@ -2265,7 +2049,6 @@ void vp8_remove_compressor(VP8_PTR *ptr) dealloc_compressor_data(cpi); vpx_free(cpi->mb.ss); vpx_free(cpi->tok); - vpx_free(cpi->cyclic_refresh_map); for (i = 0; i < sizeof(cpi->mbgraph_stats) / sizeof(cpi->mbgraph_stats[0]); i++) { @@ -2652,19 +2435,6 @@ static void update_alt_ref_frame_stats(VP8_COMP *cpi) if (!cpi->auto_gold) cpi->frames_till_gf_update_due = cpi->goldfreq; - if ((cpi->pass != 2) && cpi->frames_till_gf_update_due) - { - cpi->current_gf_interval = cpi->frames_till_gf_update_due; - - // Set the bits per frame that we should try and recover in subsequent inter frames - // to account for the extra GF spend... note that his does not apply for GF updates - // that occur coincident with a key frame as the extra cost of key frames is dealt - // with elsewhere. - - cpi->gf_overspend_bits += cpi->projected_frame_size; - cpi->non_gf_bitrate_adjustment = cpi->gf_overspend_bits / cpi->frames_till_gf_update_due; - } - // Update data structure that monitors level of reference to last GF vpx_memset(cpi->gf_active_flags, 1, (cm->mb_rows * cm->mb_cols)); cpi->gf_active_count = cm->mb_rows * cm->mb_cols; @@ -2691,25 +2461,6 @@ static void update_golden_frame_stats(VP8_COMP *cpi) if (!cpi->auto_gold) cpi->frames_till_gf_update_due = cpi->goldfreq; - if ((cpi->pass != 2) && (cpi->frames_till_gf_update_due > 0)) - { - cpi->current_gf_interval = cpi->frames_till_gf_update_due; - - // Set the bits per frame that we should try and recover in subsequent inter frames - // to account for the extra GF spend... note that his does not apply for GF updates - // that occur coincident with a key frame as the extra cost of key frames is dealt - // with elsewhere. - if ((cm->frame_type != KEY_FRAME) && !cpi->source_alt_ref_active) - { - // Calcluate GF bits to be recovered - // Projected size - av frame bits available for inter frames for clip as a whole - cpi->gf_overspend_bits += (cpi->projected_frame_size - cpi->inter_frame_target); - } - - cpi->non_gf_bitrate_adjustment = cpi->gf_overspend_bits / cpi->frames_till_gf_update_due; - - } - // Update data structure that monitors level of reference to last GF vpx_memset(cpi->gf_active_flags, 1, (cm->mb_rows * cm->mb_cols)); cpi->gf_active_count = cm->mb_rows * cm->mb_cols; @@ -3191,17 +2942,13 @@ static void encode_frame_to_data_rate // Clear down mmx registers to allow floating point in what follows vp8_clear_system_state(); - // For an alt ref frame in 2 pass we skip the call to the second pass function that sets the target bandwidth - if (cpi->pass == 2) + // For an alt ref frame in 2 pass we skip the call to the second + // pass function that sets the target bandwidth so must set it here + if (cpi->common.refresh_alt_ref_frame) { - if (cpi->common.refresh_alt_ref_frame) - { - cpi->per_frame_bandwidth = cpi->twopass.gf_bits; // Per frame bit target for the alt ref frame - cpi->target_bandwidth = cpi->twopass.gf_bits * cpi->output_frame_rate; // per second target bitrate - } + cpi->per_frame_bandwidth = cpi->twopass.gf_bits; // Per frame bit target for the alt ref frame + cpi->target_bandwidth = cpi->twopass.gf_bits * cpi->output_frame_rate; // per second target bitrate } - else - cpi->per_frame_bandwidth = (int)(cpi->target_bandwidth / cpi->output_frame_rate); // Default turn off buffer to buffer copying cm->copy_buffer_to_gf = 0; @@ -3216,12 +2963,9 @@ static void encode_frame_to_data_rate // is above a threshold cpi->zbin_mode_boost = 0; cpi->zbin_mode_boost_enabled = TRUE; - if (cpi->pass == 2) + if ( cpi->gfu_boost <= 400 ) { - if ( cpi->gfu_boost <= 400 ) - { - cpi->zbin_mode_boost_enabled = FALSE; - } + cpi->zbin_mode_boost_enabled = FALSE; } // Current default encoder behaviour for the altref sign bias @@ -3268,33 +3012,6 @@ static void encode_frame_to_data_rate } } - // Test code for segmentation - //if ( (cm->frame_type == KEY_FRAME) || ((cm->current_video_frame % 2) == 0)) - //if ( (cm->current_video_frame % 2) == 0 ) - // vp8_enable_segmentation((VP8_PTR)cpi); - //else - // vp8_disable_segmentation((VP8_PTR)cpi); - -#if 0 - // Experimental code for lagged compress and one pass - // Initialise one_pass GF frames stats - // Update stats used for GF selection - //if ( cpi->pass == 0 ) - { - cpi->one_pass_frame_index = cm->current_video_frame % MAX_LAG_BUFFERS; - - cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frames_so_far = 0; - cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_intra_error = 0.0; - cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_coded_error = 0.0; - cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_pcnt_inter = 0.0; - cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_pcnt_motion = 0.0; - cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_mvr = 0.0; - cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_mvr_abs = 0.0; - cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_mvc = 0.0; - cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_mvc_abs = 0.0; - } -#endif - //#if !CONFIG_COMPRED // This function has been deprecated for now but we may want to do // something here at a late date @@ -3418,131 +3135,101 @@ static void encode_frame_to_data_rate } } + vp8_clear_system_state(); + // Set an active best quality and if necessary active worst quality - // There is some odd behaviour for one pass here that needs attention. - if ( (cpi->pass == 2) || (cpi->ni_frames > 150)) - { - vp8_clear_system_state(); + Q = cpi->active_worst_quality; - Q = cpi->active_worst_quality; + if ( cm->frame_type == KEY_FRAME ) + { + if (cpi->gfu_boost > 600) + cpi->active_best_quality = kf_low_motion_minq[Q]; + else + cpi->active_best_quality = kf_high_motion_minq[Q]; - if ( cm->frame_type == KEY_FRAME ) + // Special case for key frames forced because we have reached + // the maximum key frame interval. Here force the Q to a range + // based on the ambient Q to reduce the risk of popping + if ( cpi->this_key_frame_forced ) { - if ( cpi->pass == 2 ) - { - if (cpi->gfu_boost > 600) - cpi->active_best_quality = kf_low_motion_minq[Q]; - else - cpi->active_best_quality = kf_high_motion_minq[Q]; - - // Special case for key frames forced because we have reached - // the maximum key frame interval. Here force the Q to a range - // based on the ambient Q to reduce the risk of popping - if ( cpi->this_key_frame_forced ) - { - int delta_qindex; - int qindex = cpi->last_boosted_qindex; + int delta_qindex; + int qindex = cpi->last_boosted_qindex; - delta_qindex = compute_qdelta( cpi, qindex, - (qindex * 0.75) ); + delta_qindex = compute_qdelta( cpi, qindex, + (qindex * 0.75) ); - cpi->active_best_quality = qindex + delta_qindex; - if (cpi->active_best_quality < cpi->best_quality) - cpi->active_best_quality = cpi->best_quality; - } - } - // One pass more conservative - else - cpi->active_best_quality = kf_high_motion_minq[Q]; + cpi->active_best_quality = qindex + delta_qindex; + if (cpi->active_best_quality < cpi->best_quality) + cpi->active_best_quality = cpi->best_quality; } + } - else if (cm->refresh_golden_frame || cpi->common.refresh_alt_ref_frame) - { - // Use the lower of cpi->active_worst_quality and recent - // average Q as basis for GF/ARF Q limit unless last frame was - // a key frame. - if ( (cpi->frames_since_key > 1) && - (cpi->avg_frame_qindex < cpi->active_worst_quality) ) - { - Q = cpi->avg_frame_qindex; - } - - // For constrained quality dont allow Q less than the cq level - if ( (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) && - (Q < cpi->cq_target_quality) ) - { - Q = cpi->cq_target_quality; - } - - if ( cpi->pass == 2 ) - { - if ( cpi->gfu_boost > 1000 ) - cpi->active_best_quality = gf_low_motion_minq[Q]; - else if ( cpi->gfu_boost < 400 ) - cpi->active_best_quality = gf_high_motion_minq[Q]; - else - cpi->active_best_quality = gf_mid_motion_minq[Q]; - - // Constrained quality use slightly lower active best. - if ( cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY ) - { - cpi->active_best_quality = - cpi->active_best_quality * 15/16; - } - } - // One pass more conservative - else - cpi->active_best_quality = gf_high_motion_minq[Q]; - } - else + else if (cm->refresh_golden_frame || cpi->common.refresh_alt_ref_frame) + { + // Use the lower of cpi->active_worst_quality and recent + // average Q as basis for GF/ARF Q limit unless last frame was + // a key frame. + if ( (cpi->frames_since_key > 1) && + (cpi->avg_frame_qindex < cpi->active_worst_quality) ) { - cpi->active_best_quality = inter_minq[Q]; - - // For the constant/constrained quality mode we dont want - // q to fall below the cq level. - if ((cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) && - (cpi->active_best_quality < cpi->cq_target_quality) ) - { - // If we are strongly undershooting the target rate in the last - // frames then use the user passed in cq value not the auto - // cq value. - if ( cpi->rolling_actual_bits < cpi->min_frame_bandwidth ) - cpi->active_best_quality = cpi->oxcf.cq_level; - else - cpi->active_best_quality = cpi->cq_target_quality; - } + Q = cpi->avg_frame_qindex; } - // If CBR and the buffer is as full then it is reasonable to allow - // higher quality on the frames to prevent bits just going to waste. - if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) + // For constrained quality dont allow Q less than the cq level + if ( (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) && + (Q < cpi->cq_target_quality) ) { - // Note that the use of >= here elliminates the risk of a devide - // by 0 error in the else if clause - if (cpi->buffer_level >= cpi->oxcf.maximum_buffer_size) - cpi->active_best_quality = cpi->best_quality; + Q = cpi->cq_target_quality; + } - else if (cpi->buffer_level > cpi->oxcf.optimal_buffer_level) - { - int Fraction = ((cpi->buffer_level - cpi->oxcf.optimal_buffer_level) * 128) / (cpi->oxcf.maximum_buffer_size - cpi->oxcf.optimal_buffer_level); - int min_qadjustment = ((cpi->active_best_quality - cpi->best_quality) * Fraction) / 128; + if ( cpi->gfu_boost > 1000 ) + cpi->active_best_quality = gf_low_motion_minq[Q]; + else if ( cpi->gfu_boost < 400 ) + cpi->active_best_quality = gf_high_motion_minq[Q]; + else + cpi->active_best_quality = gf_mid_motion_minq[Q]; - cpi->active_best_quality -= min_qadjustment; - } + // Constrained quality use slightly lower active best. + if ( cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY ) + { + cpi->active_best_quality = + cpi->active_best_quality * 15/16; } } - // Make sure constrained quality mode limits are adhered to for the first - // few frames of one pass encodes - else if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) + else { - if ( (cm->frame_type == KEY_FRAME) || - cm->refresh_golden_frame || cpi->common.refresh_alt_ref_frame ) + cpi->active_best_quality = inter_minq[Q]; + + // For the constant/constrained quality mode we dont want + // q to fall below the cq level. + if ((cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) && + (cpi->active_best_quality < cpi->cq_target_quality) ) { - cpi->active_best_quality = cpi->best_quality; + // If we are strongly undershooting the target rate in the last + // frames then use the user passed in cq value not the auto + // cq value. + if ( cpi->rolling_actual_bits < cpi->min_frame_bandwidth ) + cpi->active_best_quality = cpi->oxcf.cq_level; + else + cpi->active_best_quality = cpi->cq_target_quality; } - else if (cpi->active_best_quality < cpi->cq_target_quality) + } + + // If CBR and the buffer is as full then it is reasonable to allow + // higher quality on the frames to prevent bits just going to waste. + if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) + { + // Note that the use of >= here elliminates the risk of a devide + // by 0 error in the else if clause + if (cpi->buffer_level >= cpi->oxcf.maximum_buffer_size) + cpi->active_best_quality = cpi->best_quality; + + else if (cpi->buffer_level > cpi->oxcf.optimal_buffer_level) { - cpi->active_best_quality = cpi->cq_target_quality; + int Fraction = ((cpi->buffer_level - cpi->oxcf.optimal_buffer_level) * 128) / (cpi->oxcf.maximum_buffer_size - cpi->oxcf.optimal_buffer_level); + int min_qadjustment = ((cpi->active_best_quality - cpi->best_quality) * Fraction) / 128; + + cpi->active_best_quality -= min_qadjustment; } } @@ -3579,10 +3266,6 @@ static void encode_frame_to_data_rate else zbin_oq_high = ZBIN_OQ_MAX; - // Setup background Q adjustment for error resilliant mode - if (cpi->cyclic_refresh_mode_enabled) - cyclic_background_refresh(cpi, Q, 0); - vp8_compute_frame_size_bounds(cpi, &frame_under_shoot_limit, &frame_over_shoot_limit); // Limit Q range for the adaptive loop. @@ -3714,18 +3397,6 @@ static void encode_frame_to_data_rate } - -#if 0 - - if (cpi->pass != 1) - { - FILE *f = fopen("skip.stt", "a"); - fprintf(f, "%d, %d, %4d ", cpi->common.refresh_golden_frame, cpi->common.refresh_alt_ref_frame, cpi->prob_skip_false); - fclose(f); - } - -#endif - } if (cm->frame_type == KEY_FRAME) @@ -3748,70 +3419,12 @@ static void encode_frame_to_data_rate vp8_clear_system_state(); //__asm emms; -#if 0 - if (cpi->pass != 1) - { - FILE *f = fopen("q_used.stt", "a"); - fprintf(f, "%4d, %4d, %8d\n", cpi->common.current_video_frame, - cpi->common.base_qindex, cpi->projected_frame_size); - fclose(f); - } -#endif - - - // Test to see if the stats generated for this frame indicate that we should have coded a key frame - // (assuming that we didn't)! - if (cpi->pass != 2 && cpi->oxcf.auto_key && cm->frame_type != KEY_FRAME) - { - int key_frame_decision = decide_key_frame(cpi); - - if (key_frame_decision) - { - // Reset all our sizing numbers and recode - cm->frame_type = KEY_FRAME; - - vp8_pick_frame_size(cpi); - - // Clear the Alt reference frame active flag when we have a key frame - cpi->source_alt_ref_active = FALSE; - - // Reset the loop filter deltas and segmentation map - setup_features(cpi); - - // If segmentation is enabled force a map update for key frames - if (xd->segmentation_enabled) - { - xd->update_mb_segmentation_map = 1; - xd->update_mb_segmentation_data = 1; - } - - vp8_restore_coding_context(cpi); - - Q = vp8_regulate_q(cpi, cpi->this_frame_target); - - vp8_compute_frame_size_bounds(cpi, &frame_under_shoot_limit, &frame_over_shoot_limit); - - // Limit Q range for the adaptive loop. - bottom_index = cpi->active_best_quality; - top_index = cpi->active_worst_quality; - q_low = cpi->active_best_quality; - q_high = cpi->active_worst_quality; - - loop_count++; - Loop = TRUE; - - continue; - } - } - - vp8_clear_system_state(); - if (frame_over_shoot_limit == 0) frame_over_shoot_limit = 1; // Are we are overshooting and up against the limit of active max Q. - if (((cpi->pass != 2) || (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)) && - (Q == cpi->active_worst_quality) && + if ((cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) && + (Q == cpi->active_worst_quality) && (cpi->active_worst_quality < cpi->worst_quality) && (cpi->projected_frame_size > frame_over_shoot_limit)) { @@ -4181,36 +3794,8 @@ static void encode_frame_to_data_rate // Calculate the average Q for normal inter frames (not key or GFU // frames). - if ( cpi->pass == 2 ) - { - cpi->ni_tot_qi += Q; - cpi->ni_av_qi = (cpi->ni_tot_qi / cpi->ni_frames); - } - else - { - // Damp value for first few frames - if (cpi->ni_frames > 150 ) - { - cpi->ni_tot_qi += Q; - cpi->ni_av_qi = (cpi->ni_tot_qi / cpi->ni_frames); - } - // For one pass, early in the clip ... average the current frame Q - // value with the worstq entered by the user as a dampening measure - else - { - cpi->ni_tot_qi += Q; - cpi->ni_av_qi = ((cpi->ni_tot_qi / cpi->ni_frames) + cpi->worst_quality + 1) / 2; - } - - // If the average Q is higher than what was used in the last frame - // (after going through the recode loop to keep the frame size within range) - // then use the last frame value - 1. - // The -1 is designed to stop Q and hence the data rate, from progressively - // falling away during difficult sections, but at the same time reduce the number of - // itterations around the recode loop. - if (Q > cpi->ni_av_qi) - cpi->ni_av_qi = Q - 1; - } + cpi->ni_tot_qi += Q; + cpi->ni_av_qi = (cpi->ni_tot_qi / cpi->ni_frames); } #if 0 @@ -4972,29 +4557,6 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon } } -#if 0 - - if (cpi->common.frame_type != 0 && cpi->common.base_qindex == cpi->oxcf.worst_allowed_q) - { - skiptruecount += cpi->skip_true_count; - skipfalsecount += cpi->skip_false_count; - } - -#endif -#if 0 - - if (cpi->pass != 1) - { - FILE *f = fopen("skip.stt", "a"); - fprintf(f, "frame:%4d flags:%4x Q:%4d P:%4d Size:%5d\n", cpi->common.current_video_frame, *frame_flags, cpi->common.base_qindex, cpi->prob_skip_false, *size); - - if (cpi->is_src_frame_alt_ref == 1) - fprintf(f, "skipcount: %4d framesize: %d\n", cpi->skip_true_count , *size); - - fclose(f); - } - -#endif #endif #if HAVE_ARMV7 diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index b107ca716682b8266dcc7ba335ab50352f0d5622..5e507ac42bc423e89150ffe3f7d6125f7f813d3c 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -532,13 +532,6 @@ typedef struct VP8_COMP unsigned char *active_map; unsigned int active_map_enabled; - // Video conferencing cyclic refresh mode flags etc - // This is a mode designed to clean up the background over time in live encoding scenarious. It uses segmentation - int cyclic_refresh_mode_enabled; - int cyclic_refresh_mode_max_mbs_perframe; - int cyclic_refresh_mode_index; - int cyclic_refresh_q; - signed char *cyclic_refresh_map; TOKENLIST *tplist; unsigned int partition_sz[MAX_PARTITIONS]; diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c index 5db83018a08eefd497d9532fe8886962a85f21f8..eb04f2bd749f130f17b856868902cdc282e970eb 100644 --- a/vp8/encoder/ratectrl.c +++ b/vp8/encoder/ratectrl.c @@ -315,46 +315,11 @@ static void calc_iframe_target_size(VP8_COMP *cpi) target = estimate_bits_at_q(INTRA_FRAME, Q, cpi->common.MBs, cpi->key_frame_rate_correction_factor); } - else if (cpi->pass == 2) + else { // New Two pass RC target = cpi->per_frame_bandwidth; } - // First Frame is a special case - else if (cpi->common.current_video_frame == 0) - { - /* 1 Pass there is no information on which to base size so use - * bandwidth per second * fraction of the initial buffer - * level - */ - target = cpi->oxcf.starting_buffer_level / 2; - - if(target > cpi->oxcf.target_bandwidth * 3 / 2) - target = cpi->oxcf.target_bandwidth * 3 / 2; - } - else - { - // if this keyframe was forced, use a more recent Q estimate - int Q = (cpi->common.frame_flags & FRAMEFLAGS_KEY) - ? cpi->avg_frame_qindex : cpi->ni_av_qi; - - // Boost depends somewhat on frame rate - kf_boost = (int)(2 * cpi->output_frame_rate - 16); - - // adjustment up based on q - kf_boost = kf_boost * kfboost_qadjust(Q) / 100; - - // frame separation adjustment ( down) - if (cpi->frames_since_key < cpi->output_frame_rate / 2) - kf_boost = (int)(kf_boost - * cpi->frames_since_key / (cpi->output_frame_rate / 2)); - - if (kf_boost < 16) - kf_boost = 16; - - target = ((16 + kf_boost) * cpi->per_frame_bandwidth) >> 4; - } - if (cpi->oxcf.rc_max_intra_bitrate_pct) { @@ -367,15 +332,12 @@ static void calc_iframe_target_size(VP8_COMP *cpi) cpi->this_frame_target = target; - // TODO: if we separate rate targeting from Q targetting, move this. - // Reset the active worst quality to the baseline value for key frames. - if (cpi->pass != 2) - cpi->active_worst_quality = cpi->worst_quality; - } -// Do the best we can to define the parameteres for the next GF based on what information we have available. +// Do the best we can to define the parameteres for the next GF based +// on what information we have available. +// In this experimental code only two pass is supported. static void calc_gf_params(VP8_COMP *cpi) { int Q = (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q; @@ -398,143 +360,8 @@ static void calc_gf_params(VP8_COMP *cpi) if (pct_gf_active > gf_frame_useage) gf_frame_useage = pct_gf_active; - // Not two pass - if (cpi->pass != 2) - { - // Single Pass lagged mode: TBD - if (FALSE) - { - } - - // Single Pass compression: Has to use current and historical data - else - { -#if 0 - // Experimental code - int index = cpi->one_pass_frame_index; - int frames_to_scan = (cpi->max_gf_interval <= MAX_LAG_BUFFERS) ? cpi->max_gf_interval : MAX_LAG_BUFFERS; - - /* - // *************** Experimental code - incomplete - double decay_val = 1.0; - double IIAccumulator = 0.0; - double last_iiaccumulator = 0.0; - double IIRatio; - - cpi->one_pass_frame_index = cpi->common.current_video_frame%MAX_LAG_BUFFERS; - - for ( i = 0; i < (frames_to_scan - 1); i++ ) - { - if ( index < 0 ) - index = MAX_LAG_BUFFERS; - index --; - - if ( cpi->one_pass_frame_stats[index].frame_coded_error > 0.0 ) - { - IIRatio = cpi->one_pass_frame_stats[index].frame_intra_error / cpi->one_pass_frame_stats[index].frame_coded_error; - - if ( IIRatio > 30.0 ) - IIRatio = 30.0; - } - else - IIRatio = 30.0; - - IIAccumulator += IIRatio * decay_val; - - decay_val = decay_val * cpi->one_pass_frame_stats[index].frame_pcnt_inter; - - if ( (i > MIN_GF_INTERVAL) && - ((IIAccumulator - last_iiaccumulator) < 2.0) ) - { - break; - } - last_iiaccumulator = IIAccumulator; - } - - Boost = IIAccumulator*100.0/16.0; - cpi->baseline_gf_interval = i; - - */ -#else - - /*************************************************************/ - // OLD code - - // Adjust boost based upon ambient Q - Boost = vp8_gfboost_qadjust(Q); - - // Adjust based upon most recently measure intra useage - Boost = Boost * gf_intra_usage_adjustment[(cpi->this_frame_percent_intra < 15) ? cpi->this_frame_percent_intra : 14] / 100; - - // Adjust gf boost based upon GF usage since last GF - Boost = Boost * gf_adjust_table[gf_frame_useage] / 100; -#endif - } - - // Apply an upper limit based on Q for 1 pass encodes - // TODO. - // This is a temporay measure oas one pass not really supported yet in - // the experimental branch - if (Boost > 600 && (cpi->pass == 0)) - Boost = 600; - - // Apply lower limits to boost. - else if (Boost < 110) - Boost = 110; - - // Note the boost used - cpi->last_boost = Boost; - - } - - // Estimate next interval - // This is updated once the real frame size/boost is known. - if (cpi->oxcf.fixed_q == -1) - { - if (cpi->pass == 2) // 2 Pass - { - cpi->frames_till_gf_update_due = cpi->baseline_gf_interval; - } - else // 1 Pass - { - cpi->frames_till_gf_update_due = cpi->baseline_gf_interval; - - if (cpi->last_boost > 750) - cpi->frames_till_gf_update_due++; - - if (cpi->last_boost > 1000) - cpi->frames_till_gf_update_due++; - - if (cpi->last_boost > 1250) - cpi->frames_till_gf_update_due++; - - if (cpi->last_boost >= 1500) - cpi->frames_till_gf_update_due ++; - - if (gf_interval_table[gf_frame_useage] > cpi->frames_till_gf_update_due) - cpi->frames_till_gf_update_due = gf_interval_table[gf_frame_useage]; - - if (cpi->frames_till_gf_update_due > cpi->max_gf_interval) - cpi->frames_till_gf_update_due = cpi->max_gf_interval; - } - } - else - cpi->frames_till_gf_update_due = cpi->baseline_gf_interval; - - // ARF on or off - if (cpi->pass != 2) - { - // For now Alt ref is not allowed except in 2 pass modes. - cpi->source_alt_ref_pending = FALSE; - - /*if ( cpi->oxcf.fixed_q == -1) - { - if ( cpi->oxcf.play_alternate && (cpi->last_boost > (100 + (AF_THRESH*cpi->frames_till_gf_update_due)) ) ) - cpi->source_alt_ref_pending = TRUE; - else - cpi->source_alt_ref_pending = FALSE; - }*/ - } + // Set the gf interval + cpi->frames_till_gf_update_due = cpi->baseline_gf_interval; } @@ -545,155 +372,24 @@ static void calc_pframe_target_size(VP8_COMP *cpi) min_frame_target = 0; - if (cpi->pass == 2) - { - min_frame_target = cpi->min_frame_bandwidth; + min_frame_target = cpi->min_frame_bandwidth; - if (min_frame_target < (cpi->av_per_frame_bandwidth >> 5)) - min_frame_target = cpi->av_per_frame_bandwidth >> 5; - } - else if (min_frame_target < cpi->per_frame_bandwidth / 4) - min_frame_target = cpi->per_frame_bandwidth / 4; + if (min_frame_target < (cpi->av_per_frame_bandwidth >> 5)) + min_frame_target = cpi->av_per_frame_bandwidth >> 5; // Special alt reference frame case if (cpi->common.refresh_alt_ref_frame) { - if (cpi->pass == 2) - { - cpi->per_frame_bandwidth = cpi->twopass.gf_bits; // Per frame bit target for the alt ref frame - cpi->this_frame_target = cpi->per_frame_bandwidth; - } - - /* One Pass ??? TBD */ - /*else - { - int frames_in_section; - int allocation_chunks; - int Q = (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q; - int alt_boost; - int max_arf_rate; - - alt_boost = (cpi->gfu_boost * 3 * vp8_gfboost_qadjust(Q)) / (2 * 100); - alt_boost += (cpi->frames_till_gf_update_due * 50); - - // If alt ref is not currently active then we have a pottential double hit with GF and ARF so reduce the boost a bit. - // A similar thing is done on GFs that preceed a arf update. - if ( !cpi->source_alt_ref_active ) - alt_boost = alt_boost * 3 / 4; - - frames_in_section = cpi->frames_till_gf_update_due+1; // Standard frames + GF - allocation_chunks = (frames_in_section * 100) + alt_boost; - - // Normalize Altboost and allocations chunck down to prevent overflow - while ( alt_boost > 1000 ) - { - alt_boost /= 2; - allocation_chunks /= 2; - } - - else - { - int bits_in_section; - - if ( cpi->kf_overspend_bits > 0 ) - { - Adjustment = (cpi->kf_bitrate_adjustment <= cpi->kf_overspend_bits) ? cpi->kf_bitrate_adjustment : cpi->kf_overspend_bits; - - if ( Adjustment > (cpi->per_frame_bandwidth - min_frame_target) ) - Adjustment = (cpi->per_frame_bandwidth - min_frame_target); - - cpi->kf_overspend_bits -= Adjustment; - - // Calculate an inter frame bandwidth target for the next few frames designed to recover - // any extra bits spent on the key frame. - cpi->inter_frame_target = cpi->per_frame_bandwidth - Adjustment; - if ( cpi->inter_frame_target < min_frame_target ) - cpi->inter_frame_target = min_frame_target; - } - else - cpi->inter_frame_target = cpi->per_frame_bandwidth; - - bits_in_section = cpi->inter_frame_target * frames_in_section; - - // Avoid loss of precision but avoid overflow - if ( (bits_in_section>>7) > allocation_chunks ) - cpi->this_frame_target = alt_boost * (bits_in_section / allocation_chunks); - else - cpi->this_frame_target = (alt_boost * bits_in_section) / allocation_chunks; - } - } - */ + // Per frame bit target for the alt ref frame + cpi->per_frame_bandwidth = cpi->twopass.gf_bits; + cpi->this_frame_target = cpi->per_frame_bandwidth; } // Normal frames (gf,and inter) else { - // 2 pass - if (cpi->pass == 2) - { - cpi->this_frame_target = cpi->per_frame_bandwidth; - } - // 1 pass - else - { - // Make rate adjustment to recover bits spent in key frame - // Test to see if the key frame inter data rate correction should still be in force - if (cpi->kf_overspend_bits > 0) - { - Adjustment = (cpi->kf_bitrate_adjustment <= cpi->kf_overspend_bits) ? cpi->kf_bitrate_adjustment : cpi->kf_overspend_bits; - - if (Adjustment > (cpi->per_frame_bandwidth - min_frame_target)) - Adjustment = (cpi->per_frame_bandwidth - min_frame_target); - - cpi->kf_overspend_bits -= Adjustment; - - // Calculate an inter frame bandwidth target for the next few frames designed to recover - // any extra bits spent on the key frame. - cpi->this_frame_target = cpi->per_frame_bandwidth - Adjustment; - - if (cpi->this_frame_target < min_frame_target) - cpi->this_frame_target = min_frame_target; - } - else - cpi->this_frame_target = cpi->per_frame_bandwidth; - - // If appropriate make an adjustment to recover bits spent on a recent GF - if ((cpi->gf_overspend_bits > 0) && (cpi->this_frame_target > min_frame_target)) - { - int Adjustment = (cpi->non_gf_bitrate_adjustment <= cpi->gf_overspend_bits) ? cpi->non_gf_bitrate_adjustment : cpi->gf_overspend_bits; - - if (Adjustment > (cpi->this_frame_target - min_frame_target)) - Adjustment = (cpi->this_frame_target - min_frame_target); - - cpi->gf_overspend_bits -= Adjustment; - cpi->this_frame_target -= Adjustment; - } - - // Apply small + and - boosts for non gf frames - if ((cpi->last_boost > 150) && (cpi->frames_till_gf_update_due > 0) && - (cpi->current_gf_interval >= (MIN_GF_INTERVAL << 1))) - { - // % Adjustment limited to the range 1% to 10% - Adjustment = (cpi->last_boost - 100) >> 5; - - if (Adjustment < 1) - Adjustment = 1; - else if (Adjustment > 10) - Adjustment = 10; - - // Convert to bits - Adjustment = (cpi->this_frame_target * Adjustment) / 100; - - if (Adjustment > (cpi->this_frame_target - min_frame_target)) - Adjustment = (cpi->this_frame_target - min_frame_target); - - if (cpi->common.frames_since_golden == (cpi->current_gf_interval >> 1)) - cpi->this_frame_target += ((cpi->current_gf_interval - 1) * Adjustment); - else - cpi->this_frame_target -= Adjustment; - } - } + cpi->this_frame_target = cpi->per_frame_bandwidth; } // Sanity check that the total sum of adjustments is not above the maximum allowed @@ -708,178 +404,6 @@ static void calc_pframe_target_size(VP8_COMP *cpi) // Note the baseline target data rate for this inter frame. cpi->inter_frame_target = cpi->this_frame_target; - // One Pass specific code - if (cpi->pass == 0) - { - // Adapt target frame size with respect to any buffering constraints: - if (cpi->buffered_mode) - { - int one_percent_bits = 1 + cpi->oxcf.optimal_buffer_level / 100; - - if ((cpi->buffer_level < cpi->oxcf.optimal_buffer_level) || - (cpi->bits_off_target < cpi->oxcf.optimal_buffer_level)) - { - int percent_low = 0; - - // Decide whether or not we need to adjust the frame data rate target. - // - // If we are are below the optimal buffer fullness level and adherence - // to buffering contraints is important to the end useage then adjust - // the per frame target. - if ((cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) && - (cpi->buffer_level < cpi->oxcf.optimal_buffer_level)) - { - percent_low = - (cpi->oxcf.optimal_buffer_level - cpi->buffer_level) / - one_percent_bits; - } - // Are we overshooting the long term clip data rate... - else if (cpi->bits_off_target < 0) - { - // Adjust per frame data target downwards to compensate. - percent_low = (int)(100 * -cpi->bits_off_target / - (cpi->total_byte_count * 8)); - } - - if (percent_low > cpi->oxcf.under_shoot_pct) - percent_low = cpi->oxcf.under_shoot_pct; - else if (percent_low < 0) - percent_low = 0; - - // lower the target bandwidth for this frame. - cpi->this_frame_target -= (cpi->this_frame_target * percent_low) - / 200; - - // Are we using allowing control of active_worst_allowed_q - // according to buffer level. - if (cpi->auto_worst_q) - { - int critical_buffer_level; - - // For streaming applications the most important factor is - // cpi->buffer_level as this takes into account the - // specified short term buffering constraints. However, - // hitting the long term clip data rate target is also - // important. - if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) - { - // Take the smaller of cpi->buffer_level and - // cpi->bits_off_target - critical_buffer_level = - (cpi->buffer_level < cpi->bits_off_target) - ? cpi->buffer_level : cpi->bits_off_target; - } - // For local file playback short term buffering contraints - // are less of an issue - else - { - // Consider only how we are doing for the clip as a - // whole - critical_buffer_level = cpi->bits_off_target; - } - - // Set the active worst quality based upon the selected - // buffer fullness number. - if (critical_buffer_level < cpi->oxcf.optimal_buffer_level) - { - if ( critical_buffer_level > - (cpi->oxcf.optimal_buffer_level >> 2) ) - { - int64_t qadjustment_range = - cpi->worst_quality - cpi->ni_av_qi; - int64_t above_base = - (critical_buffer_level - - (cpi->oxcf.optimal_buffer_level >> 2)); - - // Step active worst quality down from - // cpi->ni_av_qi when (critical_buffer_level == - // cpi->optimal_buffer_level) to - // cpi->worst_quality when - // (critical_buffer_level == - // cpi->optimal_buffer_level >> 2) - cpi->active_worst_quality = - cpi->worst_quality - - ((qadjustment_range * above_base) / - (cpi->oxcf.optimal_buffer_level*3>>2)); - } - else - { - cpi->active_worst_quality = cpi->worst_quality; - } - } - else - { - cpi->active_worst_quality = cpi->ni_av_qi; - } - } - else - { - cpi->active_worst_quality = cpi->worst_quality; - } - } - else - { - int percent_high = 0; - - if ((cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) - && (cpi->buffer_level > cpi->oxcf.optimal_buffer_level)) - { - percent_high = (cpi->buffer_level - - cpi->oxcf.optimal_buffer_level) - / one_percent_bits; - } - else if (cpi->bits_off_target > cpi->oxcf.optimal_buffer_level) - { - percent_high = (int)((100 * cpi->bits_off_target) - / (cpi->total_byte_count * 8)); - } - - if (percent_high > cpi->oxcf.over_shoot_pct) - percent_high = cpi->oxcf.over_shoot_pct; - else if (percent_high < 0) - percent_high = 0; - - cpi->this_frame_target += (cpi->this_frame_target * - percent_high) / 200; - - - // Are we allowing control of active_worst_allowed_q according to bufferl level. - if (cpi->auto_worst_q) - { - // When using the relaxed buffer model stick to the user specified value - cpi->active_worst_quality = cpi->ni_av_qi; - } - else - { - cpi->active_worst_quality = cpi->worst_quality; - } - } - - // Set active_best_quality to prevent quality rising too high - cpi->active_best_quality = cpi->best_quality; - - // Worst quality obviously must not be better than best quality - if (cpi->active_worst_quality <= cpi->active_best_quality) - cpi->active_worst_quality = cpi->active_best_quality + 1; - - } - // Unbuffered mode (eg. video conferencing) - else - { - // Set the active worst quality - cpi->active_worst_quality = cpi->worst_quality; - } - - // Special trap for constrained quality mode - // "active_worst_quality" may never drop below cq level - // for any frame type. - if ( cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY && - cpi->active_worst_quality < cpi->cq_target_quality) - { - cpi->active_worst_quality = cpi->cq_target_quality; - } - } - // Test to see if we have to drop a frame // The auto-drop frame code is only used in buffered mode. // In unbufferd mode (eg vide conferencing) the descision to @@ -905,16 +429,6 @@ static void calc_pframe_target_size(VP8_COMP *cpi) cpi->drop_frame = TRUE; } -#if 0 - // Check for other drop frame crtieria (Note 2 pass cbr uses decimation on whole KF sections) - else if ((cpi->buffer_level < cpi->oxcf.drop_frames_water_mark * cpi->oxcf.optimal_buffer_level / 100) && - (cpi->drop_count < cpi->max_drop_count) && (cpi->pass == 0)) - { - cpi->drop_frame = TRUE; - } - -#endif - if (cpi->drop_frame) { // Update the buffer level variable. @@ -957,45 +471,11 @@ static void calc_pframe_target_size(VP8_COMP *cpi) // Is a fixed manual GF frequency being used if (cpi->auto_gold) { - // For one pass throw a GF if recent frame intra useage is low or the GF useage is high - if ((cpi->pass == 0) && (cpi->this_frame_percent_intra < 15 || gf_frame_useage >= 5)) - cpi->common.refresh_golden_frame = TRUE; - - // Two pass GF descision - else if (cpi->pass == 2) - cpi->common.refresh_golden_frame = TRUE; - } - -#if 0 - - // Debug stats - if (0) - { - FILE *f; - - f = fopen("gf_useaget.stt", "a"); - fprintf(f, " %8ld %10ld %10ld %10ld %10ld\n", - cpi->common.current_video_frame, cpi->gfu_boost, vp8_gfboost_qadjust(Q), cpi->gfu_boost, gf_frame_useage); - fclose(f); + cpi->common.refresh_golden_frame = TRUE; } -#endif - if (cpi->common.refresh_golden_frame == TRUE) { -#if 0 - - if (0) // p_gw - { - FILE *f; - - f = fopen("GFexit.stt", "a"); - fprintf(f, "%8ld GF coded\n", cpi->common.current_video_frame); - fclose(f); - } - -#endif - if (cpi->auto_adjust_gold_quantizer) { calc_gf_params(cpi); @@ -1008,30 +488,9 @@ static void calc_pframe_target_size(VP8_COMP *cpi) { if (cpi->oxcf.fixed_q < 0) { - if (cpi->pass == 2) - { - cpi->this_frame_target = cpi->per_frame_bandwidth; // The spend on the GF is defined in the two pass code for two pass encodes - } - else - { - int Boost = cpi->last_boost; - int frames_in_section = cpi->frames_till_gf_update_due + 1; - int allocation_chunks = (frames_in_section * 100) + (Boost - 100); - int bits_in_section = cpi->inter_frame_target * frames_in_section; - - // Normalize Altboost and allocations chunck down to prevent overflow - while (Boost > 1000) - { - Boost /= 2; - allocation_chunks /= 2; - } - - // Avoid loss of precision but avoid overflow - if ((bits_in_section >> 7) > allocation_chunks) - cpi->this_frame_target = Boost * (bits_in_section / allocation_chunks); - else - cpi->this_frame_target = (Boost * bits_in_section) / allocation_chunks; - } + // The spend on the GF is defined in the two pass code + // for two pass encodes + cpi->this_frame_target = cpi->per_frame_bandwidth; } else cpi->this_frame_target = @@ -1351,28 +810,6 @@ void vp8_adjust_key_frame_context(VP8_COMP *cpi) // Clear down mmx registers to allow floating point in what follows vp8_clear_system_state(); - // Do we have any key frame overspend to recover? - // Two-pass overspend handled elsewhere. - if ((cpi->pass != 2) - && (cpi->projected_frame_size > cpi->per_frame_bandwidth)) - { - int overspend; - - /* Update the count of key frame overspend to be recovered in - * subsequent frames. A portion of the KF overspend is treated as gf - * overspend (and hence recovered more quickly) as the kf is also a - * gf. Otherwise the few frames following each kf tend to get more - * bits allocated than those following other gfs. - */ - overspend = (cpi->projected_frame_size - cpi->per_frame_bandwidth); - cpi->kf_overspend_bits += overspend * 7 / 8; - cpi->gf_overspend_bits += overspend * 1 / 8; - - /* Work out how much to try and recover per frame. */ - cpi->kf_bitrate_adjustment = cpi->kf_overspend_bits - / estimate_keyframe_frequency(cpi); - } - cpi->frames_since_key = 0; cpi->key_frame_count++; }