blob: 992a2fda6b60b01600dc0ea21052de29587900cb [file] [log] [blame]
Yaowu Xu988f27b2016-02-09 10:35:15 -08001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xu988f27b2016-02-09 10:35:15 -08003 *
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07004 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Johann123e8a62017-12-28 14:40:49 -080010 */
Yaowu Xu988f27b2016-02-09 10:35:15 -080011
12#include <math.h>
13#include <stdlib.h>
14#include <new>
15
Tom Finegan7a07ece2017-02-07 17:14:05 -080016#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
Yaowu Xu988f27b2016-02-09 10:35:15 -080017#include "test/acm_random.h"
18#include "test/util.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070019#include "./aom_config.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070020#include "aom_dsp/psnr.h"
21#include "aom_dsp/ssim.h"
22#include "aom_ports/mem.h"
23#include "aom_ports/msvc.h"
24#include "aom_scale/yv12config.h"
Yaowu Xu988f27b2016-02-09 10:35:15 -080025
Yaowu Xuc27fc142016-08-22 16:08:15 -070026using libaom_test::ACMRandom;
Yaowu Xu988f27b2016-02-09 10:35:15 -080027
28namespace {
29
30typedef double (*LBDMetricFunc)(const YV12_BUFFER_CONFIG *source,
Yaowu Xuc0874f22016-02-05 11:30:12 -080031 const YV12_BUFFER_CONFIG *dest);
Yaowu Xu988f27b2016-02-09 10:35:15 -080032typedef double (*HBDMetricFunc)(const YV12_BUFFER_CONFIG *source,
clang-format3a826f12016-08-11 17:46:05 -070033 const YV12_BUFFER_CONFIG *dest, uint32_t in_bd,
34 uint32_t bd);
Yaowu Xuc0874f22016-02-05 11:30:12 -080035
Yaowu Xu9fb593d2016-02-17 12:38:54 -080036double compute_hbd_psnr(const YV12_BUFFER_CONFIG *source,
clang-format3a826f12016-08-11 17:46:05 -070037 const YV12_BUFFER_CONFIG *dest, uint32_t in_bd,
38 uint32_t bd) {
Yaowu Xu9fb593d2016-02-17 12:38:54 -080039 PSNR_STATS psnr;
Yaowu Xuf883b422016-08-30 14:01:10 -070040 aom_calc_highbd_psnr(source, dest, &psnr, bd, in_bd);
Yaowu Xu9fb593d2016-02-17 12:38:54 -080041 return psnr.psnr[0];
42}
43
44double compute_psnr(const YV12_BUFFER_CONFIG *source,
clang-format3a826f12016-08-11 17:46:05 -070045 const YV12_BUFFER_CONFIG *dest) {
Yaowu Xu9fb593d2016-02-17 12:38:54 -080046 PSNR_STATS psnr;
Yaowu Xuf883b422016-08-30 14:01:10 -070047 aom_calc_psnr(source, dest, &psnr);
Yaowu Xu9fb593d2016-02-17 12:38:54 -080048 return psnr.psnr[0];
49}
Yaowu Xubb8ca082016-02-05 13:03:47 -080050
51double compute_hbd_psnrhvs(const YV12_BUFFER_CONFIG *source,
clang-format3a826f12016-08-11 17:46:05 -070052 const YV12_BUFFER_CONFIG *dest, uint32_t in_bd,
53 uint32_t bd) {
Yaowu Xubb8ca082016-02-05 13:03:47 -080054 double tempy, tempu, tempv;
Yaowu Xuf883b422016-08-30 14:01:10 -070055 return aom_psnrhvs(source, dest, &tempy, &tempu, &tempv, bd, in_bd);
Yaowu Xubb8ca082016-02-05 13:03:47 -080056}
57
58double compute_psnrhvs(const YV12_BUFFER_CONFIG *source,
clang-format3a826f12016-08-11 17:46:05 -070059 const YV12_BUFFER_CONFIG *dest) {
Yaowu Xubb8ca082016-02-05 13:03:47 -080060 double tempy, tempu, tempv;
Yaowu Xuf883b422016-08-30 14:01:10 -070061 return aom_psnrhvs(source, dest, &tempy, &tempu, &tempv, 8, 8);
Yaowu Xubb8ca082016-02-05 13:03:47 -080062}
63
Yaowu Xuc0874f22016-02-05 11:30:12 -080064double compute_hbd_fastssim(const YV12_BUFFER_CONFIG *source,
clang-format3a826f12016-08-11 17:46:05 -070065 const YV12_BUFFER_CONFIG *dest, uint32_t in_bd,
66 uint32_t bd) {
Yaowu Xuc0874f22016-02-05 11:30:12 -080067 double tempy, tempu, tempv;
Yaowu Xuf883b422016-08-30 14:01:10 -070068 return aom_calc_fastssim(source, dest, &tempy, &tempu, &tempv, bd, in_bd);
Yaowu Xuc0874f22016-02-05 11:30:12 -080069}
70
71double compute_fastssim(const YV12_BUFFER_CONFIG *source,
72 const YV12_BUFFER_CONFIG *dest) {
73 double tempy, tempu, tempv;
Yaowu Xuf883b422016-08-30 14:01:10 -070074 return aom_calc_fastssim(source, dest, &tempy, &tempu, &tempv, 8, 8);
Yaowu Xuc0874f22016-02-05 11:30:12 -080075}
76
Yaowu Xuf883b422016-08-30 14:01:10 -070077double compute_hbd_aomssim(const YV12_BUFFER_CONFIG *source,
clang-format3a826f12016-08-11 17:46:05 -070078 const YV12_BUFFER_CONFIG *dest, uint32_t in_bd,
79 uint32_t bd) {
Yaowu Xuc0874f22016-02-05 11:30:12 -080080 double ssim, weight;
Yaowu Xuf883b422016-08-30 14:01:10 -070081 ssim = aom_highbd_calc_ssim(source, dest, &weight, bd, in_bd);
Yaowu Xuc0874f22016-02-05 11:30:12 -080082 return 100 * pow(ssim / weight, 8.0);
83}
84
Yaowu Xuf883b422016-08-30 14:01:10 -070085double compute_aomssim(const YV12_BUFFER_CONFIG *source,
clang-format3a826f12016-08-11 17:46:05 -070086 const YV12_BUFFER_CONFIG *dest) {
Yaowu Xuc0874f22016-02-05 11:30:12 -080087 double ssim, weight;
Yaowu Xuf883b422016-08-30 14:01:10 -070088 ssim = aom_calc_ssim(source, dest, &weight);
Yaowu Xuc0874f22016-02-05 11:30:12 -080089 return 100 * pow(ssim / weight, 8.0);
90}
Yaowu Xu988f27b2016-02-09 10:35:15 -080091
92class HBDMetricsTestBase {
93 public:
94 virtual ~HBDMetricsTestBase() {}
95
96 protected:
97 void RunAccuracyCheck() {
98 const int width = 1920;
99 const int height = 1080;
Yunqing Wanga722a112016-08-30 11:48:44 -0700100 size_t i = 0;
Yaowu Xu988f27b2016-02-09 10:35:15 -0800101 const uint8_t kPixFiller = 128;
102 YV12_BUFFER_CONFIG lbd_src, lbd_dst;
103 YV12_BUFFER_CONFIG hbd_src, hbd_dst;
104 ACMRandom rnd(ACMRandom::DeterministicSeed());
Yaowu Xuc0874f22016-02-05 11:30:12 -0800105 double lbd_db, hbd_db;
Yaowu Xu988f27b2016-02-09 10:35:15 -0800106
107 memset(&lbd_src, 0, sizeof(lbd_src));
108 memset(&lbd_dst, 0, sizeof(lbd_dst));
109 memset(&hbd_src, 0, sizeof(hbd_src));
110 memset(&hbd_dst, 0, sizeof(hbd_dst));
111
Yaowu Xuf883b422016-08-30 14:01:10 -0700112 aom_alloc_frame_buffer(&lbd_src, width, height, 1, 1, 0, 32, 16);
113 aom_alloc_frame_buffer(&lbd_dst, width, height, 1, 1, 0, 32, 16);
114 aom_alloc_frame_buffer(&hbd_src, width, height, 1, 1, 1, 32, 16);
115 aom_alloc_frame_buffer(&hbd_dst, width, height, 1, 1, 1, 32, 16);
Yaowu Xu988f27b2016-02-09 10:35:15 -0800116
117 memset(lbd_src.buffer_alloc, kPixFiller, lbd_src.buffer_alloc_sz);
118 while (i < lbd_src.buffer_alloc_sz) {
119 uint16_t spel, dpel;
120 spel = lbd_src.buffer_alloc[i];
121 // Create some distortion for dst buffer.
Yaowu Xuc0874f22016-02-05 11:30:12 -0800122 dpel = rnd.Rand8();
123 lbd_dst.buffer_alloc[i] = (uint8_t)dpel;
clang-format3a826f12016-08-11 17:46:05 -0700124 ((uint16_t *)(hbd_src.buffer_alloc))[i] = spel << (bit_depth_ - 8);
125 ((uint16_t *)(hbd_dst.buffer_alloc))[i] = dpel << (bit_depth_ - 8);
Yaowu Xu988f27b2016-02-09 10:35:15 -0800126 i++;
127 }
128
Yaowu Xuc0874f22016-02-05 11:30:12 -0800129 lbd_db = lbd_metric_(&lbd_src, &lbd_dst);
Yaowu Xuf6a7b172016-02-20 21:13:11 -0800130 hbd_db = hbd_metric_(&hbd_src, &hbd_dst, input_bit_depth_, bit_depth_);
Yaowu Xubb8ca082016-02-05 13:03:47 -0800131 EXPECT_LE(fabs(lbd_db - hbd_db), threshold_);
Yaowu Xu988f27b2016-02-09 10:35:15 -0800132
Yaowu Xubb8ca082016-02-05 13:03:47 -0800133 i = 0;
134 while (i < lbd_src.buffer_alloc_sz) {
135 uint16_t dpel;
136 // Create some small distortion for dst buffer.
137 dpel = 120 + (rnd.Rand8() >> 4);
138 lbd_dst.buffer_alloc[i] = (uint8_t)dpel;
clang-format3a826f12016-08-11 17:46:05 -0700139 ((uint16_t *)(hbd_dst.buffer_alloc))[i] = dpel << (bit_depth_ - 8);
Yaowu Xubb8ca082016-02-05 13:03:47 -0800140 i++;
141 }
142
143 lbd_db = lbd_metric_(&lbd_src, &lbd_dst);
Yaowu Xuf6a7b172016-02-20 21:13:11 -0800144 hbd_db = hbd_metric_(&hbd_src, &hbd_dst, input_bit_depth_, bit_depth_);
Yaowu Xubb8ca082016-02-05 13:03:47 -0800145 EXPECT_LE(fabs(lbd_db - hbd_db), threshold_);
146
147 i = 0;
148 while (i < lbd_src.buffer_alloc_sz) {
149 uint16_t dpel;
150 // Create some small distortion for dst buffer.
151 dpel = 126 + (rnd.Rand8() >> 6);
152 lbd_dst.buffer_alloc[i] = (uint8_t)dpel;
clang-format3a826f12016-08-11 17:46:05 -0700153 ((uint16_t *)(hbd_dst.buffer_alloc))[i] = dpel << (bit_depth_ - 8);
Yaowu Xubb8ca082016-02-05 13:03:47 -0800154 i++;
155 }
156
157 lbd_db = lbd_metric_(&lbd_src, &lbd_dst);
Yaowu Xuf6a7b172016-02-20 21:13:11 -0800158 hbd_db = hbd_metric_(&hbd_src, &hbd_dst, input_bit_depth_, bit_depth_);
Yaowu Xubb8ca082016-02-05 13:03:47 -0800159 EXPECT_LE(fabs(lbd_db - hbd_db), threshold_);
Yaowu Xu988f27b2016-02-09 10:35:15 -0800160
Yaowu Xuf883b422016-08-30 14:01:10 -0700161 aom_free_frame_buffer(&lbd_src);
162 aom_free_frame_buffer(&lbd_dst);
163 aom_free_frame_buffer(&hbd_src);
164 aom_free_frame_buffer(&hbd_dst);
Yaowu Xu988f27b2016-02-09 10:35:15 -0800165 }
166
Yaowu Xuf6a7b172016-02-20 21:13:11 -0800167 int input_bit_depth_;
Yaowu Xu988f27b2016-02-09 10:35:15 -0800168 int bit_depth_;
169 double threshold_;
170 LBDMetricFunc lbd_metric_;
171 HBDMetricFunc hbd_metric_;
172};
173
clang-format3a826f12016-08-11 17:46:05 -0700174typedef std::tr1::tuple<LBDMetricFunc, HBDMetricFunc, int, int, double>
175 MetricTestTParam;
176class HBDMetricsTest : public HBDMetricsTestBase,
177 public ::testing::TestWithParam<MetricTestTParam> {
Yaowu Xu988f27b2016-02-09 10:35:15 -0800178 public:
179 virtual void SetUp() {
180 lbd_metric_ = GET_PARAM(0);
181 hbd_metric_ = GET_PARAM(1);
Yaowu Xuf6a7b172016-02-20 21:13:11 -0800182 input_bit_depth_ = GET_PARAM(2);
183 bit_depth_ = GET_PARAM(3);
184 threshold_ = GET_PARAM(4);
Yaowu Xu988f27b2016-02-09 10:35:15 -0800185 }
186 virtual void TearDown() {}
187};
188
clang-format3a826f12016-08-11 17:46:05 -0700189TEST_P(HBDMetricsTest, RunAccuracyCheck) { RunAccuracyCheck(); }
Yaowu Xu988f27b2016-02-09 10:35:15 -0800190
191// Allow small variation due to floating point operations.
192static const double kSsim_thresh = 0.001;
Yaowu Xubb8ca082016-02-05 13:03:47 -0800193// Allow some additional errors accumulated in floating point operations.
194static const double kFSsim_thresh = 0.03;
195// Allow some extra variation due to rounding error accumulated in dct.
196static const double kPhvs_thresh = 0.3;
Yaowu Xu988f27b2016-02-09 10:35:15 -0800197
198INSTANTIATE_TEST_CASE_P(
Yaowu Xuf883b422016-08-30 14:01:10 -0700199 AOMSSIM, HBDMetricsTest,
200 ::testing::Values(MetricTestTParam(&compute_aomssim, &compute_hbd_aomssim,
clang-format3a826f12016-08-11 17:46:05 -0700201 8, 10, kSsim_thresh),
Yaowu Xuf883b422016-08-30 14:01:10 -0700202 MetricTestTParam(&compute_aomssim, &compute_hbd_aomssim,
clang-format3a826f12016-08-11 17:46:05 -0700203 10, 10, kPhvs_thresh),
Yaowu Xuf883b422016-08-30 14:01:10 -0700204 MetricTestTParam(&compute_aomssim, &compute_hbd_aomssim,
clang-format3a826f12016-08-11 17:46:05 -0700205 8, 12, kSsim_thresh),
Yaowu Xuf883b422016-08-30 14:01:10 -0700206 MetricTestTParam(&compute_aomssim, &compute_hbd_aomssim,
clang-format3a826f12016-08-11 17:46:05 -0700207 12, 12, kPhvs_thresh)));
Yaowu Xuc0874f22016-02-05 11:30:12 -0800208INSTANTIATE_TEST_CASE_P(
209 FASTSSIM, HBDMetricsTest,
clang-format3a826f12016-08-11 17:46:05 -0700210 ::testing::Values(MetricTestTParam(&compute_fastssim, &compute_hbd_fastssim,
211 8, 10, kFSsim_thresh),
212 MetricTestTParam(&compute_fastssim, &compute_hbd_fastssim,
213 10, 10, kFSsim_thresh),
214 MetricTestTParam(&compute_fastssim, &compute_hbd_fastssim,
215 8, 12, kFSsim_thresh),
216 MetricTestTParam(&compute_fastssim, &compute_hbd_fastssim,
217 12, 12, kFSsim_thresh)));
Yaowu Xubb8ca082016-02-05 13:03:47 -0800218INSTANTIATE_TEST_CASE_P(
219 PSNRHVS, HBDMetricsTest,
clang-format3a826f12016-08-11 17:46:05 -0700220 ::testing::Values(MetricTestTParam(&compute_psnrhvs, &compute_hbd_psnrhvs,
221 8, 10, kPhvs_thresh),
222 MetricTestTParam(&compute_psnrhvs, &compute_hbd_psnrhvs,
223 10, 10, kPhvs_thresh),
224 MetricTestTParam(&compute_psnrhvs, &compute_hbd_psnrhvs,
225 8, 12, kPhvs_thresh),
226 MetricTestTParam(&compute_psnrhvs, &compute_hbd_psnrhvs,
227 12, 12, kPhvs_thresh)));
Yaowu Xu9fb593d2016-02-17 12:38:54 -0800228INSTANTIATE_TEST_CASE_P(
229 PSNR, HBDMetricsTest,
230 ::testing::Values(
clang-format3a826f12016-08-11 17:46:05 -0700231 MetricTestTParam(&compute_psnr, &compute_hbd_psnr, 8, 10, kPhvs_thresh),
Yaowu Xuf6a7b172016-02-20 21:13:11 -0800232 MetricTestTParam(&compute_psnr, &compute_hbd_psnr, 10, 10,
233 kPhvs_thresh),
clang-format3a826f12016-08-11 17:46:05 -0700234 MetricTestTParam(&compute_psnr, &compute_hbd_psnr, 8, 12, kPhvs_thresh),
Yaowu Xuf6a7b172016-02-20 21:13:11 -0800235 MetricTestTParam(&compute_psnr, &compute_hbd_psnr, 12, 12,
Yaowu Xu9fb593d2016-02-17 12:38:54 -0800236 kPhvs_thresh)));
Yaowu Xu988f27b2016-02-09 10:35:15 -0800237} // namespace