Merge remote branch 'origin/master' into experimental

Change-Id: I215466afda88def40f4a5d81f5b58ec383471346
This commit is contained in:
John Koleszar 2011-08-16 00:05:10 -04:00
commit 79d8ffd213
8 changed files with 84 additions and 217 deletions

View File

@ -1,3 +1,33 @@
2011-08-15 v0.9.7-p1 "Cayuga" patch 1
This is an incremental bugfix release against Cayuga. All users of that
release are strongly encouraged to upgrade.
- Fix potential OOB reads (cdae03a)
An unbounded out of bounds read was discovered when the
decoder was requested to perform error concealment (new in
Cayuga) given a frame with corrupt partition sizes.
A bounded out of bounds read was discovered affecting all
versions of libvpx. Given an multipartition input frame that
is truncated between the mode/mv partition and the first
residiual paritition (in the block of partition offsets), up
to 3 extra bytes could have been read from the source buffer.
The code will not take any action regardless of the contents
of these undefined bytes, as the truncated buffer is detected
immediately following the read based on the calculated
starting position of the coefficient partition.
- Fix potential error concealment crash when the very first frame
is missing or corrupt (a609be5)
- Fix significant artifacts in error concealment (a4c2211, 99d870a)
- Revert 1-pass CBR rate control changes (e961317)
Further testing showed this change produced undesirable visual
artifacts, rolling back for now.
2011-08-02 v0.9.7 "Cayuga"
Our third named release, focused on a faster, higher quality, encoder.

View File

@ -132,6 +132,14 @@ CODEC_SRCS=$(call enabled,CODEC_SRCS)
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(CODEC_SRCS)
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(call enabled,CODEC_EXPORTS)
# Generate a list of all enabled sources, in particular for exporting to gyp
# based build systems.
libvpx_srcs.txt:
@echo " [CREATE] $@"
@echo $(CODEC_SRCS) | xargs -n1 echo | sort -u > $@
ifeq ($(CONFIG_EXTERNAL_BUILD),yes)
ifeq ($(CONFIG_MSVS),yes)

View File

@ -18,7 +18,6 @@
extern "C"
{
#endif
#include "vpx/vpx_codec.h"
#include "type_aliases.h"
#include "vpx_scale/yv12config.h"
#include "ppflags.h"

View File

@ -567,7 +567,6 @@ static void interpolate_mvs(MACROBLOCKD *mb,
else
{
mv->as_int = 0;
mi->bmi[row*4 + col].as_mode = NEW4X4;
mi->mbmi.need_to_clamp_mvs = 0;
}
}

View File

@ -357,11 +357,25 @@ static int frame_max_bits(VP8_COMP *cpi)
int max_bits;
// For CBR we need to also consider buffer fullness.
// If we are running below the optimal level then we need to gradually tighten up on max_bits.
if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
{
max_bits = 2 * cpi->av_per_frame_bandwidth;
max_bits -= cpi->buffered_av_per_frame_bandwidth;
max_bits *= ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0);
double buffer_fullness_ratio = (double)cpi->buffer_level / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.optimal_buffer_level);
// For CBR base this on the target average bits per frame plus the maximum sedction rate passed in by the user
max_bits = (int)(cpi->av_per_frame_bandwidth * ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0));
// If our buffer is below the optimum level
if (buffer_fullness_ratio < 1.0)
{
// The lower of max_bits / 4 or cpi->av_per_frame_bandwidth / 4.
int min_max_bits = ((cpi->av_per_frame_bandwidth >> 2) < (max_bits >> 2)) ? cpi->av_per_frame_bandwidth >> 2 : max_bits >> 2;
max_bits = (int)(max_bits * buffer_fullness_ratio);
if (max_bits < min_max_bits)
max_bits = min_max_bits; // Lowest value we will set ... which should allow the buffer to refil.
}
}
// VBR
else
@ -377,45 +391,6 @@ static int frame_max_bits(VP8_COMP *cpi)
return max_bits;
}
static int gf_group_max_bits(VP8_COMP *cpi)
{
// Max allocation for a golden frame group
int max_bits;
// For CBR we need to also consider buffer fullness.
if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
{
max_bits = cpi->av_per_frame_bandwidth * cpi->baseline_gf_interval;
if (max_bits > cpi->oxcf.optimal_buffer_level)
{
max_bits -= cpi->oxcf.optimal_buffer_level;
max_bits += cpi->buffer_level;
}
else
{
max_bits -= (cpi->buffered_av_per_frame_bandwidth
- cpi->av_per_frame_bandwidth)
* cpi->baseline_gf_interval;
}
max_bits *= ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0);
}
else
{
// For VBR base this on the bits and frames left plus the two_pass_vbrmax_section rate passed in by the user
max_bits = (int)(((double)cpi->twopass.bits_left / (cpi->twopass.total_stats->count - (double)cpi->common.current_video_frame)) * ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0));
max_bits *= cpi->baseline_gf_interval;
}
// Trap case where we are out of bits
if (max_bits < 0)
max_bits = 0;
return max_bits;
}
void vp8_init_first_pass(VP8_COMP *cpi)
{
zero_stats(cpi->twopass.total_stats);
@ -1626,7 +1601,7 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
double abs_mv_in_out_accumulator = 0.0;
double mod_err_per_mb_accumulator = 0.0;
int max_group_bits;
int max_bits = frame_max_bits(cpi); // Max for a single frame
unsigned int allow_alt_ref =
cpi->oxcf.play_alternate && cpi->oxcf.lag_in_frames;
@ -1988,9 +1963,8 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
// Clip cpi->twopass.gf_group_bits based on user supplied data rate
// variability limit (cpi->oxcf.two_pass_vbrmax_section)
max_group_bits = gf_group_max_bits(cpi);
if (cpi->twopass.gf_group_bits > max_group_bits)
cpi->twopass.gf_group_bits = max_group_bits;
if (cpi->twopass.gf_group_bits > max_bits * cpi->baseline_gf_interval)
cpi->twopass.gf_group_bits = max_bits * cpi->baseline_gf_interval;
// Reset the file position
reset_fpf_position(cpi, start_pos);
@ -2090,6 +2064,13 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
}
}
// Apply an additional limit for CBR
if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
{
if (cpi->twopass.gf_bits > (cpi->buffer_level >> 1))
cpi->twopass.gf_bits = cpi->buffer_level >> 1;
}
// Dont allow a negative value for gf_bits
if (gf_bits < 0)
gf_bits = 0;

