Commit: 18cca3be7300950c5d0506461606e5d6a9ccfd02
Parent: ef9bfd349de6ad0e71c7652f6fa96f6d979978cf
Author: Randy Palamar
Date:   Tue, 27 May 2025 15:27:54 -0600
build: encode video from build script
no need for python slop for this
Diffstat:
| M | build.c | | | 53 | ++++++++++++++++++++++++++++++++++++++++++----------- | 
| D | make_video.py | | | 64 | ---------------------------------------------------------------- | 
2 files changed, 42 insertions(+), 75 deletions(-)
diff --git a/build.c b/build.c
@@ -17,6 +17,8 @@
 #include "compiler.h"
 #include "util.h"
 
+#include "options.h"
+
 #include <stdarg.h>
 #include <stdio.h>
 
@@ -78,6 +80,9 @@ typedef struct {
 	b32   generic;
 	b32   report;
 	b32   sanitize;
+
+	b32   encode_video;
+	c8   *video_name;
 } Options;
 
 #define die(fmt, ...) die_("%s: " fmt, __FUNCTION__, ##__VA_ARGS__)
@@ -351,11 +356,12 @@ str8_equal(str8 a, str8 b)
 function void
 usage(char *argv0)
 {
-	die("%s [--debug] [--report] [--sanitize]\n"
-	    "    --debug:       dynamically link and build with debug symbols\n"
-	    "    --generic:     compile for a generic target (x86-64-v3 or armv8 with NEON)\n"
-	    "    --report:      print compilation stats (clang only)\n"
-	    "    --sanitize:    build with ASAN and UBSAN\n"
+	die("%s [--debug] [--report] [--sanitize] [--encode-video 'output']\n"
+	    "    --debug:         dynamically link and build with debug symbols\n"
+	    "    --generic:       compile for a generic target (x86-64-v3 or armv8 with NEON)\n"
+	    "    --report:        print compilation stats (clang only)\n"
+	    "    --sanitize:      build with ASAN and UBSAN\n"
+	    "    --encode-video:  encode '" RAW_OUTPUT_PATH "' to 'output'\n"
 	    , argv0);
 }
 
@@ -370,6 +376,10 @@ parse_options(s32 argc, char *argv[])
 		str8 str    = c_str_to_str8(arg);
 		if (str8_equal(str, str8("--debug"))) {
 			result.debug = 1;
+		} else if (str8_equal(str, str8("--encode-video"))) {
+			result.encode_video = 1;
+			if (argc) result.video_name = shift(argv, argc);
+			else      usage(argv0);
 		} else if (str8_equal(str, str8("--generic"))) {
 			result.generic = 1;
 		} else if (str8_equal(str, str8("--report"))) {
@@ -432,6 +442,22 @@ cmd_append_ldflags(Arena *a, CommandList *cc, b32 shared)
 	if (is_unix) cmd_append(a, cc, "-lGL");
 }
 
+function CommandList
+cmd_encode_video(Arena *a, c8 *output_name)
+{
+	CommandList result = {0};
+	cmd_append(a, &result, "ffmpeg", "-y",
+	           "-framerate", str(OUTPUT_FRAME_RATE),
+	           "-f",         "rawvideo",
+	           "-pix_fmt",   "abgr",
+	           "-s:v",       str(RENDER_TARGET_WIDTH) "x" str(RENDER_TARGET_HEIGHT),
+	           "-i",         RAW_OUTPUT_PATH,
+	           "-c:v",       "libx265",
+	           "-crf",       "22",
+	           output_name, (void *)0);
+	return result;
+}
+
 extern s32
 main(s32 argc, char *argv[])
 {
@@ -440,13 +466,18 @@ main(s32 argc, char *argv[])
 
 	Options options = parse_options(argc, argv);
 
-	CommandList c = cmd_base(&arena, &options);
-	if (is_unix) cmd_append(&arena, &c, "-D_GLFW_X11");
-	cmd_append(&arena, &c, "-Iexternal/glfw/include");
+	CommandList c;
+	if (!options.encode_video) {
+		c = cmd_base(&arena, &options);
+		if (is_unix) cmd_append(&arena, &c, "-D_GLFW_X11");
+		cmd_append(&arena, &c, "-Iexternal/glfw/include");
 
-	cmd_append(&arena, &c, OS_MAIN, "external/rglfw.c", "-o", "volviewer");
-	cmd_append_ldflags(&arena, &c, options.debug);
-	cmd_append(&arena, &c, (void *)0);
+		cmd_append(&arena, &c, OS_MAIN, "external/rglfw.c", "-o", "volviewer");
+		cmd_append_ldflags(&arena, &c, options.debug);
+		cmd_append(&arena, &c, (void *)0);
+	} else {
+		c = cmd_encode_video(&arena, options.video_name);
+	}
 
 	return !run_synchronous(arena, &c);
 }
diff --git a/make_video.py b/make_video.py
@@ -1,64 +0,0 @@
-import cv2
-import subprocess
-import tempfile as tf
-import pandas   as pd
-import numpy    as np
-import os
-
-def read_raw(file_name, points):
-    raw = np.fromfile(file_name, dtype=np.uint8)
-    real_points = [points[0], points[1], 4]
-    raw = np.squeeze(raw.reshape(real_points))
-    img = raw[:,:,(1, 2, 3, 0)]
-    return img
-
-def get_files(directory):
-    files = []
-    for filename in os.listdir(directory):
-        base, ext = os.path.splitext(filename)
-        if ext == '.bin':
-            files.append(filename)
-    return files
-
-def make_frames(directory, points):
-    imgs = []
-    for f in get_files(directory):
-        raw_file_name = os.path.join(directory, f)
-        raw           = read_raw(raw_file_name, points)
-        imgs.append(raw)
-    return imgs
-
-
-def make_video(name, frames, framerate):
-    with tf.TemporaryDirectory() as tmp:
-        count = 0
-        for frame in frames:
-            cv2.imwrite(os.path.join(tmp, "frame_{:02d}.png".format(count)), frame)
-            count = count + 1
-
-        ffmpeg_command = [
-            "ffmpeg",
-            "-y",
-            "-framerate", "{:d}".format(framerate),
-            "-i",         os.path.join(tmp, 'frame_%02d.png'),
-            "-c:v",       "libx265",
-            "-crf",       "18",
-            name
-        ]
-        subprocess.run(ffmpeg_command)
-
-
-##################################
-save = True
-out_dir   = "/tmp/downloads"
-points    = [1080, 1920]
-framerate = 60
-if save:
-    os.makedirs(out_dir, mode=0o644, exist_ok=True)
-
-frames = make_frames("/tmp/downloads/out", points)
-if save:
-    make_video(os.path.join(out_dir, "volumes.mp4"), frames, framerate)
-
-#cv2.imshow("", frames[0])
-#cv2.waitKey(0)