feat(render): auto-detect HDR from media probes, add --sdr flag (#526)

* feat(render): auto-detect HDR from media probes, add --sdr flag

Replace the --hdr opt-in model with automatic detection. When no flags
are passed, the renderer probes all video/image sources and enables HDR
output if any HDR color space is detected. Existing --hdr flag becomes
a force override. New --sdr flag forces SDR output.

Behavior matrix:
  (no flags) + HDR content → HDR output
  (no flags) + SDR content → SDR output
  --hdr → force HDR (defaults to HLG if no HDR sources)
  --sdr → force SDR (skips probing)
  --hdr --sdr → error

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: align HDR auto-detect docs and tests

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Vance Ingalls
2026-04-28 01:39:51 -07:00
committed by GitHub
co-authored by Claude Opus 4.6
parent 4d0e262eb3
commit 8e5593b6ba
11 changed files with 140 additions and 69 deletions
+17 -9
View File
@@ -6,7 +6,7 @@ const BASE: DockerRenderOptions = {
quality: "standard",
format: "mp4",
gpu: false,
hdr: false,
hdrMode: "auto",
crf: undefined,
videoBitrate: undefined,
quiet: false,
@@ -57,9 +57,8 @@ describe("buildDockerRunArgs", () => {
...FIXED_INPUT,
options: {
...BASE,
workers: 4,
gpu: true,
hdr: true,
hdrMode: "force-hdr",
crf: 18,
videoBitrate: undefined,
quiet: true,
@@ -88,8 +87,6 @@ describe("buildDockerRunArgs", () => {
"standard",
"--format",
"mp4",
"--workers",
"4",
"--crf",
"18",
"--quiet",
@@ -102,17 +99,28 @@ describe("buildDockerRunArgs", () => {
// Regression for the original PR feedback: --hdr was silently dropped from
// the docker arg array. Keep this assertion explicit (in addition to the
// snapshot above) so the failure message points directly at the flag.
it("forwards --hdr to the container when hdr is enabled", () => {
it("forwards --hdr to the container when hdrMode is force-hdr", () => {
const args = buildDockerRunArgs({
...FIXED_INPUT,
options: { ...BASE, hdr: true },
options: { ...BASE, hdrMode: "force-hdr" },
});
expect(args).toContain("--hdr");
expect(args).not.toContain("--sdr");
});
it("omits --hdr when hdr is disabled", () => {
it("forwards --sdr to the container when hdrMode is force-sdr", () => {
const args = buildDockerRunArgs({
...FIXED_INPUT,
options: { ...BASE, hdrMode: "force-sdr" },
});
expect(args).toContain("--sdr");
expect(args).not.toContain("--hdr");
});
it("omits --hdr and --sdr when hdrMode is auto", () => {
const args = buildDockerRunArgs({ ...FIXED_INPUT, options: BASE });
expect(args).not.toContain("--hdr");
expect(args).not.toContain("--sdr");
});
it("requests host GPU passthrough only when gpu is enabled", () => {
@@ -140,7 +148,7 @@ describe("buildDockerRunArgs", () => {
format: "webm",
workers: 8,
gpu: true,
hdr: true,
hdrMode: "force-hdr",
crf: 16,
videoBitrate: undefined,
quiet: true,
+3 -2
View File
@@ -24,7 +24,7 @@ export interface DockerRenderOptions {
format: "mp4" | "webm" | "mov";
workers?: number;
gpu: boolean;
hdr: boolean;
hdrMode: "auto" | "force-hdr" | "force-sdr";
crf?: number;
videoBitrate?: string;
quiet: boolean;
@@ -59,6 +59,7 @@ export function buildDockerRunArgs(input: DockerRunArgsInput): string[] {
...(options.videoBitrate ? ["--video-bitrate", options.videoBitrate] : []),
...(options.quiet ? ["--quiet"] : []),
...(options.gpu ? ["--gpu"] : []),
...(options.hdr ? ["--hdr"] : []),
...(options.hdrMode === "force-hdr" ? ["--hdr"] : []),
...(options.hdrMode === "force-sdr" ? ["--sdr"] : []),
];
}