Files
hyperframes/packages/core/src/mediaGradeAnalyzer.vendoredParity.test.ts
T

101 lines
2.9 KiB
TypeScript

// @vitest-environment node
import { describe, expect, it } from "vitest";
import {
formatMeasuredNote,
parseMediaTreatmentSignalStats,
statsToAdjust,
summarizeMediaTreatmentAnalysis,
type GradeMediaProbe,
} from "./mediaGradeAnalyzer";
const SIGNALSTATS = `frame:0 pts:0 pts_time:0
lavfi.signalstats.YMIN=4
lavfi.signalstats.YLOW=8
lavfi.signalstats.YAVG=100
lavfi.signalstats.YHIGH=240
lavfi.signalstats.YMAX=250
lavfi.signalstats.UAVG=120
lavfi.signalstats.VAVG=140
lavfi.signalstats.SATAVG=40
frame:1 pts:1 pts_time:1
lavfi.signalstats.YMIN=20
lavfi.signalstats.YLOW=20
lavfi.signalstats.YAVG=120
lavfi.signalstats.YHIGH=220
lavfi.signalstats.YMAX=230
lavfi.signalstats.UAVG=125
lavfi.signalstats.VAVG=135
lavfi.signalstats.SATAVG=60`;
const UNDEREXPOSED_SIGNALSTATS = `frame:0 pts:0 pts_time:0
lavfi.signalstats.YMIN=2
lavfi.signalstats.YLOW=8
lavfi.signalstats.YAVG=50
lavfi.signalstats.YHIGH=120
lavfi.signalstats.YMAX=135
lavfi.signalstats.UAVG=128
lavfi.signalstats.VAVG=128
lavfi.signalstats.SATAVG=30`;
const BLOWN_HIGHLIGHT_SIGNALSTATS = `frame:0 pts:0 pts_time:0
lavfi.signalstats.YMIN=70
lavfi.signalstats.YLOW=90
lavfi.signalstats.YAVG=200
lavfi.signalstats.YHIGH=248
lavfi.signalstats.YMAX=255
lavfi.signalstats.UAVG=128
lavfi.signalstats.VAVG=128
lavfi.signalstats.SATAVG=30`;
const PROBE: GradeMediaProbe = {
duration: 4,
colorSpace: "bt2020nc",
transfer: "smpte2084",
primaries: "bt2020",
pixelFormat: "yuv420p10le",
};
function productResult(signalStats = SIGNALSTATS) {
const frames = parseMediaTreatmentSignalStats(signalStats);
const summary = summarizeMediaTreatmentAnalysis(PROBE, frames);
return {
frames,
summary,
adjust: statsToAdjust(summary.measured),
note: formatMeasuredNote("/tmp/frame.png", summary.measured),
};
}
async function vendoredResult(signalStats = SIGNALSTATS) {
const moduleUrl = new URL(
"../../../skills/media-use/scripts/lib/grade-analyzer.mjs",
import.meta.url,
);
const analyzer = await import(moduleUrl.href);
const frames = analyzer.parseMediaTreatmentSignalStats(signalStats);
const summary = analyzer.summarizeMediaTreatmentAnalysis(PROBE, frames);
return {
frames,
summary,
adjust: analyzer.statsToAdjust(summary.measured),
note: analyzer.formatMeasuredNote("/tmp/frame.png", summary.measured),
};
}
describe("vendored media grade analyzer parity", () => {
it("keeps the standalone skill copy aligned with the typed product module", async () => {
expect(await vendoredResult()).toEqual(productResult());
});
it.each([
["underexposed", UNDEREXPOSED_SIGNALSTATS, 1],
["blown-highlight", BLOWN_HIGHLIGHT_SIGNALSTATS, -1],
])("covers the %s exposure branch", async (_, signalStats, expectedSign) => {
const product = productResult(signalStats);
expect(Math.sign(product.adjust.adjust.exposure)).toBe(expectedSign);
expect(await vendoredResult(signalStats)).toEqual(product);
});
});