mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-08 02:36:10 +00:00
fix(engine): merge colour per field, detect alpha correctly, defer PNG parse
Three defects in how ffprobe output and the PNG fallback are combined. The cICP fallback was unreachable. `ffprobeColorSpace ?? stillImageMeta ?.colorSpace` discarded the PNG result whenever ffprobe returned ANY colour field — and ffprobe emits color_space "gbr" for every PNG, including a plain rgb24 with no colour metadata. So on the build the parser exists for (reports gbr, does not decode cICP) an HDR PQ PNG resolved colorTransfer "" , isHdrColorSpace() returned false, and the still graded SDR. Now merged per field. hasAlpha's anchor bound to one alternative. In /(^|[^a-z])yuva|rgba|.../ the `|` is looser than concatenation, so (^|[^a-z]) guarded `yuva` and nothing else. The list also omitted abgr, ya8, ya16 and ayuv64, and `gray[a-z0-9]*a` matched only gray8a/gray16a — names FFmpeg renamed to ya8/ya16 in 2013, so dead against modern builds. A ya8 grayscale-plus-alpha PNG reported hasAlpha:false, resolveFrameFormat picked jpg and the overlay flattened to an opaque rectangle. Replaced with the start-anchored form studio-server already uses, extracted as exported pixelFormatHasAlpha so the test asserts the shipped predicate rather than a copy of the pattern. The PNG parse ran eagerly and was discarded. It sat before the first await, so readFileSync plus the CRC walk executed for every file before a single ffprobe was spawned — a caller fanning out over composition.images with Promise.all serialised entirely: 12 4K PNGs took 2649 ms against 170 ms probe-only, 2.5 s of event-loop stall that also blocks Puppeteer IPC. On the happy path the value was then thrown away. Now lazily memoized behind the paths that actually consult it. Tests: 18 pix_fmt cases against the real predicate. Reverting the regex fails 4. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
e0c6fdfe0a
commit
62b96c227e
@@ -3,7 +3,11 @@ import { EventEmitter } from "events";
|
||||
import { readFileSync } from "fs";
|
||||
import { basename, resolve } from "path";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { extractMediaMetadata, extractPngMetadataFromBuffer } from "./ffprobe.js";
|
||||
import {
|
||||
extractMediaMetadata,
|
||||
extractPngMetadataFromBuffer,
|
||||
pixelFormatHasAlpha,
|
||||
} from "./ffprobe.js";
|
||||
|
||||
function crc32(buf: Buffer): number {
|
||||
let crc = 0xffffffff;
|
||||
@@ -750,3 +754,24 @@ describe("crc32 works on every runtime the package declares", () => {
|
||||
expect(fresh.extractPngMetadataFromBuffer(png)).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("pix_fmt alpha detection", () => {
|
||||
// The old pattern's (^|[^a-z]) anchor bound to `yuva` alone, and the list
|
||||
// omitted formats real files actually use.
|
||||
const ALPHA = [
|
||||
"yuva420p",
|
||||
"rgba",
|
||||
"argb",
|
||||
"bgra",
|
||||
"abgr",
|
||||
"gbrap",
|
||||
"ya8",
|
||||
"ya16le",
|
||||
"ayuv64le",
|
||||
"yuva444p12le",
|
||||
];
|
||||
const OPAQUE = ["yuv420p", "rgb24", "gray", "gbrp", "nv12", "yuv444p10le", "bgr0", "rgb0"];
|
||||
|
||||
it.each(ALPHA)("detects alpha in %s", (fmt) => expect(pixelFormatHasAlpha(fmt)).toBe(true));
|
||||
it.each(OPAQUE)("reports %s as opaque", (fmt) => expect(pixelFormatHasAlpha(fmt)).toBe(false));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user