1 /*
2 * Copyright 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <fstream>
18 #include <iostream>
19 #include <cstring>
20
21 #include <benchmark/benchmark.h>
22
23 #include "ultrahdr_api.h"
24
25 #ifdef __ANDROID__
26 std::string kTestImagesPath = "/sdcard/test/UltrahdrBenchmarkTestRes-1.2/";
27
28 #ifdef LOG_NDEBUG
29 #include "android/log.h"
30
31 #ifndef LOG_TAG
32 #define LOG_TAG "UHDR_BENCHMARK"
33 #endif
34
35 #ifndef ALOGE
36 #define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
37 #endif
38
39 #else
40 #define ALOGE(...) ((void)0)
41 #endif
42
43 #else
44 std::string kTestImagesPath = "./data/UltrahdrBenchmarkTestRes-1.2/";
45
46 #ifdef LOG_NDEBUG
47 #include <cstdio>
48
49 #define ALOGE(...) \
50 do { \
51 fprintf(stderr, __VA_ARGS__); \
52 fprintf(stderr, "\n"); \
53 } while (0)
54
55 #else
56 #define ALOGE(...) ((void)0)
57 #endif
58
59 #endif
60
61 std::vector<std::string> kDecodeAPITestImages = {
62 "mountains_singlechannelgainmap.jpg",
63 "mountains_multichannelgainmap.jpg",
64 "mountains_singlechannelgamma.jpg",
65 "mountains_multichannelgamma.jpg",
66 };
67
68 std::vector<std::string> kEncodeApi0TestImages12MpName = {
69 "mountains_rgba1010102.raw",
70 "mountains_rgba16F.raw",
71 "mountains_p010.p010",
72 };
73
74 std::vector<std::pair<std::string, std::string>> kEncodeApi1TestImages12MpName = {
75 {"mountains_rgba1010102.raw", "mountains_rgba8888.raw"},
76 {"mountains_rgba16F.raw", "mountains_rgba8888.raw"},
77 {"mountains_p010.p010", "mountains_yuv420.yuv"},
78 };
79
80 using TestParamsDecodeAPI = std::tuple<std::string, uhdr_color_transfer_t, uhdr_img_fmt_t, bool>;
81 using TestParamsEncoderAPI0 =
82 std::tuple<std::string, int, int, uhdr_color_gamut_t, uhdr_color_transfer_t, int, float>;
83 using TestParamsEncoderAPI1 =
84 std::tuple<std::string, std::string, int, int, uhdr_color_gamut_t, uhdr_color_transfer_t,
85 uhdr_color_gamut_t, int, float, uhdr_enc_preset_t>;
86
87 std::vector<TestParamsDecodeAPI> testParamsDecodeAPI;
88 std::vector<TestParamsEncoderAPI0> testParamsAPI0;
89 std::vector<TestParamsEncoderAPI1> testParamsAPI1;
90
imgFmtToString(const uhdr_img_fmt of)91 std::string imgFmtToString(const uhdr_img_fmt of) {
92 switch (of) {
93 case UHDR_IMG_FMT_32bppRGBA8888:
94 return "rgba8888";
95 case UHDR_IMG_FMT_64bppRGBAHalfFloat:
96 return "64rgbaHalftoFloat";
97 case UHDR_IMG_FMT_32bppRGBA1010102:
98 return "rgba1010102";
99 default:
100 return "Unknown";
101 }
102 }
103
colorGamutToString(const uhdr_color_gamut_t cg)104 std::string colorGamutToString(const uhdr_color_gamut_t cg) {
105 switch (cg) {
106 case UHDR_CG_BT_709:
107 return "bt709";
108 case UHDR_CG_DISPLAY_P3:
109 return "p3";
110 case UHDR_CG_BT_2100:
111 return "bt2100";
112 default:
113 return "Unknown";
114 }
115 }
116
tfToString(const uhdr_color_transfer_t of)117 std::string tfToString(const uhdr_color_transfer_t of) {
118 switch (of) {
119 case UHDR_CT_LINEAR:
120 return "linear";
121 case UHDR_CT_HLG:
122 return "hlg";
123 case UHDR_CT_PQ:
124 return "pq";
125 case UHDR_CT_SRGB:
126 return "srgb";
127 default:
128 return "Unknown";
129 }
130 }
131
132 #define READ_BYTES(DESC, ADDR, LEN) \
133 DESC.read(static_cast<char*>(ADDR), (LEN)); \
134 if (DESC.gcount() != (LEN)) { \
135 ALOGE("Failed to read: %u bytes, read: %zu bytes", LEN, DESC.gcount()); \
136 return false; \
137 }
138
loadFile(const char * filename,uhdr_raw_image_t * handle)139 static bool loadFile(const char* filename, uhdr_raw_image_t* handle) {
140 std::ifstream ifd(filename, std::ios::binary);
141 if (ifd.good()) {
142 if (handle->fmt == UHDR_IMG_FMT_24bppYCbCrP010) {
143 const int bpp = 2;
144 READ_BYTES(ifd, handle->planes[UHDR_PLANE_Y], handle->w * handle->h * bpp)
145 READ_BYTES(ifd, handle->planes[UHDR_PLANE_UV], (handle->w / 2) * (handle->h / 2) * bpp * 2)
146 return true;
147 } else if (handle->fmt == UHDR_IMG_FMT_32bppRGBA1010102 ||
148 handle->fmt == UHDR_IMG_FMT_32bppRGBA8888 ||
149 handle->fmt == UHDR_IMG_FMT_64bppRGBAHalfFloat) {
150 const int bpp = handle->fmt == UHDR_IMG_FMT_64bppRGBAHalfFloat ? 8 : 4;
151 READ_BYTES(ifd, handle->planes[UHDR_PLANE_PACKED], handle->w * handle->h * bpp)
152 return true;
153 } else if (handle->fmt == UHDR_IMG_FMT_12bppYCbCr420) {
154 READ_BYTES(ifd, handle->planes[UHDR_PLANE_Y], handle->w * handle->h)
155 READ_BYTES(ifd, handle->planes[UHDR_PLANE_U], (handle->w / 2) * (handle->h / 2))
156 READ_BYTES(ifd, handle->planes[UHDR_PLANE_V], (handle->w / 2) * (handle->h / 2))
157 return true;
158 }
159 return false;
160 }
161 ALOGE("Unable to open file: %s", filename);
162 return false;
163 }
164
loadFile(const char * filename,void * & result,int length)165 static bool loadFile(const char* filename, void*& result, int length) {
166 std::ifstream ifd(filename, std::ios::binary | std::ios::ate);
167 if (ifd.good()) {
168 int size = ifd.tellg();
169 if (size < length) {
170 ALOGE("Requested to read %d bytes from file: %s, file contains only %d bytes", length,
171 filename, size);
172 return false;
173 }
174 ifd.seekg(0, std::ios::beg);
175 result = malloc(length);
176 if (result == nullptr) {
177 ALOGE("Failed to allocate memory to store contents of file: %s", filename);
178 return false;
179 }
180 READ_BYTES(ifd, result, length)
181 return true;
182 }
183 ALOGE("Unable to open file: %s", filename);
184 return false;
185 }
186
187 class DecBenchmark {
188 public:
189 std::string mUhdrFile;
190 uhdr_color_transfer_t mTf;
191 uhdr_img_fmt_t mOfmt;
192 bool mEnableGLES;
193
194 uhdr_compressed_image_t mUhdrImg{};
195
DecBenchmark(TestParamsDecodeAPI testParams)196 DecBenchmark(TestParamsDecodeAPI testParams) {
197 mUhdrFile = std::get<0>(testParams);
198 mTf = std::get<1>(testParams);
199 mOfmt = std::get<2>(testParams);
200 mEnableGLES = std::get<3>(testParams);
201 }
~DecBenchmark()202 ~DecBenchmark() {
203 if (mUhdrImg.data) {
204 free(mUhdrImg.data);
205 mUhdrImg.data = nullptr;
206 }
207 }
208
209 bool fillJpegImageHandle(uhdr_compressed_image_t* uhdrImg, std::string mUhdrFile);
210 };
211
fillJpegImageHandle(uhdr_compressed_image_t * uhdrImg,std::string filename)212 bool DecBenchmark::fillJpegImageHandle(uhdr_compressed_image_t* uhdrImg, std::string filename) {
213 std::ifstream ifd(filename, std::ios::binary | std::ios::ate);
214 if (ifd.good()) {
215 int size = ifd.tellg();
216 uhdrImg->capacity = size;
217 uhdrImg->data_sz = size;
218 uhdrImg->data = nullptr;
219 uhdrImg->cg = UHDR_CG_UNSPECIFIED;
220 uhdrImg->ct = UHDR_CT_UNSPECIFIED;
221 uhdrImg->range = UHDR_CR_UNSPECIFIED;
222 ifd.close();
223 return loadFile(filename.c_str(), uhdrImg->data, size);
224 }
225 return false;
226 }
227
228 class EncBenchmark {
229 public:
230 std::string mHdrFile, mSdrFile;
231 uhdr_color_gamut_t mHdrCg, mSdrCg;
232 uhdr_img_fmt_t mHdrCf, mSdrCf;
233 int mWidth, mHeight;
234 uhdr_color_transfer_t mHdrCt, mSdrCt = UHDR_CT_SRGB;
235 int mUseMultiChannelGainMap;
236 int mMapDimensionScaleFactor = 1;
237 float mGamma;
238 uhdr_enc_preset_t mEncPreset;
239
240 uhdr_raw_image_t mHdrImg{}, mSdrImg{};
241
EncBenchmark(TestParamsEncoderAPI0 testParams)242 EncBenchmark(TestParamsEncoderAPI0 testParams) {
243 mHdrFile = std::get<0>(testParams);
244 mWidth = std::get<1>(testParams);
245 mHeight = std::get<2>(testParams);
246 mHdrCg = std::get<3>(testParams);
247 mHdrCt = std::get<4>(testParams);
248 mUseMultiChannelGainMap = std::get<5>(testParams);
249 mGamma = std::get<6>(testParams);
250 };
251
EncBenchmark(TestParamsEncoderAPI1 testParams)252 EncBenchmark(TestParamsEncoderAPI1 testParams) {
253 mHdrFile = std::get<0>(testParams);
254 mSdrFile = std::get<1>(testParams);
255 mWidth = std::get<2>(testParams);
256 mHeight = std::get<3>(testParams);
257 mHdrCg = std::get<4>(testParams);
258 mHdrCt = std::get<5>(testParams);
259 mSdrCg = std::get<6>(testParams);
260 mUseMultiChannelGainMap = std::get<7>(testParams);
261 mGamma = std::get<8>(testParams);
262 mEncPreset = std::get<9>(testParams);
263 }
264
~EncBenchmark()265 ~EncBenchmark() {
266 int count = sizeof mHdrImg.planes / sizeof mHdrImg.planes[0];
267 for (int i = 0; i < count; i++) {
268 if (mHdrImg.planes[i]) {
269 free(mHdrImg.planes[i]);
270 mHdrImg.planes[i] = nullptr;
271 }
272 if (mSdrImg.planes[i]) {
273 free(mSdrImg.planes[i]);
274 mSdrImg.planes[i] = nullptr;
275 }
276 }
277 }
278
279 bool fillRawImageHandle(uhdr_raw_image_t* rawImg, int width, int height, std::string file,
280 uhdr_img_fmt_t cf, uhdr_color_gamut_t cg, uhdr_color_transfer_t ct);
281 };
282
fillRawImageHandle(uhdr_raw_image_t * rawImg,int width,int height,std::string file,uhdr_img_fmt_t cf,uhdr_color_gamut_t cg,uhdr_color_transfer_t ct)283 bool EncBenchmark::fillRawImageHandle(uhdr_raw_image_t* rawImg, int width, int height,
284 std::string file, uhdr_img_fmt_t cf, uhdr_color_gamut_t cg,
285 uhdr_color_transfer_t ct) {
286 rawImg->fmt = cf;
287 rawImg->cg = cg;
288 rawImg->ct = ct;
289 rawImg->w = width;
290 rawImg->h = height;
291 if (cf == UHDR_IMG_FMT_24bppYCbCrP010) {
292 const int bpp = 2;
293 rawImg->range = std::rand() % 2 ? UHDR_CR_FULL_RANGE : UHDR_CR_LIMITED_RANGE;
294 rawImg->planes[UHDR_PLANE_Y] = malloc(width * height * bpp);
295 rawImg->planes[UHDR_PLANE_UV] = malloc((width / 2) * (height / 2) * bpp * 2);
296 rawImg->planes[UHDR_PLANE_V] = nullptr;
297 rawImg->stride[UHDR_PLANE_Y] = width;
298 rawImg->stride[UHDR_PLANE_UV] = width;
299 rawImg->stride[UHDR_PLANE_V] = 0;
300 return loadFile(file.c_str(), rawImg);
301 } else if (cf == UHDR_IMG_FMT_32bppRGBA1010102 || cf == UHDR_IMG_FMT_32bppRGBA8888 ||
302 cf == UHDR_IMG_FMT_64bppRGBAHalfFloat) {
303 const int bpp = cf == UHDR_IMG_FMT_64bppRGBAHalfFloat ? 8 : 4;
304 rawImg->range = UHDR_CR_FULL_RANGE;
305 rawImg->planes[UHDR_PLANE_PACKED] = malloc(width * height * bpp);
306 rawImg->planes[UHDR_PLANE_UV] = nullptr;
307 rawImg->planes[UHDR_PLANE_V] = nullptr;
308 rawImg->stride[UHDR_PLANE_PACKED] = width;
309 rawImg->stride[UHDR_PLANE_UV] = 0;
310 rawImg->stride[UHDR_PLANE_V] = 0;
311 return loadFile(file.c_str(), rawImg);
312 } else if (cf == UHDR_IMG_FMT_12bppYCbCr420) {
313 rawImg->range = UHDR_CR_FULL_RANGE;
314 rawImg->planes[UHDR_PLANE_Y] = malloc(width * height);
315 rawImg->planes[UHDR_PLANE_U] = malloc((width / 2) * (height / 2));
316 rawImg->planes[UHDR_PLANE_V] = malloc((width / 2) * (height / 2));
317 rawImg->stride[UHDR_PLANE_Y] = width;
318 rawImg->stride[UHDR_PLANE_U] = width / 2;
319 rawImg->stride[UHDR_PLANE_V] = width / 2;
320 return loadFile(file.c_str(), rawImg);
321 }
322 return false;
323 }
324
BM_UHDRDecode(benchmark::State & s,TestParamsDecodeAPI testVectors)325 static void BM_UHDRDecode(benchmark::State& s, TestParamsDecodeAPI testVectors) {
326 DecBenchmark benchmark(testVectors);
327
328 s.SetLabel(benchmark.mUhdrFile + ", OutputFormat: " + imgFmtToString(benchmark.mOfmt) +
329 ", ColorTransfer: " + tfToString(benchmark.mTf) +
330 ", enableGLES: " + (benchmark.mEnableGLES ? "true" : "false"));
331
332 benchmark.mUhdrFile = kTestImagesPath + "jpegr/" + benchmark.mUhdrFile;
333
334 if (!benchmark.fillJpegImageHandle(&benchmark.mUhdrImg, benchmark.mUhdrFile)) {
335 s.SkipWithError("unable to load file : " + benchmark.mUhdrFile);
336 return;
337 }
338
339 #define RET_IF_ERR(x) \
340 { \
341 uhdr_error_info_t status = (x); \
342 if (status.error_code != UHDR_CODEC_OK) { \
343 uhdr_release_decoder(decHandle); \
344 s.SkipWithError(status.has_detail ? status.detail : "Unknown error"); \
345 return; \
346 } \
347 }
348
349 uhdr_codec_private_t* decHandle = uhdr_create_decoder();
350 for (auto _ : s) {
351 RET_IF_ERR(uhdr_dec_set_image(decHandle, &benchmark.mUhdrImg))
352 RET_IF_ERR(uhdr_dec_set_out_color_transfer(decHandle, benchmark.mTf))
353 RET_IF_ERR(uhdr_dec_set_out_img_format(decHandle, benchmark.mOfmt))
354 RET_IF_ERR(uhdr_enable_gpu_acceleration(decHandle, benchmark.mEnableGLES))
355 RET_IF_ERR(uhdr_decode(decHandle))
356 uhdr_reset_decoder(decHandle);
357 }
358 uhdr_release_decoder(decHandle);
359 #undef RET_IF_ERR
360 }
361
362 #define RET_IF_ERR(x) \
363 { \
364 uhdr_error_info_t status = (x); \
365 if (status.error_code != UHDR_CODEC_OK) { \
366 uhdr_release_encoder(encHandle); \
367 s.SkipWithError(status.has_detail ? status.detail : "Unknown error"); \
368 return; \
369 } \
370 }
371
BM_UHDREncode_Api0(benchmark::State & s,TestParamsEncoderAPI0 testVectors)372 static void BM_UHDREncode_Api0(benchmark::State& s, TestParamsEncoderAPI0 testVectors) {
373 EncBenchmark benchmark(testVectors);
374
375 s.SetLabel(
376 benchmark.mHdrFile + ", " + std::to_string(benchmark.mWidth) + "x" +
377 std::to_string(benchmark.mHeight) + ", " + colorGamutToString(benchmark.mHdrCg) + ", " +
378 (benchmark.mHdrFile.find("rgba16F") != std::string::npos ? "linear"
379 : tfToString(benchmark.mHdrCt)) +
380 ", " +
381 (benchmark.mUseMultiChannelGainMap == 0 ? "singlechannelgainmap" : "multichannelgainmap") +
382 ", gamma: " + std::to_string(benchmark.mGamma));
383
384 if (benchmark.mHdrFile.find("p010") != std::string::npos) {
385 benchmark.mHdrFile = kTestImagesPath + "p010/" + benchmark.mHdrFile;
386 benchmark.mHdrCf = UHDR_IMG_FMT_24bppYCbCrP010;
387 } else if (benchmark.mHdrFile.find("rgba1010102") != std::string::npos) {
388 benchmark.mHdrFile = kTestImagesPath + "rgba1010102/" + benchmark.mHdrFile;
389 benchmark.mHdrCf = UHDR_IMG_FMT_32bppRGBA1010102;
390 } else if (benchmark.mHdrFile.find("rgba16F") != std::string::npos) {
391 benchmark.mHdrFile = kTestImagesPath + "rgba16F/" + benchmark.mHdrFile;
392 benchmark.mHdrCf = UHDR_IMG_FMT_64bppRGBAHalfFloat;
393 benchmark.mHdrCt = UHDR_CT_LINEAR;
394 } else {
395 s.SkipWithError("Invalid file format : " + benchmark.mHdrFile);
396 return;
397 }
398
399 if (!benchmark.fillRawImageHandle(&benchmark.mHdrImg, benchmark.mWidth, benchmark.mHeight,
400 benchmark.mHdrFile, benchmark.mHdrCf, benchmark.mHdrCg,
401 benchmark.mHdrCt)) {
402 s.SkipWithError("unable to load file : " + benchmark.mHdrFile);
403 return;
404 }
405
406 uhdr_codec_private_t* encHandle = uhdr_create_encoder();
407 for (auto _ : s) {
408 RET_IF_ERR(uhdr_enc_set_raw_image(encHandle, &benchmark.mHdrImg, UHDR_HDR_IMG))
409 RET_IF_ERR(
410 uhdr_enc_set_using_multi_channel_gainmap(encHandle, benchmark.mUseMultiChannelGainMap))
411 RET_IF_ERR(uhdr_enc_set_gainmap_scale_factor(encHandle, benchmark.mMapDimensionScaleFactor))
412 RET_IF_ERR(uhdr_enc_set_gainmap_gamma(encHandle, benchmark.mGamma))
413 RET_IF_ERR(uhdr_encode(encHandle))
414 uhdr_reset_encoder(encHandle);
415 }
416 uhdr_release_encoder(encHandle);
417 }
418
BM_UHDREncode_Api1(benchmark::State & s,TestParamsEncoderAPI1 testVectors)419 static void BM_UHDREncode_Api1(benchmark::State& s, TestParamsEncoderAPI1 testVectors) {
420 EncBenchmark benchmark(testVectors);
421
422 s.SetLabel(
423 benchmark.mHdrFile + ", " + benchmark.mSdrFile + ", " + std::to_string(benchmark.mWidth) +
424 "x" + std::to_string(benchmark.mHeight) + ", hdrCg: " + colorGamutToString(benchmark.mHdrCg) +
425 ", hdrCt: " +
426 (benchmark.mHdrFile.find("rgba16F") != std::string::npos ? "linear"
427 : tfToString(benchmark.mHdrCt)) +
428 ", sdrCg: " + colorGamutToString(benchmark.mSdrCg) + ", " +
429 (benchmark.mUseMultiChannelGainMap == 0 ? "singlechannelgainmap" : "multichannelgainmap") +
430 ", gamma: " + std::to_string(benchmark.mGamma) + ", " +
431 (benchmark.mEncPreset == UHDR_USAGE_BEST_QUALITY ? "best_quality" : "realtime"));
432
433 if (benchmark.mHdrFile.find("p010") != std::string::npos) {
434 benchmark.mHdrFile = kTestImagesPath + "p010/" + benchmark.mHdrFile;
435 benchmark.mHdrCf = UHDR_IMG_FMT_24bppYCbCrP010;
436 } else if (benchmark.mHdrFile.find("rgba1010102") != std::string::npos) {
437 benchmark.mHdrFile = kTestImagesPath + "rgba1010102/" + benchmark.mHdrFile;
438 benchmark.mHdrCf = UHDR_IMG_FMT_32bppRGBA1010102;
439 } else if (benchmark.mHdrFile.find("rgba16F") != std::string::npos) {
440 benchmark.mHdrFile = kTestImagesPath + "rgba16F/" + benchmark.mHdrFile;
441 benchmark.mHdrCf = UHDR_IMG_FMT_64bppRGBAHalfFloat;
442 benchmark.mHdrCt = UHDR_CT_LINEAR;
443 } else {
444 s.SkipWithError("Invalid hdr file format : " + benchmark.mHdrFile);
445 return;
446 }
447
448 if (benchmark.mSdrFile.find("yuv420") != std::string::npos) {
449 benchmark.mSdrFile = kTestImagesPath + "yuv420/" + benchmark.mSdrFile;
450 benchmark.mSdrCf = UHDR_IMG_FMT_12bppYCbCr420;
451 } else if (benchmark.mSdrFile.find("rgba8888") != std::string::npos) {
452 benchmark.mSdrFile = kTestImagesPath + "rgba8888/" + benchmark.mSdrFile;
453 benchmark.mSdrCf = UHDR_IMG_FMT_32bppRGBA8888;
454 } else {
455 s.SkipWithError("Invalid sdr file format : " + benchmark.mSdrFile);
456 return;
457 }
458
459 if (!benchmark.fillRawImageHandle(&benchmark.mHdrImg, benchmark.mWidth, benchmark.mHeight,
460 benchmark.mHdrFile, benchmark.mHdrCf, benchmark.mHdrCg,
461 benchmark.mHdrCt)) {
462 s.SkipWithError("unable to load file : " + benchmark.mHdrFile);
463 return;
464 }
465 if (!benchmark.fillRawImageHandle(&benchmark.mSdrImg, benchmark.mWidth, benchmark.mHeight,
466 benchmark.mSdrFile, benchmark.mSdrCf, benchmark.mSdrCg,
467 benchmark.mSdrCt)) {
468 s.SkipWithError("unable to load sdr file : " + benchmark.mSdrFile);
469 return;
470 }
471
472 uhdr_codec_private_t* encHandle = uhdr_create_encoder();
473 for (auto _ : s) {
474 RET_IF_ERR(uhdr_enc_set_raw_image(encHandle, &benchmark.mHdrImg, UHDR_HDR_IMG))
475 RET_IF_ERR(uhdr_enc_set_raw_image(encHandle, &benchmark.mSdrImg, UHDR_SDR_IMG))
476 RET_IF_ERR(
477 uhdr_enc_set_using_multi_channel_gainmap(encHandle, benchmark.mUseMultiChannelGainMap))
478 RET_IF_ERR(uhdr_enc_set_gainmap_scale_factor(encHandle, benchmark.mMapDimensionScaleFactor))
479 RET_IF_ERR(uhdr_enc_set_gainmap_gamma(encHandle, benchmark.mGamma))
480 RET_IF_ERR(uhdr_enc_set_preset(encHandle, benchmark.mEncPreset))
481 RET_IF_ERR(uhdr_encode(encHandle))
482 uhdr_reset_encoder(encHandle);
483 }
484 uhdr_release_encoder(encHandle);
485 }
486
addTestVectors()487 void addTestVectors() {
488 for (const auto& uhdrFile : kDecodeAPITestImages) {
489 /* Decode API - uhdrFile, colorTransfer, imgFormat, enableGLES */
490 testParamsDecodeAPI.push_back({uhdrFile, UHDR_CT_HLG, UHDR_IMG_FMT_32bppRGBA1010102, false});
491 testParamsDecodeAPI.push_back({uhdrFile, UHDR_CT_PQ, UHDR_IMG_FMT_32bppRGBA1010102, false});
492 testParamsDecodeAPI.push_back(
493 {uhdrFile, UHDR_CT_LINEAR, UHDR_IMG_FMT_64bppRGBAHalfFloat, false});
494 testParamsDecodeAPI.push_back({uhdrFile, UHDR_CT_HLG, UHDR_IMG_FMT_32bppRGBA1010102, true});
495 testParamsDecodeAPI.push_back({uhdrFile, UHDR_CT_PQ, UHDR_IMG_FMT_32bppRGBA1010102, true});
496 testParamsDecodeAPI.push_back(
497 {uhdrFile, UHDR_CT_LINEAR, UHDR_IMG_FMT_64bppRGBAHalfFloat, true});
498 testParamsDecodeAPI.push_back({uhdrFile, UHDR_CT_SRGB, UHDR_IMG_FMT_32bppRGBA8888, false});
499 }
500
501 for (const auto& hdrFile : kEncodeApi0TestImages12MpName) {
502 /* Encode API 0 - hdrFile, width, height, hdrColorGamut, hdrColorTransfer,
503 useMultiChannelGainmap, gamma */
504 testParamsAPI0.push_back({hdrFile, 4080, 3072, UHDR_CG_BT_2100, UHDR_CT_PQ, 0, 1.0f});
505 testParamsAPI0.push_back({hdrFile, 4080, 3072, UHDR_CG_BT_2100, UHDR_CT_PQ, 1, 1.0f});
506 testParamsAPI0.push_back({hdrFile, 4080, 3072, UHDR_CG_BT_2100, UHDR_CT_PQ, 0, 1.571f});
507 testParamsAPI0.push_back({hdrFile, 4080, 3072, UHDR_CG_BT_2100, UHDR_CT_PQ, 1, 1.616f});
508 }
509
510 for (const auto& inputFiles : kEncodeApi1TestImages12MpName) {
511 /* Encode API 1 - hdrFile, sdrFile, width, height, hdrColorGamut, hdrColorTransfer,
512 sdrColorGamut, useMultiChannelGainmap, gamma, encPreset */
513 testParamsAPI1.push_back({inputFiles.first, inputFiles.second, 4080, 3072, UHDR_CG_BT_2100,
514 UHDR_CT_PQ, UHDR_CG_BT_709, 0, 1.0f, UHDR_USAGE_REALTIME});
515 testParamsAPI1.push_back({inputFiles.first, inputFiles.second, 4080, 3072, UHDR_CG_BT_2100,
516 UHDR_CT_PQ, UHDR_CG_BT_709, 1, 1.0f, UHDR_USAGE_REALTIME});
517 testParamsAPI1.push_back({inputFiles.first, inputFiles.second, 4080, 3072, UHDR_CG_BT_2100,
518 UHDR_CT_PQ, UHDR_CG_BT_709, 0, 1.571f, UHDR_USAGE_REALTIME});
519 testParamsAPI1.push_back({inputFiles.first, inputFiles.second, 4080, 3072, UHDR_CG_BT_2100,
520 UHDR_CT_PQ, UHDR_CG_BT_709, 0, 1.0f, UHDR_USAGE_BEST_QUALITY});
521 testParamsAPI1.push_back({inputFiles.first, inputFiles.second, 4080, 3072, UHDR_CG_BT_2100,
522 UHDR_CT_PQ, UHDR_CG_BT_709, 1, 1.571f, UHDR_USAGE_REALTIME});
523 testParamsAPI1.push_back({inputFiles.first, inputFiles.second, 4080, 3072, UHDR_CG_BT_2100,
524 UHDR_CT_PQ, UHDR_CG_BT_709, 1, 1.0f, UHDR_USAGE_BEST_QUALITY});
525 testParamsAPI1.push_back({inputFiles.first, inputFiles.second, 4080, 3072, UHDR_CG_BT_2100,
526 UHDR_CT_PQ, UHDR_CG_BT_709, 0, 1.571f, UHDR_USAGE_BEST_QUALITY});
527 testParamsAPI1.push_back({inputFiles.first, inputFiles.second, 4080, 3072, UHDR_CG_BT_2100,
528 UHDR_CT_PQ, UHDR_CG_BT_709, 1, 1.571f, UHDR_USAGE_BEST_QUALITY});
529 }
530 }
531
registerBenchmarks()532 void registerBenchmarks() {
533 for (auto& param : testParamsDecodeAPI) {
534 benchmark::RegisterBenchmark("BM_UHDRDecode", BM_UHDRDecode, param)
535 ->Unit(benchmark::kMillisecond);
536 }
537 for (auto& param : testParamsAPI0) {
538 benchmark::RegisterBenchmark("BM_UHDREncode_Api0", BM_UHDREncode_Api0, param)
539 ->Unit(benchmark::kMillisecond);
540 }
541 for (auto& param : testParamsAPI1) {
542 benchmark::RegisterBenchmark("BM_UHDREncode_Api1", BM_UHDREncode_Api1, param)
543 ->Unit(benchmark::kMillisecond);
544 }
545 }
546
main(int argc,char ** argv)547 int main(int argc, char** argv) {
548 addTestVectors();
549 registerBenchmarks();
550 benchmark::Initialize(&argc, argv);
551 benchmark::RunSpecifiedBenchmarks(nullptr, nullptr);
552 benchmark::Shutdown();
553 return 0;
554 }
555