lossless_test.cc (7629B)
1 /* 2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved. 3 * 4 * This source code is subject to the terms of the BSD 2 Clause License and 5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License 6 * was not distributed with this source code in the LICENSE file, you can 7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open 8 * Media Patent License 1.0 was not distributed with this source code in the 9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent. 10 */ 11 12 #include "gtest/gtest.h" 13 14 #include "config/aom_config.h" 15 16 #include "test/codec_factory.h" 17 #include "test/encode_test_driver.h" 18 #include "test/i420_video_source.h" 19 #include "test/util.h" 20 #include "test/y4m_video_source.h" 21 22 namespace { 23 24 const int kMaxPsnr = 100; 25 26 class LosslessTestLarge 27 : public ::libaom_test::CodecTestWith3Params<libaom_test::TestMode, 28 aom_rc_mode, int>, 29 public ::libaom_test::EncoderTest { 30 protected: 31 LosslessTestLarge() 32 : EncoderTest(GET_PARAM(0)), psnr_(kMaxPsnr), nframes_(0), 33 encoding_mode_(GET_PARAM(1)), rc_end_usage_(GET_PARAM(2)), 34 cpu_used_(GET_PARAM(3)) {} 35 36 ~LosslessTestLarge() override = default; 37 38 void SetUp() override { 39 InitializeConfig(encoding_mode_); 40 cfg_.rc_end_usage = rc_end_usage_; 41 } 42 43 void PreEncodeFrameHook(::libaom_test::VideoSource *video, 44 ::libaom_test::Encoder *encoder) override { 45 if (video->frame() == 0) { 46 // Only call Control if quantizer > 0 to verify that using quantizer 47 // alone will activate lossless 48 if (cfg_.rc_max_quantizer > 0 || cfg_.rc_min_quantizer > 0) { 49 encoder->Control(AV1E_SET_LOSSLESS, 1); 50 } 51 encoder->Control(AOME_SET_CPUUSED, cpu_used_); 52 } 53 } 54 55 void BeginPassHook(unsigned int /*pass*/) override { 56 psnr_ = kMaxPsnr; 57 nframes_ = 0; 58 } 59 60 void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) override { 61 if (pkt->data.psnr.psnr[0] < psnr_) psnr_ = pkt->data.psnr.psnr[0]; 62 } 63 64 double GetMinPsnr() const { return psnr_; } 65 66 bool HandleDecodeResult(const aom_codec_err_t res_dec, 67 libaom_test::Decoder *decoder) override { 68 EXPECT_EQ(AOM_CODEC_OK, res_dec) << decoder->DecodeError(); 69 if (AOM_CODEC_OK == res_dec) { 70 aom_codec_ctx_t *ctx_dec = decoder->GetDecoder(); 71 AOM_CODEC_CONTROL_TYPECHECKED(ctx_dec, AOMD_GET_LAST_QUANTIZER, 72 &base_qindex_); 73 EXPECT_EQ(base_qindex_, 0) 74 << "Error: Base_qindex is non zero for lossless coding"; 75 } 76 return AOM_CODEC_OK == res_dec; 77 } 78 79 void TestLosslessEncoding(); 80 void TestLosslessEncodingVGALag0(); 81 void TestLosslessEncoding444(); 82 void TestLosslessEncodingCtrl(); 83 84 private: 85 double psnr_; 86 unsigned int nframes_; 87 libaom_test::TestMode encoding_mode_; 88 aom_rc_mode rc_end_usage_; 89 int cpu_used_; 90 int base_qindex_; 91 }; 92 93 void LosslessTestLarge::TestLosslessEncoding() { 94 const aom_rational timebase = { 33333333, 1000000000 }; 95 cfg_.g_timebase = timebase; 96 cfg_.rc_target_bitrate = 2000; 97 cfg_.g_lag_in_frames = 25; 98 cfg_.rc_min_quantizer = 0; 99 cfg_.rc_max_quantizer = 0; 100 101 init_flags_ = AOM_CODEC_USE_PSNR; 102 103 // intentionally changed the dimension for better testing coverage 104 libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, 105 timebase.den, timebase.num, 0, 5); 106 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 107 const double psnr_lossless = GetMinPsnr(); 108 EXPECT_GE(psnr_lossless, kMaxPsnr); 109 } 110 111 void LosslessTestLarge::TestLosslessEncodingVGALag0() { 112 const aom_rational timebase = { 33333333, 1000000000 }; 113 cfg_.g_timebase = timebase; 114 cfg_.rc_target_bitrate = 2000; 115 cfg_.g_lag_in_frames = 0; 116 cfg_.rc_min_quantizer = 0; 117 cfg_.rc_max_quantizer = 0; 118 119 init_flags_ = AOM_CODEC_USE_PSNR; 120 121 libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 122 timebase.den, timebase.num, 0, 30); 123 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 124 const double psnr_lossless = GetMinPsnr(); 125 EXPECT_GE(psnr_lossless, kMaxPsnr); 126 } 127 128 void LosslessTestLarge::TestLosslessEncoding444() { 129 libaom_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 5); 130 131 cfg_.g_profile = 1; 132 cfg_.g_timebase = video.timebase(); 133 cfg_.rc_target_bitrate = 2000; 134 cfg_.g_lag_in_frames = 25; 135 cfg_.rc_min_quantizer = 0; 136 cfg_.rc_max_quantizer = 0; 137 138 init_flags_ = AOM_CODEC_USE_PSNR; 139 140 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 141 const double psnr_lossless = GetMinPsnr(); 142 EXPECT_GE(psnr_lossless, kMaxPsnr); 143 } 144 145 void LosslessTestLarge::TestLosslessEncodingCtrl() { 146 const aom_rational timebase = { 33333333, 1000000000 }; 147 cfg_.g_timebase = timebase; 148 cfg_.rc_target_bitrate = 2000; 149 cfg_.g_lag_in_frames = 25; 150 // Intentionally set Q > 0, to make sure control can be used to activate 151 // lossless 152 cfg_.rc_min_quantizer = 10; 153 cfg_.rc_max_quantizer = 20; 154 155 init_flags_ = AOM_CODEC_USE_PSNR; 156 157 libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, 158 timebase.den, timebase.num, 0, 5); 159 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 160 const double psnr_lossless = GetMinPsnr(); 161 EXPECT_GE(psnr_lossless, kMaxPsnr); 162 } 163 164 TEST_P(LosslessTestLarge, TestLosslessEncoding) { TestLosslessEncoding(); } 165 166 TEST_P(LosslessTestLarge, TestLosslessEncodingVGALag0) { 167 TestLosslessEncodingVGALag0(); 168 } 169 170 TEST_P(LosslessTestLarge, TestLosslessEncoding444) { 171 TestLosslessEncoding444(); 172 } 173 174 TEST_P(LosslessTestLarge, TestLosslessEncodingCtrl) { 175 TestLosslessEncodingCtrl(); 176 } 177 178 class LosslessAllIntraTestLarge : public LosslessTestLarge {}; 179 180 TEST_P(LosslessAllIntraTestLarge, TestLosslessEncodingCtrl) { 181 const aom_rational timebase = { 33333333, 1000000000 }; 182 cfg_.g_timebase = timebase; 183 // Intentionally set Q > 0, to make sure control can be used to activate 184 // lossless 185 cfg_.rc_min_quantizer = 10; 186 cfg_.rc_max_quantizer = 20; 187 188 init_flags_ = AOM_CODEC_USE_PSNR; 189 190 libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, 191 timebase.den, timebase.num, 0, 5); 192 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 193 const double psnr_lossless = GetMinPsnr(); 194 EXPECT_GE(psnr_lossless, kMaxPsnr); 195 } 196 197 using LosslessRealtimeTestLarge = LosslessTestLarge; 198 199 TEST_P(LosslessRealtimeTestLarge, TestLosslessEncoding) { 200 TestLosslessEncoding(); 201 } 202 203 TEST_P(LosslessRealtimeTestLarge, TestLosslessEncodingVGALag0) { 204 TestLosslessEncodingVGALag0(); 205 } 206 207 TEST_P(LosslessRealtimeTestLarge, TestLosslessEncoding444) { 208 TestLosslessEncoding444(); 209 } 210 211 TEST_P(LosslessRealtimeTestLarge, TestLosslessEncodingCtrl) { 212 TestLosslessEncodingCtrl(); 213 } 214 215 AV1_INSTANTIATE_TEST_SUITE(LosslessTestLarge, 216 ::testing::Values(::libaom_test::kOnePassGood, 217 ::libaom_test::kTwoPassGood), 218 ::testing::Values(AOM_Q, AOM_VBR, AOM_CBR, AOM_CQ), 219 ::testing::Values(0)); // cpu_used 220 221 AV1_INSTANTIATE_TEST_SUITE(LosslessAllIntraTestLarge, 222 ::testing::Values(::libaom_test::kAllIntra), 223 ::testing::Values(AOM_Q), 224 ::testing::Values(6, 9)); // cpu_used 225 226 AV1_INSTANTIATE_TEST_SUITE(LosslessRealtimeTestLarge, 227 ::testing::Values(::libaom_test::kRealTime), 228 ::testing::Values(AOM_Q, AOM_VBR, AOM_CBR, AOM_CQ), 229 ::testing::Range(6, 11)); // cpu_used 230 } // namespace