191037db265ecdd914a26e056cf69207b4f50924ehkuang/*
22ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian *  Copyright (c) 2013 The WebM project authors. All Rights Reserved.
32ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian *
42ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian *  Use of this source code is governed by a BSD-style license
52ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian *  that can be found in the LICENSE file in the root of the source
62ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian *  tree. An additional intellectual property rights grant can be found
72ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian *  in the file PATENTS.  All contributing project authors may
82ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian *  be found in the AUTHORS file in the root of the source tree.
92ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian */
107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
1191037db265ecdd914a26e056cf69207b4f50924ehkuang#include "third_party/googletest/src/include/gtest/gtest.h"
127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#include "./vpx_config.h"
1491037db265ecdd914a26e056cf69207b4f50924ehkuang#include "test/codec_factory.h"
1591037db265ecdd914a26e056cf69207b4f50924ehkuang#include "test/encode_test_driver.h"
1691037db265ecdd914a26e056cf69207b4f50924ehkuang#include "test/i420_video_source.h"
1791037db265ecdd914a26e056cf69207b4f50924ehkuang#include "test/util.h"
182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "test/y4m_video_source.h"
1991037db265ecdd914a26e056cf69207b4f50924ehkuang
2091037db265ecdd914a26e056cf69207b4f50924ehkuangnamespace {
2191037db265ecdd914a26e056cf69207b4f50924ehkuang
2291037db265ecdd914a26e056cf69207b4f50924ehkuangconst int kMaxPsnr = 100;
2391037db265ecdd914a26e056cf69207b4f50924ehkuang
247bc9febe8749e98a3812a0dc4380ceae75c29450Johannclass LosslessTest
257bc9febe8749e98a3812a0dc4380ceae75c29450Johann    : public ::libvpx_test::EncoderTest,
267bc9febe8749e98a3812a0dc4380ceae75c29450Johann      public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
2791037db265ecdd914a26e056cf69207b4f50924ehkuang protected:
287ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  LosslessTest()
297bc9febe8749e98a3812a0dc4380ceae75c29450Johann      : EncoderTest(GET_PARAM(0)), psnr_(kMaxPsnr), nframes_(0),
307bc9febe8749e98a3812a0dc4380ceae75c29450Johann        encoding_mode_(GET_PARAM(1)) {}
3191037db265ecdd914a26e056cf69207b4f50924ehkuang
327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  virtual ~LosslessTest() {}
3391037db265ecdd914a26e056cf69207b4f50924ehkuang
3491037db265ecdd914a26e056cf69207b4f50924ehkuang  virtual void SetUp() {
3591037db265ecdd914a26e056cf69207b4f50924ehkuang    InitializeConfig();
3691037db265ecdd914a26e056cf69207b4f50924ehkuang    SetMode(encoding_mode_);
3791037db265ecdd914a26e056cf69207b4f50924ehkuang  }
3891037db265ecdd914a26e056cf69207b4f50924ehkuang
39ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
40ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                                  ::libvpx_test::Encoder *encoder) {
41ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (video->frame() == 1) {
42ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      // Only call Control if quantizer > 0 to verify that using quantizer
43ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      // alone will activate lossless
44ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      if (cfg_.rc_max_quantizer > 0 || cfg_.rc_min_quantizer > 0) {
45ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        encoder->Control(VP9E_SET_LOSSLESS, 1);
46ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      }
47ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
48ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
49ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
5091037db265ecdd914a26e056cf69207b4f50924ehkuang  virtual void BeginPassHook(unsigned int /*pass*/) {
519b35249446b07f40ac5fcc3205f2c048616efacchkuang    psnr_ = kMaxPsnr;
5291037db265ecdd914a26e056cf69207b4f50924ehkuang    nframes_ = 0;
5391037db265ecdd914a26e056cf69207b4f50924ehkuang  }
5491037db265ecdd914a26e056cf69207b4f50924ehkuang
5591037db265ecdd914a26e056cf69207b4f50924ehkuang  virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
567bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (pkt->data.psnr.psnr[0] < psnr_) psnr_ = pkt->data.psnr.psnr[0];
5791037db265ecdd914a26e056cf69207b4f50924ehkuang  }
5891037db265ecdd914a26e056cf69207b4f50924ehkuang
597bc9febe8749e98a3812a0dc4380ceae75c29450Johann  double GetMinPsnr() const { return psnr_; }
6091037db265ecdd914a26e056cf69207b4f50924ehkuang
6191037db265ecdd914a26e056cf69207b4f50924ehkuang private:
6291037db265ecdd914a26e056cf69207b4f50924ehkuang  double psnr_;
6391037db265ecdd914a26e056cf69207b4f50924ehkuang  unsigned int nframes_;
6491037db265ecdd914a26e056cf69207b4f50924ehkuang  libvpx_test::TestMode encoding_mode_;
6591037db265ecdd914a26e056cf69207b4f50924ehkuang};
6691037db265ecdd914a26e056cf69207b4f50924ehkuang
677ce0a1d1337c01056ba24006efab21f00e179e04Vignesh VenkatasubramanianTEST_P(LosslessTest, TestLossLessEncoding) {
6891037db265ecdd914a26e056cf69207b4f50924ehkuang  const vpx_rational timebase = { 33333333, 1000000000 };
6991037db265ecdd914a26e056cf69207b4f50924ehkuang  cfg_.g_timebase = timebase;
7091037db265ecdd914a26e056cf69207b4f50924ehkuang  cfg_.rc_target_bitrate = 2000;
7191037db265ecdd914a26e056cf69207b4f50924ehkuang  cfg_.g_lag_in_frames = 25;
7291037db265ecdd914a26e056cf69207b4f50924ehkuang  cfg_.rc_min_quantizer = 0;
7391037db265ecdd914a26e056cf69207b4f50924ehkuang  cfg_.rc_max_quantizer = 0;
7491037db265ecdd914a26e056cf69207b4f50924ehkuang
7591037db265ecdd914a26e056cf69207b4f50924ehkuang  init_flags_ = VPX_CODEC_USE_PSNR;
7691037db265ecdd914a26e056cf69207b4f50924ehkuang
7791037db265ecdd914a26e056cf69207b4f50924ehkuang  // intentionally changed the dimension for better testing coverage
789b35249446b07f40ac5fcc3205f2c048616efacchkuang  libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                                     timebase.den, timebase.num, 0, 10);
802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  const double psnr_lossless = GetMinPsnr();
822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  EXPECT_GE(psnr_lossless, kMaxPsnr);
832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
857ce0a1d1337c01056ba24006efab21f00e179e04Vignesh VenkatasubramanianTEST_P(LosslessTest, TestLossLessEncoding444) {
862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  libvpx_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 10);
872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  cfg_.g_profile = 1;
892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  cfg_.g_timebase = video.timebase();
902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  cfg_.rc_target_bitrate = 2000;
912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  cfg_.g_lag_in_frames = 25;
922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  cfg_.rc_min_quantizer = 0;
932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  cfg_.rc_max_quantizer = 0;
942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  init_flags_ = VPX_CODEC_USE_PSNR;
962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
979b35249446b07f40ac5fcc3205f2c048616efacchkuang  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
9891037db265ecdd914a26e056cf69207b4f50924ehkuang  const double psnr_lossless = GetMinPsnr();
9991037db265ecdd914a26e056cf69207b4f50924ehkuang  EXPECT_GE(psnr_lossless, kMaxPsnr);
10091037db265ecdd914a26e056cf69207b4f50924ehkuang}
1012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
1027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh VenkatasubramanianTEST_P(LosslessTest, TestLossLessEncodingCtrl) {
103ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const vpx_rational timebase = { 33333333, 1000000000 };
104ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  cfg_.g_timebase = timebase;
105ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  cfg_.rc_target_bitrate = 2000;
106ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  cfg_.g_lag_in_frames = 25;
107ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  // Intentionally set Q > 0, to make sure control can be used to activate
108ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  // lossless
109ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  cfg_.rc_min_quantizer = 10;
110ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  cfg_.rc_max_quantizer = 20;
111ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
112ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  init_flags_ = VPX_CODEC_USE_PSNR;
113ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
114ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
115ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                                     timebase.den, timebase.num, 0, 10);
116ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
117ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const double psnr_lossless = GetMinPsnr();
118ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  EXPECT_GE(psnr_lossless, kMaxPsnr);
119ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
120ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh VenkatasubramanianVP9_INSTANTIATE_TEST_CASE(LosslessTest,
1227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                          ::testing::Values(::libvpx_test::kRealTime,
1237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                                            ::libvpx_test::kOnePassGood,
1247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                                            ::libvpx_test::kTwoPassGood));
12591037db265ecdd914a26e056cf69207b4f50924ehkuang}  // namespace
126