summaryrefslogtreecommitdiff
path: root/vp8
diff options
context:
space:
mode:
authorPaul Wilkins <paulwilkins@google.com>2010-10-02 17:31:46 +0100
committerPaul Wilkins <paulwilkins@google.com>2010-10-02 17:31:46 +0100
commit788c0eb54ef741153557953c22fe3f14bceb13d3 (patch)
tree05176cab025db0fe5e41e1c1ef53e2eccfa21a87 /vp8
parentf143a8119129411522a3c153b0bff6514c3a165d (diff)
downloadlibvpx-788c0eb54ef741153557953c22fe3f14bceb13d3.tar
libvpx-788c0eb54ef741153557953c22fe3f14bceb13d3.tar.gz
libvpx-788c0eb54ef741153557953c22fe3f14bceb13d3.tar.bz2
libvpx-788c0eb54ef741153557953c22fe3f14bceb13d3.zip
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
Diffstat (limited to 'vp8')
-rw-r--r--vp8/encoder/firstpass.c86
-rw-r--r--vp8/encoder/onyx_if.c4
2 files changed, 64 insertions, 26 deletions
diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c
index 0a6e8c50e..13633e9a4 100644
--- a/vp8/encoder/firstpass.c
+++ b/vp8/encoder/firstpass.c
@@ -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_cabs = 0.0;
- double this_mv_rabs;
- double this_mv_cabs;
double mv_ratio_accumulator = 0.0;
- double distance_factor = 0.0;
double decay_accumulator = 1.0;
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))
{
double r;
- double motion_factor;
double this_frame_mvr_ratio;
double this_frame_mvc_ratio;
+ double motion_decay;
+ double motion_pct = next_frame.pcnt_motion;
i++; // Increment the loop counter
@@ -1287,12 +1285,8 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
break;
// Accumulate motion stats.
- motion_factor = next_frame.pcnt_motion;
- this_mv_rabs = fabs(next_frame.mvr_abs * motion_factor);
- 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);
+ mv_accumulator_rabs += fabs(next_frame.mvr_abs * motion_pct);
+ mv_accumulator_cabs += fabs(next_frame.mvc_abs * motion_pct);
//Accumulate Motion In/Out of frame stats
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);
// 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_mvc_ratio = fabs(next_frame.mvc_abs) / DOUBLE_DIVIDE_CHECK(fabs(next_frame.MVc));
+ this_frame_mvr_ratio = fabs(next_frame.mvr_abs) /
+ DOUBLE_DIVIDE_CHECK(fabs(next_frame.MVr));
+
+ this_frame_mvc_ratio = fabs(next_frame.mvc_abs) /
+ 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_mvr_ratio < next_frame.mvr_abs) ? (this_frame_mvr_ratio * motion_factor) : next_frame.mvr_abs * motion_factor;
- mv_ratio_accumulator += (this_frame_mvc_ratio < next_frame.mvc_abs) ? (this_frame_mvc_ratio * motion_factor) : next_frame.mvc_abs * motion_factor;
+ mv_ratio_accumulator +=
+ (this_frame_mvc_ratio < next_frame.mvc_abs)
+ ? (this_frame_mvc_ratio * motion_pct)
+ : next_frame.mvc_abs * motion_pct;
}
else
{
@@ -1334,14 +1338,26 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
loop_decay_rate = next_frame.pcnt_inter;
// High % motion -> somewhat higher decay rate
- if ((1.0 - (next_frame.pcnt_motion / 10.0)) < loop_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;
- distance_factor = sqrt((this_mv_rabs * this_mv_rabs) + (this_mv_cabs * this_mv_cabs)) / 300.0;
- distance_factor = ((distance_factor > 1.0) ? 0.0 : (1.0 - distance_factor));
-
- if (distance_factor < loop_decay_rate)
- loop_decay_rate = distance_factor;
+ // 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;
+ }
// Cumulative effect of decay
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++)
{
double r;
+ double motion_decay;
+ double motion_pct = next_frame.pcnt_motion;
if (EOF == vp8_input_stats(cpi, &next_frame))
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 )
loop_decay_rate = next_frame.pcnt_inter;
- if ((1.0 - (next_frame.pcnt_motion / 10.0)) < loop_decay_rate)
- loop_decay_rate = (1.0 - (next_frame.pcnt_motion / 10.0));
+ // High % motion -> somewhat higher decay rate
+ 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 < 0.1 ? 0.1 : decay_accumulator;
boost_score += (decay_accumulator * r);
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 46c283d68..6b7333f1d 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -4247,7 +4247,7 @@ static void encode_frame_to_data_rate
if (cpi->avg_frame_qindex < cpi->active_worst_quality)
Q = cpi->avg_frame_qindex;
- if ( cpi->gfu_boost > 1000 )
+ 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];
@@ -4265,7 +4265,7 @@ static void encode_frame_to_data_rate
// KEY FRAMES
else
{
- if (cpi->gfu_boost > 1000)
+ if (cpi->gfu_boost > 600)
cpi->active_best_quality = kf_low_motion_minq[Q];
else
cpi->active_best_quality = kf_high_motion_minq[Q];