[FFmpeg-cvslog] avcodec/libjxl: add #ifdef guards for libjxl >= 0.8.0 features

Leo Izen git at videolan.org
Mon Feb 6 20:06:13 EET 2023


ffmpeg | branch: master | Leo Izen <leo.izen at gmail.com> | Sat Feb  4 16:29:15 2023 -0500| [000934830620c03be55644e054f9ffaaadac2a0a] | committer: Leo Izen

avcodec/libjxl: add #ifdef guards for libjxl >= 0.8.0 features

Since many distributions ship libjxl 0.7.0 still, we'd still prefer to
compile against that, but don't want to lose the features that require
libjxl 0.8.0 or greater. For this reason I've added preprocessor #ifdef
guards around the features that aren't necessarily in libjxl 0.7.0.

Signed-off-by: Leo Izen <leo.izen at gmail.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=000934830620c03be55644e054f9ffaaadac2a0a
---

 libavcodec/libjxl.h    | 12 ++++++++++++
 libavcodec/libjxldec.c | 19 +++++++++++++------
 libavcodec/libjxlenc.c | 18 ++++++++++++++----
 3 files changed, 39 insertions(+), 10 deletions(-)

diff --git a/libavcodec/libjxl.h b/libavcodec/libjxl.h
index 5387c438fd..e305b6e758 100644
--- a/libavcodec/libjxl.h
+++ b/libavcodec/libjxl.h
@@ -27,8 +27,20 @@
 #ifndef AVCODEC_LIBJXL_H
 #define AVCODEC_LIBJXL_H
 
+#include <jxl/decode.h>
 #include <jxl/memory_manager.h>
 
+/*
+ * libjxl version 0.7.0 and earlier doesn't contain these macros at all
+ * so to detect version 0.7.0 versus 0.8.0 we need to define them ourselves
+ */
+#ifndef JPEGXL_COMPUTE_NUMERIC_VERSION
+    #define JPEGXL_COMPUTE_NUMERIC_VERSION(major,minor,patch) ((major<<24) | (minor<<16) | (patch<<8) | 0)
+#endif
+#ifndef JPEGXL_NUMERIC_VERSION
+    #define JPEGXL_NUMERIC_VERSION JPEGXL_COMPUTE_NUMERIC_VERSION(0, 7, 0)
+#endif
+
 /**
  * Transform threadcount in ffmpeg to one used by libjxl.
  *
diff --git a/libavcodec/libjxldec.c b/libavcodec/libjxldec.c
index abe08eb400..045a1535f9 100644
--- a/libavcodec/libjxldec.c
+++ b/libavcodec/libjxldec.c
@@ -47,7 +47,9 @@ typedef struct LibJxlDecodeContext {
     JxlDecoder *decoder;
     JxlBasicInfo basic_info;
     JxlPixelFormat jxl_pixfmt;
+#if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
     JxlBitDepth jxl_bit_depth;
+#endif
     JxlDecoderStatus events;
     AVBufferRef *iccp;
 } LibJxlDecodeContext;
@@ -94,14 +96,17 @@ static av_cold int libjxl_decode_init(AVCodecContext *avctx)
     return libjxl_init_jxl_decoder(avctx);
 }
 
-static enum AVPixelFormat libjxl_get_pix_fmt(AVCodecContext *avctx, const JxlBasicInfo *basic_info,
-                                             JxlPixelFormat *format, JxlBitDepth *depth)
+static enum AVPixelFormat libjxl_get_pix_fmt(AVCodecContext *avctx, LibJxlDecodeContext *ctx)
 {
+    const JxlBasicInfo *basic_info = &ctx->basic_info;
+    JxlPixelFormat *format = &ctx->jxl_pixfmt;
     format->endianness = JXL_NATIVE_ENDIAN;
     format->num_channels = basic_info->num_color_channels + (basic_info->alpha_bits > 0);
-    depth->bits_per_sample = avctx->bits_per_raw_sample = basic_info->bits_per_sample;
-    depth->type = JXL_BIT_DEPTH_FROM_PIXEL_FORMAT;
-    depth->exponent_bits_per_sample = basic_info->exponent_bits_per_sample;
+#if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
+    ctx->jxl_bit_depth.bits_per_sample = avctx->bits_per_raw_sample = basic_info->bits_per_sample;
+    ctx->jxl_bit_depth.type = JXL_BIT_DEPTH_FROM_PIXEL_FORMAT;
+    ctx->jxl_bit_depth.exponent_bits_per_sample = basic_info->exponent_bits_per_sample;
+#endif
     /* Gray */
     if (basic_info->num_color_channels == 1) {
         if (basic_info->bits_per_sample <= 8) {
@@ -372,7 +377,7 @@ static int libjxl_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_f
                 av_log(avctx, AV_LOG_ERROR, "Bad libjxl basic info event\n");
                 return AVERROR_EXTERNAL;
             }
-            avctx->pix_fmt = libjxl_get_pix_fmt(avctx, &ctx->basic_info, &ctx->jxl_pixfmt, &ctx->jxl_bit_depth);
+            avctx->pix_fmt = libjxl_get_pix_fmt(avctx, ctx);
             if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
                 av_log(avctx, AV_LOG_ERROR, "Bad libjxl pixel format\n");
                 return AVERROR_EXTERNAL;
@@ -395,10 +400,12 @@ static int libjxl_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_f
                 av_log(avctx, AV_LOG_ERROR, "Bad libjxl dec need image out buffer event\n");
                 return AVERROR_EXTERNAL;
             }
