2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
4 * 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.
17 #include "third_party/googletest/src/googletest/include/gtest/gtest.h"
18 #include "test/acm_random.h"
19 #include "test/util.h"
21 #include "config/aom_config.h"
23 #include "aom_dsp/psnr.h"
24 #include "aom_dsp/ssim.h"
25 #include "aom_ports/mem.h"
26 #include "aom_ports/msvc.h"
27 #include "aom_scale/yv12config.h"
29 using libaom_test::ACMRandom
;
33 typedef double (*LBDMetricFunc
)(const YV12_BUFFER_CONFIG
*source
,
34 const YV12_BUFFER_CONFIG
*dest
);
35 typedef double (*HBDMetricFunc
)(const YV12_BUFFER_CONFIG
*source
,
36 const YV12_BUFFER_CONFIG
*dest
, uint32_t in_bd
,
39 double compute_hbd_psnr(const YV12_BUFFER_CONFIG
*source
,
40 const YV12_BUFFER_CONFIG
*dest
, uint32_t in_bd
,
43 aom_calc_highbd_psnr(source
, dest
, &psnr
, bd
, in_bd
);
47 double compute_psnr(const YV12_BUFFER_CONFIG
*source
,
48 const YV12_BUFFER_CONFIG
*dest
) {
50 aom_calc_psnr(source
, dest
, &psnr
);
54 double compute_hbd_psnrhvs(const YV12_BUFFER_CONFIG
*source
,
55 const YV12_BUFFER_CONFIG
*dest
, uint32_t in_bd
,
57 double tempy
, tempu
, tempv
;
58 return aom_psnrhvs(source
, dest
, &tempy
, &tempu
, &tempv
, bd
, in_bd
);
61 double compute_psnrhvs(const YV12_BUFFER_CONFIG
*source
,
62 const YV12_BUFFER_CONFIG
*dest
) {
63 double tempy
, tempu
, tempv
;
64 return aom_psnrhvs(source
, dest
, &tempy
, &tempu
, &tempv
, 8, 8);
67 double compute_hbd_fastssim(const YV12_BUFFER_CONFIG
*source
,
68 const YV12_BUFFER_CONFIG
*dest
, uint32_t in_bd
,
70 double tempy
, tempu
, tempv
;
71 return aom_calc_fastssim(source
, dest
, &tempy
, &tempu
, &tempv
, bd
, in_bd
);
74 double compute_fastssim(const YV12_BUFFER_CONFIG
*source
,
75 const YV12_BUFFER_CONFIG
*dest
) {
76 double tempy
, tempu
, tempv
;
77 return aom_calc_fastssim(source
, dest
, &tempy
, &tempu
, &tempv
, 8, 8);
80 double compute_hbd_aomssim(const YV12_BUFFER_CONFIG
*source
,
81 const YV12_BUFFER_CONFIG
*dest
, uint32_t in_bd
,
83 double ssim
[2], weight
[2];
84 aom_highbd_calc_ssim(source
, dest
, weight
, bd
, in_bd
, ssim
);
85 return 100 * pow(ssim
[0] / weight
[0], 8.0);
88 double compute_aomssim(const YV12_BUFFER_CONFIG
*source
,
89 const YV12_BUFFER_CONFIG
*dest
) {
91 aom_lowbd_calc_ssim(source
, dest
, &weight
, &ssim
);
92 return 100 * pow(ssim
/ weight
, 8.0);
95 class HBDMetricsTestBase
{
97 virtual ~HBDMetricsTestBase() {}
100 void RunAccuracyCheck() {
101 const int width
= 1920;
102 const int height
= 1080;
104 const uint8_t kPixFiller
= 128;
105 YV12_BUFFER_CONFIG lbd_src
, lbd_dst
;
106 YV12_BUFFER_CONFIG hbd_src
, hbd_dst
;
107 ACMRandom
rnd(ACMRandom::DeterministicSeed());
108 double lbd_db
, hbd_db
;
110 memset(&lbd_src
, 0, sizeof(lbd_src
));
111 memset(&lbd_dst
, 0, sizeof(lbd_dst
));
112 memset(&hbd_src
, 0, sizeof(hbd_src
));
113 memset(&hbd_dst
, 0, sizeof(hbd_dst
));
115 aom_alloc_frame_buffer(&lbd_src
, width
, height
, 1, 1, 0, 32, 16);
116 aom_alloc_frame_buffer(&lbd_dst
, width
, height
, 1, 1, 0, 32, 16);
117 aom_alloc_frame_buffer(&hbd_src
, width
, height
, 1, 1, 1, 32, 16);
118 aom_alloc_frame_buffer(&hbd_dst
, width
, height
, 1, 1, 1, 32, 16);
120 memset(lbd_src
.buffer_alloc
, kPixFiller
, lbd_src
.buffer_alloc_sz
);
121 while (i
< lbd_src
.buffer_alloc_sz
) {
123 spel
= lbd_src
.buffer_alloc
[i
];
124 // Create some distortion for dst buffer.
126 lbd_dst
.buffer_alloc
[i
] = (uint8_t)dpel
;
127 ((uint16_t *)(hbd_src
.buffer_alloc
))[i
] = spel
<< (bit_depth_
- 8);
128 ((uint16_t *)(hbd_dst
.buffer_alloc
))[i
] = dpel
<< (bit_depth_
- 8);
132 lbd_db
= lbd_metric_(&lbd_src
, &lbd_dst
);
133 hbd_db
= hbd_metric_(&hbd_src
, &hbd_dst
, input_bit_depth_
, bit_depth_
);
134 EXPECT_LE(fabs(lbd_db
- hbd_db
), threshold_
);
137 while (i
< lbd_src
.buffer_alloc_sz
) {
139 // Create some small distortion for dst buffer.
140 dpel
= 120 + (rnd
.Rand8() >> 4);
141 lbd_dst
.buffer_alloc
[i
] = (uint8_t)dpel
;
142 ((uint16_t *)(hbd_dst
.buffer_alloc
))[i
] = dpel
<< (bit_depth_
- 8);
146 lbd_db
= lbd_metric_(&lbd_src
, &lbd_dst
);
147 hbd_db
= hbd_metric_(&hbd_src
, &hbd_dst
, input_bit_depth_
, bit_depth_
);
148 EXPECT_LE(fabs(lbd_db
- hbd_db
), threshold_
);
151 while (i
< lbd_src
.buffer_alloc_sz
) {
153 // Create some small distortion for dst buffer.
154 dpel
= 126 + (rnd
.Rand8() >> 6);
155 lbd_dst
.buffer_alloc
[i
] = (uint8_t)dpel
;
156 ((uint16_t *)(hbd_dst
.buffer_alloc
))[i
] = dpel
<< (bit_depth_
- 8);
160 lbd_db
= lbd_metric_(&lbd_src
, &lbd_dst
);
161 hbd_db
= hbd_metric_(&hbd_src
, &hbd_dst
, input_bit_depth_
, bit_depth_
);
162 EXPECT_LE(fabs(lbd_db
- hbd_db
), threshold_
);
164 aom_free_frame_buffer(&lbd_src
);
165 aom_free_frame_buffer(&lbd_dst
);
166 aom_free_frame_buffer(&hbd_src
);
167 aom_free_frame_buffer(&hbd_dst
);
170 int input_bit_depth_
;
173 LBDMetricFunc lbd_metric_
;
174 HBDMetricFunc hbd_metric_
;
177 typedef std::tuple
<LBDMetricFunc
, HBDMetricFunc
, int, int, double>
179 class HBDMetricsTest
: public HBDMetricsTestBase
,
180 public ::testing::TestWithParam
<MetricTestTParam
> {
182 virtual void SetUp() {
183 lbd_metric_
= GET_PARAM(0);
184 hbd_metric_
= GET_PARAM(1);
185 input_bit_depth_
= GET_PARAM(2);
186 bit_depth_
= GET_PARAM(3);
187 threshold_
= GET_PARAM(4);
189 virtual void TearDown() {}
192 TEST_P(HBDMetricsTest
, RunAccuracyCheck
) { RunAccuracyCheck(); }
194 // Allow small variation due to floating point operations.
195 static const double kSsim_thresh
= 0.001;
196 // Allow some additional errors accumulated in floating point operations.
197 static const double kFSsim_thresh
= 0.03;
198 // Allow some extra variation due to rounding error accumulated in dct.
199 static const double kPhvs_thresh
= 0.3;
201 INSTANTIATE_TEST_SUITE_P(
202 AOMSSIM
, HBDMetricsTest
,
203 ::testing::Values(MetricTestTParam(&compute_aomssim
, &compute_hbd_aomssim
,
204 8, 10, kSsim_thresh
),
205 MetricTestTParam(&compute_aomssim
, &compute_hbd_aomssim
,
206 10, 10, kPhvs_thresh
),
207 MetricTestTParam(&compute_aomssim
, &compute_hbd_aomssim
,
208 8, 12, kSsim_thresh
),
209 MetricTestTParam(&compute_aomssim
, &compute_hbd_aomssim
,
210 12, 12, kPhvs_thresh
)));
211 INSTANTIATE_TEST_SUITE_P(
212 FASTSSIM
, HBDMetricsTest
,
213 ::testing::Values(MetricTestTParam(&compute_fastssim
, &compute_hbd_fastssim
,
214 8, 10, kFSsim_thresh
),
215 MetricTestTParam(&compute_fastssim
, &compute_hbd_fastssim
,
216 10, 10, kFSsim_thresh
),
217 MetricTestTParam(&compute_fastssim
, &compute_hbd_fastssim
,
218 8, 12, kFSsim_thresh
),
219 MetricTestTParam(&compute_fastssim
, &compute_hbd_fastssim
,
220 12, 12, kFSsim_thresh
)));
221 INSTANTIATE_TEST_SUITE_P(
222 PSNRHVS
, HBDMetricsTest
,
223 ::testing::Values(MetricTestTParam(&compute_psnrhvs
, &compute_hbd_psnrhvs
,
224 8, 10, kPhvs_thresh
),
225 MetricTestTParam(&compute_psnrhvs
, &compute_hbd_psnrhvs
,
226 10, 10, kPhvs_thresh
),
227 MetricTestTParam(&compute_psnrhvs
, &compute_hbd_psnrhvs
,
228 8, 12, kPhvs_thresh
),
229 MetricTestTParam(&compute_psnrhvs
, &compute_hbd_psnrhvs
,
230 12, 12, kPhvs_thresh
)));
231 INSTANTIATE_TEST_SUITE_P(
232 PSNR
, HBDMetricsTest
,
234 MetricTestTParam(&compute_psnr
, &compute_hbd_psnr
, 8, 10, kPhvs_thresh
),
235 MetricTestTParam(&compute_psnr
, &compute_hbd_psnr
, 10, 10,
237 MetricTestTParam(&compute_psnr
, &compute_hbd_psnr
, 8, 12, kPhvs_thresh
),
238 MetricTestTParam(&compute_psnr
, &compute_hbd_psnr
, 12, 12,