History

avcodec/libjxl: add Jpeg XL decoding via libjxl

This commit adds decoding support to libavcodec for Jpeg XL images via the external library libjxl.

Leo Izen committed 4 years ago

Commit 458cc7e1 parent 0008c158 files · +413 −0Browse files

Unified · Split

8 files
  1. MAINTAINERS +1 −0
  2. configure +5 −0
  3. doc/general_contents.texi +7 −0
  4. libavcodec/Makefile +1 −0
  5. libavcodec/allcodecs.c +1 −0
  6. libavcodec/libjxl.c +70 −0
  7. libavcodec/libjxl.h +48 −0
  8. libavcodec/libjxldec.c +280 −0
MAINTAINERS+1−0
@@ -194,6 +194,7 @@ Codecs: · 193 unmodified lines
194 libcodec2.c Tomas Härdin194 libcodec2.c Tomas Härdin
195 libdirac* David Conrad195 libdirac* David Conrad
196 libdavs2.c Huiwen Ren196 libdavs2.c Huiwen Ren
197 libjxl*.c, libjxl.h Leo Izen
197 libgsm.c Michel Bardiaux198 libgsm.c Michel Bardiaux
198 libkvazaar.c Arttu Ylä-Outinen199 libkvazaar.c Arttu Ylä-Outinen
199 libopenh264enc.c Martin Storsjo, Linjie Fu200 libopenh264enc.c Martin Storsjo, Linjie Fu
configure+5−0
@@ -240,6 +240,7 @@ External library support: · 239 unmodified lines
240 --enable-libiec61883 enable iec61883 via libiec61883 [no]240 --enable-libiec61883 enable iec61883 via libiec61883 [no]
241 --enable-libilbc enable iLBC de/encoding via libilbc [no]241 --enable-libilbc enable iLBC de/encoding via libilbc [no]
242 --enable-libjack enable JACK audio sound server [no]242 --enable-libjack enable JACK audio sound server [no]
243 --enable-libjxl enable JPEG XL decoding via libjxl [no]
243 --enable-libklvanc enable Kernel Labs VANC processing [no]244 --enable-libklvanc enable Kernel Labs VANC processing [no]
244 --enable-libkvazaar enable HEVC encoding via libkvazaar [no]245 --enable-libkvazaar enable HEVC encoding via libkvazaar [no]
245 --enable-liblensfun enable lensfun lens correction [no]246 --enable-liblensfun enable lensfun lens correction [no]
@@ -1833,6 +1834,7 @@ EXTERNAL_LIBRARY_LIST=" · 1587 unmodified lines
1833 libiec618831834 libiec61883
1834 libilbc1835 libilbc
1835 libjack1836 libjack
1837 libjxl
1836 libklvanc1838 libklvanc
1837 libkvazaar1839 libkvazaar
1838 libmodplug1840 libmodplug
@@ -3331,6 +3333,7 @@ libgsm_ms_decoder_deps="libgsm" · 1492 unmodified lines
3331libgsm_ms_encoder_deps="libgsm"3333libgsm_ms_encoder_deps="libgsm"
3332libilbc_decoder_deps="libilbc"3334libilbc_decoder_deps="libilbc"
3333libilbc_encoder_deps="libilbc"3335libilbc_encoder_deps="libilbc"
3336libjxl_decoder_deps="libjxl libjxl_threads"
3334libkvazaar_encoder_deps="libkvazaar"3337libkvazaar_encoder_deps="libkvazaar"
3335libmodplug_demuxer_deps="libmodplug"3338libmodplug_demuxer_deps="libmodplug"
3336libmp3lame_encoder_deps="libmp3lame"3339libmp3lame_encoder_deps="libmp3lame"
@@ -6545,6 +6548,8 @@ enabled libgsm && { for gsm_hdr in "gsm.h" "gsm/gsm.h"; do · 3208 unmodified lines
6545 check_lib libgsm "${gsm_hdr}" gsm_create -lgsm && break;6548 check_lib libgsm "${gsm_hdr}" gsm_create -lgsm && break;
6546 done || die "ERROR: libgsm not found"; }6549 done || die "ERROR: libgsm not found"; }
6547enabled libilbc && require libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc $pthreads_extralibs6550enabled libilbc && require libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc $pthreads_extralibs
6551enabled libjxl && require_pkg_config libjxl "libjxl >= 0.7.0" jxl/decode.h JxlDecoderVersion &&
6552 require_pkg_config libjxl_threads "libjxl_threads >= 0.7.0" jxl/thread_parallel_runner.h JxlThreadParallelRunner
6548enabled libklvanc && require libklvanc libklvanc/vanc.h klvanc_context_create -lklvanc6553enabled libklvanc && require libklvanc libklvanc/vanc.h klvanc_context_create -lklvanc
6549enabled libkvazaar && require_pkg_config libkvazaar "kvazaar >= 0.8.1" kvazaar.h kvz_api_get6554enabled libkvazaar && require_pkg_config libkvazaar "kvazaar >= 0.8.1" kvazaar.h kvz_api_get
6550enabled liblensfun && require_pkg_config liblensfun lensfun lensfun.h lf_db_new6555enabled liblensfun && require_pkg_config liblensfun lensfun lensfun.h lf_db_new
doc/general_contents.texi+7−0
@@ -171,6 +171,13 @@ Go to @url{https://github.com/TimothyGu/libilbc} and follow the instructions for · 170 unmodified lines
171installing the library. Then pass @code{--enable-libilbc} to configure to171installing the library. Then pass @code{--enable-libilbc} to configure to
172enable it.172enable it.
173 173
174@section libjxl
175
176JPEG XL is an image format intended to fully replace legacy JPEG for an extended
177period of life. See @url{https://jpegxl.info/} for more information, and see
178@url{https://github.com/libjxl/libjxl} for the library source. You can pass
179@code{--enable-libjxl} to configure in order enable the libjxl wrapper.
180
174@section libvpx181@section libvpx
175 182
176FFmpeg can make use of the libvpx library for VP8/VP9 decoding and encoding.183FFmpeg can make use of the libvpx library for VP8/VP9 decoding and encoding.
libavcodec/Makefile+1−0
@@ -1062,6 +1062,7 @@ OBJS-$(CONFIG_LIBGSM_MS_DECODER) += libgsmdec.o · 1061 unmodified lines
1062OBJS-$(CONFIG_LIBGSM_MS_ENCODER) += libgsmenc.o1062OBJS-$(CONFIG_LIBGSM_MS_ENCODER) += libgsmenc.o
1063OBJS-$(CONFIG_LIBILBC_DECODER) += libilbc.o1063OBJS-$(CONFIG_LIBILBC_DECODER) += libilbc.o
1064OBJS-$(CONFIG_LIBILBC_ENCODER) += libilbc.o1064OBJS-$(CONFIG_LIBILBC_ENCODER) += libilbc.o
1065OBJS-$(CONFIG_LIBJXL_DECODER) += libjxldec.o libjxl.o
1065OBJS-$(CONFIG_LIBKVAZAAR_ENCODER) += libkvazaar.o1066OBJS-$(CONFIG_LIBKVAZAAR_ENCODER) += libkvazaar.o
1066OBJS-$(CONFIG_LIBMP3LAME_ENCODER) += libmp3lame.o1067OBJS-$(CONFIG_LIBMP3LAME_ENCODER) += libmp3lame.o
1067OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER) += libopencore-amr.o1068OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER) += libopencore-amr.o
libavcodec/allcodecs.c+1−0
@@ -751,6 +751,7 @@ extern const FFCodec ff_libgsm_ms_encoder; · 750 unmodified lines
751extern const FFCodec ff_libgsm_ms_decoder;751extern const FFCodec ff_libgsm_ms_decoder;
752extern const FFCodec ff_libilbc_encoder;752extern const FFCodec ff_libilbc_encoder;
753extern const FFCodec ff_libilbc_decoder;753extern const FFCodec ff_libilbc_decoder;
754extern const FFCodec ff_libjxl_decoder;
754extern const FFCodec ff_libmp3lame_encoder;755extern const FFCodec ff_libmp3lame_encoder;
755extern const FFCodec ff_libopencore_amrnb_encoder;756extern const FFCodec ff_libopencore_amrnb_encoder;
756extern const FFCodec ff_libopencore_amrnb_decoder;757extern const FFCodec ff_libopencore_amrnb_decoder;
libavcodec/libjxl.c+70−0
@@ -0,0 +1,70 @@
1/*
2 * JPEG XL de/encoding via libjxl, common support implementation
3 * Copyright (c) 2021 Leo Izen <leo.izen@gmail.com>
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22/**
23 * @file
24 * JPEG XL via libjxl common support implementation
25 */
26
27#include "libavutil/cpu.h"
28#include "libavutil/mem.h"
29
30#include <jxl/memory_manager.h>
31#include "libjxl.h"
32
33size_t ff_libjxl_get_threadcount(int threads)
34{
35 if (threads <= 0)
36 return av_cpu_count();
37 if (threads == 1)
38 return 0;
39 return threads;
40}
41
42/**
43 * Wrapper around av_malloc used as a jpegxl_alloc_func.
44 *
45 * @param opaque opaque pointer for jpegxl_alloc_func, always ignored
46 * @param size Size in bytes for the memory block to be allocated
47 * @return Pointer to the allocated block, or `NULL` if it cannot be allocated
48 */
49static void *libjxl_av_malloc(void *opaque, size_t size)
50{
51 return av_malloc(size);
52}
53
54/**
55 * Wrapper around av_free used as a jpegxl_free_func.
56 *
57 * @param opaque opaque pointer for jpegxl_free_func, always ignored
58 * @param address Pointer to the allocated block, to free. `NULL` permitted as a no-op.
59 */
60static void libjxl_av_free(void *opaque, void *address)
61{
62 av_free(address);
63}
64
65void ff_libjxl_init_memory_manager(JxlMemoryManager *manager)
66{
67 manager->opaque = NULL;
68 manager->alloc = &libjxl_av_malloc;
69 manager->free = &libjxl_av_free;
70}
libavcodec/libjxl.h+48−0
@@ -0,0 +1,48 @@
1/*
2 * JPEG XL de/encoding via libjxl, common support header
3 * Copyright (c) 2021 Leo Izen <leo.izen@gmail.com>
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22/**
23 * @file
24 * JPEG XL via libjxl common support header
25 */
26
27#ifndef AVCODEC_LIBJXL_H
28#define AVCODEC_LIBJXL_H
29
30#include <jxl/memory_manager.h>
31
32/**
33 * Transform threadcount in ffmpeg to one used by libjxl.
34 *
35 * @param threads ffmpeg's threads AVOption
36 * @return thread count for libjxl's parallel runner
37 */
38size_t ff_libjxl_get_threadcount(int threads);
39
40/**
41 * Initialize and populate a JxlMemoryManager
42 * with av_malloc() and av_free() so libjxl will use these
43 * functions.
44 * @param manager a pointer to a JxlMemoryManager struct
45 */
46void ff_libjxl_init_memory_manager(JxlMemoryManager *manager);
47
48#endif /* AVCODEC_LIBJXL_H */
libavcodec/libjxldec.c+280−0
@@ -0,0 +1,280 @@
1/*
2 * JPEG XL decoding support via libjxl
3 * Copyright (c) 2021 Leo Izen <leo.izen@gmail.com>
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22/**
23 * @file
24 * JPEG XL decoder using libjxl
25 */
26
27#include "libavutil/avassert.h"
28#include "libavutil/buffer.h"
29#include "libavutil/common.h"
30#include "libavutil/error.h"
31#include "libavutil/mem.h"
32#include "libavutil/pixdesc.h"
33#include "libavutil/pixfmt.h"
34#include "libavutil/frame.h"
35
36#include "avcodec.h"
37#include "codec_internal.h"
38#include "internal.h"
39
40#include <jxl/decode.h>
41#include <jxl/thread_parallel_runner.h>
42#include "libjxl.h"
43
44typedef struct LibJxlDecodeContext {
45 void *runner;
46 JxlDecoder *decoder;
47 JxlBasicInfo basic_info;
48 JxlPixelFormat jxl_pixfmt;
49 JxlDecoderStatus events;
50 AVBufferRef *iccp;
51} LibJxlDecodeContext;
52
53static int libjxl_init_jxl_decoder(AVCodecContext *avctx)
54{
55 LibJxlDecodeContext *ctx = avctx->priv_data;
56
57 ctx->events = JXL_DEC_BASIC_INFO | JXL_DEC_FULL_IMAGE | JXL_DEC_COLOR_ENCODING;
58 if (JxlDecoderSubscribeEvents(ctx->decoder, ctx->events) != JXL_DEC_SUCCESS) {
59 av_log(avctx, AV_LOG_ERROR, "Error subscribing to JXL events\n");
60 return AVERROR_EXTERNAL;
61 }
62
63 if (JxlDecoderSetParallelRunner(ctx->decoder, JxlThreadParallelRunner, ctx->runner) != JXL_DEC_SUCCESS) {
64 av_log(avctx, AV_LOG_ERROR, "Failed to set JxlThreadParallelRunner\n");
65 return AVERROR_EXTERNAL;
66 }
67
68 memset(&ctx->basic_info, 0, sizeof(JxlBasicInfo));
69 memset(&ctx->jxl_pixfmt, 0, sizeof(JxlPixelFormat));
70
71 return 0;
72}
73
74static av_cold int libjxl_decode_init(AVCodecContext *avctx)
75{
76 LibJxlDecodeContext *ctx = avctx->priv_data;
77 JxlMemoryManager manager;
78
79 ff_libjxl_init_memory_manager(&manager);
80 ctx->decoder = JxlDecoderCreate(&manager);
81 if (!ctx->decoder) {
82 av_log(avctx, AV_LOG_ERROR, "Failed to create JxlDecoder\n");
83 return AVERROR_EXTERNAL;
84 }
85
86 ctx->runner = JxlThreadParallelRunnerCreate(&manager, ff_libjxl_get_threadcount(avctx->thread_count));
87 if (!ctx->runner) {
88 av_log(avctx, AV_LOG_ERROR, "Failed to create JxlThreadParallelRunner\n");
89 return AVERROR_EXTERNAL;
90 }
91
92 return libjxl_init_jxl_decoder(avctx);
93}
94
95static enum AVPixelFormat libjxl_get_pix_fmt(AVCodecContext *avctx, JxlBasicInfo *basic_info, JxlPixelFormat *format)
96{
97 format->endianness = JXL_NATIVE_ENDIAN;
98 format->num_channels = basic_info->num_color_channels + (basic_info->alpha_bits > 0);
99 /* Gray */
100 if (basic_info->num_color_channels == 1) {
101 if (basic_info->bits_per_sample <= 8) {
102 format->data_type = JXL_TYPE_UINT8;
103 return basic_info->alpha_bits ? AV_PIX_FMT_YA8 : AV_PIX_FMT_GRAY8;
104 }
105 if (basic_info->exponent_bits_per_sample || basic_info->bits_per_sample > 16) {
106 if (basic_info->alpha_bits)
107 return AV_PIX_FMT_NONE;
108 format->data_type = JXL_TYPE_FLOAT;
109 return AV_PIX_FMT_GRAYF32;
110 }
111 format->data_type = JXL_TYPE_UINT16;
112 return basic_info->alpha_bits ? AV_PIX_FMT_YA16 : AV_PIX_FMT_GRAY16;
113 }
114 /* rgb only */
115 /* libjxl only supports packed RGB and gray output at the moment */
116 if (basic_info->num_color_channels == 3) {
117 if (basic_info->bits_per_sample <= 8) {
118 format->data_type = JXL_TYPE_UINT8;
119 return basic_info->alpha_bits ? AV_PIX_FMT_RGBA : AV_PIX_FMT_RGB24;
120 }
121 if (basic_info->bits_per_sample > 16)
122 av_log(avctx, AV_LOG_WARNING, "Downsampling larger integer to 16-bit via libjxl\n");
123 if (basic_info->exponent_bits_per_sample)
124 av_log(avctx, AV_LOG_WARNING, "Downsampling float to 16-bit integer via libjxl\n");
125 format->data_type = JXL_TYPE_UINT16;
126 return basic_info->alpha_bits ? AV_PIX_FMT_RGBA64 : AV_PIX_FMT_RGB48;
127 }
128
129 return AV_PIX_FMT_NONE;
130}
131
132static int libjxl_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *avpkt)
133{
134 LibJxlDecodeContext *ctx = avctx->priv_data;
135 uint8_t *buf = avpkt->data;
136 size_t remaining = avpkt->size, iccp_len;
137 JxlDecoderStatus jret;
138 int ret;
139 *got_frame = 0;
140
141 while (1) {
142
143 jret = JxlDecoderSetInput(ctx->decoder, buf, remaining);
144
145 if (jret == JXL_DEC_ERROR) {
146 /* this should never happen here unless there's a bug in libjxl */
147 av_log(avctx, AV_LOG_ERROR, "Unknown libjxl decode error\n");
148 return AVERROR_EXTERNAL;
149 }
150
151 jret = JxlDecoderProcessInput(ctx->decoder);
152 /*
153 * JxlDecoderReleaseInput returns the number
154 * of bytes remaining to be read, rather than
155 * the number of bytes that it did read
156 */
157 remaining = JxlDecoderReleaseInput(ctx->decoder);
158 buf = avpkt->data + avpkt->size - remaining;
159
160 switch(jret) {
161 case JXL_DEC_ERROR:
162 av_log(avctx, AV_LOG_ERROR, "Unknown libjxl decode error\n");
163 return AVERROR_INVALIDDATA;
164 case JXL_DEC_NEED_MORE_INPUT:
165 if (remaining == 0) {
166 av_log(avctx, AV_LOG_ERROR, "Unexpected end of JXL codestream\n");
167 return AVERROR_INVALIDDATA;
168 }
169 av_log(avctx, AV_LOG_DEBUG, "NEED_MORE_INPUT event emitted\n");
170 continue;
171 case JXL_DEC_BASIC_INFO:
172 av_log(avctx, AV_LOG_DEBUG, "BASIC_INFO event emitted\n");
173 if (JxlDecoderGetBasicInfo(ctx->decoder, &ctx->basic_info) != JXL_DEC_SUCCESS) {
174 /*
175 * this should never happen
176 * if it does it is likely a libjxl decoder bug
177 */
178 av_log(avctx, AV_LOG_ERROR, "Bad libjxl basic info event\n");
179 return AVERROR_EXTERNAL;
180 }
181 avctx->pix_fmt = libjxl_get_pix_fmt(avctx, &ctx->basic_info, &ctx->jxl_pixfmt);
182 if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
183 av_log(avctx, AV_LOG_ERROR, "Bad libjxl pixel format\n");
184 return AVERROR_EXTERNAL;
185 }
186 ret = ff_set_dimensions(avctx, ctx->basic_info.xsize, ctx->basic_info.ysize);
187 if (ret < 0)
188 return ret;
189 continue;
190 case JXL_DEC_COLOR_ENCODING:
191 av_log(avctx, AV_LOG_DEBUG, "COLOR_ENCODING event emitted\n");
192 jret = JxlDecoderGetICCProfileSize(ctx->decoder, &ctx->jxl_pixfmt, JXL_COLOR_PROFILE_TARGET_ORIGINAL, &iccp_len);
193 if (jret == JXL_DEC_SUCCESS && iccp_len > 0) {
194 av_buffer_unref(&ctx->iccp);
195 ctx->iccp = av_buffer_alloc(iccp_len);
196 if (!ctx->iccp)
197 return AVERROR(ENOMEM);
198 jret = JxlDecoderGetColorAsICCProfile(ctx->decoder, &ctx->jxl_pixfmt, JXL_COLOR_PROFILE_TARGET_ORIGINAL, ctx->iccp->data, iccp_len);
199 if (jret != JXL_DEC_SUCCESS)
200 av_buffer_unref(&ctx->iccp);
201 }
202 continue;
203 case JXL_DEC_NEED_IMAGE_OUT_BUFFER:
204 av_log(avctx, AV_LOG_DEBUG, "NEED_IMAGE_OUT_BUFFER event emitted\n");
205 ret = ff_get_buffer(avctx, frame, 0);
206 if (ret < 0)
207 return ret;
208 ctx->jxl_pixfmt.align = frame->linesize[0];
209 if (JxlDecoderSetImageOutBuffer(ctx->decoder, &ctx->jxl_pixfmt, frame->data[0], frame->buf[0]->size) != JXL_DEC_SUCCESS) {
210 av_log(avctx, AV_LOG_ERROR, "Bad libjxl dec need image out buffer event\n");
211 return AVERROR_EXTERNAL;
212 }
213 continue;
214 case JXL_DEC_FULL_IMAGE:
215 /* full image is one frame, even if animated */
216 av_log(avctx, AV_LOG_DEBUG, "FULL_IMAGE event emitted\n");
217 frame->pict_type = AV_PICTURE_TYPE_I;
218 frame->key_frame = 1;
219 if (ctx->iccp) {
220 AVFrameSideData *sd = av_frame_new_side_data_from_buf(frame, AV_FRAME_DATA_ICC_PROFILE, ctx->iccp);
221 if (!sd)
222 return AVERROR(ENOMEM);
223 /* ownership is transfered, and it is not ref-ed */
224 ctx->iccp = NULL;
225 }
226 *got_frame = 1;
227 return avpkt->size - remaining;
228 case JXL_DEC_SUCCESS:
229 av_log(avctx, AV_LOG_DEBUG, "SUCCESS event emitted\n");
230 /*
231 * The SUCCESS event isn't fired until after JXL_DEC_FULL_IMAGE. If this
232 * stream only contains one JXL image then JXL_DEC_SUCCESS will never fire.
233 * If the image2 sequence being decoded contains several JXL files, then
234 * libjxl will fire this event after the next AVPacket has been passed,
235 * which means the current packet is actually the next image in the sequence.
236 * This is why we reset the decoder and populate the packet data now, since
237 * this is the next packet and it has not been decoded yet. The decoder does
238 * have to be reset to allow us to use it for the next image, or libjxl
239 * will become very confused if the header information is not identical.
240 */
241 JxlDecoderReset(ctx->decoder);
242 libjxl_init_jxl_decoder(avctx);
243 buf = avpkt->data;
244 remaining = avpkt->size;
245 continue;
246 default:
247 av_log(avctx, AV_LOG_ERROR, "Bad libjxl event: %d\n", jret);
248 return AVERROR_EXTERNAL;
249 }
250 }
251}
252
253static av_cold int libjxl_decode_close(AVCodecContext *avctx)
254{
255 LibJxlDecodeContext *ctx = avctx->priv_data;
256
257 if (ctx->runner)
258 JxlThreadParallelRunnerDestroy(ctx->runner);
259 ctx->runner = NULL;
260 if (ctx->decoder)
261 JxlDecoderDestroy(ctx->decoder);
262 ctx->decoder = NULL;
263 av_buffer_unref(&ctx->iccp);
264
265 return 0;
266}
267
268const FFCodec ff_libjxl_decoder = {
269 .p.name = "libjxl",
270 .p.long_name = NULL_IF_CONFIG_SMALL("libjxl JPEG XL"),
271 .p.type = AVMEDIA_TYPE_VIDEO,
272 .p.id = AV_CODEC_ID_JPEGXL,
273 .priv_data_size = sizeof(LibJxlDecodeContext),
274 .init = libjxl_decode_init,
275 FF_CODEC_DECODE_CB(libjxl_decode_frame),
276 .close = libjxl_decode_close,
277 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_OTHER_THREADS,
278 .caps_internal = FF_CODEC_CAP_AUTO_THREADS | FF_CODEC_CAP_INIT_CLEANUP,
279 .p.wrapper_name = "libjxl",
280};

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t