diff --git a/configure b/configure index 145a29496..d76adede4 100755 --- a/configure +++ b/configure @@ -226,7 +226,7 @@ EXPERIMENT_LIST=" newlpf enhanced_interp superblocks - feature_updates + featureupdates " CONFIG_LIST=" external_build diff --git a/vp8/common/loopfilter.c b/vp8/common/loopfilter.c index 083e1de7e..65f50acc6 100644 --- a/vp8/common/loopfilter.c +++ b/vp8/common/loopfilter.c @@ -576,7 +576,7 @@ void vp8_loop_filter_frame_yonly } } - +#if CONFIG_FEATUREUPDATES // TODO: Multiple copies of loop filtering code should be pruned and // cut down. This just adds yet another so that I can do an if // on segment. @@ -707,7 +707,7 @@ void vp8_loop_filter_frame_segment(VP8_COMMON *cm, MACROBLOCKD *xd, } } - +#endif void vp8_loop_filter_partial_frame ( diff --git a/vp8/encoder/picklpf.c b/vp8/encoder/picklpf.c index 99214e7f5..a856493f5 100644 --- a/vp8/encoder/picklpf.c +++ b/vp8/encoder/picklpf.c @@ -268,8 +268,7 @@ void vp8cx_pick_filter_level_fast(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi) void vp8cx_set_alt_lf_level(VP8_COMP *cpi, int filt_val) { } - - +#if CONFIG_FEATUREUPDATES void vp8cx_pick_filter_level_sg(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi, int segment) { VP8_COMMON *cm = &cpi->common; @@ -483,5 +482,184 @@ void vp8cx_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi) if (segfeature_active(xd, i, SEG_LVL_ALT_LF)) { set_segdata(xd, i, SEG_LVL_ALT_LF, filt_lev[i] - filt_lev[0]); + xd->update_mb_segmentation_data != + segfeature_changed( xd,i,SEG_LVL_ALT_LF); } } +#else +void vp8cx_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi) +{ + VP8_COMMON *cm = &cpi->common; + + int best_err = 0; + int filt_err = 0; + int min_filter_level = get_min_filter_level(cpi, cm->base_qindex); + int max_filter_level = get_max_filter_level(cpi, cm->base_qindex); + + int filter_step; + int filt_high = 0; + int filt_mid = cm->filter_level; // Start search at previous frame filter level + int filt_low = 0; + int filt_best; + int filt_direction = 0; + + int Bias = 0; // Bias against raising loop filter and in favour of lowering it + + // Make a copy of the unfiltered / processed recon buffer +#if HAVE_ARMV7 +#if CONFIG_RUNTIME_CPU_DETECT + if (cm->rtcd.flags & HAS_NEON) +#endif + { + vp8_yv12_copy_frame_yonly_no_extend_frame_borders_neon(cm->frame_to_show, &cpi->last_frame_uf); + } +#if CONFIG_RUNTIME_CPU_DETECT + else +#endif +#endif +#if !HAVE_ARMV7 || CONFIG_RUNTIME_CPU_DETECT + { + vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cpi->last_frame_uf); + } +#endif + + if (cm->frame_type == KEY_FRAME) + cm->sharpness_level = 0; + else + cm->sharpness_level = cpi->oxcf.Sharpness; + + // Start the search at the previous frame filter level unless it is now out of range. + filt_mid = cm->filter_level; + + if (filt_mid < min_filter_level) + filt_mid = min_filter_level; + else if (filt_mid > max_filter_level) + filt_mid = max_filter_level; + + // Define the initial step size + filter_step = (filt_mid < 16) ? 4 : filt_mid / 4; + + // Get baseline error score + vp8cx_set_alt_lf_level(cpi, filt_mid); + vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_mid); + + best_err = vp8_calc_ss_err(sd, cm->frame_to_show, IF_RTCD(&cpi->rtcd.variance)); + filt_best = filt_mid; + + // Re-instate the unfiltered frame +#if HAVE_ARMV7 +#if CONFIG_RUNTIME_CPU_DETECT + if (cm->rtcd.flags & HAS_NEON) +#endif + { + vp8_yv12_copy_frame_yonly_no_extend_frame_borders_neon(&cpi->last_frame_uf, cm->frame_to_show); + } +#if CONFIG_RUNTIME_CPU_DETECT + else +#endif +#endif +#if !HAVE_ARMV7 || CONFIG_RUNTIME_CPU_DETECT + { + vp8_yv12_copy_frame_yonly_ptr(&cpi->last_frame_uf, cm->frame_to_show); + } +#endif + + while (filter_step > 0) + { + Bias = (best_err >> (15 - (filt_mid / 8))) * filter_step; //PGW change 12/12/06 for small images + + // jbb chg: 20100118 - in sections with lots of new material coming in don't bias as much to a low filter value + if (cpi->twopass.section_intra_rating < 20) + Bias = Bias * cpi->twopass.section_intra_rating / 20; + + filt_high = ((filt_mid + filter_step) > max_filter_level) ? max_filter_level : (filt_mid + filter_step); + filt_low = ((filt_mid - filter_step) < min_filter_level) ? min_filter_level : (filt_mid - filter_step); + + if ((filt_direction <= 0) && (filt_low != filt_mid)) + { + // Get Low filter error score + vp8cx_set_alt_lf_level(cpi, filt_low); + vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_low); + + filt_err = vp8_calc_ss_err(sd, cm->frame_to_show, IF_RTCD(&cpi->rtcd.variance)); + + // Re-instate the unfiltered frame +#if HAVE_ARMV7 +#if CONFIG_RUNTIME_CPU_DETECT + if (cm->rtcd.flags & HAS_NEON) +#endif + { + vp8_yv12_copy_frame_yonly_no_extend_frame_borders_neon(&cpi->last_frame_uf, cm->frame_to_show); + } +#if CONFIG_RUNTIME_CPU_DETECT + else +#endif +#endif +#if !HAVE_ARMV7 || CONFIG_RUNTIME_CPU_DETECT + { + vp8_yv12_copy_frame_yonly_ptr(&cpi->last_frame_uf, cm->frame_to_show); + } +#endif + + // If value is close to the best so far then bias towards a lower loop filter value. + if ((filt_err - Bias) < best_err) + { + // Was it actually better than the previous best? + if (filt_err < best_err) + best_err = filt_err; + + filt_best = filt_low; + } + } + + // Now look at filt_high + if ((filt_direction >= 0) && (filt_high != filt_mid)) + { + vp8cx_set_alt_lf_level(cpi, filt_high); + vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_high); + + filt_err = vp8_calc_ss_err(sd, cm->frame_to_show, IF_RTCD(&cpi->rtcd.variance)); + + // Re-instate the unfiltered frame +#if HAVE_ARMV7 +#if CONFIG_RUNTIME_CPU_DETECT + if (cm->rtcd.flags & HAS_NEON) +#endif + { + vp8_yv12_copy_frame_yonly_no_extend_frame_borders_neon(&cpi->last_frame_uf, cm->frame_to_show); + } +#if CONFIG_RUNTIME_CPU_DETECT + else +#endif +#endif +#if !HAVE_ARMV7 || CONFIG_RUNTIME_CPU_DETECT + { + vp8_yv12_copy_frame_yonly_ptr(&cpi->last_frame_uf, cm->frame_to_show); + } +#endif + + // Was it better than the previous best? + if (filt_err < (best_err - Bias)) + { + best_err = filt_err; + filt_best = filt_high; + } + } + + // Half the step distance if the best filter value was the same as last time + if (filt_best == filt_mid) + { + filter_step = filter_step / 2; + filt_direction = 0; + } + else + { + filt_direction = (filt_best < filt_mid) ? -1 : 1; + filt_mid = filt_best; + } + } + + cm->filter_level = filt_best; +} +#endif +