From 297fa47d563b2aac1632fad61b27a0e55647491d Mon Sep 17 00:00:00 2001 From: roi32 <75878108+roi32@users.noreply.github.com> Date: Thu, 23 Apr 2026 18:53:36 +0300 Subject: [PATCH] test(engine): cover h265 NVENC in preset-mapping regression tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit hevc_nvenc uses the same p1..p7 preset vocabulary as h264_nvenc, so the mapping in `mapPresetForGpuEncoder` applies to both codecs. The initial regression suite only covered `codec: "h264"`, which left a gap: a future refactor that split the H.264 and H.265 NVENC paths could silently regress one codec without any test catching it. Add three-case loops (ultrafast → p1, medium → p4, veryslow → p7) under `codec: "h265"` to both `buildEncoderArgs` and `buildStreamingArgs` test blocks. Each case also asserts that `-c:v hevc_nvenc` is selected so the test fails loudly if the codec plumbing is broken, not just the preset translation. Follow-up to #442 per review comment from @jrusso1020. --- .../engine/src/services/chunkEncoder.test.ts | 20 +++++++++++++++++++ .../src/services/streamingEncoder.test.ts | 18 +++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/packages/engine/src/services/chunkEncoder.test.ts b/packages/engine/src/services/chunkEncoder.test.ts index efb7d2691..6a2fe93c5 100644 --- a/packages/engine/src/services/chunkEncoder.test.ts +++ b/packages/engine/src/services/chunkEncoder.test.ts @@ -190,6 +190,26 @@ describe("buildEncoderArgs GPU preset mapping", () => { expect(presetArg(args)).toBe("p5"); }); + // hevc_nvenc uses the same p1..p7 preset vocabulary as h264_nvenc, so the + // mapping must apply to both codecs. Locks in "H.264 and H.265 NVENC share + // the preset mapping" against a future refactor that might split the path. + it("translates libx264 preset names to NVENC p1..p7 for h265 as well", () => { + for (const [libx264, nvencPreset] of [ + ["ultrafast", "p1"], + ["medium", "p4"], + ["veryslow", "p7"], + ] as const) { + const args = buildEncoderArgs( + { ...baseOptions, codec: "h265", preset: libx264, quality: 23, useGpu: true }, + inputArgs, + "out.mp4", + "nvenc", + ); + expect(args[args.indexOf("-c:v") + 1]).toBe("hevc_nvenc"); + expect(presetArg(args)).toBe(nvencPreset); + } + }); + it("rewrites QSV's unsupported ultrafast preset to veryfast", () => { const args = buildEncoderArgs( { ...baseOptions, codec: "h264", preset: "ultrafast", quality: 28, useGpu: true }, diff --git a/packages/engine/src/services/streamingEncoder.test.ts b/packages/engine/src/services/streamingEncoder.test.ts index 214413501..65e124fdf 100644 --- a/packages/engine/src/services/streamingEncoder.test.ts +++ b/packages/engine/src/services/streamingEncoder.test.ts @@ -191,6 +191,24 @@ describe("buildStreamingArgs", () => { expect(presetArg(args)).toBe("p4"); }); + // Same mapping applies to hevc_nvenc: NVENC's preset vocabulary is + // codec-agnostic, so the helper must translate for H.265 too. + it("translates libx264 preset names to NVENC pN for h265 as well", () => { + for (const [libx264, nvencPreset] of [ + ["ultrafast", "p1"], + ["medium", "p4"], + ["veryslow", "p7"], + ] as const) { + const args = buildStreamingArgs( + { ...baseGpu, codec: "h265", preset: libx264 }, + "/tmp/out.mp4", + "nvenc", + ); + expect(args[args.indexOf("-c:v") + 1]).toBe("hevc_nvenc"); + expect(presetArg(args)).toBe(nvencPreset); + } + }); + it("rewrites QSV's unsupported ultrafast preset to veryfast", () => { const args = buildStreamingArgs(baseGpu, "/tmp/out.mp4", "qsv"); expect(presetArg(args)).toBe("veryfast");