Tune effect of motion on KF/GF boost in two pass;
This code adjust the impact of the amount and speed of motion on GF and KF boost. Sections with lots of slow motion will tend to have a somewhat bigger boost and sections with fast motion may have less. There is a knock on effect to the selection of the active quantizer range. This will likely require further tuning but helps with a couple of particularly bad edge cases. Change-Id: Ic2449cda7305672b69acf42fc0a845b77ac98d40
This commit is contained in:
		@@ -1218,10 +1218,7 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    double mv_accumulator_rabs  = 0.0;
 | 
					    double mv_accumulator_rabs  = 0.0;
 | 
				
			||||||
    double mv_accumulator_cabs  = 0.0;
 | 
					    double mv_accumulator_cabs  = 0.0;
 | 
				
			||||||
    double this_mv_rabs;
 | 
					 | 
				
			||||||
    double this_mv_cabs;
 | 
					 | 
				
			||||||
    double mv_ratio_accumulator = 0.0;
 | 
					    double mv_ratio_accumulator = 0.0;
 | 
				
			||||||
    double distance_factor = 0.0;
 | 
					 | 
				
			||||||
    double decay_accumulator = 1.0;
 | 
					    double decay_accumulator = 1.0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    double boost_factor = IIFACTOR;
 | 
					    double boost_factor = IIFACTOR;
 | 
				
			||||||
@@ -1270,9 +1267,10 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
 | 
				
			|||||||
    while (((i < cpi->max_gf_interval) || ((cpi->frames_to_key - i) < MIN_GF_INTERVAL)) && (i < cpi->frames_to_key))
 | 
					    while (((i < cpi->max_gf_interval) || ((cpi->frames_to_key - i) < MIN_GF_INTERVAL)) && (i < cpi->frames_to_key))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        double r;
 | 
					        double r;
 | 
				
			||||||
        double motion_factor;
 | 
					 | 
				
			||||||
        double this_frame_mvr_ratio;
 | 
					        double this_frame_mvr_ratio;
 | 
				
			||||||
        double this_frame_mvc_ratio;
 | 
					        double this_frame_mvc_ratio;
 | 
				
			||||||
 | 
					        double motion_decay;
 | 
				
			||||||
 | 
					        double motion_pct = next_frame.pcnt_motion;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        i++;                                                    // Increment the loop counter
 | 
					        i++;                                                    // Increment the loop counter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1287,12 +1285,8 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
 | 
				
			|||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Accumulate motion stats.
 | 
					        // Accumulate motion stats.
 | 
				
			||||||
        motion_factor = next_frame.pcnt_motion;
 | 
					        mv_accumulator_rabs += fabs(next_frame.mvr_abs * motion_pct);
 | 
				
			||||||
        this_mv_rabs = fabs(next_frame.mvr_abs * motion_factor);
 | 
					        mv_accumulator_cabs += fabs(next_frame.mvc_abs * motion_pct);
 | 
				
			||||||
        this_mv_cabs = fabs(next_frame.mvc_abs * motion_factor);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        mv_accumulator_rabs += fabs(next_frame.mvr_abs * motion_factor);
 | 
					 | 
				
			||||||
        mv_accumulator_cabs += fabs(next_frame.mvc_abs * motion_factor);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Accumulate Motion In/Out of frame stats
 | 
					        //Accumulate Motion In/Out of frame stats
 | 
				
			||||||
        this_frame_mv_in_out = next_frame.mv_in_out_count * next_frame.pcnt_motion;
 | 
					        this_frame_mv_in_out = next_frame.mv_in_out_count * next_frame.pcnt_motion;
 | 
				
			||||||
