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
diff --git a/test/encode_test_driver.cc b/test/encode_test_driver.cc
index 25e38bb..92849ba 100644
--- a/test/encode_test_driver.cc
+++ b/test/encode_test_driver.cc
@@ -152,17 +152,19 @@
#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 0000000..f9b9681
--- /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 281928c..f670513 100644
--- a/test/test.cmake
+++ b/test/test.cmake
@@ -101,6 +101,12 @@
"${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}