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@gmail.com>
This commit is contained in:
Leo Izen 2023-02-04 16:29:15 -05:00
parent c5aeb8f4db
commit 0009348306
No known key found for this signature in database
GPG Key ID: 5A71C331FD2FA19A
3 changed files with 39 additions and 10 deletions

View File

@ -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.
*

View File

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

View File

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