@@ -1300,13 +1294,23 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
 | 
				
			|||||||
        abs_mv_in_out_accumulator += fabs(next_frame.mv_in_out_count * next_frame.pcnt_motion);
 | 
					        abs_mv_in_out_accumulator += fabs(next_frame.mv_in_out_count * next_frame.pcnt_motion);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // If there is a significant amount of motion
 | 
					        // If there is a significant amount of motion
 | 
				
			||||||
        if (motion_factor > 0.05)
 | 
					        if (motion_pct > 0.05)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            this_frame_mvr_ratio = fabs(next_frame.mvr_abs) / DOUBLE_DIVIDE_CHECK(fabs(next_frame.MVr));
 | 
					            this_frame_mvr_ratio = fabs(next_frame.mvr_abs) /
 | 
				
			||||||
            this_frame_mvc_ratio = fabs(next_frame.mvc_abs) / DOUBLE_DIVIDE_CHECK(fabs(next_frame.MVc));
 | 
					                                   DOUBLE_DIVIDE_CHECK(fabs(next_frame.MVr));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            mv_ratio_accumulator += (this_frame_mvr_ratio < next_frame.mvr_abs) ? (this_frame_mvr_ratio * motion_factor) : next_frame.mvr_abs * motion_factor;
 | 
					            this_frame_mvc_ratio = fabs(next_frame.mvc_abs) /
 | 
				
			||||||
            mv_ratio_accumulator += (this_frame_mvc_ratio < next_frame.mvc_abs) ? (this_frame_mvc_ratio * motion_factor) : next_frame.mvc_abs * motion_factor;
 | 
					                                   DOUBLE_DIVIDE_CHECK(fabs(next_frame.MVc));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            mv_ratio_accumulator +=
 | 
				
			||||||
 | 
					                (this_frame_mvr_ratio < next_frame.mvr_abs)
 | 
				
			||||||
 | 
					                    ? (this_frame_mvr_ratio * motion_pct)
 | 
				
			||||||
 | 
					                    : next_frame.mvr_abs * motion_pct;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            mv_ratio_accumulator +=
 | 
				
			||||||
 | 
					                (this_frame_mvc_ratio < next_frame.mvc_abs)
 | 
				
			||||||
 | 
					                    ? (this_frame_mvc_ratio * motion_pct)
 | 
				
			||||||
 | 
					                    : next_frame.mvc_abs * motion_pct;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -1334,14 +1338,26 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
 | 
				
			|||||||
        loop_decay_rate = next_frame.pcnt_inter;
 | 
					        loop_decay_rate = next_frame.pcnt_inter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // High % motion -> somewhat higher decay rate
 | 
					        // High % motion -> somewhat higher decay rate
 | 
				
			||||||
        if ((1.0 - (next_frame.pcnt_motion / 10.0)) < loop_decay_rate)
 | 
					        motion_decay = (1.0 - (motion_pct / 20.0));
 | 
				
			||||||
            loop_decay_rate = (1.0 - (next_frame.pcnt_motion / 10.0));
 | 
					        if (motion_decay < loop_decay_rate)
 | 
				
			||||||
 | 
					            loop_decay_rate = motion_decay;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        distance_factor = sqrt((this_mv_rabs * this_mv_rabs) + (this_mv_cabs * this_mv_cabs)) / 300.0;
 | 
					        // Adjustment to decay rate based on speed of motion
 | 
				
			||||||
        distance_factor = ((distance_factor > 1.0) ? 0.0 : (1.0 - distance_factor));
 | 
					        {
 | 
				
			||||||
 | 
					            double this_mv_rabs;
 | 
				
			||||||
 | 
					            double this_mv_cabs;
 | 
				
			||||||
 | 
					            double distance_factor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this_mv_rabs = fabs(next_frame.mvr_abs * motion_pct);
 | 
				
			||||||
 | 
					            this_mv_cabs = fabs(next_frame.mvc_abs * motion_pct);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            distance_factor = sqrt((this_mv_rabs * this_mv_rabs) +
 | 
				
			||||||
 | 
					                                   (this_mv_cabs * this_mv_cabs)) / 250.0;
 | 
				
			||||||
 | 
					            distance_factor = ((distance_factor > 1.0)
 | 
				
			||||||
 | 
					                                    ? 0.0 : (1.0 - distance_factor));
 | 
				
			||||||
            if (distance_factor < loop_decay_rate)
 | 
					            if (distance_factor < loop_decay_rate)
 | 
				
			||||||
                loop_decay_rate = distance_factor;
 | 
					                loop_decay_rate = distance_factor;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Cumulative effect of decay
 | 
					        // Cumulative effect of decay
 | 
				
			||||||
        decay_accumulator = decay_accumulator * loop_decay_rate;
 | 
					        decay_accumulator = decay_accumulator * loop_decay_rate;
 | 
				
			||||||
@@ -2281,6 +2297,8 @@ void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
 | 
				
			|||||||
    for (i = 0 ; i < cpi->frames_to_key ; i++)
 | 
					    for (i = 0 ; i < cpi->frames_to_key ; i++)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        double r;
 | 
					        double r;
 | 
				
			||||||
 | 
					        double motion_decay;
 | 
				
			||||||
 | 
					        double motion_pct = next_frame.pcnt_motion;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (EOF == vp8_input_stats(cpi, &next_frame))
 | 
					        if (EOF == vp8_input_stats(cpi, &next_frame))
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
@@ -2294,10 +2312,30 @@ void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
 | 
				
			|||||||
        //if ( next_frame.pcnt_inter < loop_decay_rate )
 | 
					        //if ( next_frame.pcnt_inter < loop_decay_rate )
 | 
				
			||||||
        loop_decay_rate = next_frame.pcnt_inter;
 | 
					        loop_decay_rate = next_frame.pcnt_inter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ((1.0 - (next_frame.pcnt_motion / 10.0)) < loop_decay_rate)
 | 
					        // High % motion -> somewhat higher decay rate
 | 
				
			||||||
            loop_decay_rate = (1.0 - (next_frame.pcnt_motion / 10.0));
 | 
					        motion_decay = (1.0 - (motion_pct / 20.0));
 | 
				
			||||||
 | 
					        if (motion_decay < loop_decay_rate)
 | 
				
			||||||
 | 
					            loop_decay_rate = motion_decay;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Adjustment to decay rate based on speed of motion
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            double this_mv_rabs;
 | 
				
			||||||
 | 
					            double this_mv_cabs;
 | 
				
			||||||
 | 
					            double distance_factor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this_mv_rabs = fabs(next_frame.mvr_abs * motion_pct);
 | 
				
			||||||
 | 
					            this_mv_cabs = fabs(next_frame.mvc_abs * motion_pct);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            distance_factor = sqrt((this_mv_rabs * this_mv_rabs) +
 | 
				
			||||||
 | 
					                                   (this_mv_cabs * this_mv_cabs)) / 250.0;
 | 
				
			||||||
 | 
					            distance_factor = ((distance_factor > 1.0)
 | 
				
			||||||
 | 
					                                    ? 0.0 : (1.0 - distance_factor));
 | 
				
			||||||
 | 
					            if (distance_factor < loop_decay_rate)
 | 
				
			||||||
 | 
					                loop_decay_rate = distance_factor;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        decay_accumulator = decay_accumulator * loop_decay_rate;
 | 
					        decay_accumulator = decay_accumulator * loop_decay_rate;
 | 
				
			||||||
 | 
					        decay_accumulator = decay_accumulator < 0.1 ? 0.1 : decay_accumulator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        boost_score += (decay_accumulator * r);
 | 
					        boost_score += (decay_accumulator * r);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4265,7 +4265,7 @@ static void encode_frame_to_data_rate
 | 
				
			|||||||
           // KEY FRAMES
 | 
					           // KEY FRAMES
 | 
				
			||||||
           else
 | 
					           else
 | 
				
			||||||
           {
 | 
					           {
 | 
				
			||||||
               if (cpi->gfu_boost > 1000)
 | 
					               if (cpi->gfu_boost > 600)
 | 
				
			||||||
                   cpi->active_best_quality = kf_low_motion_minq[Q];
 | 
					                   cpi->active_best_quality = kf_low_motion_minq[Q];
 | 
				
			||||||
               else
 | 
					               else
 | 
				
			||||||
                   cpi->active_best_quality = kf_high_motion_minq[Q];
 | 
					                   cpi->active_best_quality = kf_high_motion_minq[Q];
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user