volviewer

Volumetric Data Toy Viewer
git clone anongit@rnpnr.xyz:volviewer.git
Log | Files | Refs | Feed | LICENSE

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:
Mbuild.c | 53++++++++++++++++++++++++++++++++++++++++++-----------
Dmake_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)