Re-factor and simplify arnr filter.
Use a weaker filter for second level arf frames. Average gain across all sets and metrics ~0.3% Remove code for arnr_type which is no longer supported in VP9 which always uses a centered blur. Re-factor and some cleanup. Change-Id: Ieb4b8940e99e4e02b3fcc9fca6f2d4109e6ed639
This commit is contained in:
parent
c0061cc24f
commit
e3e6e06155
@ -2578,9 +2578,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
|
||||
|
||||
if (cpi->oxcf.arnr_max_frames > 0) {
|
||||
// Produce the filtered ARF frame.
|
||||
// TODO(agrange) merge these two functions.
|
||||
vp9_configure_arnr_filter(cpi, arf_src_index, rc->gfu_boost);
|
||||
vp9_temporal_filter_prepare(cpi, arf_src_index);
|
||||
vp9_temporal_filter(cpi, arf_src_index);
|
||||
vp9_extend_frame_borders(&cpi->alt_ref_buffer);
|
||||
force_src_buffer = &cpi->alt_ref_buffer;
|
||||
}
|
||||
|
@ -355,150 +355,32 @@ static void temporal_filter_iterate_c(VP9_COMP *cpi,
|
||||
mbd->plane[i].pre[0].buf = input_buffer[i];
|
||||
}
|
||||
|
||||
void vp9_temporal_filter_prepare(VP9_COMP *cpi, int distance) {
|
||||
VP9_COMMON *const cm = &cpi->common;
|
||||
int frame = 0;
|
||||
int frames_to_blur_backward = 0;
|
||||
int frames_to_blur_forward = 0;
|
||||
int frames_to_blur = 0;
|
||||
int start_frame = 0;
|
||||
int strength = cpi->active_arnr_strength;
|
||||
int blur_type = cpi->oxcf.arnr_type;
|
||||
int max_frames = cpi->active_arnr_frames;
|
||||
const int num_frames_backward = distance;
|
||||
const int num_frames_forward = vp9_lookahead_depth(cpi->lookahead)
|
||||
- (num_frames_backward + 1);
|
||||
struct scale_factors sf;
|
||||
|
||||
switch (blur_type) {
|
||||
case 1:
|
||||
// Backward Blur
|
||||
frames_to_blur_backward = num_frames_backward;
|
||||
|
||||
if (frames_to_blur_backward >= max_frames)
|
||||
frames_to_blur_backward = max_frames - 1;
|
||||
|
||||
frames_to_blur = frames_to_blur_backward + 1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// Forward Blur
|
||||
frames_to_blur_forward = num_frames_forward;
|
||||
|
||||
if (frames_to_blur_forward >= max_frames)
|
||||
frames_to_blur_forward = max_frames - 1;
|
||||
|
||||
frames_to_blur = frames_to_blur_forward + 1;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
default:
|
||||
// Center Blur
|
||||
frames_to_blur_forward = num_frames_forward;
|
||||
frames_to_blur_backward = num_frames_backward;
|
||||
|
||||
if (frames_to_blur_forward > frames_to_blur_backward)
|
||||
frames_to_blur_forward = frames_to_blur_backward;
|
||||
|
||||
if (frames_to_blur_backward > frames_to_blur_forward)
|
||||
frames_to_blur_backward = frames_to_blur_forward;
|
||||
|
||||
// When max_frames is even we have 1 more frame backward than forward
|
||||
if (frames_to_blur_forward > (max_frames - 1) / 2)
|
||||
frames_to_blur_forward = ((max_frames - 1) / 2);
|
||||
|
||||
if (frames_to_blur_backward > (max_frames / 2))
|
||||
frames_to_blur_backward = (max_frames / 2);
|
||||
|
||||
frames_to_blur = frames_to_blur_backward + frames_to_blur_forward + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
start_frame = distance + frames_to_blur_forward;
|
||||
|
||||
#ifdef DEBUGFWG
|
||||
// DEBUG FWG
|
||||
printf(
|
||||
"max:%d FBCK:%d FFWD:%d ftb:%d ftbbck:%d ftbfwd:%d sei:%d lasei:%d "
|
||||
"start:%d",
|
||||
max_frames, num_frames_backward, num_frames_forward, frames_to_blur,
|
||||
frames_to_blur_backward, frames_to_blur_forward, cpi->source_encode_index,
|
||||
cpi->last_alt_ref_sei, start_frame);
|
||||
#endif
|
||||
|
||||
// Setup scaling factors. Scaling on each of the arnr frames is not supported
|
||||
vp9_setup_scale_factors_for_frame(&sf,
|
||||
get_frame_new_buffer(cm)->y_crop_width,
|
||||
get_frame_new_buffer(cm)->y_crop_height,
|
||||
cm->width, cm->height);
|
||||
|
||||
// Setup frame pointers, NULL indicates frame not included in filter
|
||||
vp9_zero(cpi->frames);
|
||||
for (frame = 0; frame < frames_to_blur; frame++) {
|
||||
int which_buffer = start_frame - frame;
|
||||
struct lookahead_entry *buf = vp9_lookahead_peek(cpi->lookahead,
|
||||
which_buffer);
|
||||
cpi->frames[frames_to_blur - 1 - frame] = &buf->img;
|
||||
}
|
||||
|
||||
temporal_filter_iterate_c(cpi, frames_to_blur, frames_to_blur_backward,
|
||||
strength, &sf);
|
||||
}
|
||||
|
||||
void vp9_configure_arnr_filter(VP9_COMP *cpi,
|
||||
const unsigned int frames_to_arnr,
|
||||
const int group_boost) {
|
||||
int half_gf_int;
|
||||
int frames_after_arf;
|
||||
int frames_bwd = cpi->oxcf.arnr_max_frames - 1;
|
||||
int frames_fwd = cpi->oxcf.arnr_max_frames - 1;
|
||||
// Apply buffer limits and context specific adjustments to arnr filter.
|
||||
static void adjust_arnr_filter(VP9_COMP *cpi,
|
||||
int distance, int group_boost) {
|
||||
const int frames_after_arf =
|
||||
vp9_lookahead_depth(cpi->lookahead) - distance - 1;
|
||||
int frames_fwd = (cpi->oxcf.arnr_max_frames - 1) >> 1;
|
||||
int frames_bwd;
|
||||
int q;
|
||||
|
||||
// Define the arnr filter width for this group of frames. We only
|
||||
// filter frames that lie within a distance of half the GF interval
|
||||
// from the ARF frame. We also have to trap cases where the filter
|
||||
// extends beyond the end of the lookahead buffer.
|
||||
// Note: frames_to_arnr parameter is the offset of the arnr
|
||||
// frame from the current frame.
|
||||
half_gf_int = cpi->rc.baseline_gf_interval >> 1;
|
||||
frames_after_arf = vp9_lookahead_depth(cpi->lookahead)
|
||||
- frames_to_arnr - 1;
|
||||
// Define the forward and backwards filter limits for this arnr group.
|
||||
if (frames_fwd > frames_after_arf)
|
||||
frames_fwd = frames_after_arf;
|
||||
if (frames_fwd > distance)
|
||||
frames_fwd = distance;
|
||||
|
||||
switch (cpi->oxcf.arnr_type) {
|
||||
case 1: // Backward filter
|
||||
frames_fwd = 0;
|
||||
if (frames_bwd > half_gf_int)
|
||||
frames_bwd = half_gf_int;
|
||||
break;
|
||||
frames_bwd = frames_fwd;
|
||||
|
||||
case 2: // Forward filter
|
||||
if (frames_fwd > half_gf_int)
|
||||
frames_fwd = half_gf_int;
|
||||
if (frames_fwd > frames_after_arf)
|
||||
frames_fwd = frames_after_arf;
|
||||
frames_bwd = 0;
|
||||
break;
|
||||
|
||||
case 3: // Centered filter
|
||||
default:
|
||||
frames_fwd >>= 1;
|
||||
if (frames_fwd > frames_after_arf)
|
||||
frames_fwd = frames_after_arf;
|
||||
if (frames_fwd > half_gf_int)
|
||||
frames_fwd = half_gf_int;
|
||||
|
||||
frames_bwd = frames_fwd;
|
||||
|
||||
// For even length filter there is one more frame backward
|
||||
// than forward: e.g. len=6 ==> bbbAff, len=7 ==> bbbAfff.
|
||||
if (frames_bwd < half_gf_int)
|
||||
frames_bwd += (cpi->oxcf.arnr_max_frames + 1) & 0x1;
|
||||
break;
|
||||
}
|
||||
// For even length filter there is one more frame backward
|
||||
// than forward: e.g. len=6 ==> bbbAff, len=7 ==> bbbAfff.
|
||||
if (frames_bwd < distance)
|
||||
frames_bwd += (cpi->oxcf.arnr_max_frames + 1) & 0x1;
|
||||
|
||||
// Set the baseline active filter size.
|
||||
cpi->active_arnr_frames = frames_bwd + 1 + frames_fwd;
|
||||
|
||||
// Adjust the strength based on active max q
|
||||
// Adjust the strength based on active max q.
|
||||
if (cpi->common.current_video_frame > 1)
|
||||
q = ((int)vp9_convert_qindex_to_q(
|
||||
cpi->rc.avg_frame_qindex[INTER_FRAME]));
|
||||
@ -521,4 +403,50 @@ void vp9_configure_arnr_filter(VP9_COMP *cpi,
|
||||
if (cpi->active_arnr_strength > (group_boost / 300)) {
|
||||
cpi->active_arnr_strength = (group_boost / 300);
|
||||
}
|
||||
|
||||
// Adjustments for second level arf in multi arf case.
|
||||
if (cpi->pass == 2 && cpi->multi_arf_allowed) {
|
||||
const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
|
||||
if (gf_group->rf_level[gf_group->index] != GF_ARF_STD) {
|
||||
cpi->active_arnr_strength >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vp9_temporal_filter(VP9_COMP *cpi, int distance) {
|
||||
VP9_COMMON *const cm = &cpi->common;
|
||||
RATE_CONTROL *const rc = &cpi->rc;
|
||||
int frame;
|
||||
int frames_to_blur;
|
||||
int start_frame;
|
||||
int strength;
|
||||
int frames_to_blur_backward;
|
||||
int frames_to_blur_forward;
|
||||
struct scale_factors sf;
|
||||
|
||||
// Apply context specific adjustments to the arnr filter parameters.
|
||||
adjust_arnr_filter(cpi, distance, rc->gfu_boost);
|
||||
strength = cpi->active_arnr_strength;
|
||||
frames_to_blur = cpi->active_arnr_frames;
|
||||
frames_to_blur_backward = (frames_to_blur / 2);
|
||||
frames_to_blur_forward = ((frames_to_blur - 1) / 2);
|
||||
start_frame = distance + frames_to_blur_forward;
|
||||
|
||||
// Setup scaling factors. Scaling on each of the arnr frames not supported.
|
||||
vp9_setup_scale_factors_for_frame(&sf,
|
||||
get_frame_new_buffer(cm)->y_crop_width,
|
||||
get_frame_new_buffer(cm)->y_crop_height,
|
||||
cm->width, cm->height);
|
||||
|
||||
// Setup frame pointers, NULL indicates frame not included in filter.
|
||||
vp9_zero(cpi->frames);
|
||||
for (frame = 0; frame < frames_to_blur; ++frame) {
|
||||
const int which_buffer = start_frame - frame;
|
||||
struct lookahead_entry *buf = vp9_lookahead_peek(cpi->lookahead,
|
||||
which_buffer);
|
||||
cpi->frames[frames_to_blur - 1 - frame] = &buf->img;
|
||||
}
|
||||
|
||||
temporal_filter_iterate_c(cpi, frames_to_blur, frames_to_blur_backward,
|
||||
strength, &sf);
|
||||
}
|
||||
|
@ -16,10 +16,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
void vp9_temporal_filter_init();
|
||||
void vp9_temporal_filter_prepare(VP9_COMP *cpi, int distance);
|
||||
void vp9_configure_arnr_filter(VP9_COMP *cpi,
|
||||
const unsigned int frames_to_arnr,
|
||||
const int group_boost);
|
||||
void vp9_temporal_filter(VP9_COMP *cpi, int distance);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
Loading…
x
Reference in New Issue
Block a user