123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- /*
- * 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 <limits.h>
- #include <stdio.h>
- #include <string.h>
- #include <tuple>
- #include "third_party/googletest/src/include/gtest/gtest.h"
- #include "./vpx_config.h"
- #if CONFIG_VP9_ENCODER
- #include "./vp9_rtcd.h"
- #endif
- #include "test/acm_random.h"
- #include "test/clear_system_state.h"
- #include "test/register_state_check.h"
- #include "test/util.h"
- #include "vpx_dsp/ssim.h"
- #include "vpx_mem/vpx_mem.h"
- extern "C" double vpx_get_ssim_metrics(uint8_t *img1, int img1_pitch,
- uint8_t *img2, int img2_pitch, int width,
- int height, Ssimv *sv2, Metrics *m,
- int do_inconsistency);
- using libvpx_test::ACMRandom;
- namespace {
- class ConsistencyTestBase : public ::testing::Test {
- public:
- ConsistencyTestBase(int width, int height) : width_(width), height_(height) {}
- static void SetUpTestCase() {
- source_data_[0] = reinterpret_cast<uint8_t *>(
- vpx_memalign(kDataAlignment, kDataBufferSize));
- reference_data_[0] = reinterpret_cast<uint8_t *>(
- vpx_memalign(kDataAlignment, kDataBufferSize));
- source_data_[1] = reinterpret_cast<uint8_t *>(
- vpx_memalign(kDataAlignment, kDataBufferSize));
- reference_data_[1] = reinterpret_cast<uint8_t *>(
- vpx_memalign(kDataAlignment, kDataBufferSize));
- ssim_array_ = new Ssimv[kDataBufferSize / 16];
- }
- static void ClearSsim() { memset(ssim_array_, 0, kDataBufferSize / 16); }
- static void TearDownTestCase() {
- vpx_free(source_data_[0]);
- source_data_[0] = NULL;
- vpx_free(reference_data_[0]);
- reference_data_[0] = NULL;
- vpx_free(source_data_[1]);
- source_data_[1] = NULL;
- vpx_free(reference_data_[1]);
- reference_data_[1] = NULL;
- delete[] ssim_array_;
- }
- virtual void TearDown() { libvpx_test::ClearSystemState(); }
- protected:
- // Handle frames up to 640x480
- static const int kDataAlignment = 16;
- static const int kDataBufferSize = 640 * 480;
- virtual void SetUp() {
- source_stride_ = (width_ + 31) & ~31;
- reference_stride_ = width_ * 2;
- rnd_.Reset(ACMRandom::DeterministicSeed());
- }
- void FillRandom(uint8_t *data, int stride, int width, int height) {
- for (int h = 0; h < height; ++h) {
- for (int w = 0; w < width; ++w) {
- data[h * stride + w] = rnd_.Rand8();
- }
- }
- }
- void FillRandom(uint8_t *data, int stride) {
- FillRandom(data, stride, width_, height_);
- }
- void Copy(uint8_t *reference, uint8_t *source) {
- memcpy(reference, source, kDataBufferSize);
- }
- void Blur(uint8_t *data, int stride, int taps) {
- int sum = 0;
- int half_taps = taps / 2;
- for (int h = 0; h < height_; ++h) {
- for (int w = 0; w < taps; ++w) {
- sum += data[w + h * stride];
- }
- for (int w = taps; w < width_; ++w) {
- sum += data[w + h * stride] - data[w - taps + h * stride];
- data[w - half_taps + h * stride] = (sum + half_taps) / taps;
- }
- }
- for (int w = 0; w < width_; ++w) {
- for (int h = 0; h < taps; ++h) {
- sum += data[h + w * stride];
- }
- for (int h = taps; h < height_; ++h) {
- sum += data[w + h * stride] - data[(h - taps) * stride + w];
- data[(h - half_taps) * stride + w] = (sum + half_taps) / taps;
- }
- }
- }
- int width_, height_;
- static uint8_t *source_data_[2];
- int source_stride_;
- static uint8_t *reference_data_[2];
- int reference_stride_;
- static Ssimv *ssim_array_;
- Metrics metrics_;
- ACMRandom rnd_;
- };
- #if CONFIG_VP9_ENCODER
- typedef std::tuple<int, int> ConsistencyParam;
- class ConsistencyVP9Test
- : public ConsistencyTestBase,
- public ::testing::WithParamInterface<ConsistencyParam> {
- public:
- ConsistencyVP9Test() : ConsistencyTestBase(GET_PARAM(0), GET_PARAM(1)) {}
- protected:
- double CheckConsistency(int frame) {
- EXPECT_LT(frame, 2) << "Frame to check has to be less than 2.";
- return vpx_get_ssim_metrics(source_data_[frame], source_stride_,
- reference_data_[frame], reference_stride_,
- width_, height_, ssim_array_, &metrics_, 1);
- }
- };
- #endif // CONFIG_VP9_ENCODER
- uint8_t *ConsistencyTestBase::source_data_[2] = { NULL, NULL };
- uint8_t *ConsistencyTestBase::reference_data_[2] = { NULL, NULL };
- Ssimv *ConsistencyTestBase::ssim_array_ = NULL;
- #if CONFIG_VP9_ENCODER
- TEST_P(ConsistencyVP9Test, ConsistencyIsZero) {
- FillRandom(source_data_[0], source_stride_);
- Copy(source_data_[1], source_data_[0]);
- Copy(reference_data_[0], source_data_[0]);
- Blur(reference_data_[0], reference_stride_, 3);
- Copy(reference_data_[1], source_data_[0]);
- Blur(reference_data_[1], reference_stride_, 3);
- double inconsistency = CheckConsistency(1);
- inconsistency = CheckConsistency(0);
- EXPECT_EQ(inconsistency, 0.0)
- << "Should have 0 inconsistency if they are exactly the same.";
- // If sources are not consistent reference frames inconsistency should
- // be less than if the source is consistent.
- FillRandom(source_data_[0], source_stride_);
- FillRandom(source_data_[1], source_stride_);
- FillRandom(reference_data_[0], reference_stride_);
- FillRandom(reference_data_[1], reference_stride_);
- CheckConsistency(0);
- inconsistency = CheckConsistency(1);
- Copy(source_data_[1], source_data_[0]);
- CheckConsistency(0);
- double inconsistency2 = CheckConsistency(1);
- EXPECT_LT(inconsistency, inconsistency2)
- << "Should have less inconsistency if source itself is inconsistent.";
- // Less of a blur should be less inconsistent than more blur coming off a
- // a frame with no blur.
- ClearSsim();
- FillRandom(source_data_[0], source_stride_);
- Copy(source_data_[1], source_data_[0]);
- Copy(reference_data_[0], source_data_[0]);
- Copy(reference_data_[1], source_data_[0]);
- Blur(reference_data_[1], reference_stride_, 4);
- CheckConsistency(0);
- inconsistency = CheckConsistency(1);
- ClearSsim();
- Copy(reference_data_[1], source_data_[0]);
- Blur(reference_data_[1], reference_stride_, 8);
- CheckConsistency(0);
- inconsistency2 = CheckConsistency(1);
- EXPECT_LT(inconsistency, inconsistency2)
- << "Stronger Blur should produce more inconsistency.";
- }
- #endif // CONFIG_VP9_ENCODER
- using std::make_tuple;
- //------------------------------------------------------------------------------
- // C functions
- #if CONFIG_VP9_ENCODER
- const ConsistencyParam c_vp9_tests[] = { make_tuple(320, 240),
- make_tuple(318, 242),
- make_tuple(318, 238) };
- INSTANTIATE_TEST_CASE_P(C, ConsistencyVP9Test,
- ::testing::ValuesIn(c_vp9_tests));
- #endif
- } // namespace
|