diff options
-rw-r--r-- | vp8/encoder/firstpass.c | 24 | ||||
-rw-r--r-- | vp8/encoder/mbgraph.c | 8 | ||||
-rw-r--r-- | vp8/encoder/onyx_if.c | 79 | ||||
-rw-r--r-- | vp8/encoder/onyx_int.h | 7 | ||||
-rw-r--r-- | vp8/encoder/quantize.c | 26 | ||||
-rw-r--r-- | vp8/encoder/ratectrl.c | 10 |
6 files changed, 106 insertions, 48 deletions
diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c index 901404617..19ae70684 100644 --- a/vp8/encoder/firstpass.c +++ b/vp8/encoder/firstpass.c @@ -3032,10 +3032,26 @@ static void find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) // We do three calculations for kf size. // The first is based on the error score for the whole kf group. - // The second (optionaly) on the key frames own error if this is smaller than the average for the group. - // The final one insures that the frame receives at least the allocation it would have received based on its own error score vs the error score remaining - - allocation_chunks = ((cpi->twopass.frames_to_key - 1) * 100) + kf_boost; // cpi->twopass.frames_to_key-1 because key frame itself is taken care of by kf_boost + // The second (optionaly) on the key frames own error if this is + // smaller than the average for the group. + // The final one insures that the frame receives at least the + // allocation it would have received based on its own error score vs + // the error score remaining + // Special case if the sequence appears almost totaly static + // as measured by the decay accumulator. In this case we want to + // spend almost all of the bits on the key frame. + // cpi->twopass.frames_to_key-1 because key frame itself is taken + // care of by kf_boost. + if ( decay_accumulator >= 0.99 ) + { + allocation_chunks = + ((cpi->twopass.frames_to_key - 1) * 10) + kf_boost; + } + else + { + allocation_chunks = + ((cpi->twopass.frames_to_key - 1) * 100) + kf_boost; + } // Normalize Altboost and allocations chunck down to prevent overflow while (kf_boost > 1000) diff --git a/vp8/encoder/mbgraph.c b/vp8/encoder/mbgraph.c index ad40c9e33..4f9ba125b 100644 --- a/vp8/encoder/mbgraph.c +++ b/vp8/encoder/mbgraph.c @@ -477,12 +477,16 @@ void separate_arf_mbs //if ( ncnt[1] && (ncnt[0] / ncnt[1] < 10) ) if ( 1 ) { - cpi->mbgraph_use_arf_segmentation = ncnt[1]; + // Note % of blocks that are marked as static + cpi->static_mb_pct = + (ncnt[1] * 100) / cm->MBs; + vp8_enable_segmentation((VP8_PTR) cpi); } else { - cpi->mbgraph_use_arf_segmentation = 0; + cpi->static_mb_pct = 0; + vp8_disable_segmentation((VP8_PTR) cpi); } diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index b60d996a8..25b56691d 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -492,6 +492,7 @@ static void init_seg_features(VP8_COMP *cpi) vpx_memset( cpi->segmentation_map, 0, (cm->mb_rows * cm->mb_cols)); xd->update_mb_segmentation_map = 0; xd->update_mb_segmentation_data = 0; + cpi->static_mb_pct = 0; // Disable segmentation vp8_disable_segmentation((VP8_PTR)cpi); @@ -507,6 +508,7 @@ static void init_seg_features(VP8_COMP *cpi) vpx_memset( cpi->segmentation_map, 0, (cm->mb_rows * cm->mb_cols)); xd->update_mb_segmentation_map = 0; xd->update_mb_segmentation_data = 0; + cpi->static_mb_pct = 0; // Disable segmentation and individual segment features by default vp8_disable_segmentation((VP8_PTR)cpi); @@ -557,7 +559,7 @@ static void init_seg_features(VP8_COMP *cpi) set_segdata( xd, 1, SEG_LVL_ALT_LF, -2 ); enable_segfeature(xd, 1, SEG_LVL_ALT_LF); - if ( high_q ) + if ( high_q || (cpi->static_mb_pct == 100) ) { set_segref(xd, 1, ALTREF_FRAME); enable_segfeature(xd, 1, SEG_LVL_REF_FRAME); @@ -1973,6 +1975,8 @@ static void init_config(VP8_PTR ptr, VP8_CONFIG *oxcf) cpi->total_actual_bits = 0; cpi->total_target_vs_actual = 0; + cpi->static_mb_pct = 0; + #if VP8_TEMPORAL_ALT_REF { int i; @@ -2233,6 +2237,7 @@ void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf) { cpi->last_q[0] = cpi->oxcf.fixed_q; cpi->last_q[1] = cpi->oxcf.fixed_q; + cpi->last_boosted_qindex = cpi->oxcf.fixed_q; } cpi->Speed = cpi->oxcf.cpu_used; @@ -2694,6 +2699,9 @@ void vp8_remove_compressor(VP8_PTR *ptr) fprintf(f, "%7.3f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t%8.0f\n", dr, cpi->total / cpi->count, total_psnr, cpi->totalp / cpi->count, total_psnr2, total_ssim, total_encode_time); +// fprintf(f, "%7.3f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t%8.0f %10ld\n", +// dr, cpi->total / cpi->count, total_psnr, cpi->totalp / cpi->count, total_psnr2, total_ssim, +// total_encode_time, cpi->tot_recode_hits); } if (cpi->b_calculate_ssimg) @@ -2702,6 +2710,9 @@ void vp8_remove_compressor(VP8_PTR *ptr) fprintf(f, "%7.3f\t%6.4f\t%6.4f\t%6.4f\t%6.4f\t%8.0f\n", dr, cpi->total_ssimg_y / cpi->count, cpi->total_ssimg_u / cpi->count, cpi->total_ssimg_v / cpi->count, cpi->total_ssimg_all / cpi->count, total_encode_time); +// fprintf(f, "%7.3f\t%6.4f\t%6.4f\t%6.4f\t%6.4f\t%8.0f %10ld\n", dr, +// cpi->total_ssimg_y / cpi->count, cpi->total_ssimg_u / cpi->count, +// cpi->total_ssimg_v / cpi->count, cpi->total_ssimg_all / cpi->count, total_encode_time, cpi->tot_recode_hits); } fclose(f); @@ -4134,10 +4145,15 @@ static void encode_frame_to_data_rate // 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; + int delta_qindex; + int qindex = cpi->last_boosted_qindex; + + 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 @@ -4248,8 +4264,16 @@ static void encode_frame_to_data_rate if ( cpi->active_worst_quality < cpi->active_best_quality ) cpi->active_worst_quality = cpi->active_best_quality; - // Determine initial Q to try - Q = vp8_regulate_q(cpi, cpi->this_frame_target); + // Specuial case code to try and match quality with forced key frames + if ( (cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced ) + { + Q = cpi->last_boosted_qindex; + } + else + { + // Determine initial Q to try + Q = vp8_regulate_q(cpi, cpi->this_frame_target); + } last_zbin_oq = cpi->zbin_over_quant; // Set highest allowed value for Zbin over quant @@ -4527,23 +4551,32 @@ static void encode_frame_to_data_rate &cm->yv12_fb[cm->new_fb_idx], IF_RTCD(&cpi->rtcd.variance)); + int high_err_target = cpi->ambient_err; + int low_err_target = ((cpi->ambient_err * 3) >> 2); + // The key frame is not good enough - if ( kf_err > ((cpi->ambient_err * 7) >> 3) ) + if ( (kf_err > high_err_target) && + (cpi->projected_frame_size <= frame_over_shoot_limit) ) { // Lower q_high q_high = (Q > q_low) ? (Q - 1) : q_low; // Adjust Q - Q = (q_high + q_low) >> 1; + Q = (Q * high_err_target) / kf_err; + if ( Q < ((q_high + q_low) >> 1)) + Q = (q_high + q_low) >> 1; } // The key frame is much better than the previous frame - else if ( kf_err < (cpi->ambient_err >> 1) ) + else if ( (kf_err < low_err_target) && + (cpi->projected_frame_size >= frame_under_shoot_limit) ) { // Raise q_low q_low = (Q < q_high) ? (Q + 1) : q_high; // Adjust Q - Q = (q_high + q_low + 1) >> 1; + Q = (Q * low_err_target) / kf_err; + if ( Q > ((q_high + q_low + 1) >> 1)) + Q = (q_high + q_low + 1) >> 1; } // Clamp Q to upper and lower limits: @@ -4569,14 +4602,12 @@ static void encode_frame_to_data_rate // Frame is too large if (cpi->projected_frame_size > cpi->this_frame_target) { - //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 zbin_oq_low = (cpi->zbin_over_quant < zbin_oq_high) ? (cpi->zbin_over_quant + 1) : zbin_oq_high; - //if ( undershoot_seen || (Q == MAXQ) ) - if (undershoot_seen) + if ( undershoot_seen || (loop_count > 1) ) { // Update rate_correction_factor unless cpi->active_worst_quality has changed. if (!active_worst_qchanged) @@ -4619,7 +4650,7 @@ static void encode_frame_to_data_rate else // else lower zbin_oq_high zbin_oq_high = (cpi->zbin_over_quant > zbin_oq_low) ? (cpi->zbin_over_quant - 1) : zbin_oq_low; - if (overshoot_seen) + if ( overshoot_seen || (loop_count > 1) ) { // Update rate_correction_factor unless cpi->active_worst_quality has changed. if (!active_worst_qchanged) @@ -4845,6 +4876,20 @@ static void encode_frame_to_data_rate cpi->last_q[cm->frame_type] = cm->base_qindex; + // Keep record of last boosted (KF/KF/ARF) Q value. + // If the current frame is coded at a lower Q then we also update it. + // If all mbs in this group are skipped only update if the Q value is + // better than that already stored. + // This is used to help set quality in forced key frames to reduce popping + if ( (cm->base_qindex < cpi->last_boosted_qindex) || + ( (cpi->static_mb_pct < 100) && + ( (cm->frame_type == KEY_FRAME) || + cm->refresh_alt_ref_frame || + (cm->refresh_golden_frame && !cpi->is_src_frame_alt_ref) ) ) ) + { + cpi->last_boosted_qindex = cm->base_qindex; + } + if (cm->frame_type == KEY_FRAME) { vp8_adjust_key_frame_context(cpi); @@ -4991,7 +5036,7 @@ static void encode_frame_to_data_rate if (cpi->twopass.total_left_stats->coded_error != 0.0) fprintf(f, "%10d %10d %10d %10d %10d %10d %10d" - "%6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f" + "%7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f" "%6d %5d %5d %5d %8d %8.2f %10d %10.3f" "%10.3f %8d\n", cpi->common.current_video_frame, cpi->this_frame_target, @@ -5023,7 +5068,7 @@ static void encode_frame_to_data_rate cpi->tot_recode_hits); else fprintf(f, "%10d %10d %10d %10d %10d %10d %10d" - "%6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f" + "%7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f" "%6d %5d %5d %5d %8d %8.2f %10d %10.3f" "%8d\n", cpi->common.current_video_frame, diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index f47a46408..002f30a97 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -383,6 +383,7 @@ typedef struct VP8_COMP int this_frame_target; int projected_frame_size; int last_q[2]; // Separate values for Intra/Inter + int last_boosted_qindex; // Last boosted GF/KF/ARF q double rate_correction_factor; double key_frame_rate_correction_factor; @@ -483,11 +484,7 @@ typedef struct VP8_COMP #endif MBGRAPH_FRAME_STATS mbgraph_stats[MAX_LAG_BUFFERS]; int mbgraph_n_frames; // number of frames filled in the above - int mbgraph_use_arf_segmentation; // set if part of an ARF is considered to be a - // poor predictor, and thus coeffs are skipped - // or coded at a higher Q using MB-segmentation - // this value is the number of MBs that are - // poor predictors (> 0 and < common.MBs) + int static_mb_pct; // % forced skip mbs by segmentation int decimation_factor; int decimation_count; diff --git a/vp8/encoder/quantize.c b/vp8/encoder/quantize.c index 68b10cc4c..d7316f74e 100644 --- a/vp8/encoder/quantize.c +++ b/vp8/encoder/quantize.c @@ -1271,30 +1271,18 @@ void vp8cx_frame_init_quantizer(VP8_COMP *cpi) void vp8_set_quantizer(struct VP8_COMP *cpi, int Q) { VP8_COMMON *cm = &cpi->common; - int update = 0; - int new_delta_q; - cm->base_qindex = Q; - - /* if any of the delta_q values are changing update flag has to be set */ - /* currently only y2dc_delta_q may change */ + // if any of the delta_q values are changing update flag will + // have to be set. cm->y1dc_delta_q = 0; cm->y2ac_delta_q = 0; cm->uvdc_delta_q = 0; cm->uvac_delta_q = 0; + cm->y2dc_delta_q = 0; - if (Q < 4) - { - new_delta_q = 4-Q; - } - else - new_delta_q = 0; - - update |= cm->y2dc_delta_q != new_delta_q; - cm->y2dc_delta_q = new_delta_q; - - /* quantizer has to be reinitialized for any delta_q changes */ - if(update) - vp8cx_init_quantizer(cpi); + // quantizer has to be reinitialized if any delta_q changes. + // As there are not any here for now this is inactive code. + //if(update) + // vp8cx_init_quantizer(cpi); } diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c index d2e680f89..fd3f8d7b2 100644 --- a/vp8/encoder/ratectrl.c +++ b/vp8/encoder/ratectrl.c @@ -24,7 +24,7 @@ #include "encodemv.h" -#define MIN_BPB_FACTOR 0.01 +#define MIN_BPB_FACTOR 0.005 #define MAX_BPB_FACTOR 50 extern const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES]; @@ -1477,6 +1477,14 @@ void vp8_compute_frame_size_bounds(VP8_COMP *cpi, int *frame_under_shoot_limit, } } } + + // For very small rate targets where the fractional adjustment + // (eg * 7/8) may be tiny make sure there is at least a minimum + // range. + *frame_over_shoot_limit += 200; + *frame_under_shoot_limit -= 200; + if ( *frame_under_shoot_limit < 0 ) + *frame_under_shoot_limit = 0; } } |