No description
  • C++ 91.6%
  • Nix 4.2%
  • CMake 1.9%
  • C 1.9%
  • Python 0.4%
Find a file
2026-06-25 09:08:37 -04:00
kernels more stuff 2026-06-25 09:08:37 -04:00
scripts more stuff 2026-06-25 09:08:37 -04:00
src more stuff 2026-06-25 09:08:37 -04:00
.envrc cleanup 2026-06-24 22:26:05 -04:00
.gitignore cleanup 2026-06-24 22:26:05 -04:00
CMakeLists.txt more stuff 2026-06-25 09:08:37 -04:00
flake.lock cleanup 2026-06-24 22:26:05 -04:00
flake.nix more stuff 2026-06-25 09:08:37 -04:00
README.md more stuff 2026-06-25 09:08:37 -04:00
shell.nix cleanup 2026-06-24 22:26:05 -04:00

blended

blended converts high-frame-rate video into lower-frame-rate video by blending decoded frames in groups sized by the number of configured weights. The default uses four equal weights, so the default behavior still targets 240 fps input and 60 fps output.

It prefers an ffmpeg OpenCL filtergraph path for fast end-to-end processing. If that path is unavailable in auto mode, it falls back to a native streaming engine that decodes with ffmpeg, blends with OpenCL when possible, and otherwise uses a threaded CPU fallback.

Quick Start

nix develop
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build

./build/blended input.mp4

With flakes:

nix run . -- input.mp4
nix build
./result/bin/blended input.mp4

Usage

blended <input> [output] [options]

Useful examples:

blended input.mp4
blended input.mp4 output.mp4
blended input.mp4 output.mp4 --weights 1,3,3,1
blended input.mp4 output.mp4 --weights 1,1
blended input.mp4 output.mp4 --scale 0.5
blended input.mp4 output.mp4 --engine native --encoder h264_vaapi --qp 20
blended input.mp4 output.mp4 --engine ffmpeg-opencl --encoder libx264 --crf 16 --preset faster

Inspection commands:

blended --help
blended --version
blended --list-opencl
clinfo
ffmpeg -hwaccels

Options

  • --weights w1,...,wN: N non-negative values, where N is the number of decoded input frames blended into one output frame. Supports 1..64 weights. They are normalized automatically, so --weights 1,3,3,1 is valid. If omitted, four frames are weighted evenly.
  • --scale factor: uniformly scale output dimensions after blending and before encoding. Values below 1 downscale and values above 1 upscale. Scaling uses ffmpeg Lanczos3, and dimensions are rounded to the nearest even pixel count for encoder compatibility.
  • --engine auto|ffmpeg-opencl|native: auto tries ffmpeg-opencl first, then falls back to native.
  • --encoder auto|h264_vaapi|hevc_vaapi|libx264|libx265: auto uses libx264 for ffmpeg-opencl; the native engine uses h264_vaapi when the VAAPI render node exists, otherwise libx264.
  • --crf 0..51: quality for software encoders. Lower is higher quality and larger output. Defaults are 18 for x264 and 20 for x265.
  • --qp 0..51: quality for VAAPI encoders. Lower is higher quality and larger output. Defaults are 18 for H.264 VAAPI and 20 for HEVC VAAPI.
  • --preset name: software encoder speed/compression preset. Defaults are veryfast for x264 and fast for x265.
  • --vaapi-device path: render node used by VAAPI encoders. Defaults to /dev/dri/renderD128.
  • --fps n: explicit output frame rate. Accepts positive integers and rational rates such as 30000/1001. If omitted, the output frame rate is input fps / N, where N is the number of weights; if the input rate cannot be probed, it falls back to 60.
  • output: optional output path. If omitted, the output is written next to the input as <input name without extension>-blended.mp4.

Build Details

Local CMake build:

cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build
cmake --install build --prefix "$PWD/dist"

The CPU fallback is portable by default. To optimize it for the local machine:

cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DBLENDED_NATIVE_ARCH=ON

The Nix package wraps the installed binary so ffmpeg and ffprobe are available on PATH at runtime.

Runtime Notes

  • The output frame count is based on complete groups of N decoded input frames, where N is the number of weights. Any incomplete trailing group is dropped.
  • ffmpeg-opencl blends in NV12 through ffmpeg's OpenCL filter path and avoids piping raw RGBA frames through this process.
  • On the tested AMD ffmpeg stack, direct OpenCL-to-VAAPI zero-copy mapping is not available. If VAAPI is requested with ffmpeg-opencl, blended uses libx264 for that engine.
  • The native engine decodes and encodes with ffmpeg, blends with OpenCL if an OpenCL device is available, and falls back to threaded CPU blending otherwise.
  • On NixOS, OpenCL device discovery depends on the installed GPU runtime and ICD files under /etc/OpenCL/vendors. For AMD, configure ROCm OpenCL or another OpenCL ICD.

Repository Hygiene

Generated build outputs, Nix result links, logs, object files, and local .mp4 scratch videos are ignored. Keep large sample videos outside Git unless they are intentionally published as release assets.