Skip to content

Export: a 10-bit H.265 format for dark gradients - #858

Merged
CaYatur merged 1 commit into
mainfrom
feat/hevc-10bit
Oct 27, 2026
Merged

CaYatur merged 1 commit into
mainfrom
feat/hevc-10bit

Conversation

@CaYatur

@CaYatur CaYatur commented Oct 27, 2026

Copy link
Copy Markdown
Owner

What

A twelfth export format, MP4 — H.265 10-bit (H.265 Main 10, yuv420p10le, BT.709 and hvc1 tags). It is opt-in: existing formats, profiles and their ffmpeg arguments are unchanged.

Why

Dark, smooth gradients band in 8-bit: the YUV conversion and the compression turn them into flat steps. The picture is still drawn in 8-bit RGBA, so 10-bit does not remove steps already in the drawing; it stops the encoder adding more.

How

  • depth: 10 on the format; videoArgs adds -profile:v main10 and yuv420p10le (x265) or p010le (NVENC, Quick Sync).
  • ffmpeg's AMF encoder takes no 10-bit input, so AMF is not offered for this format (tenBit flag on the encoder table).
  • 10-bit is probed with its own key (hevc_nvenc@10) and the real 10-bit arguments, since a GPU can encode 8-bit and not 10-bit. pickEncoder and available look the key up themselves; the capabilities list uses it too.
  • takesYuv420 is false for this format, so frames go as RGBA, not through the GPU's 8-bit I420 path.

Measured

Dark gradient scene, 1080p30, 4 s, PSNR against the raw RGBA frames the renderer sent (16-bit RGB, no dithering):

size PSNR
x265 8-bit 560 kB 48.35 dB
x265 10-bit 553 kB 49.87 dB
NVENC 8-bit 740 kB 49.42 dB
NVENC 10-bit 710 kB 51.20 dB

A contrast-stretched crop shows large flat blocks in the 8-bit file; the 10-bit one follows the gradient. ffprobe: Main 10, yuv420p10le, bt709 primaries, transfer, matrix and range for both encoders. Speed: about 1.6× the 8-bit time (RGBA instead of I420). Quick Sync could not be checked on this machine; it is offered only where its own 10-bit test encode passes.

Tests

Four new tests: arguments per encoder, no I420 path, AMF excluded and separate probe keys, encoder choice following the 10-bit probe. npm test: 3577/3577.

Adds "MP4 — H.265 10-bit" (Main 10, yuv420p10le, BT.709 and hvc1 tags)
with x265, NVENC and Quick Sync. AMF is not offered: ffmpeg's AMF encoder
takes no 10-bit input. 10-bit is probed separately from 8-bit
(hevc_nvenc@10), since a GPU can encode one and not the other. The format
takes RGBA frames; the GPU's 8-bit I420 path is not used.

Measured on a dark gradient (1080p30, 4 s) against the raw RGBA frames at
about the same size: x265 48.35 -> 49.87 dB PSNR, NVENC 49.42 -> 51.20 dB.
Existing formats and profiles are unchanged.

Co-authored-by: caganturgut <271973834+caganturgut@users.noreply.github.com>
@CaYatur
CaYatur merged commit 11c9bce into main Oct 27, 2026
5 checks passed
@CaYatur
CaYatur deleted the feat/hevc-10bit branch October 27, 2026 14:37
@cayadraft

cayadraft Bot commented Oct 27, 2026

Copy link
Copy Markdown

@CaYatur

CaYaDraft — pull request

Summary
This pull request adds a new export format, "MP4 — H.265 10-bit," designed to reduce banding in dark gradients by encoding video at 10-bit depth instead of the standard 8-bit. The implementation introduces specific probe keys and arguments for both x265 and NVENC encoders to support this format while excluding AMF, which does not handle 10-bit input.

Files

  • CHANGELOG.md (updated version history)
  • README.md & README.tr.md (minor text changes)
  • ROADMAP.md (test count update)
  • src/main/main.js (encoder probing logic for 10-bit)
  • src/shared/export-formats.js (format definitions and probe keys)
  • src/shared/i18n.js (new format label)
  • tests/export-formats.test.js (added tests for 10-bit support)

Note
Nothing blocking is visible from the text.


Stopping here. I will not merge, push, or change this pull request until you ask.

/caya explain describes the diff. /caya plan previews the next edit. /caya revise adds a commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant