summaryrefslogtreecommitdiff
path: root/vp8
diff options
context:
space:
mode:
authorPaul Wilkins <paulwilkins@google.com>2010-09-01 02:45:12 -0700
committerCode Review <code-review@webmproject.org>2010-09-01 02:45:12 -0700
commit18c902f8a416ae97de8143840234a416700a1e64 (patch)
treeca1dd881a1abc998bdb9b66fca1da03cebf49de9 /vp8
parent0e78efad0be73d293880d1b71053c0d70a50a080 (diff)
parentc239a1b67c9c5ff25a04ba89eca45245b1e615a2 (diff)
downloadlibvpx-18c902f8a416ae97de8143840234a416700a1e64.tar
libvpx-18c902f8a416ae97de8143840234a416700a1e64.tar.gz
libvpx-18c902f8a416ae97de8143840234a416700a1e64.tar.bz2
libvpx-18c902f8a416ae97de8143840234a416700a1e64.zip
Merge "Improved Force Key Frame Behaviour"
Diffstat (limited to 'vp8')
-rw-r--r--vp8/encoder/firstpass.c54
-rw-r--r--vp8/encoder/onyx_if.c22
-rw-r--r--vp8/encoder/ratectrl.c7
3 files changed, 46 insertions, 37 deletions
diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c
index 5cbd2a43e..a58b9b75d 100644
--- a/vp8/encoder/firstpass.c
+++ b/vp8/encoder/firstpass.c
@@ -2095,33 +2095,34 @@ void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
kf_group_intra_err += this_frame->intra_error;
kf_group_coded_err += this_frame->coded_error;
+ // load a the next frame's stats
vpx_memcpy(&last_frame, this_frame, sizeof(*this_frame));
+ vp8_input_stats(cpi, this_frame);
// Provided that we are not at the end of the file...
- if (EOF != vp8_input_stats(cpi, this_frame))
+ if (cpi->oxcf.auto_key
+ && lookup_next_frame_stats(cpi, &next_frame) != EOF)
{
- if (lookup_next_frame_stats(cpi, &next_frame) != EOF)
- {
- if (test_candidate_kf(cpi, &last_frame, this_frame, &next_frame))
- break;
- }
- }
-
- // Step on to the next frame
- cpi->frames_to_key ++;
+ if (test_candidate_kf(cpi, &last_frame, this_frame, &next_frame))
+ break;
- // If we don't have a real key frame within the next two
- // forcekeyframeevery intervals then break out of the loop.
- if (cpi->frames_to_key >= 2 *(int)cpi->key_frame_frequency)
- break;
+ // Step on to the next frame
+ cpi->frames_to_key ++;
+ // If we don't have a real key frame within the next two
+ // forcekeyframeevery intervals then break out of the loop.
+ if (cpi->frames_to_key >= 2 *(int)cpi->key_frame_frequency)
+ break;
+ } else
+ cpi->frames_to_key ++;
}
// If there is a max kf interval set by the user we must obey it.
// We already breakout of the loop above at 2x max.
// This code centers the extra kf if the actual natural
// interval is between 1x and 2x
- if ( cpi->frames_to_key > (int)cpi->key_frame_frequency )
+ if (cpi->oxcf.auto_key
+ && cpi->frames_to_key > (int)cpi->key_frame_frequency )
{
cpi->frames_to_key /= 2;
@@ -2388,23 +2389,34 @@ void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
cpi->kf_bits = (3 * cpi->buffer_level) >> 2;
}
- // If the key frame is actually easier than the average for the kf group (which does sometimes happen... eg a blank intro frame)
- // Then use an alternate calculation based on the kf error score which should give a smaller key frame.
+ // If the key frame is actually easier than the average for the
+ // kf group (which does sometimes happen... eg a blank intro frame)
+ // Then use an alternate calculation based on the kf error score
+ // which should give a smaller key frame.
if (kf_mod_err < kf_group_err / cpi->frames_to_key)
{
- double alt_kf_grp_bits = ((double)cpi->bits_left * (kf_mod_err * (double)cpi->frames_to_key) / cpi->modified_total_error_left) ;
+ double alt_kf_grp_bits =
+ ((double)cpi->bits_left *
+ (kf_mod_err * (double)cpi->frames_to_key) /
+ DOUBLE_DIVIDE_CHECK(cpi->modified_total_error_left));
- alt_kf_bits = (int)((double)kf_boost * (alt_kf_grp_bits / (double)allocation_chunks));
+ alt_kf_bits = (int)((double)kf_boost *
+ (alt_kf_grp_bits / (double)allocation_chunks));
if (cpi->kf_bits > alt_kf_bits)
{
cpi->kf_bits = alt_kf_bits;
}
}
- // Else if it is much harder than other frames in the group make sure it at least receives an allocation in keeping with its relative error score
+ // Else if it is much harder than other frames in the group make sure
+ // it at least receives an allocation in keeping with its relative
+ // error score
else
{
- alt_kf_bits = (int)((double)cpi->bits_left * (kf_mod_err / cpi->modified_total_error_left));
+ alt_kf_bits =
+ (int)((double)cpi->bits_left *
+ (kf_mod_err /
+ DOUBLE_DIVIDE_CHECK(cpi->modified_total_error_left)));
if (alt_kf_bits > cpi->kf_bits)
{
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 99c434f52..fe83ae976 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -2818,23 +2818,17 @@ static int pick_frame_size(VP8_COMP *cpi)
cm->frame_type = KEY_FRAME;
}
- // Auto key frames (Only two pass will enter here)
- else if (cm->frame_type == KEY_FRAME)
- {
- vp8_calc_auto_iframe_target_size(cpi);
- }
- // Forced key frames (by interval or an external signal)
- else if ((cm->frame_flags & FRAMEFLAGS_KEY) ||
- (cpi->oxcf.auto_key && (cpi->frames_since_key % cpi->key_frame_frequency == 0)))
+ // Special case for forced key frames
+ // The frame sizing here is still far from ideal for 2 pass.
+ else if (cm->frame_flags & FRAMEFLAGS_KEY)
{
- // Key frame from VFW/auto-keyframe/first frame
cm->frame_type = KEY_FRAME;
-
resize_key_frame(cpi);
-
- // Compute target frame size
- if (cpi->pass != 2)
- vp8_calc_iframe_target_size(cpi);
+ vp8_calc_iframe_target_size(cpi);
+ }
+ else if (cm->frame_type == KEY_FRAME)
+ {
+ vp8_calc_auto_iframe_target_size(cpi);
}
else
{
diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c
index d32808165..371272268 100644
--- a/vp8/encoder/ratectrl.c
+++ b/vp8/encoder/ratectrl.c
@@ -1444,6 +1444,9 @@ void vp8_adjust_key_frame_context(VP8_COMP *cpi)
}
else
{
+ int last_kf_interval =
+ (cpi->frames_since_key > 0) ? cpi->frames_since_key : 1;
+
// reset keyframe context and calculate weighted average of last KEY_FRAME_CONTEXT keyframes
for (i = 0; i < KEY_FRAME_CONTEXT; i++)
{
@@ -1454,8 +1457,8 @@ void vp8_adjust_key_frame_context(VP8_COMP *cpi)
}
else
{
- cpi->prior_key_frame_size[KEY_FRAME_CONTEXT - 1] = cpi->projected_frame_size;
- cpi->prior_key_frame_distance[KEY_FRAME_CONTEXT - 1] = cpi->frames_since_key;
+ cpi->prior_key_frame_size[i] = cpi->projected_frame_size;
+ cpi->prior_key_frame_distance[i] = last_kf_interval;
}
av_key_frame_bits += prior_key_frame_weight[i] * cpi->prior_key_frame_size[i];