Add --alt-ref-aq=<int> option

In the future this option will activate adaptive quantization special
for altref frames. Encoder will  create the adaptive quantization map
on the basis of lookahead buffers similarity which is the estimate of
the future motion compensation performance.

Change-Id: Ia0088b3babb0f9a4899c79d8d819947ba5a03df2
This commit is contained in:
Yury Gitman 2016-07-18 12:17:58 -07:00
parent 5260a6675e
commit d7c20079a6
6 changed files with 196 additions and 2 deletions

View File

@ -0,0 +1,157 @@
/*
* Copyright (c) 2012 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/i420_video_source.h"
#include "test/util.h"
namespace {
class AltRefAqSegmentTest
: public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
protected:
AltRefAqSegmentTest() : EncoderTest(GET_PARAM(0)) {}
virtual ~AltRefAqSegmentTest() {}
virtual void SetUp() {
InitializeConfig();
SetMode(GET_PARAM(1));
set_cpu_used_ = GET_PARAM(2);
aq_mode_ = 0;
alt_ref_aq_mode_ = 0;
}
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 1) {
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
encoder->Control(VP9E_SET_ALT_REF_AQ, alt_ref_aq_mode_);
encoder->Control(VP9E_SET_AQ_MODE, aq_mode_);
encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 100);
}
}
int set_cpu_used_;
int aq_mode_;
int alt_ref_aq_mode_;
};
// Validate that this ALT_REF_AQ/AQ segmentation mode
// (ALT_REF_AQ=0, AQ=0/no_aq)
// encodes and decodes without a mismatch.
TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ0) {
cfg_.rc_min_quantizer = 8;
cfg_.rc_max_quantizer = 56;
cfg_.rc_end_usage = VPX_VBR;
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 500;
cfg_.rc_buf_sz = 1000;
cfg_.rc_target_bitrate = 300;
aq_mode_ = 0;
alt_ref_aq_mode_ = 1;
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 100);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}
// Validate that this ALT_REF_AQ/AQ segmentation mode
// (ALT_REF_AQ=0, AQ=1/variance_aq)
// encodes and decodes without a mismatch.
TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ1) {
cfg_.rc_min_quantizer = 8;
cfg_.rc_max_quantizer = 56;
cfg_.rc_end_usage = VPX_VBR;
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 500;
cfg_.rc_buf_sz = 1000;
cfg_.rc_target_bitrate = 300;
aq_mode_ = 1;
alt_ref_aq_mode_ = 1;
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 100);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}
// Validate that this ALT_REF_AQ/AQ segmentation mode
// (ALT_REF_AQ=0, AQ=2/complexity_aq)
// encodes and decodes without a mismatch.
TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ2) {
cfg_.rc_min_quantizer = 8;
cfg_.rc_max_quantizer = 56;
cfg_.rc_end_usage = VPX_VBR;
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 500;
cfg_.rc_buf_sz = 1000;
cfg_.rc_target_bitrate = 300;
aq_mode_ = 2;
alt_ref_aq_mode_ = 1;
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 100);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}
// Validate that this ALT_REF_AQ/AQ segmentation mode
// (ALT_REF_AQ=0, AQ=3/cyclicrefresh_aq)
// encodes and decodes without a mismatch.
TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ3) {
cfg_.rc_min_quantizer = 8;
cfg_.rc_max_quantizer = 56;
cfg_.rc_end_usage = VPX_VBR;
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 500;
cfg_.rc_buf_sz = 1000;
cfg_.rc_target_bitrate = 300;
aq_mode_ = 3;
alt_ref_aq_mode_ = 1;
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 100);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}
// Validate that this ALT_REF_AQ/AQ segmentation mode
// (ALT_REF_AQ=0, AQ=4/equator360_aq)
// encodes and decodes without a mismatch.
TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ4) {
cfg_.rc_min_quantizer = 8;
cfg_.rc_max_quantizer = 56;
cfg_.rc_end_usage = VPX_VBR;
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 500;
cfg_.rc_buf_sz = 1000;
cfg_.rc_target_bitrate = 300;
aq_mode_ = 4;
alt_ref_aq_mode_ = 1;
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 100);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}
VP9_INSTANTIATE_TEST_CASE(AltRefAqSegmentTest,
::testing::Values(::libvpx_test::kOnePassGood,
::libvpx_test::kTwoPassGood),
::testing::Range(2, 5));
} // namespace

View File

@ -20,6 +20,7 @@ LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ivf_video_source.h
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += ../y4minput.h ../y4minput.c
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += altref_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += aq_segment_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += alt_ref_aq_segment_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += datarate_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += encode_api_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += error_resilience_test.cc

View File

@ -116,6 +116,9 @@ typedef enum {
COMPLEXITY_AQ = 2,
CYCLIC_REFRESH_AQ = 3,
EQUATOR360_AQ = 4,
// AQ based on lookahead temporal
// variance (only valid for altref frames)
LOOKAHEAD_AQ = 5,
AQ_MODE_COUNT // This should always be the last member of the enum
} AQ_MODE;
@ -178,6 +181,9 @@ typedef struct VP9EncoderConfig {
int cq_level;
AQ_MODE aq_mode; // Adaptive Quantization mode
// Special handling of Adaptive Quantization for AltRef frames
int alt_ref_aq;
// Internal frame size scaling.
RESIZE_TYPE resize_mode;
int scaled_frame_width;

View File

@ -43,6 +43,7 @@ struct vp9_extracfg {
unsigned int target_level;
unsigned int frame_parallel_decoding_mode;
AQ_MODE aq_mode;
int alt_ref_aq;
unsigned int frame_periodic_boost;
vpx_bit_depth_t bit_depth;
vp9e_tune_content content;
@ -73,6 +74,7 @@ static struct vp9_extracfg default_extra_cfg = {
255, // target_level
1, // frame_parallel_decoding_mode
NO_AQ, // aq_mode
0, // alt_ref_aq
0, // frame_periodic_delta_q
VPX_BITS_8, // Bit depth
VP9E_CONTENT_DEFAULT, // content
@ -155,7 +157,8 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx,
RANGE_CHECK_HI(cfg, rc_max_quantizer, 63);
RANGE_CHECK_HI(cfg, rc_min_quantizer, cfg->rc_max_quantizer);
RANGE_CHECK_BOOL(extra_cfg, lossless);
RANGE_CHECK(extra_cfg, aq_mode, 0, AQ_MODE_COUNT - 1);
RANGE_CHECK(extra_cfg, aq_mode, 0, AQ_MODE_COUNT - 2);
RANGE_CHECK(extra_cfg, alt_ref_aq, 0, 1);
RANGE_CHECK(extra_cfg, frame_periodic_boost, 0, 1);
RANGE_CHECK_HI(cfg, g_threads, 64);
RANGE_CHECK_HI(cfg, g_lag_in_frames, MAX_LAG_BUFFERS);
@ -495,6 +498,7 @@ static vpx_codec_err_t set_encoder_config(
oxcf->frame_parallel_decoding_mode = extra_cfg->frame_parallel_decoding_mode;
oxcf->aq_mode = extra_cfg->aq_mode;
oxcf->alt_ref_aq = extra_cfg->alt_ref_aq;
oxcf->frame_periodic_boost = extra_cfg->frame_periodic_boost;
@ -756,6 +760,13 @@ static vpx_codec_err_t ctrl_set_aq_mode(vpx_codec_alg_priv_t *ctx,
return update_extra_cfg(ctx, &extra_cfg);
}
static vpx_codec_err_t ctrl_set_alt_ref_aq(vpx_codec_alg_priv_t *ctx,
va_list args) {
struct vp9_extracfg extra_cfg = ctx->extra_cfg;
extra_cfg.alt_ref_aq = CAST(VP9E_SET_ALT_REF_AQ, args);
return update_extra_cfg(ctx, &extra_cfg);
}
static vpx_codec_err_t ctrl_set_min_gf_interval(vpx_codec_alg_priv_t *ctx,
va_list args) {
struct vp9_extracfg extra_cfg = ctx->extra_cfg;
@ -1497,6 +1508,7 @@ static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
{ VP9E_SET_LOSSLESS, ctrl_set_lossless },
{ VP9E_SET_FRAME_PARALLEL_DECODING, ctrl_set_frame_parallel_decoding_mode },
{ VP9E_SET_AQ_MODE, ctrl_set_aq_mode },
{ VP9E_SET_ALT_REF_AQ, ctrl_set_alt_ref_aq },
{ VP9E_SET_FRAME_PERIODIC_BOOST, ctrl_set_frame_periodic_boost },
{ VP9E_SET_SVC, ctrl_set_svc },
{ VP9E_SET_SVC_PARAMETERS, ctrl_set_svc_parameters },

View File

@ -551,7 +551,17 @@ enum vp8e_enc_control_id {
*
* Supported in codecs: VP9
*/
VP9E_GET_LEVEL
VP9E_GET_LEVEL,
/*!\brief Codec control function to enable/disable special mode for altref
* adaptive quantization. You can use it with --aq-mode concurrently.
*
* Enable special adaptive quantization for altref frames based on their
* expected prediction quality for the future frames.
*
* Supported in codecs: VP9
*/
VP9E_SET_ALT_REF_AQ
};
/*!\brief vpx 1-D scaling mode
@ -774,6 +784,9 @@ VPX_CTRL_USE_TYPE(VP9E_SET_FRAME_PARALLEL_DECODING, unsigned int)
VPX_CTRL_USE_TYPE(VP9E_SET_AQ_MODE, unsigned int)
#define VPX_CTRL_VP9E_SET_AQ_MODE
VPX_CTRL_USE_TYPE(VP9E_SET_ALT_REF_AQ, int)
#define VPX_CTRL_VP9E_SET_ALT_REF_AQ
VPX_CTRL_USE_TYPE(VP9E_SET_FRAME_PERIODIC_BOOST, unsigned int)
#define VPX_CTRL_VP9E_SET_FRAME_PERIODIC_BOOST

View File

@ -401,6 +401,9 @@ static const arg_def_t aq_mode = ARG_DEF(
NULL, "aq-mode", 1,
"Adaptive quantization mode (0: off (default), 1: variance 2: complexity, "
"3: cyclic refresh, 4: equator360)");
static const arg_def_t alt_ref_aq = ARG_DEF(NULL, "alt-ref-aq", 1,
"Special adaptive quantization for "
"the alternate reference frames.");
static const arg_def_t frame_periodic_boost =
ARG_DEF(NULL, "frame-boost", 1,
"Enable frame periodic boost (0: off (default), 1: on)");
@ -477,6 +480,7 @@ static const arg_def_t *vp9_args[] = { &cpu_used_vp9,
&lossless,
&frame_parallel_decoding,
&aq_mode,
&alt_ref_aq,
&frame_periodic_boost,
&noise_sens,
&tune_content,
@ -506,6 +510,7 @@ static const int vp9_arg_ctrl_map[] = { VP8E_SET_CPUUSED,
VP9E_SET_LOSSLESS,
VP9E_SET_FRAME_PARALLEL_DECODING,
VP9E_SET_AQ_MODE,
VP9E_SET_ALT_REF_AQ,
VP9E_SET_FRAME_PERIODIC_BOOST,
VP9E_SET_NOISE_SENSITIVITY,
VP9E_SET_TUNE_CONTENT,