Repository navigation
FFmpeg decoder: support planar GBR and 9-bit output - #1920
Merged
Merged
Conversation
FFmpeg's HEVC decoder returns GBRP/GBRP10/GBRP12 instead of YUV 4:4:4 for streams signaling matrix_coefficients 0. Map the G, B, R planes onto Y, Cb, Cr, which is how libheif stores the identity matrix.
This was referenced Sep 25, 2026
FFmpeg returns GRAY9 and YUV420P9/422P9/444P9 (and GBRP9 for AVC with the identity matrix) for 9-bit streams, which were rejected as unsupported pixel formats while libde265 decodes the same files.
farindk
added a commit
that referenced
this pull request
Sep 29, 2026
AVC codes up to 14 bits per sample in the High 4:4:4 Predictive profile. For a 4:4:4 stream that signals matrix_coefficients 0, FFmpeg returns GBRP14, which was still rejected as an unsupported pixel format while YUV444P14 was accepted. Follow-up to #1920.
farindk
added a commit
that referenced
this pull request
Sep 29, 2026
FFmpeg's JPEG decoder returns GBRP for a JPEG that was coded without colour transform (Adobe marker with transform 0, or the component IDs 'R', 'G', 'B'). Since #1920, this format is accepted and its planes are stored as Y, Cb, Cr. For codecs without CICP signalling, the plugin attaches no colour profile to the decoded image. When the file has no 'colr' box either, libheif converted the G, B, R planes with the default YCbCr matrix and the image was decoded with wrong colours. Attach a profile with matrix_coefficients 0 in this case. The colour primaries and the transfer characteristics remain unspecified.
Member
|
Thanks for the PR. I merged it unchanged. Since you had no 9 bit sample, I generated test files and checked the new
I added a few commits on top:
Two things that may matter for your move from libde265 to FFmpeg:
I left out The test files are in https://github.com/farindk/heif-testcorpus:
The HEVC images are in the repository. The AVC and JPEG images are generated |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This came up while migrating Telegram Desktop from libheif + libde265 to libheif + FFmpeg. Both commits add pixel formats that FFmpeg returns and the plugin rejected as unsupported, while libde265 decodes the same files.
Planar GBR. FFmpeg's HEVC decoder returns
AV_PIX_FMT_GBRP/GBRP10/GBRP12instead of YUV 4:4:4 when a 4:4:4 stream signalsmatrix_coefficients = 0(seelibavcodec/hevc_ps.c). The G, B, R planes map directly onto Y, Cb, Cr, which is how libheif represents the identity matrix, and the plugin already takes the nclx profile from the stream, so it only needs to accept these formats.9-bit. FFmpeg returns
GRAY9andYUV420P9/422P9/444P9for 9-bit streams (andGBRP9for 9-bit AVC with the identity matrix).Tested with FFmpeg 6.1.6: 13 files from KDE kimageformats'
autotests/read/heic(rgb,rgba,crop-*) that failed before, and x265-encoded 8/10/12-bit 4:4:4 files with matrix 0, now decode pixel-identically to libde265's output. The 9-bit mappings follow the same pattern; I had no 9-bit sample to test with.🤖 Generated with Claude Code