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.
16 #include "third_party/googletest/src/googletest/include/gtest/gtest.h"
17 #include "test/acm_random.h"
18 #include "test/util.h"
19 #include "./aom_config.h"
20 #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"
26 using libaom_test::ACMRandom
;
30 typedef double (*LBDMetricFunc
)(const YV12_BUFFER_CONFIG
*source
,
31 const YV12_BUFFER_CONFIG
*dest
);
32 typedef double (*HBDMetricFunc
)(const YV12_BUFFER_CONFIG
*source
,
33 const YV12_BUFFER_CONFIG
*dest
, uint32_t in_bd
,
36 double compute_hbd_psnr(const YV12_BUFFER_CONFIG
*source
,
37 const YV12_BUFFER_CONFIG
*dest
, uint32_t in_bd
,
40 aom_calc_highbd_psnr(source
, dest
, &psnr
, bd
, in_bd
);
44 double compute_psnr(const YV12_BUFFER_CONFIG
*source
,
45 const YV12_BUFFER_CONFIG
*dest
) {
47 aom_calc_psnr(source
, dest
, &psnr
);
51 double compute_hbd_psnrhvs(const YV12_BUFFER_CONFIG
*source
,
52 const YV12_BUFFER_CONFIG
*dest
, uint32_t in_bd
,
54 double tempy
, tempu
, tempv
;
55 return aom_psnrhvs(source
, dest
, &tempy
, &tempu
, &tempv
, bd
, in_bd
);
58 double compute_psnrhvs(const YV12_BUFFER_CONFIG
*source
,
59 const YV12_BUFFER_CONFIG
*dest
) {
60 double tempy
, tempu
, tempv
;
61 return aom_psnrhvs(source
, dest
, &tempy
, &tempu
, &tempv
, 8, 8);
64 double compute_hbd_fastssim(const YV12_BUFFER_CONFIG
*source
,
65 const YV12_BUFFER_CONFIG
*dest
, uint32_t in_bd
,
67 double tempy
, tempu
, tempv
;
68 return aom_calc_fastssim(source
, dest
, &tempy
, &tempu
, &tempv
, bd
, in_bd
);
71 double compute_fastssim(const YV12_BUFFER_CONFIG
*source
,
72 const YV12_BUFFER_CONFIG
*dest
) {
73 double tempy
, tempu
, tempv
;
74 return aom_calc_fastssim(source
, dest
, &tempy
, &tempu
, &tempv
, 8, 8);
77 double compute_hbd_aomssim(const YV12_BUFFER_CONFIG
*source
,
78 const YV12_BUFFER_CONFIG
*dest
, uint32_t in_bd
,
81 ssim
= aom_highbd_calc_ssim(source
, dest
, &weight
, bd
, in_bd
);
82 return 100 * pow(ssim
/ weight
, 8.0);
85 double compute_aomssim(const YV12_BUFFER_CONFIG
*source
,
86 const YV12_BUFFER_CONFIG
*dest
) {
88 ssim
= aom_calc_ssim(source
, dest
, &weight
);
89 return 100 * pow(ssim
/ weight
, 8.0);
92 class HBDMetricsTestBase
{
94 virtual ~HBDMetricsTestBase() {}
97 void RunAccuracyCheck() {
98 const int width
= 1920;
99 const int height
= 1080;
101 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());
105 double lbd_db
, hbd_db
;
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
));
112 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);
117 memset(lbd_src
.buffer_alloc
, kPixFiller
, lbd_src
.buffer_alloc_sz
);
118 while (i
< lbd_src
.buffer_alloc_sz
) {
120 spel
= lbd_src
.buffer_alloc
[i
];
121 // Create some distortion for dst buffer.
123 lbd_dst
.buffer_alloc
[i
] = (uint8_t)dpel
;
124 ((uint16_t *)(hbd_src
.buffer_alloc
))[i
] = spel
<< (bit_depth_
- 8);
125 ((uint16_t *)(hbd_dst
.buffer_alloc
))[i
] = dpel
<< (bit_depth_
- 8);
129 lbd_db
= lbd_metric_(&lbd_src
, &lbd_dst
);
130 hbd_db
= hbd_metric_(&hbd_src
, &hbd_dst
, input_bit_depth_
, bit_depth_
);
131 EXPECT_LE(fabs(lbd_db
- hbd_db
), threshold_
);
134 while (i
< lbd_src
.buffer_alloc_sz
) {
136 // Create some small distortion for dst buffer.
137 dpel
= 120 + (rnd
.Rand8() >> 4);
138 lbd_dst
.buffer_alloc
[i
] = (uint8_t)dpel
;
139 ((uint16_t *)(hbd_dst
.buffer_alloc
))[i
] = dpel
<< (bit_depth_
- 8);
143 lbd_db
= lbd_metric_(&lbd_src
, &lbd_dst
);
144 hbd_db
= hbd_metric_(&hbd_src
, &hbd_dst
, input_bit_depth_
, bit_depth_
);
145 EXPECT_LE(fabs(lbd_db
- hbd_db
), threshold_
);
148 while (i
< lbd_src
.buffer_alloc_sz
) {
150 // Create some small distortion for dst buffer.
151 dpel
= 126 + (rnd
.Rand8() >> 6);
152 lbd_dst
.buffer_alloc
[i
] = (uint8_t)dpel
;
153 ((uint16_t *)(hbd_dst
.buffer_alloc
))[i
] = dpel
<< (bit_depth_
- 8);
157 lbd_db
= lbd_metric_(&lbd_src
, &lbd_dst
);
158 hbd_db
= hbd_metric_(&hbd_src
, &hbd_dst
, input_bit_depth_
, bit_depth_
);
159 EXPECT_LE(fabs(lbd_db
- hbd_db
), threshold_
);
161 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
);
167 int input_bit_depth_
;
170 LBDMetricFunc lbd_metric_
;
171 HBDMetricFunc hbd_metric_
;
174 typedef std::tr1::tuple
<LBDMetricFunc
, HBDMetricFunc
, int, int, double>
176 class HBDMetricsTest
: public HBDMetricsTestBase
,
177 public ::testing::TestWithParam
<MetricTestTParam
> {
179 virtual void SetUp() {
180 lbd_metric_
= GET_PARAM(0);
181 hbd_metric_
= GET_PARAM(1);
182 input_bit_depth_
= GET_PARAM(2);
183 bit_depth_
= GET_PARAM(3);
184 threshold_
= GET_PARAM(4);
186 virtual void TearDown() {}
189 TEST_P(HBDMetricsTest
, RunAccuracyCheck
) { RunAccuracyCheck(); }
191 // Allow small variation due to floating point operations.
192 static const double kSsim_thresh
= 0.001;
193 // Allow some additional errors accumulated in floating point operations.
194 static const double kFSsim_thresh
= 0.03;
195 // Allow some extra variation due to rounding error accumulated in dct.
196 static const double kPhvs_thresh
= 0.3;
198 INSTANTIATE_TEST_CASE_P(
199 AOMSSIM
, HBDMetricsTest
,
200 ::testing::Values(MetricTestTParam(&compute_aomssim
, &compute_hbd_aomssim
,
201 8, 10, kSsim_thresh
),
202 MetricTestTParam(&compute_aomssim
, &compute_hbd_aomssim
,
203 10, 10, kPhvs_thresh
),
204 MetricTestTParam(&compute_aomssim
, &compute_hbd_aomssim
,
205 8, 12, kSsim_thresh
),
206 MetricTestTParam(&compute_aomssim
, &compute_hbd_aomssim
,
207 12, 12, kPhvs_thresh
)));
208 INSTANTIATE_TEST_CASE_P(
209 FASTSSIM
, HBDMetricsTest
,
210 ::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
)));
218 INSTANTIATE_TEST_CASE_P(
219 PSNRHVS
, HBDMetricsTest
,
220 ::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
)));
228 INSTANTIATE_TEST_CASE_P(
229 PSNR
, HBDMetricsTest
,
231 MetricTestTParam(&compute_psnr
, &compute_hbd_psnr
, 8, 10, kPhvs_thresh
),
232 MetricTestTParam(&compute_psnr
, &compute_hbd_psnr
, 10, 10,
234 MetricTestTParam(&compute_psnr
, &compute_hbd_psnr
, 8, 12, kPhvs_thresh
),
235 MetricTestTParam(&compute_psnr
, &compute_hbd_psnr
, 12, 12,