diff --git a/test/borders_test.cc b/test/borders_test.cc index a2f5a1bdd..b30be4580 100644 --- a/test/borders_test.cc +++ b/test/borders_test.cc @@ -35,6 +35,7 @@ class BordersTest : public ::libvpx_test::EncoderTest, encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1); encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7); encoder->Control(VP8E_SET_ARNR_STRENGTH, 5); + encoder->Control(VP8E_SET_ARNR_TYPE, 3); } } diff --git a/test/cpu_speed_test.cc b/test/cpu_speed_test.cc index ca201bbc7..be651b4fe 100644 --- a/test/cpu_speed_test.cc +++ b/test/cpu_speed_test.cc @@ -37,6 +37,7 @@ class CpuSpeedTest : public ::libvpx_test::EncoderTest, encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1); encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7); encoder->Control(VP8E_SET_ARNR_STRENGTH, 5); + encoder->Control(VP8E_SET_ARNR_TYPE, 3); } } diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h index 8f3249407..7483f7fd1 100644 --- a/vp9/encoder/vp9_encoder.h +++ b/vp9/encoder/vp9_encoder.h @@ -276,6 +276,7 @@ typedef struct VP9EncoderConfig { int arnr_max_frames; int arnr_strength; + int arnr_type; int tile_columns; int tile_rows; diff --git a/vp9/encoder/vp9_temporal_filter.c b/vp9/encoder/vp9_temporal_filter.c index ca9339155..498810f6e 100644 --- a/vp9/encoder/vp9_temporal_filter.c +++ b/vp9/encoder/vp9_temporal_filter.c @@ -345,33 +345,74 @@ static void temporal_filter_iterate_c(VP9_COMP *cpi, 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; - int frames_to_blur_backward = distance; - int frames_to_blur_forward = vp9_lookahead_depth(cpi->lookahead) - - (distance + 1); + const int num_frames_backward = distance; + const int num_frames_forward = vp9_lookahead_depth(cpi->lookahead) + - (num_frames_backward + 1); struct scale_factors sf; - // Determine which input frames to filter. - if (frames_to_blur_forward > frames_to_blur_backward) - frames_to_blur_forward = frames_to_blur_backward; + switch (blur_type) { + case 1: + // Backward Blur + frames_to_blur_backward = num_frames_backward; - if (frames_to_blur_backward > frames_to_blur_forward) - frames_to_blur_backward = frames_to_blur_forward; + if (frames_to_blur_backward >= max_frames) + frames_to_blur_backward = max_frames - 1; - // 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; + frames_to_blur = frames_to_blur_backward + 1; + break; - if (frames_to_blur_backward > (max_frames / 2)) - frames_to_blur_backward = max_frames / 2; + case 2: + // Forward Blur + frames_to_blur_forward = num_frames_forward; - frames_to_blur = frames_to_blur_backward + frames_to_blur_forward + 1; + 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, @@ -380,7 +421,7 @@ void vp9_temporal_filter_prepare(VP9_COMP *cpi, int distance) { // Setup frame pointers, NULL indicates frame not included in filter vp9_zero(cpi->frames); - for (frame = 0; frame < frames_to_blur; ++frame) { + 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); @@ -394,11 +435,11 @@ 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) { - int q; int half_gf_int; int frames_after_arf; - int frames_bwd; - int frames_fwd = (cpi->oxcf.arnr_max_frames - 1) >> 1; + int frames_bwd = cpi->oxcf.arnr_max_frames - 1; + int frames_fwd = cpi->oxcf.arnr_max_frames - 1; + 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 @@ -410,26 +451,47 @@ void vp9_configure_arnr_filter(VP9_COMP *cpi, frames_after_arf = vp9_lookahead_depth(cpi->lookahead) - frames_to_arnr - 1; - if (frames_fwd > frames_after_arf) - frames_fwd = frames_after_arf; - if (frames_fwd > half_gf_int) - frames_fwd = half_gf_int; + 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; - // 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; + 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; + } cpi->active_arnr_frames = frames_bwd + 1 + frames_fwd; // 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])); + q = ((int)vp9_convert_qindex_to_q( + cpi->rc.avg_frame_qindex[INTER_FRAME])); else - q = ((int)vp9_convert_qindex_to_q(cpi->rc.avg_frame_qindex[KEY_FRAME])); - + q = ((int)vp9_convert_qindex_to_q( + cpi->rc.avg_frame_qindex[KEY_FRAME])); if (q > 16) { cpi->active_arnr_strength = cpi->oxcf.arnr_strength; } else { diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c index 1ca9fb93a..449e7d897 100644 --- a/vp9/vp9_cx_iface.c +++ b/vp9/vp9_cx_iface.c @@ -30,6 +30,7 @@ struct vp9_extracfg { unsigned int tile_rows; unsigned int arnr_max_frames; unsigned int arnr_strength; + unsigned int arnr_type; vp8e_tuning tuning; unsigned int cq_level; // constrained quality level unsigned int rc_max_intra_bitrate_pct; @@ -59,6 +60,7 @@ static const struct extraconfig_map extracfg_map[] = { 0, // tile_rows 7, // arnr_max_frames 5, // arnr_strength + 3, // arnr_type VP8_TUNE_PSNR, // tuning 10, // cq_level 0, // rc_max_intra_bitrate_pct @@ -201,6 +203,7 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx, RANGE_CHECK_HI(extra_cfg, sharpness, 7); RANGE_CHECK(extra_cfg, arnr_max_frames, 0, 15); RANGE_CHECK_HI(extra_cfg, arnr_strength, 6); + RANGE_CHECK(extra_cfg, arnr_type, 1, 3); RANGE_CHECK(extra_cfg, cq_level, 0, 63); // TODO(yaowu): remove this when ssim tuning is implemented for vp9 @@ -364,6 +367,7 @@ static vpx_codec_err_t set_encoder_config( oxcf->arnr_max_frames = extra_cfg->arnr_max_frames; oxcf->arnr_strength = extra_cfg->arnr_strength; + oxcf->arnr_type = extra_cfg->arnr_type; oxcf->tuning = extra_cfg->tuning; @@ -494,6 +498,7 @@ static vpx_codec_err_t ctrl_set_param(vpx_codec_alg_priv_t *ctx, int ctrl_id, MAP(VP9E_SET_TILE_ROWS, extra_cfg.tile_rows); MAP(VP8E_SET_ARNR_MAXFRAMES, extra_cfg.arnr_max_frames); MAP(VP8E_SET_ARNR_STRENGTH, extra_cfg.arnr_strength); + MAP(VP8E_SET_ARNR_TYPE, extra_cfg.arnr_type); MAP(VP8E_SET_TUNING, extra_cfg.tuning); MAP(VP8E_SET_CQ_LEVEL, extra_cfg.cq_level); MAP(VP8E_SET_MAX_INTRA_BITRATE_PCT, extra_cfg.rc_max_intra_bitrate_pct); @@ -1107,6 +1112,7 @@ static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = { {VP9E_SET_TILE_ROWS, ctrl_set_param}, {VP8E_SET_ARNR_MAXFRAMES, ctrl_set_param}, {VP8E_SET_ARNR_STRENGTH, ctrl_set_param}, + {VP8E_SET_ARNR_TYPE, ctrl_set_param}, {VP8E_SET_TUNING, ctrl_set_param}, {VP8E_SET_CQ_LEVEL, ctrl_set_param}, {VP8E_SET_MAX_INTRA_BITRATE_PCT, ctrl_set_param}, diff --git a/vpx/vp8cx.h b/vpx/vp8cx.h index 8944a2664..bc8df807e 100644 --- a/vpx/vp8cx.h +++ b/vpx/vp8cx.h @@ -160,8 +160,10 @@ enum vp8e_enc_control_id { scale as used by the rc_*_quantizer config parameters */ VP8E_SET_ARNR_MAXFRAMES, /**< control function to set the max number of frames blurred creating arf*/ - VP8E_SET_ARNR_STRENGTH, /**< control function to set the filter strength for the arf */ - VP8E_SET_ARNR_TYPE, /**< control function to set the type of filter to use for the arf*/ + VP8E_SET_ARNR_STRENGTH, //!< control function to set the filter + //!< strength for the arf + VP8E_SET_ARNR_TYPE, //!< control function to set the type of + //!< filter to use for the arf VP8E_SET_TUNING, /**< control function to set visual tuning */ /*!\brief control function to set constrained quality level * diff --git a/vpxenc.c b/vpxenc.c index 3b8591e30..8e8ed2344 100644 --- a/vpxenc.c +++ b/vpxenc.c @@ -363,7 +363,7 @@ static const arg_def_t frame_periodic_boost = ARG_DEF( static const arg_def_t *vp9_args[] = { &cpu_used, &auto_altref, &noise_sens, &sharpness, &static_thresh, - &tile_cols, &tile_rows, &arnr_maxframes, &arnr_strength, + &tile_cols, &tile_rows, &arnr_maxframes, &arnr_strength, &arnr_type, &tune_ssim, &cq_level, &max_intra_rate_pct, &lossless, &frame_parallel_decoding, &aq_mode, &frame_periodic_boost, NULL @@ -372,7 +372,7 @@ static const int vp9_arg_ctrl_map[] = { VP8E_SET_CPUUSED, VP8E_SET_ENABLEAUTOALTREF, VP8E_SET_NOISE_SENSITIVITY, VP8E_SET_SHARPNESS, VP8E_SET_STATIC_THRESHOLD, VP9E_SET_TILE_COLUMNS, VP9E_SET_TILE_ROWS, - VP8E_SET_ARNR_MAXFRAMES, VP8E_SET_ARNR_STRENGTH, + VP8E_SET_ARNR_MAXFRAMES, VP8E_SET_ARNR_STRENGTH, VP8E_SET_ARNR_TYPE, VP8E_SET_TUNING, VP8E_SET_CQ_LEVEL, VP8E_SET_MAX_INTRA_BITRATE_PCT, VP9E_SET_LOSSLESS, VP9E_SET_FRAME_PARALLEL_DECODING, VP9E_SET_AQ_MODE, VP9E_SET_FRAME_PERIODIC_BOOST,