From: Ronald S. Bultje Date: Thu, 4 Oct 2012 23:38:21 +0000 (-0700) Subject: Add a unit test for CQ mode. X-Git-Tag: v1.2.0~59 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1a89bc04e81aeaea22e7a9c12641219a443af640;p=platform%2Fupstream%2Flibvpx.git Add a unit test for CQ mode. Change-Id: I66c391987eabc5ea0159bf4a2a4fd8e8e163872f --- diff --git a/test/cq_test.cc b/test/cq_test.cc new file mode 100644 index 0000000..42ee2a2 --- /dev/null +++ b/test/cq_test.cc @@ -0,0 +1,106 @@ +/* + * 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 +#include "third_party/googletest/src/include/gtest/gtest.h" +#include "test/encode_test_driver.h" +#include "test/i420_video_source.h" + +// CQ level range: [kCQLevelMin, kCQLevelMax). +const int kCQLevelMin = 4; +const int kCQLevelMax = 63; +const int kCQLevelStep = 8; +const int kCQTargetBitrate = 2000; + +namespace { + +class CQTest : public libvpx_test::EncoderTest, + public ::testing::TestWithParam { + protected: + CQTest() : cq_level_(GetParam()) { init_flags_ = VPX_CODEC_USE_PSNR; } + virtual ~CQTest() {} + + virtual void SetUp() { + InitializeConfig(); + SetMode(libvpx_test::kTwoPassGood); + } + + virtual void BeginPassHook(unsigned int /*pass*/) { + file_size_ = 0; + psnr_ = 0.0; + n_frames_ = 0; + } + + virtual bool Continue() const { + return !HasFatalFailure() && !abort_; + } + + virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video, + libvpx_test::Encoder *encoder) { + if (video->frame() == 1) { + if (cfg_.rc_end_usage == VPX_CQ) { + encoder->Control(VP8E_SET_CQ_LEVEL, cq_level_); + } + encoder->Control(VP8E_SET_CPUUSED, 3); + } + } + + virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) { + psnr_ += pow(10.0, pkt->data.psnr.psnr[0] / 10.0); + n_frames_++; + } + + virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) { + file_size_ += pkt->data.frame.sz; + } + + double GetLinearPSNROverBitrate() const { + double avg_psnr = log10(psnr_ / n_frames_) * 10.0; + return pow(10.0, avg_psnr / 10.0) / file_size_; + } + + int file_size() const { return file_size_; } + int n_frames() const { return n_frames_; } + + private: + int cq_level_; + int file_size_; + double psnr_; + int n_frames_; +}; + +int prev_actual_bitrate = kCQTargetBitrate; +TEST_P(CQTest, LinearPSNRIsHigherForCQLevel) { + const vpx_rational timebase = { 33333333, 1000000000 }; + cfg_.g_timebase = timebase; + cfg_.rc_target_bitrate = kCQTargetBitrate; + cfg_.g_lag_in_frames = 25; + + cfg_.rc_end_usage = VPX_CQ; + libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, + timebase.den, timebase.num, 0, 30); + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + const double cq_psnr_lin = GetLinearPSNROverBitrate(); + const int cq_actual_bitrate = file_size() * 8 * 30 / (n_frames() * 1000); + EXPECT_LE(cq_actual_bitrate, kCQTargetBitrate); + EXPECT_LE(cq_actual_bitrate, prev_actual_bitrate); + prev_actual_bitrate = cq_actual_bitrate; + + // try targeting the approximate same bitrate with VBR mode + cfg_.rc_end_usage = VPX_VBR; + cfg_.rc_target_bitrate = cq_actual_bitrate; + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + const double vbr_psnr_lin = GetLinearPSNROverBitrate(); + EXPECT_GE(cq_psnr_lin, vbr_psnr_lin); +} + +INSTANTIATE_TEST_CASE_P(CQLevelRange, CQTest, + ::testing::Range(kCQLevelMin, kCQLevelMax, + kCQLevelStep)); +} // namespace diff --git a/test/test.mk b/test/test.mk index 0dfbdbe..fc4fa07 100644 --- a/test/test.mk +++ b/test/test.mk @@ -10,6 +10,7 @@ LIBVPX_TEST_SRCS-yes += util.h ## LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += altref_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += config_test.cc +LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += cq_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += encode_test_driver.cc LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += encode_test_driver.h LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += i420_video_source.h