xref: /aosp_15_r20/external/libultrahdr/benchmark/benchmark_test.cpp (revision 89a0ef05262152531a00a15832a2d3b1e3990773)
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