From 26ac047896dc80fca73bd3d79296f08a70efd070 Mon Sep 17 00:00:00 2001 From: Imdad Sardharwalla <imdad.sardharwalla@argondesign.com> Date: Thu, 18 Jan 2018 15:00:24 +0000 Subject: [PATCH] Added a test for monochrome encoding. The test encodes 5 frames of a video using the --monochrome flag and verifies that the decoded frames satisfy: - each frame's monochrome flag is set to 1 - each frame's U and V planes are set to a constant, and this constant is the same for all decoded frames - the initial frame's Y PSNR value is 'high enough' - the Y PSNR values remain fairly constant across all of the frames Change-Id: I4239ddfb745ed9746547737b4bc99963c71e51c0 --- test/encode_test_driver.cc | 8 ++- test/monochrome_test.cc | 130 +++++++++++++++++++++++++++++++++++++ test/test.cmake | 6 ++ 3 files changed, 141 insertions(+), 3 deletions(-) create mode 100644 test/monochrome_test.cc diff --git a/test/encode_test_driver.cc b/test/encode_test_driver.cc index 25e38bb141..92849ba4ef 100644 --- a/test/encode_test_driver.cc +++ b/test/encode_test_driver.cc @@ -152,17 +152,19 @@ static bool compare_img(const aom_image_t *img1, const aom_image_t *img2, #if CONFIG_CICP if (img1->fmt != img2->fmt || img1->cp != img2->cp || img1->tc != img2->tc || img1->mc != img2->mc || img1->d_w != img2->d_w || - img1->d_h != img2->d_h) { + img1->d_h != img2->d_h || img1->monochrome != img2->monochrome) { #else if (img1->fmt != img2->fmt || img1->cs != img2->cs || - img1->d_w != img2->d_w || img1->d_h != img2->d_h) { + img1->d_w != img2->d_w || img1->d_h != img2->d_h || + img1->monochrome != img2->monochrome) { #endif if (mismatch_row != NULL) *mismatch_row = -1; if (mismatch_col != NULL) *mismatch_col = -1; return false; } - for (int plane = 0; plane < 3; plane++) { + const int num_planes = img1->monochrome ? 1 : 3; + for (int plane = 0; plane < num_planes; plane++) { if (!compare_plane(img1->planes[plane], img1->stride[plane], img2->planes[plane], img2->stride[plane], aom_img_plane_width(img1, plane), diff --git a/test/monochrome_test.cc b/test/monochrome_test.cc new file mode 100644 index 0000000000..f9b9681ac2 --- /dev/null +++ b/test/monochrome_test.cc @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2016, Alliance for Open Media. All rights reserved + * + * This source code is subject to the terms of the BSD 2 Clause License and + * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License + * was not distributed with this source code in the LICENSE file, you can + * obtain it at www.aomedia.org/license/software. If the Alliance for Open + * Media Patent License 1.0 was not distributed with this source code in the + * PATENTS file, you can obtain it at www.aomedia.org/license/patent. +*/ + +#include <climits> +#include <vector> +#include "third_party/googletest/src/googletest/include/gtest/gtest.h" +#include "test/codec_factory.h" +#include "test/encode_test_driver.h" +#include "test/i420_video_source.h" +#include "test/video_source.h" +#include "test/util.h" + +namespace { + +class MonochromeTest + : public ::libaom_test::CodecTestWithParam<libaom_test::TestMode>, + public ::libaom_test::EncoderTest { + protected: + MonochromeTest() : EncoderTest(GET_PARAM(0)), frame0_psnr_y_(0.) {} + + virtual ~MonochromeTest() {} + + virtual void SetUp() { + InitializeConfig(); + SetMode(GET_PARAM(1)); + } + + virtual void DecompressedFrameHook(const aom_image_t &img, + aom_codec_pts_t pts) { + (void)pts; + + // Get value of top-left corner pixel of U plane + int chroma_value = img.planes[AOM_PLANE_U][0]; + + bool is_chroma_constant = + ComparePlaneToValue(img, AOM_PLANE_U, chroma_value) && + ComparePlaneToValue(img, AOM_PLANE_V, chroma_value); + + // Chroma planes should be constant + EXPECT_TRUE(is_chroma_constant); + + // Monochrome flag on image should be set + EXPECT_EQ(img.monochrome, 1); + + chroma_value_list_.push_back(chroma_value); + } + + // Returns true if all pixels on the plane are equal to value, and returns + // false otherwise. + bool ComparePlaneToValue(const aom_image_t &img, const int plane, + const int value) { + const int w = aom_img_plane_width(&img, plane); + const int h = aom_img_plane_height(&img, plane); + const uint8_t *const buf = img.planes[plane]; + const int stride = img.stride[plane]; + + for (int r = 0; r < h; ++r) { + for (int c = 0; c < w; ++c) { + if (buf[r * stride + c] != value) return false; + } + } + return true; + } + + virtual void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) { + // Check that the initial Y PSNR value is 'high enough', and check that + // subsequent Y PSNR values are 'close' to this initial value. + if (frame0_psnr_y_ == 0.) { + frame0_psnr_y_ = pkt->data.psnr.psnr[1]; + EXPECT_GT(frame0_psnr_y_, 29.); + } + EXPECT_NEAR(pkt->data.psnr.psnr[1], frame0_psnr_y_, 2.5); + } + + std::vector<int> chroma_value_list_; + double frame0_psnr_y_; +}; + +TEST_P(MonochromeTest, TestMonochromeEncoding) { + ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, + 30, 1, 0, 5); + + init_flags_ = AOM_CODEC_USE_PSNR; + + cfg_.g_w = 352; + cfg_.g_h = 288; + + cfg_.rc_buf_initial_sz = 500; + cfg_.rc_buf_optimal_sz = 600; + cfg_.rc_buf_sz = 1000; + cfg_.rc_min_quantizer = 2; + cfg_.rc_max_quantizer = 56; + cfg_.rc_undershoot_pct = 50; + cfg_.rc_overshoot_pct = 50; + cfg_.rc_end_usage = AOM_CBR; + cfg_.kf_mode = AOM_KF_AUTO; + cfg_.g_lag_in_frames = 1; + cfg_.kf_min_dist = cfg_.kf_max_dist = 3000; + // Enable dropped frames. + cfg_.rc_dropframe_thresh = 1; + // Disable error_resilience mode. + cfg_.g_error_resilient = 0; + // Run at low bitrate. + cfg_.rc_target_bitrate = 40; + // Set monochrome encoding flag + cfg_.monochrome = 1; + + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + + // Check that the chroma planes are equal across all frames + std::vector<int>::const_iterator iter = chroma_value_list_.begin(); + int initial_chroma_value = *iter; + for (; iter != chroma_value_list_.end(); ++iter) { + // Check that all decoded frames have the same constant chroma planes. + EXPECT_EQ(*iter, initial_chroma_value); + } +} + +AV1_INSTANTIATE_TEST_CASE(MonochromeTest, + ::testing::Values(::libaom_test::kTwoPassGood)); + +} // namespace diff --git a/test/test.cmake b/test/test.cmake index 281928ccde..f67051318e 100644 --- a/test/test.cmake +++ b/test/test.cmake @@ -101,6 +101,12 @@ set(AOM_UNIT_TEST_ENCODER_SOURCES "${AOM_ROOT}/test/y4m_video_source.h" "${AOM_ROOT}/test/yuv_video_source.h") +if (CONFIG_MONO_VIDEO) + set(AOM_UNIT_TEST_ENCODER_SOURCES + ${AOM_UNIT_TEST_ENCODER_SOURCES} + "${AOM_ROOT}/test/monochrome_test.cc") +endif () + if (NOT BUILD_SHARED_LIBS) set(AOM_UNIT_TEST_ENCODER_SOURCES ${AOM_UNIT_TEST_ENCODER_SOURCES} -- GitLab