View File

@ -1529,7 +1529,6 @@ static void init_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
cpi->rolling_actual_bits = cpi->av_per_frame_bandwidth;
cpi->long_rolling_target_bits = cpi->av_per_frame_bandwidth;
cpi->long_rolling_actual_bits = cpi->av_per_frame_bandwidth;
cpi->buffered_av_per_frame_bandwidth = cpi->av_per_frame_bandwidth;
cpi->total_actual_bits = 0;
cpi->total_target_vs_actual = 0;
@ -1625,7 +1624,7 @@ void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
break;
}
if (cpi->pass == 0 && cpi->oxcf.end_usage != USAGE_STREAM_FROM_SERVER)
if (cpi->pass == 0)
cpi->auto_worst_q = 1;
cpi->oxcf.worst_allowed_q = q_trans[oxcf->worst_allowed_q];
@ -3273,116 +3272,6 @@ void loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm)
}
static void update_buffer_level(VP8_COMP *cpi)
{
int64_t tmp;
/* Update the buffered average bitrate.
*
* The buffered average bitrate tracks the bitrate over the buffer
* window. Here we simulate taking a frame of average size out
* of the buffer, and putting in the new frame just encoded.
* It is calculated accordingly:
*
* A = Average Bits Per Frame In The Buffer
* P = New Frame Size
* N = Number of bits in the buffer
*
* We recalculate the average as so:
* (N-A)*A + A*P A * (N - A + P)
* A' = ------------- = ---------------
* N N
*
* This is modeled after a the standard algorithm for a moving
* average with fixed weighting (eg A' = ((N-1)*A + 1*P) / N). This makes
* the step response nonlinear but consistent with expected behavior --
* when A is large, the model adapts more quickly, since there are
* fewer frames in the buffer and conversely when A is small there
* will be more frames in the buffer so the average will adapt
* slowly.
*
* TODO(jkoleszar): This may give poor step response in some situations,
* for example motion following a long static section. It might be
* worth experimenting more with weighting by av_per_frame_bandwidth
* rather than buffered_av_per_frame_bandwidth or using a more accurate
* algorithm to get faster response. Current testing showed worse results
* with that setting though.
*
*/
/* Guard against buffered_av_per_frame_bandwidth falling to 0. Should
* never happen, but without this check, it would be irrecoverable.
*/
if(cpi->buffered_av_per_frame_bandwidth == 0)
cpi->buffered_av_per_frame_bandwidth = 1;
tmp = cpi->oxcf.maximum_buffer_size
- cpi->buffered_av_per_frame_bandwidth
+ cpi->projected_frame_size;
tmp *= cpi->buffered_av_per_frame_bandwidth;
cpi->buffered_av_per_frame_bandwidth = tmp
/ cpi->oxcf.maximum_buffer_size;
if(cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
{
/* In CBR mode, buffer level is synthesized from the buffered
* average per-frame bandwidth to get the response characteristics
* of that model, rather than using the unbounded (wrt buffer size)
* bits_off_target. ie, the long term average bitrate doesn't
* matter in CBR mode. If the clip is consistently undershooting
* because it is very static, for example, you don't want to blow
* your short term bitrate budget trying to the the long term spend
* up to the target when you hit a motion section.
*
* Instead, the ratio of buffered_av_per_frame_bandwidth to the
* target av_per_frame_bandwidth is taken, scaled by
* maximum_buffer_size and centered around optimal_buffer_level,
* which presents the expected behavior of buffer_level for the other
* parts of the rate control code which handle the targeting.
*
* Note that this only happens after the starting_buffer_level
* has passed, to give the model a chance to stabilize.
*/
if(cpi->total_actual_bits > cpi->oxcf.starting_buffer_level)
{
tmp = (int64_t)cpi->buffered_av_per_frame_bandwidth
* cpi->oxcf.maximum_buffer_size
/ cpi->av_per_frame_bandwidth;
cpi->buffer_level = cpi->oxcf.maximum_buffer_size
- tmp
+ cpi->oxcf.optimal_buffer_level;
}
else
cpi->buffer_level = cpi->oxcf.optimal_buffer_level;
/* Accumulate recent overshoot error.
*
* If this frame is larger than the target, then accumulate
* that error to apply as a damping factor later. Only care about
* recent overshoot, so this value decays by (N-P)/N
*/
if(cpi->total_actual_bits > cpi->oxcf.starting_buffer_level)
{
int64_t decayed_overshoot;
decayed_overshoot = cpi->accumulated_overshoot;
decayed_overshoot *= (cpi->oxcf.maximum_buffer_size
- cpi->projected_frame_size);
decayed_overshoot /= cpi->oxcf.maximum_buffer_size;
cpi->accumulated_overshoot = decayed_overshoot;
cpi->accumulated_overshoot +=
(cpi->projected_frame_size > cpi->av_per_frame_bandwidth)
? cpi->projected_frame_size - cpi->av_per_frame_bandwidth
: 0;
}
}
else
cpi->buffer_level = cpi->bits_off_target;
}
static void encode_frame_to_data_rate
(
VP8_COMP *cpi,
@ -3628,8 +3517,7 @@ static void encode_frame_to_data_rate
// For CBR if the buffer reaches its maximum level then we can no longer
// save up bits for later frames so we might as well use them up
// on the current frame.
if (cpi->pass == 2
&& (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) &&
if ((cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) &&
(cpi->buffer_level >= cpi->oxcf.optimal_buffer_level) && cpi->buffered_mode)
{
int Adjustment = cpi->active_worst_quality / 4; // Max adjustment is 1/4
@ -3720,10 +3608,6 @@ static void encode_frame_to_data_rate
}
else
{
if(cpi->pass != 2)
Q = cpi->auto_worst_q?
cpi->active_worst_quality:cpi->avg_frame_qindex;
cpi->active_best_quality = inter_minq[Q];
// For the constant/constrained quality mode we dont want
@ -4036,17 +3920,15 @@ static void encode_frame_to_data_rate
(cpi->active_worst_quality < cpi->worst_quality) &&
(cpi->projected_frame_size > frame_over_shoot_limit))
{
/* step down active_worst_quality such that the corresponding
* active_best_quality will be equal to the current
* active_worst_quality + 1. Once the limit on active_best_quality
* is reached, active_worst_quality will equal worst_quality.
*/
int i;
int over_size_percent = ((cpi->projected_frame_size - frame_over_shoot_limit) * 100) / frame_over_shoot_limit;
for(i=cpi->active_worst_quality; i<cpi->worst_quality; i++)
if(inter_minq[i] >= cpi->active_worst_quality + 1)
break;
cpi->active_worst_quality = i;
// If so is there any scope for relaxing it
while ((cpi->active_worst_quality < cpi->worst_quality) && (over_size_percent > 0))
{
cpi->active_worst_quality++;
top_index = cpi->active_worst_quality;
over_size_percent = (int)(over_size_percent * 0.96); // Assume 1 qstep = about 4% on frame size.
}
// If we have updated the active max Q do not call vp8_update_rate_correction_factors() this loop.
active_worst_qchanged = TRUE;
@ -4434,9 +4316,10 @@ static void encode_frame_to_data_rate
// Update the buffer level variable.
// Non-viewable frames are a special case and are treated as pure overhead.
if ( cm->show_frame )
cpi->bits_off_target += cpi->av_per_frame_bandwidth;
cpi->bits_off_target -= cpi->projected_frame_size;
if ( !cm->show_frame )
cpi->bits_off_target -= cpi->projected_frame_size;
else
cpi->bits_off_target += cpi->av_per_frame_bandwidth - cpi->projected_frame_size;
// Rolling monitors of whether we are over or underspending used to help regulate min and Max Q in two pass.
cpi->rolling_target_bits = ((cpi->rolling_target_bits * 3) + cpi->this_frame_target + 2) / 4;
@ -4450,7 +4333,7 @@ static void encode_frame_to_data_rate
// Debug stats
cpi->total_target_vs_actual += (cpi->this_frame_target - cpi->projected_frame_size);
update_buffer_level(cpi);
cpi->buffer_level = cpi->bits_off_target;
// Update bits left to the kf and gf groups to account for overshoot or undershoot on these frames
if (cm->frame_type == KEY_FRAME)

View File

@ -348,10 +348,6 @@ typedef struct VP8_COMP
int per_frame_bandwidth; // Current section per frame bandwidth target
int av_per_frame_bandwidth; // Average frame size target for clip
int min_frame_bandwidth; // Minimum allocation that should be used for any frame
int buffered_av_per_frame_bandwidth; // Average bitrate over the last buffer
int buffered_av_per_frame_bandwidth_rem; // Average bitrate remainder
int accumulated_overshoot; // Accumulated # of bits spent > target
int inter_frame_target;
double output_frame_rate;
int64_t last_time_stamp_seen;

View File

@ -653,7 +653,7 @@ static void calc_pframe_target_size(VP8_COMP *cpi)
int min_frame_target;
int Adjustment;
min_frame_target = 1;
min_frame_target = 0;
if (cpi->pass == 2)
{
@ -662,11 +662,9 @@ static void calc_pframe_target_size(VP8_COMP *cpi)
if (min_frame_target < (cpi->av_per_frame_bandwidth >> 5))
min_frame_target = cpi->av_per_frame_bandwidth >> 5;
}
else
{
if (min_frame_target < cpi->per_frame_bandwidth / 4)
min_frame_target = cpi->per_frame_bandwidth / 4;
}
else if (min_frame_target < cpi->per_frame_bandwidth / 4)
min_frame_target = cpi->per_frame_bandwidth / 4;
// Special alt reference frame case
if (cpi->common.refresh_alt_ref_frame)
@ -1159,33 +1157,6 @@ static void calc_pframe_target_size(VP8_COMP *cpi)
}
}
if (cpi->pass==0
&& cpi->common.refresh_golden_frame
&& cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) {
int64_t adjust;
/*
frames_in_buffer = cpi->oxcf.maximum_buffer_size
/ cpi->av_per_frame_bandwidth;
gf_in_buffer = frames_in_buffer /
cpi->frames_till_gf_update_due;
overshoot_per_gf = cpi->accumulated_overshoot / gf_in_buffer;
*/
adjust = cpi->accumulated_overshoot;
adjust *= cpi->frames_till_gf_update_due + 1;
adjust *= cpi->av_per_frame_bandwidth;
adjust /= cpi->oxcf.maximum_buffer_size;
if (adjust > (cpi->this_frame_target - min_frame_target))
adjust = (cpi->this_frame_target - min_frame_target);
else if (adjust < 0)
adjust = 0;
cpi->this_frame_target -= adjust;
}
}