summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHunter Kvalevog <hunter@kvog.sh>2026-02-26 21:46:32 -0600
committerHunter Kvalevog <hunter@kvog.sh>2026-02-26 21:46:32 -0600
commita288d2b6836d398098098cf69e4f88db7799f49e (patch)
tree72471a450544ec9ec9f575500c2bb62cc9cc9136
parent7633174bd62a47a50e0f7512b3094bd6a7c53b19 (diff)
yuvbench: libswscale
-rwxr-xr-xyuvbench/build-macos-aarch64-clang.sh8
-rw-r--r--yuvbench/yuvbench.c49
-rw-r--r--yuvbench/yuvbench_swscale.c41
3 files changed, 78 insertions, 20 deletions
diff --git a/yuvbench/build-macos-aarch64-clang.sh b/yuvbench/build-macos-aarch64-clang.sh
index 3aa3943..18706e8 100755
--- a/yuvbench/build-macos-aarch64-clang.sh
+++ b/yuvbench/build-macos-aarch64-clang.sh
@@ -1,11 +1,11 @@
#!/bin/sh
-CFLAGS="-Wall -Wextra -Wpedantic -O3 -g -DYUVBENCH_ACCELERATE -DYUVBENCH_BAD"
-LFLAGS="-framework Accelerate"
+CFLAGS="-Wall -Wextra -Wpedantic -O3 -g -DYUVBENCH_ACCELERATE -DYUVBENCH_BAD -DYUVBENCH_SWSCALE"
+LFLAGS="-framework Accelerate $(pkg-config --libs libswscale)"
mkdir -p build
set -x
clang -o build/yuvbench.o $CFLAGS -c ./yuvbench.c
clang -o build/yuvbench_accelerate.o $CFLAGS -c ./yuvbench_accelerate.c
clang -o build/yuvbench_accelerate.S $CFLAGS -S ./yuvbench_accelerate.c
clang -o build/yuvbench_bad.o $CFLAGS -c ./yuvbench_bad.c
-clang -o build/yuvbench_bad.S $CFLAGS -S ./yuvbench_bad.c
-clang -o build/yuvbench $LFLAGS build/yuvbench.o build/yuvbench_accelerate.o build/yuvbench_bad.o
+clang -o build/yuvbench_swscale.o $CFLAGS $(pkg-config --cflags libswscale) -c ./yuvbench_swscale.c
+clang -o build/yuvbench $LFLAGS build/yuvbench.o build/yuvbench_accelerate.o build/yuvbench_bad.o build/yuvbench_swscale.o
diff --git a/yuvbench/yuvbench.c b/yuvbench/yuvbench.c
index 5ef344c..095104e 100644
--- a/yuvbench/yuvbench.c
+++ b/yuvbench/yuvbench.c
@@ -9,6 +9,9 @@ Backend yuvbench_accelerate(void);
#ifdef YUVBENCH_BAD
Backend yuvbench_bad(void);
#endif
+#ifdef YUVBENCH_SWSCALE
+Backend yuvbench_swscale(void);
+#endif
static struct
{
@@ -18,6 +21,7 @@ static struct
size_t inp_len;
void* out_buf;
size_t out_len;
+ bool show;
} G = { 0 };
static void run_backend(Backend b)
@@ -79,22 +83,25 @@ static void run_backend(Backend b)
printf("max result: %fms\n", ts_max * 1000.0f);
printf("avg result: %fms\n", ts_avg * 1000.0f);
-#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();
- }
+
+ if (G.show) {
+ // Display last result
+#if 1 && (defined(__APPLE__) || defined(__linux__))
+ char cmd[512] = { 0 };
+ snprintf(cmd, sizeof(cmd), "ffplay -hide_banner -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)
@@ -159,6 +166,14 @@ int main(int argc, char** argv)
fread(G.inp_buf, 1, G.inp_len, f);
fclose(f);
}
+
+ // Parse other CLI
+ for (int i = 2; i < argc; ++i) {
+ const char* s = argv[i];
+ if (!strcmp(s, "show")) {
+ G.show = true;
+ }
+ }
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
@@ -176,5 +191,7 @@ int main(int argc, char** argv)
#ifdef YUVBENCH_BAD
run_backend(yuvbench_bad());
#endif
-
+#ifdef YUVBENCH_SWSCALE
+ run_backend(yuvbench_swscale());
+#endif
}
diff --git a/yuvbench/yuvbench_swscale.c b/yuvbench/yuvbench_swscale.c
new file mode 100644
index 0000000..556e5e3
--- /dev/null
+++ b/yuvbench/yuvbench_swscale.c
@@ -0,0 +1,41 @@
+#include "yuvbench.h"
+
+#include <libswscale/swscale.h>
+
+static bool yuvbench_swscale_init(Ctx* ctx)
+{
+ struct SwsContext* sws = sws_getContext(ctx->inp_w, ctx->inp_h, AV_PIX_FMT_YUV420P,
+ ctx->inp_w, ctx->inp_h, AV_PIX_FMT_RGB24,
+ 0, 0, 0, 0);
+ ctx->user = sws;
+ return !!sws;
+}
+
+static void yuvbench_swscale_deinit(Ctx* ctx)
+{
+ sws_freeContext(ctx->user);
+}
+
+static bool yuvbench_swscale_convert(Ctx* ctx)
+{
+ struct SwsContext* sws = ctx->user;
+ const uint32_t w = ctx->inp_w;
+ const uint32_t h = ctx->inp_h;
+ const uint8_t* Y = (const uint8_t*)ctx->inp_buf;
+ const uint8_t* Cb = Y + (w * h);
+ const uint8_t* Cr = Cb + (w / 2 * h / 2);
+ const uint8_t* const src_slices[] = { Y, Cb, Cr };
+ const int src_strides[] = { w, w / 2, w / 2 };
+ uint8_t* const dst_slices[] = { ctx->out_buf };
+ const int dst_strides[] = { w * 3 };
+ return sws_scale(sws, src_slices, src_strides, 0, h, dst_slices, dst_strides) == (int)h;
+}
+
+Backend yuvbench_swscale(void)
+{
+ Backend b = { 0 };
+ b.init_fn = yuvbench_swscale_init;
+ b.deinit_fn = yuvbench_swscale_deinit;
+ b.convert_fn = yuvbench_swscale_convert;
+ return b;
+}