diff options
-rw-r--r-- | vp8/encoder/onyx_if.c | 97 | ||||
-rw-r--r-- | vp8/encoder/onyx_int.h | 3 | ||||
-rw-r--r-- | vp8/vp8_cx_iface.c | 2 |
3 files changed, 75 insertions, 27 deletions
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index e0d1d7043..47fc3f78e 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -1551,6 +1551,7 @@ void vp8_init_config(VP8_PTR ptr, VP8_CONFIG *oxcf) cpi->auto_worst_q = 0; cpi->oxcf.best_allowed_q = MINQ; cpi->oxcf.worst_allowed_q = MAXQ; + cpi->oxcf.cq_level = MINQ; cpi->oxcf.end_usage = USAGE_STREAM_FROM_SERVER; cpi->oxcf.starting_buffer_level = 4000; @@ -1651,6 +1652,7 @@ void vp8_init_config(VP8_PTR ptr, VP8_CONFIG *oxcf) cpi->oxcf.worst_allowed_q = q_trans[oxcf->worst_allowed_q]; cpi->oxcf.best_allowed_q = q_trans[oxcf->best_allowed_q]; + cpi->oxcf.cq_level = q_trans[cpi->oxcf.cq_level]; if (oxcf->fixed_q >= 0) { @@ -1740,6 +1742,8 @@ void vp8_init_config(VP8_PTR ptr, VP8_CONFIG *oxcf) cpi->avg_frame_qindex = cpi->oxcf.worst_allowed_q; cpi->best_quality = cpi->oxcf.best_allowed_q; cpi->active_best_quality = cpi->oxcf.best_allowed_q; + cpi->cq_target_quality = cpi->oxcf.cq_level; + cpi->buffered_mode = (cpi->oxcf.optimal_buffer_level > 0) ? TRUE : FALSE; cpi->rolling_target_bits = cpi->av_per_frame_bandwidth; @@ -1936,6 +1940,7 @@ void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf) cpi->oxcf.worst_allowed_q = q_trans[oxcf->worst_allowed_q]; cpi->oxcf.best_allowed_q = q_trans[oxcf->best_allowed_q]; + cpi->oxcf.cq_level = q_trans[cpi->oxcf.cq_level]; if (oxcf->fixed_q >= 0) { @@ -2028,7 +2033,6 @@ void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf) cpi->active_best_quality = cpi->oxcf.best_allowed_q; cpi->buffered_mode = (cpi->oxcf.optimal_buffer_level > 0) ? TRUE : FALSE; - // Experimental cq target value cpi->cq_target_quality = cpi->oxcf.cq_level; cpi->rolling_target_bits = cpi->av_per_frame_bandwidth; @@ -3817,29 +3821,28 @@ static void encode_frame_to_data_rate 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 - // close to but just below the ambient Q to minimize the risk - // of popping - if ( cpi->this_key_frame_forced ) - { - cpi->active_worst_quality = cpi->avg_frame_qindex * 7/8; - cpi->active_best_quality = cpi->avg_frame_qindex * 2/3; - } - else + if ( cpi->pass == 2 ) { - 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]; - } - // One pass more conservative - else + 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 ) + { + if ( cpi->active_best_quality > cpi->avg_frame_qindex * 7/8) + cpi->active_best_quality = cpi->avg_frame_qindex * 7/8; + else if ( cpi->active_best_quality < cpi->avg_frame_qindex >> 2 ) + cpi->active_best_quality = cpi->avg_frame_qindex >> 2; + } } - } + // One pass more conservative + else + cpi->active_best_quality = kf_high_motion_minq[Q]; + } else if (cm->refresh_golden_frame || cpi->common.refresh_alt_ref_frame) { @@ -4153,9 +4156,44 @@ static void encode_frame_to_data_rate active_worst_qchanged = FALSE; #if !(CONFIG_REALTIME_ONLY) + // Special case handling for forced key frames + if ( (cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced ) + { + int last_q = Q; + int kf_err = vp8_calc_ss_err(cpi->Source, + &cm->yv12_fb[cm->new_fb_idx], + IF_RTCD(&cpi->rtcd.variance)); + + // The key frame is not good enough + if ( kf_err > ((cpi->ambient_err * 3) >> 2) ) + { + // Lower q_high + q_high = (Q > q_low) ? (Q - 1) : q_low; + + // Adjust Q + Q = (q_high + q_low) >> 1; + } + // The key frame is much better than the previous frame + else if ( kf_err < (cpi->ambient_err >> 1) ) + { + // Raise q_low + q_low = (Q < q_high) ? (Q + 1) : q_high; + + // Adjust Q + Q = (q_high + q_low + 1) >> 1; + } + + // Clamp Q to upper and lower limits: + if (Q > q_high) + Q = q_high; + else if (Q < q_low) + Q = q_low; + + Loop = ((Q != last_q)) ? TRUE : FALSE; + } // Is the projected frame size out of range and are we allowed to attempt to recode. - if ( recode_loop_test( cpi, + else if ( recode_loop_test( cpi, frame_over_shoot_limit, frame_under_shoot_limit, Q, top_index, bottom_index ) ) { @@ -4171,7 +4209,7 @@ static void encode_frame_to_data_rate //if ( cpi->zbin_over_quant == 0 ) q_low = (Q < q_high) ? (Q + 1) : q_high; // Raise Qlow as to at least the current value - if (cpi->zbin_over_quant > 0) // If we are using over quant do the same for zbin_oq_low + if (cpi->zbin_over_quant > 0) // If we are using over quant do the same for zbin_oq_low zbin_oq_low = (cpi->zbin_over_quant < zbin_oq_high) ? (cpi->zbin_over_quant + 1) : zbin_oq_high; //if ( undershoot_seen || (Q == MAXQ) ) @@ -4314,6 +4352,16 @@ static void encode_frame_to_data_rate } #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 + if ( cpi->next_key_frame_forced && (cpi->frames_to_key == 0) ) + { + cpi->ambient_err = vp8_calc_ss_err(cpi->Source, + &cm->yv12_fb[cm->new_fb_idx], + IF_RTCD(&cpi->rtcd.variance)); + } + // 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 vp8_update_gf_useage_maps(cpi, cm, &cpi->mb); @@ -4343,7 +4391,6 @@ 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 vp8_update_gf_useage_maps(cpi, cm, &cpi->mb); @@ -4374,8 +4421,6 @@ static void encode_frame_to_data_rate else cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx]; - - //#pragma omp parallel sections { diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index 6b07e2f22..45fafd5b6 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -320,6 +320,9 @@ typedef struct unsigned int this_key_frame_forced; unsigned int next_key_frame_forced; + // Ambient reconstruction err target for force key frames + int ambient_err; + unsigned int mode_check_freq[MAX_MODES]; unsigned int mode_test_hit_counts[MAX_MODES]; unsigned int mode_chosen_counts[MAX_MODES]; diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c index 09a9151bc..8d8e19e44 100644 --- a/vp8/vp8_cx_iface.c +++ b/vp8/vp8_cx_iface.c @@ -313,6 +313,7 @@ static vpx_codec_err_t set_vp8e_config(VP8_CONFIG *oxcf, oxcf->best_allowed_q = cfg.rc_min_quantizer; oxcf->worst_allowed_q = cfg.rc_max_quantizer; + oxcf->cq_level = vp8_cfg.cq_level; oxcf->fixed_q = -1; oxcf->under_shoot_pct = cfg.rc_undershoot_pct; @@ -349,7 +350,6 @@ static vpx_codec_err_t set_vp8e_config(VP8_CONFIG *oxcf, oxcf->arnr_type = vp8_cfg.arnr_type; oxcf->tuning = vp8_cfg.tuning; - oxcf->cq_level = vp8_cfg.cq_level; /* printf("Current VP8 Settings: \n"); |