blob: fa9cfc158d599013fd4228de0eb61ef59c639d86 [file] [log] [blame]
Yaowu Xu988f27b2016-02-09 10:35:15 -08001/*
2 * Copyright (c) 2016 The WebM project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include <math.h>
12#include <stdlib.h>
13#include <new>
14
15#include "third_party/googletest/src/include/gtest/gtest.h"
16#include "test/acm_random.h"
17#include "test/util.h"
18#include "./vpx_config.h"
19#include "vpx_dsp/ssim.h"
20#include "vpx_ports/mem.h"
21#include "vpx_ports/msvc.h"
22#include "vpx_scale/yv12config.h"
23
24
25using libvpx_test::ACMRandom;
26
27namespace {
28
29typedef double (*LBDMetricFunc)(const YV12_BUFFER_CONFIG *source,
Yaowu Xuc0874f22016-02-05 11:30:12 -080030 const YV12_BUFFER_CONFIG *dest);
Yaowu Xu988f27b2016-02-09 10:35:15 -080031typedef double (*HBDMetricFunc)(const YV12_BUFFER_CONFIG *source,
32 const YV12_BUFFER_CONFIG *dest,
Yaowu Xuc0874f22016-02-05 11:30:12 -080033 uint32_t bd);
34
35double compute_hbd_fastssim(const YV12_BUFFER_CONFIG *source,
36 const YV12_BUFFER_CONFIG *dest,
37 uint32_t bit_depth) {
38 double tempy, tempu, tempv;
39 return vpx_calc_fastssim(source, dest,
40 &tempy, &tempu, &tempv, bit_depth);
41}
42
43double compute_fastssim(const YV12_BUFFER_CONFIG *source,
44 const YV12_BUFFER_CONFIG *dest) {
45 double tempy, tempu, tempv;
46 return vpx_calc_fastssim(source, dest,
47 &tempy, &tempu, &tempv, 8);
48}
49
50double compute_hbd_vpxssim(const YV12_BUFFER_CONFIG *source,
51 const YV12_BUFFER_CONFIG *dest,
52 uint32_t bit_depth) {
53 double ssim, weight;
54 ssim = vpx_highbd_calc_ssim(source, dest, &weight, bit_depth);
55 return 100 * pow(ssim / weight, 8.0);
56}
57
58double compute_vpxssim(const YV12_BUFFER_CONFIG *source,
59 const YV12_BUFFER_CONFIG *dest) {
60 double ssim, weight;
61 ssim = vpx_calc_ssim(source, dest, &weight);
62 return 100 * pow(ssim / weight, 8.0);
63}
Yaowu Xu988f27b2016-02-09 10:35:15 -080064
65class HBDMetricsTestBase {
66 public:
67 virtual ~HBDMetricsTestBase() {}
68
69 protected:
70 void RunAccuracyCheck() {
71 const int width = 1920;
72 const int height = 1080;
73 int i = 0;
74 const uint8_t kPixFiller = 128;
75 YV12_BUFFER_CONFIG lbd_src, lbd_dst;
76 YV12_BUFFER_CONFIG hbd_src, hbd_dst;
77 ACMRandom rnd(ACMRandom::DeterministicSeed());
Yaowu Xuc0874f22016-02-05 11:30:12 -080078 double lbd_db, hbd_db;
Yaowu Xu988f27b2016-02-09 10:35:15 -080079
80 memset(&lbd_src, 0, sizeof(lbd_src));
81 memset(&lbd_dst, 0, sizeof(lbd_dst));
82 memset(&hbd_src, 0, sizeof(hbd_src));
83 memset(&hbd_dst, 0, sizeof(hbd_dst));
84
85 vpx_alloc_frame_buffer(&lbd_src, width, height, 1, 1, 0, 32, 16);
86 vpx_alloc_frame_buffer(&lbd_dst, width, height, 1, 1, 0, 32, 16);
87 vpx_alloc_frame_buffer(&hbd_src, width, height, 1, 1, 1, 32, 16);
88 vpx_alloc_frame_buffer(&hbd_dst, width, height, 1, 1, 1, 32, 16);
89
90 memset(lbd_src.buffer_alloc, kPixFiller, lbd_src.buffer_alloc_sz);
91 while (i < lbd_src.buffer_alloc_sz) {
92 uint16_t spel, dpel;
93 spel = lbd_src.buffer_alloc[i];
94 // Create some distortion for dst buffer.
Yaowu Xuc0874f22016-02-05 11:30:12 -080095 dpel = rnd.Rand8();
96 lbd_dst.buffer_alloc[i] = (uint8_t)dpel;
Yaowu Xu988f27b2016-02-09 10:35:15 -080097 ((uint16_t*)(hbd_src.buffer_alloc))[i] = spel << (bit_depth_ - 8);
98 ((uint16_t*)(hbd_dst.buffer_alloc))[i] = dpel << (bit_depth_ - 8);
99 i++;
100 }
101
Yaowu Xuc0874f22016-02-05 11:30:12 -0800102 lbd_db = lbd_metric_(&lbd_src, &lbd_dst);
103 hbd_db = hbd_metric_(&hbd_src, &hbd_dst, bit_depth_);
Yaowu Xu988f27b2016-02-09 10:35:15 -0800104
Yaowu Xuc0874f22016-02-05 11:30:12 -0800105 printf("%10f \n", lbd_db);
106 printf("%10f \n", hbd_db);
Yaowu Xu988f27b2016-02-09 10:35:15 -0800107
108 vpx_free_frame_buffer(&lbd_src);
109 vpx_free_frame_buffer(&lbd_dst);
110 vpx_free_frame_buffer(&hbd_src);
111 vpx_free_frame_buffer(&hbd_dst);
112
113 EXPECT_LE(fabs(lbd_db - hbd_db), threshold_);
114 }
115
116 int bit_depth_;
117 double threshold_;
118 LBDMetricFunc lbd_metric_;
119 HBDMetricFunc hbd_metric_;
120};
121
122typedef std::tr1::tuple<LBDMetricFunc,
123 HBDMetricFunc, int, double> MetricTestTParam;
124class HBDMetricsTest
125 : public HBDMetricsTestBase,
126 public ::testing::TestWithParam<MetricTestTParam> {
127 public:
128 virtual void SetUp() {
129 lbd_metric_ = GET_PARAM(0);
130 hbd_metric_ = GET_PARAM(1);
131 bit_depth_ = GET_PARAM(2);
132 threshold_ = GET_PARAM(3);
133 }
134 virtual void TearDown() {}
135};
136
137TEST_P(HBDMetricsTest, RunAccuracyCheck) {
138 RunAccuracyCheck();
139}
140
141// Allow small variation due to floating point operations.
142static const double kSsim_thresh = 0.001;
Yaowu Xuc0874f22016-02-05 11:30:12 -0800143// Allow some variation from accumulated errors in floating point operations.
144static const double kFSsim_thresh = 0.01;
Yaowu Xu988f27b2016-02-09 10:35:15 -0800145
146INSTANTIATE_TEST_CASE_P(
Yaowu Xuc0874f22016-02-05 11:30:12 -0800147 VPXSSIM, HBDMetricsTest,
Yaowu Xu988f27b2016-02-09 10:35:15 -0800148 ::testing::Values(
Yaowu Xuc0874f22016-02-05 11:30:12 -0800149 MetricTestTParam(&compute_vpxssim, &compute_hbd_vpxssim, 10,
Yaowu Xu988f27b2016-02-09 10:35:15 -0800150 kSsim_thresh),
Yaowu Xuc0874f22016-02-05 11:30:12 -0800151 MetricTestTParam(&compute_vpxssim, &compute_hbd_vpxssim, 12,
Yaowu Xu988f27b2016-02-09 10:35:15 -0800152 kSsim_thresh)));
Yaowu Xuc0874f22016-02-05 11:30:12 -0800153INSTANTIATE_TEST_CASE_P(
154 FASTSSIM, HBDMetricsTest,
155 ::testing::Values(
156 MetricTestTParam(&compute_fastssim, &compute_hbd_fastssim, 10,
157 kFSsim_thresh),
158 MetricTestTParam(&compute_fastssim, &compute_hbd_fastssim, 12,
159 kFSsim_thresh)));
Yaowu Xu988f27b2016-02-09 10:35:15 -0800160} // namespace
161