mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-05 00:56:23 +00:00
fix(engine): support AMD AMF GPU encoding
This commit is contained in:
@@ -256,6 +256,28 @@ describe("buildEncoderArgs GPU preset mapping", () => {
|
||||
);
|
||||
expect(presetArg(args)).toBe("medium");
|
||||
});
|
||||
|
||||
it("uses AMD AMF encoder names and quality flags when selected", () => {
|
||||
const h264Args = buildEncoderArgs(
|
||||
{ ...baseOptions, codec: "h264", preset: "medium", quality: 23, useGpu: true },
|
||||
inputArgs,
|
||||
"out.mp4",
|
||||
"amf",
|
||||
);
|
||||
expect(h264Args[h264Args.indexOf("-c:v") + 1]).toBe("h264_amf");
|
||||
expect(h264Args[h264Args.indexOf("-qp_i") + 1]).toBe("23");
|
||||
expect(h264Args).toContain("-bf");
|
||||
expect(h264Args[h264Args.indexOf("-bf") + 1]).toBe("0");
|
||||
|
||||
const h265Args = buildEncoderArgs(
|
||||
{ ...baseOptions, codec: "h265", preset: "medium", quality: 23, useGpu: true },
|
||||
inputArgs,
|
||||
"out.mp4",
|
||||
"amf",
|
||||
);
|
||||
expect(h265Args[h265Args.indexOf("-c:v") + 1]).toBe("hevc_amf");
|
||||
expect(h265Args[h265Args.indexOf("-qp_i") + 1]).toBe("23");
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildEncoderArgs color space", () => {
|
||||
@@ -529,7 +551,7 @@ describe("buildEncoderArgs lockGopForChunkConcat", () => {
|
||||
|
||||
it("true is a no-op on GPU encoders", () => {
|
||||
// GPU encoders take a separate code path; lockGopForChunkConcat does not
|
||||
// wire `-g` / `-keyint_min` into nvenc/qsv/vaapi.
|
||||
// wire `-g` / `-keyint_min` into nvenc/amf/qsv/vaapi.
|
||||
const args = buildEncoderArgs(
|
||||
{
|
||||
...baseOptions,
|
||||
@@ -816,7 +838,7 @@ describe("buildEncoderArgs HDR color space", () => {
|
||||
});
|
||||
|
||||
it("tags BT.2020 + transfer for HDR GPU H.265 (no mastering metadata via -x265-params)", () => {
|
||||
// GPU encoders (nvenc, videotoolbox, qsv, vaapi) still emit the BT.2020
|
||||
// GPU encoders (nvenc, videotoolbox, amf, qsv, vaapi) still emit the BT.2020
|
||||
// color tags via the codec-level -colorspace/-color_primaries/-color_trc
|
||||
// flags, but cannot accept x265-params, so HDR static mastering metadata
|
||||
// (master-display, max-cll) is not embedded. Acceptable for previews,
|
||||
|
||||
@@ -140,9 +140,13 @@ export function buildEncoderArgs(
|
||||
if (bitrate) args.push("-b:v", bitrate);
|
||||
else args.push("-global_quality", String(quality));
|
||||
break;
|
||||
case "amf":
|
||||
if (bitrate) args.push("-b:v", bitrate);
|
||||
else args.push("-rc", "cqp", "-qp_i", String(quality), "-qp_p", String(quality));
|
||||
break;
|
||||
}
|
||||
|
||||
// Same B-frame story as the SW branch below — nvenc emits B-frames
|
||||
// Same B-frame story as the SW branch below — nvenc/amf emit B-frames
|
||||
// by default (qsv via b_strategy, vaapi too), and the negative-DTS
|
||||
// freeze hits the same downstream players. The unconditional
|
||||
// `-avoid_negative_ts make_zero` near the bottom of this function
|
||||
@@ -153,7 +157,10 @@ export function buildEncoderArgs(
|
||||
// negative DTS in practice on macOS Sonoma+.
|
||||
if (
|
||||
codec === "h264" &&
|
||||
(gpuEncoder === "nvenc" || gpuEncoder === "qsv" || gpuEncoder === "vaapi")
|
||||
(gpuEncoder === "nvenc" ||
|
||||
gpuEncoder === "qsv" ||
|
||||
gpuEncoder === "vaapi" ||
|
||||
gpuEncoder === "amf")
|
||||
) {
|
||||
args.push("-bf", "0");
|
||||
if (gpuEncoder === "qsv") {
|
||||
|
||||
@@ -265,6 +265,26 @@ describe("buildStreamingArgs", () => {
|
||||
const args = buildStreamingArgs({ ...baseGpu, preset: "medium" }, "/tmp/out.mp4", "qsv");
|
||||
expect(presetArg(args)).toBe("medium");
|
||||
});
|
||||
|
||||
it("uses AMD AMF encoder names and quality flags when selected", () => {
|
||||
const h264Args = buildStreamingArgs(
|
||||
{ ...baseGpu, preset: "medium", quality: 23 },
|
||||
"/tmp/out.mp4",
|
||||
"amf",
|
||||
);
|
||||
expect(h264Args[h264Args.indexOf("-c:v") + 1]).toBe("h264_amf");
|
||||
expect(h264Args[h264Args.indexOf("-qp_i") + 1]).toBe("23");
|
||||
expect(h264Args).toContain("-bf");
|
||||
expect(h264Args[h264Args.indexOf("-bf") + 1]).toBe("0");
|
||||
|
||||
const h265Args = buildStreamingArgs(
|
||||
{ ...baseGpu, codec: "h265", preset: "medium", quality: 23 },
|
||||
"/tmp/out.mp4",
|
||||
"amf",
|
||||
);
|
||||
expect(h265Args[h265Args.indexOf("-c:v") + 1]).toBe("hevc_amf");
|
||||
expect(h265Args[h265Args.indexOf("-qp_i") + 1]).toBe("23");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -231,14 +231,21 @@ export function buildStreamingArgs(
|
||||
if (bitrate) args.push("-b:v", bitrate);
|
||||
else args.push("-global_quality", String(quality));
|
||||
break;
|
||||
case "amf":
|
||||
if (bitrate) args.push("-b:v", bitrate);
|
||||
else args.push("-rc", "cqp", "-qp_i", String(quality), "-qp_p", String(quality));
|
||||
break;
|
||||
}
|
||||
|
||||
// Mirror SW branch: GPU h264 paths emit B-frames by default (nvenc, qsv,
|
||||
// vaapi) and produce the same negative-DTS freeze for downstream players.
|
||||
// Mirror SW branch: GPU h264 paths emit B-frames by default (nvenc, amf,
|
||||
// qsv, vaapi) and produce the same negative-DTS freeze for downstream players.
|
||||
// See chunkEncoder.buildEncoderArgs for the full explanation.
|
||||
if (
|
||||
codec === "h264" &&
|
||||
(gpuEncoder === "nvenc" || gpuEncoder === "qsv" || gpuEncoder === "vaapi")
|
||||
(gpuEncoder === "nvenc" ||
|
||||
gpuEncoder === "qsv" ||
|
||||
gpuEncoder === "vaapi" ||
|
||||
gpuEncoder === "amf")
|
||||
) {
|
||||
args.push("-bf", "0");
|
||||
if (gpuEncoder === "qsv") {
|
||||
|
||||
Reference in New Issue
Block a user