diff mbox series

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

Message ID 20230204232840.3194-1-leo.izen@gmail.com
State Accepted
Commit 000934830620c03be55644e054f9ffaaadac2a0a
Headers show
Series [FFmpeg-devel] avcodec/libjxl: add #ifdef guards for libjxl >= 0.8.0 features | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Leo Izen Feb. 4, 2023, 11:28 p.m. UTC
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@gmail.com>
---
 libavcodec/libjxl.h    | 12 ++++++++++++
 libavcodec/libjxldec.c | 19 +++++++++++++------
 libavcodec/libjxlenc.c | 18 ++++++++++++++----
 3 files changed, 39 insertions(+), 10 deletions(-)

Comments

Leo Izen Feb. 4, 2023, 11:30 p.m. UTC | #1
On 2/4/23 18:28, Leo Izen wrote:
 > 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@gmail.com>

This is an alternative to the above patch. I replied it to the previous 
patch so they can be compared but only one should be applied.

- Leo Izen (thebombzen)
diff mbox series

Patch

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 */