Improved Force Key Frame Behaviour
These changes improve the behaviour of the code with forced key frames sent in by a calling application. The sizing of the frames is still suboptimal for two pass in particular but the behaviour is much better than it was. Change-Id: I35fae610c67688ccc69d11f385e87dfc884e65a1
This commit is contained in:
Родитель
0b94f5d6e8
Коммит
c239a1b67c
|
@ -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;
|
||||
}
|
||||
}
|
||||
if (test_candidate_kf(cpi, &last_frame, this_frame, &next_frame))
|
||||
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;
|
||||
// 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)
|
||||
{
|
||||
|
|
|
@ -2818,24 +2818,18 @@ static int pick_frame_size(VP8_COMP *cpi)
|
|||
cm->frame_type = KEY_FRAME;
|
||||
|
||||
}
|
||||
// Auto key frames (Only two pass will enter here)
|
||||
// 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)
|
||||
{
|
||||
cm->frame_type = KEY_FRAME;
|
||||
resize_key_frame(cpi);
|
||||
vp8_calc_iframe_target_size(cpi);
|
||||
}
|
||||
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)))
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
// INTER frame: compute target frame size
|
||||
|
|
|
@ -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];
|
||||
|
|
Загрузка…
Ссылка в новой задаче