1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
3*77c1e3ccSAndroid Build Coastguard Worker *
4*77c1e3ccSAndroid Build Coastguard Worker * This source code is subject to the terms of the BSD 2 Clause License and
5*77c1e3ccSAndroid Build Coastguard Worker * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6*77c1e3ccSAndroid Build Coastguard Worker * was not distributed with this source code in the LICENSE file, you can
7*77c1e3ccSAndroid Build Coastguard Worker * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8*77c1e3ccSAndroid Build Coastguard Worker * Media Patent License 1.0 was not distributed with this source code in the
9*77c1e3ccSAndroid Build Coastguard Worker * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10*77c1e3ccSAndroid Build Coastguard Worker */
11*77c1e3ccSAndroid Build Coastguard Worker #include "config/aom_config.h"
12*77c1e3ccSAndroid Build Coastguard Worker
13*77c1e3ccSAndroid Build Coastguard Worker #include "av1/encoder/av1_quantize.h"
14*77c1e3ccSAndroid Build Coastguard Worker #include "gtest/gtest.h"
15*77c1e3ccSAndroid Build Coastguard Worker #include "test/codec_factory.h"
16*77c1e3ccSAndroid Build Coastguard Worker #include "test/encode_test_driver.h"
17*77c1e3ccSAndroid Build Coastguard Worker #include "test/i420_video_source.h"
18*77c1e3ccSAndroid Build Coastguard Worker #include "test/util.h"
19*77c1e3ccSAndroid Build Coastguard Worker #include "test/y4m_video_source.h"
20*77c1e3ccSAndroid Build Coastguard Worker
21*77c1e3ccSAndroid Build Coastguard Worker namespace {
22*77c1e3ccSAndroid Build Coastguard Worker
23*77c1e3ccSAndroid Build Coastguard Worker const ::libaom_test::TestMode kTestMode[] =
24*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_REALTIME_ONLY
25*77c1e3ccSAndroid Build Coastguard Worker { ::libaom_test::kRealTime };
26*77c1e3ccSAndroid Build Coastguard Worker #else
27*77c1e3ccSAndroid Build Coastguard Worker { ::libaom_test::kRealTime, ::libaom_test::kOnePassGood };
28*77c1e3ccSAndroid Build Coastguard Worker #endif
29*77c1e3ccSAndroid Build Coastguard Worker
30*77c1e3ccSAndroid Build Coastguard Worker class QMTest
31*77c1e3ccSAndroid Build Coastguard Worker : public ::libaom_test::CodecTestWith2Params<libaom_test::TestMode, int>,
32*77c1e3ccSAndroid Build Coastguard Worker public ::libaom_test::EncoderTest {
33*77c1e3ccSAndroid Build Coastguard Worker protected:
QMTest()34*77c1e3ccSAndroid Build Coastguard Worker QMTest() : EncoderTest(GET_PARAM(0)) {}
35*77c1e3ccSAndroid Build Coastguard Worker ~QMTest() override = default;
36*77c1e3ccSAndroid Build Coastguard Worker
SetUp()37*77c1e3ccSAndroid Build Coastguard Worker void SetUp() override {
38*77c1e3ccSAndroid Build Coastguard Worker InitializeConfig(GET_PARAM(1));
39*77c1e3ccSAndroid Build Coastguard Worker set_cpu_used_ = GET_PARAM(2);
40*77c1e3ccSAndroid Build Coastguard Worker }
41*77c1e3ccSAndroid Build Coastguard Worker
PreEncodeFrameHook(::libaom_test::VideoSource * video,::libaom_test::Encoder * encoder)42*77c1e3ccSAndroid Build Coastguard Worker void PreEncodeFrameHook(::libaom_test::VideoSource *video,
43*77c1e3ccSAndroid Build Coastguard Worker ::libaom_test::Encoder *encoder) override {
44*77c1e3ccSAndroid Build Coastguard Worker if (video->frame() == 0) {
45*77c1e3ccSAndroid Build Coastguard Worker encoder->Control(AOME_SET_CPUUSED, set_cpu_used_);
46*77c1e3ccSAndroid Build Coastguard Worker encoder->Control(AV1E_SET_ENABLE_QM, 1);
47*77c1e3ccSAndroid Build Coastguard Worker encoder->Control(AV1E_SET_QM_MIN, qm_min_);
48*77c1e3ccSAndroid Build Coastguard Worker encoder->Control(AV1E_SET_QM_MAX, qm_max_);
49*77c1e3ccSAndroid Build Coastguard Worker
50*77c1e3ccSAndroid Build Coastguard Worker encoder->Control(AOME_SET_MAX_INTRA_BITRATE_PCT, 100);
51*77c1e3ccSAndroid Build Coastguard Worker if (mode_ == ::libaom_test::kRealTime) {
52*77c1e3ccSAndroid Build Coastguard Worker encoder->Control(AV1E_SET_ALLOW_WARPED_MOTION, 0);
53*77c1e3ccSAndroid Build Coastguard Worker encoder->Control(AV1E_SET_ENABLE_GLOBAL_MOTION, 0);
54*77c1e3ccSAndroid Build Coastguard Worker encoder->Control(AV1E_SET_ENABLE_OBMC, 0);
55*77c1e3ccSAndroid Build Coastguard Worker }
56*77c1e3ccSAndroid Build Coastguard Worker }
57*77c1e3ccSAndroid Build Coastguard Worker }
58*77c1e3ccSAndroid Build Coastguard Worker
DoTest(int qm_min,int qm_max)59*77c1e3ccSAndroid Build Coastguard Worker void DoTest(int qm_min, int qm_max) {
60*77c1e3ccSAndroid Build Coastguard Worker qm_min_ = qm_min;
61*77c1e3ccSAndroid Build Coastguard Worker qm_max_ = qm_max;
62*77c1e3ccSAndroid Build Coastguard Worker cfg_.kf_max_dist = 12;
63*77c1e3ccSAndroid Build Coastguard Worker cfg_.rc_min_quantizer = 8;
64*77c1e3ccSAndroid Build Coastguard Worker cfg_.rc_max_quantizer = 56;
65*77c1e3ccSAndroid Build Coastguard Worker cfg_.rc_end_usage = AOM_CBR;
66*77c1e3ccSAndroid Build Coastguard Worker cfg_.g_lag_in_frames = 6;
67*77c1e3ccSAndroid Build Coastguard Worker cfg_.rc_buf_initial_sz = 500;
68*77c1e3ccSAndroid Build Coastguard Worker cfg_.rc_buf_optimal_sz = 500;
69*77c1e3ccSAndroid Build Coastguard Worker cfg_.rc_buf_sz = 1000;
70*77c1e3ccSAndroid Build Coastguard Worker cfg_.rc_target_bitrate = 300;
71*77c1e3ccSAndroid Build Coastguard Worker ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352,
72*77c1e3ccSAndroid Build Coastguard Worker 288, 30, 1, 0, 15);
73*77c1e3ccSAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
74*77c1e3ccSAndroid Build Coastguard Worker }
75*77c1e3ccSAndroid Build Coastguard Worker
76*77c1e3ccSAndroid Build Coastguard Worker int set_cpu_used_;
77*77c1e3ccSAndroid Build Coastguard Worker int qm_min_;
78*77c1e3ccSAndroid Build Coastguard Worker int qm_max_;
79*77c1e3ccSAndroid Build Coastguard Worker };
80*77c1e3ccSAndroid Build Coastguard Worker
81*77c1e3ccSAndroid Build Coastguard Worker // encodes and decodes without a mismatch.
TEST_P(QMTest,TestNoMisMatchQM1)82*77c1e3ccSAndroid Build Coastguard Worker TEST_P(QMTest, TestNoMisMatchQM1) { DoTest(5, 9); }
83*77c1e3ccSAndroid Build Coastguard Worker
84*77c1e3ccSAndroid Build Coastguard Worker // encodes and decodes without a mismatch.
TEST_P(QMTest,TestNoMisMatchQM2)85*77c1e3ccSAndroid Build Coastguard Worker TEST_P(QMTest, TestNoMisMatchQM2) { DoTest(0, 8); }
86*77c1e3ccSAndroid Build Coastguard Worker
87*77c1e3ccSAndroid Build Coastguard Worker // encodes and decodes without a mismatch.
TEST_P(QMTest,TestNoMisMatchQM3)88*77c1e3ccSAndroid Build Coastguard Worker TEST_P(QMTest, TestNoMisMatchQM3) { DoTest(9, 15); }
89*77c1e3ccSAndroid Build Coastguard Worker
90*77c1e3ccSAndroid Build Coastguard Worker AV1_INSTANTIATE_TEST_SUITE(QMTest, ::testing::ValuesIn(kTestMode),
91*77c1e3ccSAndroid Build Coastguard Worker ::testing::Range(5, 9));
92*77c1e3ccSAndroid Build Coastguard Worker
93*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
94*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
95*77c1e3ccSAndroid Build Coastguard Worker const unsigned int min_q;
96*77c1e3ccSAndroid Build Coastguard Worker const unsigned int max_q;
97*77c1e3ccSAndroid Build Coastguard Worker } QuantParam;
98*77c1e3ccSAndroid Build Coastguard Worker
99*77c1e3ccSAndroid Build Coastguard Worker const QuantParam QuantTestParams[] = {
100*77c1e3ccSAndroid Build Coastguard Worker { 0, 10 }, { 0, 60 }, { 20, 35 }, { 35, 50 }, { 50, 63 }
101*77c1e3ccSAndroid Build Coastguard Worker };
102*77c1e3ccSAndroid Build Coastguard Worker
operator <<(std::ostream & os,const QuantParam & test_arg)103*77c1e3ccSAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, const QuantParam &test_arg) {
104*77c1e3ccSAndroid Build Coastguard Worker return os << "QuantParam { min_q:" << test_arg.min_q
105*77c1e3ccSAndroid Build Coastguard Worker << " max_q:" << test_arg.max_q << " }";
106*77c1e3ccSAndroid Build Coastguard Worker }
107*77c1e3ccSAndroid Build Coastguard Worker
108*77c1e3ccSAndroid Build Coastguard Worker /*
109*77c1e3ccSAndroid Build Coastguard Worker * This class is used to test whether base_qindex is within min
110*77c1e3ccSAndroid Build Coastguard Worker * and max quantizer range configured by user.
111*77c1e3ccSAndroid Build Coastguard Worker */
112*77c1e3ccSAndroid Build Coastguard Worker class QuantizerBoundsCheckTestLarge
113*77c1e3ccSAndroid Build Coastguard Worker : public ::libaom_test::CodecTestWith3Params<libaom_test::TestMode,
114*77c1e3ccSAndroid Build Coastguard Worker QuantParam, aom_rc_mode>,
115*77c1e3ccSAndroid Build Coastguard Worker public ::libaom_test::EncoderTest {
116*77c1e3ccSAndroid Build Coastguard Worker protected:
QuantizerBoundsCheckTestLarge()117*77c1e3ccSAndroid Build Coastguard Worker QuantizerBoundsCheckTestLarge()
118*77c1e3ccSAndroid Build Coastguard Worker : EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
119*77c1e3ccSAndroid Build Coastguard Worker quant_param_(GET_PARAM(2)), rc_end_usage_(GET_PARAM(3)) {
120*77c1e3ccSAndroid Build Coastguard Worker quant_bound_violated_ = false;
121*77c1e3ccSAndroid Build Coastguard Worker }
122*77c1e3ccSAndroid Build Coastguard Worker ~QuantizerBoundsCheckTestLarge() override = default;
123*77c1e3ccSAndroid Build Coastguard Worker
SetUp()124*77c1e3ccSAndroid Build Coastguard Worker void SetUp() override {
125*77c1e3ccSAndroid Build Coastguard Worker InitializeConfig(encoding_mode_);
126*77c1e3ccSAndroid Build Coastguard Worker const aom_rational timebase = { 1, 30 };
127*77c1e3ccSAndroid Build Coastguard Worker cfg_.g_timebase = timebase;
128*77c1e3ccSAndroid Build Coastguard Worker cfg_.rc_end_usage = rc_end_usage_;
129*77c1e3ccSAndroid Build Coastguard Worker cfg_.g_threads = 1;
130*77c1e3ccSAndroid Build Coastguard Worker cfg_.rc_min_quantizer = quant_param_.min_q;
131*77c1e3ccSAndroid Build Coastguard Worker cfg_.rc_max_quantizer = quant_param_.max_q;
132*77c1e3ccSAndroid Build Coastguard Worker cfg_.g_lag_in_frames = 35;
133*77c1e3ccSAndroid Build Coastguard Worker if (rc_end_usage_ != AOM_Q) {
134*77c1e3ccSAndroid Build Coastguard Worker cfg_.rc_target_bitrate = 400;
135*77c1e3ccSAndroid Build Coastguard Worker }
136*77c1e3ccSAndroid Build Coastguard Worker }
137*77c1e3ccSAndroid Build Coastguard Worker
DoDecode() const138*77c1e3ccSAndroid Build Coastguard Worker bool DoDecode() const override { return true; }
139*77c1e3ccSAndroid Build Coastguard Worker
PreEncodeFrameHook(::libaom_test::VideoSource * video,::libaom_test::Encoder * encoder)140*77c1e3ccSAndroid Build Coastguard Worker void PreEncodeFrameHook(::libaom_test::VideoSource *video,
141*77c1e3ccSAndroid Build Coastguard Worker ::libaom_test::Encoder *encoder) override {
142*77c1e3ccSAndroid Build Coastguard Worker if (video->frame() == 0) {
143*77c1e3ccSAndroid Build Coastguard Worker encoder->Control(AOME_SET_CPUUSED, 5);
144*77c1e3ccSAndroid Build Coastguard Worker }
145*77c1e3ccSAndroid Build Coastguard Worker }
146*77c1e3ccSAndroid Build Coastguard Worker
HandleDecodeResult(const aom_codec_err_t res_dec,libaom_test::Decoder * decoder)147*77c1e3ccSAndroid Build Coastguard Worker bool HandleDecodeResult(const aom_codec_err_t res_dec,
148*77c1e3ccSAndroid Build Coastguard Worker libaom_test::Decoder *decoder) override {
149*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(AOM_CODEC_OK, res_dec) << decoder->DecodeError();
150*77c1e3ccSAndroid Build Coastguard Worker if (AOM_CODEC_OK == res_dec) {
151*77c1e3ccSAndroid Build Coastguard Worker aom_codec_ctx_t *ctx_dec = decoder->GetDecoder();
152*77c1e3ccSAndroid Build Coastguard Worker AOM_CODEC_CONTROL_TYPECHECKED(ctx_dec, AOMD_GET_LAST_QUANTIZER,
153*77c1e3ccSAndroid Build Coastguard Worker &base_qindex_);
154*77c1e3ccSAndroid Build Coastguard Worker min_bound_qindex_ = av1_quantizer_to_qindex(cfg_.rc_min_quantizer);
155*77c1e3ccSAndroid Build Coastguard Worker max_bound_qindex_ = av1_quantizer_to_qindex(cfg_.rc_max_quantizer);
156*77c1e3ccSAndroid Build Coastguard Worker if ((base_qindex_ < min_bound_qindex_ ||
157*77c1e3ccSAndroid Build Coastguard Worker base_qindex_ > max_bound_qindex_) &&
158*77c1e3ccSAndroid Build Coastguard Worker quant_bound_violated_ == false) {
159*77c1e3ccSAndroid Build Coastguard Worker quant_bound_violated_ = true;
160*77c1e3ccSAndroid Build Coastguard Worker }
161*77c1e3ccSAndroid Build Coastguard Worker }
162*77c1e3ccSAndroid Build Coastguard Worker return AOM_CODEC_OK == res_dec;
163*77c1e3ccSAndroid Build Coastguard Worker }
164*77c1e3ccSAndroid Build Coastguard Worker
165*77c1e3ccSAndroid Build Coastguard Worker ::libaom_test::TestMode encoding_mode_;
166*77c1e3ccSAndroid Build Coastguard Worker const QuantParam quant_param_;
167*77c1e3ccSAndroid Build Coastguard Worker int base_qindex_;
168*77c1e3ccSAndroid Build Coastguard Worker int min_bound_qindex_;
169*77c1e3ccSAndroid Build Coastguard Worker int max_bound_qindex_;
170*77c1e3ccSAndroid Build Coastguard Worker bool quant_bound_violated_;
171*77c1e3ccSAndroid Build Coastguard Worker aom_rc_mode rc_end_usage_;
172*77c1e3ccSAndroid Build Coastguard Worker };
173*77c1e3ccSAndroid Build Coastguard Worker
TEST_P(QuantizerBoundsCheckTestLarge,QuantizerBoundsCheckEncodeTest)174*77c1e3ccSAndroid Build Coastguard Worker TEST_P(QuantizerBoundsCheckTestLarge, QuantizerBoundsCheckEncodeTest) {
175*77c1e3ccSAndroid Build Coastguard Worker libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
176*77c1e3ccSAndroid Build Coastguard Worker cfg_.g_timebase.den, cfg_.g_timebase.num,
177*77c1e3ccSAndroid Build Coastguard Worker 0, 50);
178*77c1e3ccSAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
179*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(quant_bound_violated_, false);
180*77c1e3ccSAndroid Build Coastguard Worker }
181*77c1e3ccSAndroid Build Coastguard Worker
182*77c1e3ccSAndroid Build Coastguard Worker AV1_INSTANTIATE_TEST_SUITE(QuantizerBoundsCheckTestLarge,
183*77c1e3ccSAndroid Build Coastguard Worker ::testing::Values(::libaom_test::kOnePassGood,
184*77c1e3ccSAndroid Build Coastguard Worker ::libaom_test::kTwoPassGood),
185*77c1e3ccSAndroid Build Coastguard Worker ::testing::ValuesIn(QuantTestParams),
186*77c1e3ccSAndroid Build Coastguard Worker ::testing::Values(AOM_Q, AOM_VBR, AOM_CBR, AOM_CQ));
187*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY
188*77c1e3ccSAndroid Build Coastguard Worker } // namespace
189