summaryrefslogtreecommitdiff
path: root/yuvbench/yuvbench.c
diff options
context:
space:
mode:
Diffstat (limited to 'yuvbench/yuvbench.c')
-rw-r--r--yuvbench/yuvbench.c133
1 files changed, 126 insertions, 7 deletions
diff --git a/yuvbench/yuvbench.c b/yuvbench/yuvbench.c
index 8b0d0d5..1d34f0b 100644
--- a/yuvbench/yuvbench.c
+++ b/yuvbench/yuvbench.c
@@ -1,5 +1,99 @@
#include "yuvbench.h"
+#define KBENCH_IMPLEMENTATION
+#include "kbench.h"
+
+#ifdef YUVBENCH_BAD
+Backend yuvbench_bad(void);
+#endif
+
+static struct
+{
+ uint32_t inp_w;
+ uint32_t inp_h;
+ void* inp_buf;
+ size_t inp_len;
+ void* out_buf;
+ size_t out_len;
+} G = { 0 };
+
+static void run_backend(Backend b)
+{
+ Ctx ctx = { 0 };
+ ctx.inp_w = G.inp_w;
+ ctx.inp_h = G.inp_h;
+ ctx.inp_buf = G.inp_buf;
+ ctx.inp_len = G.inp_len;
+ ctx.out_buf = G.out_buf;
+ ctx.out_len = G.out_len;
+
+ if (b.init_fn && !b.init_fn(&ctx)) {
+ printf("Init failed\n");
+ return;
+ }
+
+ if (!b.convert_fn) {
+ printf("No convert function");
+ return;
+ }
+
+ printf("running warnups...\n");
+ int warmup = 20;
+ for (int i = 0; i < warmup; ++i) {
+ b.convert_fn(&ctx);
+ }
+
+ printf("testing...\n");
+ int tests = 200;
+ double* tests_table = calloc(tests, sizeof(double)); assert(tests_table);
+ for (int i = 0; i < tests; ++i) {
+ uintptr_t t0 = KBenchTS();
+ if (!b.convert_fn(&ctx)) {
+ printf("Conversion failed\n");
+ return;
+ }
+ uintptr_t t1 = KBenchTS();
+ tests_table[i] = KBenchElapsedTime(t0, t1);
+ }
+
+ if (b.deinit_fn) {
+ b.deinit_fn(&ctx);
+ }
+
+ double ts_min = -1.0f;
+ double ts_max = -1.0f;
+ double ts_avg = 0.0f;
+ for (int i = 0; i < tests; ++i) {
+ if (ts_min < 0 || tests_table[i] < ts_min) {
+ ts_min = tests_table[i];
+ }
+ if (ts_max < 0 || tests_table[i] > ts_max) {
+ ts_max = tests_table[i];
+ }
+ ts_avg += (tests_table[i] / (double)tests);
+ }
+ printf("min result: %f\n", ts_min);
+ printf("max result: %f\n", ts_max);
+ printf("avg result: %f\n", ts_avg);
+
+#if 0 && (defined(__APPLE__) || defined(__linux__))
+ // Display last result
+ char cmd[512] = { 0 };
+ snprintf(cmd, sizeof(cmd), "ffplay -f rawvideo -pixel_format rgb24 -video_size %dx%d -", G.inp_w, G.inp_h);
+ FILE* pipe_fp = popen(cmd, "w");
+ if (!pipe_fp) {
+ printf("Failed to open ffplay: %s\n", strerror(errno));
+ abort();
+ }
+ fwrite(G.out_buf, 1, G.out_len, pipe_fp);
+ fflush(pipe_fp);
+ if (pclose(pipe_fp) == -1) {
+ printf("Failed to close ffplay: %s\n", strerror(errno));
+ abort();
+ }
+#endif
+}
+
int main(int argc, char** argv)
{
// The source file should be raw YUV 4:2:0 pixel data packed with no padding.
@@ -10,8 +104,6 @@ int main(int argc, char** argv)
}
// Decode with and height from file name
- int inp_w = 0;
- int inp_h = 0;
{
// Scan for last "-"
const char* suffix = 0;
@@ -28,8 +120,8 @@ int main(int argc, char** argv)
for (; *suffix; ++suffix) {
const char c = *suffix;
if (c >= '0' && c <= '9') {
- inp_w *= 10;
- inp_w += (int)(c - '0');
+ G.inp_w *= 10;
+ G.inp_w += (int)(c - '0');
} else if (c == 'x') {
++suffix;
break;
@@ -41,8 +133,8 @@ int main(int argc, char** argv)
for (; *suffix; ++suffix) {
const char c = *suffix;
if (c >= '0' && c <= '9') {
- inp_h *= 10;
- inp_h += (int)(c - '0');
+ G.inp_h *= 10;
+ G.inp_h += (int)(c - '0');
} else if (c == '.') {
break;
} else {
@@ -50,6 +142,33 @@ int main(int argc, char** argv)
return 1;
}
}
+ // Read from disk
+ FILE* f = fopen(argv[1], "rb");
+ if (!f) {
+ printf("Failed to open file: %s\n", strerror(errno));
+ return 1;
+ }
+ fseek(f, 0, SEEK_END);
+ G.inp_len = ftell(f);
+ fseek(f, 0, SEEK_SET);
+ assert(G.inp_len && "Zero-length file");
+ G.inp_buf = calloc(1, G.inp_len);
+ fread(G.inp_buf, 1, G.inp_len, f);
+ fclose(f);
+ }
+ printf("Input image is %dx%d YUV 4:2:0\n", G.inp_w, G.inp_h);
+ printf("Input buffer size: %lu\n", G.inp_len);
+ // 1x full res luminance plane + 2x half res chroma planes
+ const size_t expected_len = (G.inp_w * G.inp_h) + ((G.inp_w / 2 * G.inp_h / 2) * 2);
+ if (G.inp_len != expected_len) {
+ printf("Expected file length %lu but got %lu. Allowing.\n", expected_len, G.inp_len);
}
- printf("Input image is %dx%d YUV 4:2:0\n", inp_w, inp_h);
+
+ G.out_len = G.inp_w * G.inp_h * 3; // RGB888
+ G.out_buf = calloc(1, G.out_len);
+
+#ifdef YUVBENCH_BAD
+ run_backend(yuvbench_bad());
+#endif
+
}