Repository navigation
perf(engine): encode high quality with the x264 fast preset - #6640
Conversation
Edit accuracy: accurate 271 (base branch 271), smooth 139 of thoseThe gate passes. Quarantined, measured but not gated (0) |
There was a problem hiding this comment.
Verdict: APPROVE · 0 blocker · 0 important · 1 nit · head 487ef3bc
One-value change; every reader of ENCODER_PRESETS.high follows it as the body says (local/streaming x264, HDR x265 via getEncoderPreset, distributed chunks via renderChunk + cfrRateControlArgs, NVENC fast→p4, QSV passthrough). The segment-resume hash keys on preset, so cached slow segments are not reused. CI, regression and Windows render verification all pass at this head.
- nit:
packages/engine/src/services/chunkEncoder.test.ts:1074is still titled "translates the high slow preset to NVENC p5". It passesslowexplicitly, so it still passes, but high no longer uses that preset.
Scope
I read chunkEncoder.ts getEncoderPreset, gpuEncoder.ts preset maps, distributed plan.ts/renderChunk.ts/assemble.ts, and segmentManifest.ts. cli/src/cloud/offload.ts hard-codes its own slow for asset re-encodes and is unaffected. Product note, not a finding: high now runs a faster preset than standard (medium). Merge waits on the product call.
What
--quality high(anddelivery) encodes with the x264fastpreset instead ofslow, at the same CRF 15. Same visual quality, about half the encoder CPU, so high-quality renders stop waiting on the encoder after capture ends.Why
x264
slowis often the slowest part of a high-quality render: capture finishes and the render then waits for the encoder to drain. On real frames from a render,fastreaches the same quality at the same CRF for half the CPU:slow(today)fast(this PR)mediumWhy under 100 lines
One lever: the high tier's preset is one value in
ENCODER_PRESETS. The rest is the two tests that pin it.Related work
Refs #5945.
How
ENCODER_PRESETS.high.presetgoes fromslowtofast. Everything that reads the high tier follows:cfrRateControlArgs);slow->fast. On the same 1,271 frames (10-bit, CRF 15): 394.7 -> 153.1 CPU s, 20.3 -> 15.0 MB, VMAF 97.49 (96.41) -> 97.19 (96.04). A larger step than x264's, still far under one just-noticeable difference;fasttop4(wasp5), the level standard already uses; QSV getsfast;CRF, rate control,
x264-paramsand every other quality setting are unchanged. Standard and draft are unchanged.Test plan
chunkEncoder.test.ts > ENCODER_PRESETS > high uses the fast preset with low CRF for better qualityandassemble.test.ts > assemble() > cfr re-encode keeps the chunks' rate control(each fails with only the test change applied).chunkEncoder.test.ts109 passed,assemble.test.ts20 passed;tsc --noEmit(engine) exit 0; oxfmt and oxlint clean.Before / after
Published
hyperframes@0.8.210vs the same bundle with only the preset changed,hyperframes render --quality high. Apple M4 Pro (14 cores, 24 GB), interleaved, medians (3 runs for the short fixtures, 2 for the long ones).wall - compiledrops compile, which is network-bound. VMAF is against a lossless (--crf 0) render of the same frames.style-11-prod, 1080x1920, 14 soverlay-montage-prod+ one mix-blend layer, 42 sThis 14-core Mac mostly keeps up with
slowat 4 workers. Where the encoder is the limit, the gap opens: the same Mac with 8 capture workers (#6636) leaves the encoder less CPU.style-11-prod, 14 sPeak memory (CLI + Chrome + ffmpeg) is equal or lower with
faston every fixture.