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)