Commit 21dc3ea0 for libheif
commit 21dc3ea00b09a91a1251593056b412416d73e76d
Author: Dirk Farin <dirk.farin@gmail.com>
Date: Tue Sep 29 18:54:12 2026 +0200
Document the HEVC bit depths of the FFmpeg decoder and the 15 bit limit
FFmpeg's HEVC decoder handles 8, 9, 10 and 12 bits per sample. All other
bit depths have to be decoded with libde265, which needs v1.1.3 to decode
image sequences with more than 12 bits correctly.
Also state in the README that HEVC images are limited to 15 bits, because
the 'hvcC' box cannot signal 16 bits.
diff --git a/README.md b/README.md
index 35fa80c1..00813311 100644
--- a/README.md
+++ b/README.md
@@ -296,6 +296,13 @@ You can also add plugin directories programmatically.
* The FFMPEG decoding plugin can make use of h265 hardware decoders. However, it currently (v1.17.0, ffmpeg v4.4.2) does not work
correctly with all streams. Thus, libheif still prefers the libde265 decoder if it is available.
+* The FFMPEG decoder handles HEVC images with 8, 9, 10 and 12 bits per sample only. Images with 11 bits or with 13 to 15 bits
+ have to be decoded with libde265. Use libde265 v1.1.3 or later for these, since earlier versions do not decode image sequences
+ with more than 12 bits correctly.
+
+* HEVC images can have up to 15 bits per sample. HEVC itself allows 16 bits, but the `hvcC` box of the file format cannot signal
+ this bit depth. libheif refuses to encode HEVC images with 16 bits per sample.
+
* The "webcodecs" HEVC decoder can only be used in emscripten builds since it uses the web-browser's API. For the same reason, it is not available as a plugin.
## Usage
diff --git a/libheif/plugins/decoder_ffmpeg.cc b/libheif/plugins/decoder_ffmpeg.cc
index bd1c2fe2..0f315a54 100644
--- a/libheif/plugins/decoder_ffmpeg.cc
+++ b/libheif/plugins/decoder_ffmpeg.cc
@@ -118,6 +118,12 @@ static int ffmpeg_does_support_format(heif_compression_format format)
{
switch(format) {
case heif_compression_HEVC:
+ // FFmpeg's HEVC decoder handles 8, 9, 10 and 12 bits per sample only (FFmpeg 6.1 and 7.1).
+ // For streams with 11 bits or with 13 to 16 bits, avcodec_send_packet() fails. libde265
+ // decodes all bit depths and is the decoder to use for these streams. It has the higher
+ // priority, so that it is chosen whenever it is available.
+ // We cannot return 0 for the bit depths that FFmpeg does not handle: the format
+ // description passed to does_support_format2() holds the compression format only.
return avcodec_find_decoder(AV_CODEC_ID_HEVC) ? FFMPEG_DECODER_PLUGIN_PRIORITY : 0;
case heif_compression_AVC:
return avcodec_find_decoder(AV_CODEC_ID_H264) ? FFMPEG_DECODER_PLUGIN_PRIORITY : 0;