Skip to content

Add support for NotchLC via ffmpeg#200

Open
dev-joss wants to merge 7 commits into
Marginal:masterfrom
dev-joss:feat/notchlc
Open

Add support for NotchLC via ffmpeg#200
dev-joss wants to merge 7 commits into
Marginal:masterfrom
dev-joss:feat/notchlc

Conversation

@dev-joss

Copy link
Copy Markdown

Tested with https://samples.ffmpeg.org/V-codecs/NotchLC/big_buck_bunny%20NotchLC%20Optimal%20Encoding%201920.mov

Alpha videos have artifacts but that is an ffmpeg bug.

dev-joss and others added 4 commits July 10, 2026 22:20
NotchLC video is carried in native .mov files with FourCC 'nclc', which
macOS demuxes but can't decode. Register the codec with the videodecoder
extension and route it to FFmpeg's built-in notchlc decoder, following the
existing native-container codec pattern (FLIC, HAP, etc.). No FFmpeg
reconfigure needed since all decoders are compiled in by default.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Unlike the RGB-group codecs it was grouped with, NotchLC's decode_init()
ignores codec_tag and bits_per_coded_sample and unconditionally sets
pix_fmt and full color info, so the shared color_range/color_space
assignment (and its comment) don't apply. Split it into a standalone
no-op case with an accurate comment.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ffmpeg's NotchLC decoder outputs a YUV-family planar format tagged with the
RGB/identity matrix, which zscale/zimg rejects ("YUV color family cannot have
RGB matrix coefficients"), dropping every frame to black. Relabel to the
memory-identical GBR-planar format so it takes an RGB conversion path.

INCOMPLETE: colour is still wrong (green cast).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… GBR

FFmpeg's notchlc decoder emits full-range BT.709 YUV (yuva444p12le) but
mislabels the matrix as RGB/identity (AVCOL_SPC_RGB). The previous commit
worked around zscale's "YUV family + RGB matrix" rejection by relabeling the
planes as the memory-identical gbrap12le. That routed Y->Green, Cb->Blue,
Cr->Red with no matrix applied, scrambling the image (green/magenta cast).

Instead, correct the matrix tag to AVCOL_SPC_BT709 and leave the format as
yuv. The frame then takes the normal YUV->RGB path (zscale), which converts
full-range 709 correctly. Verified against Big Buck Bunny (known reference)
and a brand-logo sample: both render with natural colour.

Still guarded to yuva444p12le so genuine RGB/GBR codecs (QTRLE, HAP, DXV,
FLIC) keep taking the RGB path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread videodecoder/videodecoder.swift Outdated
Comment thread videodecoder/videodecoder.swift

@Marginal Marginal left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. And thanks for providing a test sample.
Happy to merge once you've made a couple of changes.

@dev-joss dev-joss requested a review from Marginal July 12, 2026 14:16
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.

2 participants