+#if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
             if (JxlDecoderSetImageOutBitDepth(ctx->decoder, &ctx->jxl_bit_depth) != JXL_DEC_SUCCESS) {
                 av_log(avctx, AV_LOG_ERROR, "Error setting output bit depth\n");
                 return AVERROR_EXTERNAL;
             }
+#endif
             continue;
         case JXL_DEC_FULL_IMAGE:
             /* full image is one frame, even if animated */
diff --git a/libavcodec/libjxlenc.c b/libavcodec/libjxlenc.c
index c51024f180..897452f575 100644
--- a/libavcodec/libjxlenc.c
+++ b/libavcodec/libjxlenc.c
@@ -250,7 +250,10 @@ static int libjxl_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFra
     JxlBasicInfo info;
     JxlColorEncoding jxl_color;
     JxlPixelFormat jxl_fmt;
+    int bits_per_sample;
+#if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
     JxlBitDepth jxl_bit_depth;
+#endif
     JxlEncoderStatus jret;
     int ret;
     size_t available = ctx->buffer_size;
@@ -270,22 +273,26 @@ static int libjxl_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFra
     info.ysize = frame->height;
     info.num_extra_channels = (jxl_fmt.num_channels + 1) % 2;
     info.num_color_channels = jxl_fmt.num_channels - info.num_extra_channels;
-    jxl_bit_depth.bits_per_sample = av_get_bits_per_pixel(pix_desc) / jxl_fmt.num_channels;
+    bits_per_sample = av_get_bits_per_pixel(pix_desc) / jxl_fmt.num_channels;
     info.bits_per_sample = avctx->bits_per_raw_sample > 0 && !(pix_desc->flags & AV_PIX_FMT_FLAG_FLOAT)
-                           ? avctx->bits_per_raw_sample : jxl_bit_depth.bits_per_sample;
+                           ? avctx->bits_per_raw_sample : bits_per_sample;
     info.alpha_bits = (info.num_extra_channels > 0) * info.bits_per_sample;
     if (pix_desc->flags & AV_PIX_FMT_FLAG_FLOAT) {
         info.exponent_bits_per_sample = info.bits_per_sample > 16 ? 8 : 5;
         info.alpha_exponent_bits = info.alpha_bits ? info.exponent_bits_per_sample : 0;
         jxl_fmt.data_type = info.bits_per_sample > 16 ? JXL_TYPE_FLOAT : JXL_TYPE_FLOAT16;
-        jxl_bit_depth.exponent_bits_per_sample = info.exponent_bits_per_sample;
     } else {
         info.exponent_bits_per_sample = 0;
         info.alpha_exponent_bits = 0;
         jxl_fmt.data_type = info.bits_per_sample <= 8 ? JXL_TYPE_UINT8 : JXL_TYPE_UINT16;
-        jxl_bit_depth.exponent_bits_per_sample = 0;
     }
+
+#if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
+    jxl_bit_depth.bits_per_sample = bits_per_sample;
     jxl_bit_depth.type = JXL_BIT_DEPTH_FROM_PIXEL_FORMAT;
+    jxl_bit_depth.exponent_bits_per_sample = pix_desc->flags & AV_PIX_FMT_FLAG_FLOAT ?
+                                             info.exponent_bits_per_sample : 0;
+#endif
 
     /* JPEG XL format itself does not support limited range */
     if (avctx->color_range == AVCOL_RANGE_MPEG ||
@@ -362,8 +369,11 @@ static int libjxl_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFra
         av_log(avctx, AV_LOG_WARNING, "Could not set ICC Profile\n");
     if (JxlEncoderSetColorEncoding(ctx->encoder, &jxl_color) != JXL_ENC_SUCCESS)
         av_log(avctx, AV_LOG_WARNING, "Failed to set JxlColorEncoding\n");
+
+#if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
     if (JxlEncoderSetFrameBitDepth(ctx->options, &jxl_bit_depth) != JXL_ENC_SUCCESS)
         av_log(avctx, AV_LOG_WARNING, "Failed to set JxlBitDepth\n");
+#endif
 
     /* depending on basic info, level 10 might
      * be required instead of level 5 */



More information about the ffmpeg-cvslog mailing list