FFmpeg
libjxldec.c
Go to the documentation of this file.
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/csp.h"
31 #include "libavutil/error.h"
32 #include "libavutil/mem.h"
33 #include "libavutil/pixdesc.h"
34 #include "libavutil/pixfmt.h"
35 #include "libavutil/frame.h"
36 
37 #include "avcodec.h"
38 #include "codec_internal.h"
39 #include "decode.h"
40 
41 #include <jxl/decode.h>
42 #include <jxl/thread_parallel_runner.h>
43 #include "libjxl.h"
44 
45 typedef struct LibJxlDecodeContext {
46  void *runner;
47  JxlDecoder *decoder;
48  JxlBasicInfo basic_info;
49  JxlPixelFormat jxl_pixfmt;
50 #if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
51  JxlBitDepth jxl_bit_depth;
52 #endif
53  JxlDecoderStatus events;
56 
58 {
60 
61  ctx->events = JXL_DEC_BASIC_INFO | JXL_DEC_FULL_IMAGE | JXL_DEC_COLOR_ENCODING;
62  if (JxlDecoderSubscribeEvents(ctx->decoder, ctx->events) != JXL_DEC_SUCCESS) {
63  av_log(avctx, AV_LOG_ERROR, "Error subscribing to JXL events\n");
64  return AVERROR_EXTERNAL;
65  }
66 
67  if (JxlDecoderSetParallelRunner(ctx->decoder, JxlThreadParallelRunner, ctx->runner) != JXL_DEC_SUCCESS) {
68  av_log(avctx, AV_LOG_ERROR, "Failed to set JxlThreadParallelRunner\n");
69  return AVERROR_EXTERNAL;
70  }
71 
72  memset(&ctx->basic_info, 0, sizeof(JxlBasicInfo));
73  memset(&ctx->jxl_pixfmt, 0, sizeof(JxlPixelFormat));
74 
75  return 0;
76 }
77 
79 {
81  JxlMemoryManager manager;
82 
84  ctx->decoder = JxlDecoderCreate(&manager);
85  if (!ctx->decoder) {
86  av_log(avctx, AV_LOG_ERROR, "Failed to create JxlDecoder\n");
87  return AVERROR_EXTERNAL;
88  }
89 
90  ctx->runner = JxlThreadParallelRunnerCreate(&manager, ff_libjxl_get_threadcount(avctx->thread_count));
91  if (!ctx->runner) {
92  av_log(avctx, AV_LOG_ERROR, "Failed to create JxlThreadParallelRunner\n");
93  return AVERROR_EXTERNAL;
94  }
95 
96  return libjxl_init_jxl_decoder(avctx);
97 }
98 
100 {
101  const JxlBasicInfo *basic_info = &ctx->basic_info;
102  JxlPixelFormat *format = &ctx->jxl_pixfmt;
103  format->endianness = JXL_NATIVE_ENDIAN;
104  format->num_channels = basic_info->num_color_channels + (basic_info->alpha_bits > 0);
105 #if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
106  ctx->jxl_bit_depth.bits_per_sample = avctx->bits_per_raw_sample = basic_info->bits_per_sample;
107  ctx->jxl_bit_depth.type = JXL_BIT_DEPTH_FROM_PIXEL_FORMAT;
108  ctx->jxl_bit_depth.exponent_bits_per_sample = basic_info->exponent_bits_per_sample;
109 #endif
110  /* Gray */
111  if (basic_info->num_color_channels == 1) {
112  if (basic_info->bits_per_sample <= 8) {
113  format->data_type = JXL_TYPE_UINT8;
114  return basic_info->alpha_bits ? AV_PIX_FMT_YA8 : AV_PIX_FMT_GRAY8;
115  }
116  if (basic_info->exponent_bits_per_sample || basic_info->bits_per_sample > 16) {
117  if (basic_info->alpha_bits)
118  return AV_PIX_FMT_NONE;
119  format->data_type = JXL_TYPE_FLOAT;
120  return AV_PIX_FMT_GRAYF32;
121  }
122  format->data_type = JXL_TYPE_UINT16;
123  return basic_info->alpha_bits ? AV_PIX_FMT_YA16 : AV_PIX_FMT_GRAY16;
124  }
125  /* rgb only */
126  /* libjxl only supports packed RGB and gray output at the moment */
127  if (basic_info->num_color_channels == 3) {
128  if (basic_info->bits_per_sample <= 8) {
129  format->data_type = JXL_TYPE_UINT8;
130  return basic_info->alpha_bits ? AV_PIX_FMT_RGBA : AV_PIX_FMT_RGB24;
131  }
132  if (basic_info->exponent_bits_per_sample)
133  av_log(avctx, AV_LOG_WARNING, "Downsampling float to 16-bit integer via libjxl\n");
134  else if (basic_info->bits_per_sample > 16)
135  av_log(avctx, AV_LOG_WARNING, "Downsampling larger integer to 16-bit via libjxl\n");
136  format->data_type = JXL_TYPE_UINT16;
137  return basic_info->alpha_bits ? AV_PIX_FMT_RGBA64 : AV_PIX_FMT_RGB48;
138  }
139 
140  return AV_PIX_FMT_NONE;
141 }
142 
143 static enum AVColorPrimaries libjxl_get_primaries(void *avctx, const JxlColorEncoding *jxl_color)
144 {
146  enum AVColorPrimaries prim;
147 
148  /* libjxl populates these double values even if it uses an enum space */
149  desc.prim.r.x = av_d2q(jxl_color->primaries_red_xy[0], 300000);
150  desc.prim.r.y = av_d2q(jxl_color->primaries_red_xy[1], 300000);
151  desc.prim.g.x = av_d2q(jxl_color->primaries_green_xy[0], 300000);
152  desc.prim.g.y = av_d2q(jxl_color->primaries_green_xy[1], 300000);
153  desc.prim.b.x = av_d2q(jxl_color->primaries_blue_xy[0], 300000);
154  desc.prim.b.y = av_d2q(jxl_color->primaries_blue_xy[1], 300000);
155  desc.wp.x = av_d2q(jxl_color->white_point_xy[0], 300000);
156  desc.wp.y = av_d2q(jxl_color->white_point_xy[1], 300000);
157 
159  if (prim == AVCOL_PRI_UNSPECIFIED) {
160  /* try D65 with the same primaries */
161  /* BT.709 uses D65 white point */
163  av_log(avctx, AV_LOG_WARNING, "Changing unknown white point to D65\n");
165  }
166 
167  return prim;
168 }
169 
170 static enum AVColorTransferCharacteristic libjxl_get_trc(void *avctx, const JxlColorEncoding *jxl_color)
171 {
172  switch (jxl_color->transfer_function) {
173  case JXL_TRANSFER_FUNCTION_709: return AVCOL_TRC_BT709;
174  case JXL_TRANSFER_FUNCTION_LINEAR: return AVCOL_TRC_LINEAR;
175  case JXL_TRANSFER_FUNCTION_SRGB: return AVCOL_TRC_IEC61966_2_1;
176  case JXL_TRANSFER_FUNCTION_PQ: return AVCOL_TRC_SMPTE2084;
177  case JXL_TRANSFER_FUNCTION_DCI: return AVCOL_TRC_SMPTE428;
178  case JXL_TRANSFER_FUNCTION_HLG: return AVCOL_TRC_ARIB_STD_B67;
179  case JXL_TRANSFER_FUNCTION_GAMMA:
180  if (jxl_color->gamma > 0.45355 && jxl_color->gamma < 0.45555)
181  return AVCOL_TRC_GAMMA22;
182  else if (jxl_color->gamma > 0.35614 && jxl_color->gamma < 0.35814)
183  return AVCOL_TRC_GAMMA28;
184  else
185  av_log(avctx, AV_LOG_WARNING, "Unsupported gamma transfer: %f\n", jxl_color->gamma);
186  break;
187  default:
188  av_log(avctx, AV_LOG_WARNING, "Unknown transfer function: %d\n", jxl_color->transfer_function);
189  }
190 
191  return AVCOL_TRC_UNSPECIFIED;
192 }
193 
194 static int libjxl_get_icc(AVCodecContext *avctx)
195 {
197  size_t icc_len;
198  JxlDecoderStatus jret;
199  /* an ICC profile is present, and we can meaningfully get it,
200  * because the pixel data is not XYB-encoded */
201  jret = JxlDecoderGetICCProfileSize(ctx->decoder, &ctx->jxl_pixfmt, JXL_COLOR_PROFILE_TARGET_DATA, &icc_len);
202  if (jret == JXL_DEC_SUCCESS && icc_len > 0) {
203  av_buffer_unref(&ctx->iccp);
204  ctx->iccp = av_buffer_alloc(icc_len);
205  if (!ctx->iccp)
206  return AVERROR(ENOMEM);
207  jret = JxlDecoderGetColorAsICCProfile(ctx->decoder, &ctx->jxl_pixfmt, JXL_COLOR_PROFILE_TARGET_DATA,
208  ctx->iccp->data, icc_len);
209  if (jret != JXL_DEC_SUCCESS) {
210  av_log(avctx, AV_LOG_WARNING, "Unable to obtain ICC Profile\n");
211  av_buffer_unref(&ctx->iccp);
212  }
213  }
214 
215  return 0;
216 }
217 
218 /*
219  * There's generally four cases when it comes to decoding a libjxl image
220  * with regard to color encoding:
221  * (a) There is an embedded ICC profile in the image, and the image is XYB-encoded.
222  * (b) There is an embedded ICC profile in the image, and the image is not XYB-encoded.
223  * (c) There is no embedded ICC profile, and FFmpeg supports the tagged colorspace.
224  * (d) There is no embedded ICC profile, and FFmpeg does not support the tagged colorspace.
225  *
226  * In case (b), we forward the pixel data as is and forward the ICC Profile as-is.
227  * In case (c), we request the pixel data in the space it's tagged as,
228  * and tag the space accordingly.
229  * In case (a), libjxl does not support getting the pixel data in the space described by the ICC
230  * profile, so instead we request the pixel data in BT.2020/PQ as it is the widest
231  * space that FFmpeg supports.
232  * In case (d), we also request wide-gamut pixel data as a fallback since FFmpeg doesn't support
233  * the custom primaries tagged in the space.
234  */
236 {
238  JxlDecoderStatus jret;
239  int ret;
240  JxlColorEncoding jxl_color;
241  /* set this flag if we need to fall back on wide gamut */
242  int fallback = 0;
243 
244  jret = JxlDecoderGetColorAsEncodedProfile(ctx->decoder, NULL, JXL_COLOR_PROFILE_TARGET_ORIGINAL, &jxl_color);
245  if (jret == JXL_DEC_SUCCESS) {
246  /* enum values describe the colors of this image */
247  jret = JxlDecoderSetPreferredColorProfile(ctx->decoder, &jxl_color);
248  if (jret == JXL_DEC_SUCCESS)
249  jret = JxlDecoderGetColorAsEncodedProfile(ctx->decoder, &ctx->jxl_pixfmt, JXL_COLOR_PROFILE_TARGET_DATA, &jxl_color);
250  /* if we couldn't successfully request the pixel data space, we fall back on wide gamut */
251  /* this code path is very unlikely to happen in practice */
252  if (jret != JXL_DEC_SUCCESS)
253  fallback = 1;
254  } else {
255  /* an ICC Profile is present in the stream */
256  if (ctx->basic_info.uses_original_profile) {
257  /* uses_original_profile is the same as !xyb_encoded */
258  av_log(avctx, AV_LOG_VERBOSE, "Using embedded ICC Profile\n");
259  if ((ret = libjxl_get_icc(avctx)) < 0)
260  return ret;
261  } else {
262  /*
263  * an XYB-encoded image with an embedded ICC profile can't always have the
264  * pixel data requested in the original space, so libjxl has no feature
265  * to allow this to happen, so we fall back on wide gamut
266  */
267  fallback = 1;
268  }
269  }
270 
271  avctx->color_range = frame->color_range = AVCOL_RANGE_JPEG;
272  if (ctx->jxl_pixfmt.num_channels >= 3)
273  avctx->colorspace = AVCOL_SPC_RGB;
276 
277  if (!ctx->iccp) {
278  /* checking enum values */
279  if (!fallback) {
280  if (avctx->colorspace == AVCOL_SPC_RGB)
281  avctx->color_primaries = libjxl_get_primaries(avctx, &jxl_color);
282  avctx->color_trc = libjxl_get_trc(avctx, &jxl_color);
283  }
284  /* fall back on wide gamut if enum values fail */
285  if (avctx->color_primaries == AVCOL_PRI_UNSPECIFIED) {
286  if (avctx->colorspace == AVCOL_SPC_RGB) {
287  av_log(avctx, AV_LOG_WARNING, "Falling back on wide gamut output\n");
288  jxl_color.primaries = JXL_PRIMARIES_2100;
290  }
291  /* libjxl requires this set even for grayscale */
292  jxl_color.white_point = JXL_WHITE_POINT_D65;
293  }
294  if (avctx->color_trc == AVCOL_TRC_UNSPECIFIED) {
295  if (ctx->jxl_pixfmt.data_type == JXL_TYPE_FLOAT
296  || ctx->jxl_pixfmt.data_type == JXL_TYPE_FLOAT16) {
297  av_log(avctx, AV_LOG_WARNING, "Falling back on Linear Light transfer\n");
298  jxl_color.transfer_function = JXL_TRANSFER_FUNCTION_LINEAR;
299  avctx->color_trc = AVCOL_TRC_LINEAR;
300  } else {
301  av_log(avctx, AV_LOG_WARNING, "Falling back on iec61966-2-1/sRGB transfer\n");
302  jxl_color.transfer_function = JXL_TRANSFER_FUNCTION_SRGB;
304  }
305  }
306  /* all colors will be in-gamut so we want accurate colors */
307  jxl_color.rendering_intent = JXL_RENDERING_INTENT_RELATIVE;
308  jxl_color.color_space = avctx->colorspace == AVCOL_SPC_RGB ? JXL_COLOR_SPACE_RGB : JXL_COLOR_SPACE_GRAY;
309  jret = JxlDecoderSetPreferredColorProfile(ctx->decoder, &jxl_color);
310  if (jret != JXL_DEC_SUCCESS) {
311  av_log(avctx, AV_LOG_WARNING, "Unable to set fallback color encoding\n");
312  /*
313  * This should only happen if there's a non-XYB encoded image with custom primaries
314  * embedded as enums and no embedded ICC Profile.
315  * In this case, libjxl will synthesize an ICC Profile for us.
316  */
319  if ((ret = libjxl_get_icc(avctx)) < 0)
320  return ret;
321  }
322  }
323 
324  frame->color_trc = avctx->color_trc;
325  frame->color_primaries = avctx->color_primaries;
326  frame->colorspace = avctx->colorspace;
327 
328  return 0;
329 }
330 
331 static int libjxl_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *avpkt)
332 {
334  const uint8_t *buf = avpkt->data;
335  size_t remaining = avpkt->size;
336  JxlDecoderStatus jret;
337  int ret;
338  *got_frame = 0;
339 
340  while (1) {
341 
342  jret = JxlDecoderSetInput(ctx->decoder, buf, remaining);
343 
344  if (jret == JXL_DEC_ERROR) {
345  /* this should never happen here unless there's a bug in libjxl */
346  av_log(avctx, AV_LOG_ERROR, "Unknown libjxl decode error\n");
347  return AVERROR_EXTERNAL;
348  }
349 
350  jret = JxlDecoderProcessInput(ctx->decoder);
351  /*
352  * JxlDecoderReleaseInput returns the number
353  * of bytes remaining to be read, rather than
354  * the number of bytes that it did read
355  */
356  remaining = JxlDecoderReleaseInput(ctx->decoder);
357  buf = avpkt->data + avpkt->size - remaining;
358 
359  switch(jret) {
360  case JXL_DEC_ERROR:
361  av_log(avctx, AV_LOG_ERROR, "Unknown libjxl decode error\n");
362  return AVERROR_INVALIDDATA;
363  case JXL_DEC_NEED_MORE_INPUT:
364  if (remaining == 0) {
365  av_log(avctx, AV_LOG_ERROR, "Unexpected end of JXL codestream\n");
366  return AVERROR_INVALIDDATA;
367  }
368  av_log(avctx, AV_LOG_DEBUG, "NEED_MORE_INPUT event emitted\n");
369  continue;
370  case JXL_DEC_BASIC_INFO:
371  av_log(avctx, AV_LOG_DEBUG, "BASIC_INFO event emitted\n");
372  if (JxlDecoderGetBasicInfo(ctx->decoder, &ctx->basic_info) != JXL_DEC_SUCCESS) {
373  /*
374  * this should never happen
375  * if it does it is likely a libjxl decoder bug
376  */
377  av_log(avctx, AV_LOG_ERROR, "Bad libjxl basic info event\n");
378  return AVERROR_EXTERNAL;
379  }
380  avctx->pix_fmt = libjxl_get_pix_fmt(avctx, ctx);
381  if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
382  av_log(avctx, AV_LOG_ERROR, "Bad libjxl pixel format\n");
383  return AVERROR_EXTERNAL;
384  }
385  if ((ret = ff_set_dimensions(avctx, ctx->basic_info.xsize, ctx->basic_info.ysize)) < 0)
386  return ret;
387  continue;
388  case JXL_DEC_COLOR_ENCODING:
389  av_log(avctx, AV_LOG_DEBUG, "COLOR_ENCODING event emitted\n");
390  if ((ret = libjxl_color_encoding_event(avctx, frame)) < 0)
391  return ret;
392  continue;
393  case JXL_DEC_NEED_IMAGE_OUT_BUFFER:
394  av_log(avctx, AV_LOG_DEBUG, "NEED_IMAGE_OUT_BUFFER event emitted\n");
395  if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
396  return ret;
397  ctx->jxl_pixfmt.align = frame->linesize[0];
398  if (JxlDecoderSetImageOutBuffer(ctx->decoder, &ctx->jxl_pixfmt, frame->data[0], frame->buf[0]->size)
399  != JXL_DEC_SUCCESS) {
400  av_log(avctx, AV_LOG_ERROR, "Bad libjxl dec need image out buffer event\n");
401  return AVERROR_EXTERNAL;
402  }
403 #if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
404  if (JxlDecoderSetImageOutBitDepth(ctx->decoder, &ctx->jxl_bit_depth) != JXL_DEC_SUCCESS) {
405  av_log(avctx, AV_LOG_ERROR, "Error setting output bit depth\n");
406  return AVERROR_EXTERNAL;
407  }
408 #endif
409  continue;
410  case JXL_DEC_FULL_IMAGE:
411  /* full image is one frame, even if animated */
412  av_log(avctx, AV_LOG_DEBUG, "FULL_IMAGE event emitted\n");
413  frame->pict_type = AV_PICTURE_TYPE_I;
414  frame->key_frame = 1;
415  if (ctx->iccp) {
417  if (!sd)
418  return AVERROR(ENOMEM);
419  /* ownership is transfered, and it is not ref-ed */
420  ctx->iccp = NULL;
421  }
422  *got_frame = 1;
423  return avpkt->size - remaining;
424  case JXL_DEC_SUCCESS:
425  av_log(avctx, AV_LOG_DEBUG, "SUCCESS event emitted\n");
426  /*
427  * The SUCCESS event isn't fired until after JXL_DEC_FULL_IMAGE. If this
428  * stream only contains one JXL image then JXL_DEC_SUCCESS will never fire.
429  * If the image2 sequence being decoded contains several JXL files, then
430  * libjxl will fire this event after the next AVPacket has been passed,
431  * which means the current packet is actually the next image in the sequence.
432  * This is why we reset the decoder and populate the packet data now, since
433  * this is the next packet and it has not been decoded yet. The decoder does
434  * have to be reset to allow us to use it for the next image, or libjxl
435  * will become very confused if the header information is not identical.
436  */
437  JxlDecoderReset(ctx->decoder);
439  buf = avpkt->data;
440  remaining = avpkt->size;
441  continue;
442  default:
443  av_log(avctx, AV_LOG_ERROR, "Bad libjxl event: %d\n", jret);
444  return AVERROR_EXTERNAL;
445  }
446  }
447 }
448 
450 {
452 
453  if (ctx->runner)
454  JxlThreadParallelRunnerDestroy(ctx->runner);
455  ctx->runner = NULL;
456  if (ctx->decoder)
457  JxlDecoderDestroy(ctx->decoder);
458  ctx->decoder = NULL;
459  av_buffer_unref(&ctx->iccp);
460 
461  return 0;
462 }
463 
465  .p.name = "libjxl",
466  CODEC_LONG_NAME("libjxl JPEG XL"),
467  .p.type = AVMEDIA_TYPE_VIDEO,
468  .p.id = AV_CODEC_ID_JPEGXL,
469  .priv_data_size = sizeof(LibJxlDecodeContext),
472  .close = libjxl_decode_close,
473  .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_OTHER_THREADS,
474  .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
477  .p.wrapper_name = "libjxl",
478 };
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
libjxl_init_jxl_decoder
static int libjxl_init_jxl_decoder(AVCodecContext *avctx)
Definition: libjxldec.c:57
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
ff_libjxl_get_threadcount
size_t ff_libjxl_get_threadcount(int threads)
Transform threadcount in ffmpeg to one used by libjxl.
Definition: libjxl.c:33
FF_CODEC_CAP_INIT_CLEANUP
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: codec_internal.h:42
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
AV_PIX_FMT_YA8
@ AV_PIX_FMT_YA8
8 bits gray, 8 bits alpha
Definition: pixfmt.h:133
AVCodecContext::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:1002
AVColorTransferCharacteristic
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition: pixfmt.h:558
AVColorPrimariesDesc::wp
AVWhitepointCoefficients wp
Definition: csp.h:79
AVColorPrimariesDesc
Struct that contains both white point location and primaries location, providing the complete descrip...
Definition: csp.h:78
LibJxlDecodeContext::decoder
JxlDecoder * decoder
Definition: libjxldec.c:47
AVCOL_TRC_LINEAR
@ AVCOL_TRC_LINEAR
"Linear transfer characteristics"
Definition: pixfmt.h:567
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:330
pixdesc.h
AVCodecContext::color_trc
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition: avcodec.h:995
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:661
AVPacket::data
uint8_t * data
Definition: packet.h:374
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:561
libjxl_decode_init
static av_cold int libjxl_decode_init(AVCodecContext *avctx)
Definition: libjxldec.c:78
FF_CODEC_CAP_NOT_INIT_THREADSAFE
#define FF_CODEC_CAP_NOT_INIT_THREADSAFE
The codec is not known to be init-threadsafe (i.e.
Definition: codec_internal.h:34
FFCodec
Definition: codec_internal.h:127
libjxl.h
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
AVCOL_SPC_RGB
@ AVCOL_SPC_RGB
order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB), YZX and ST 428-1
Definition: pixfmt.h:588
AVColorPrimaries
AVColorPrimaries
Chromaticity coordinates of the source primaries.
Definition: pixfmt.h:533
ff_set_dimensions
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
Definition: utils.c:91
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
AVCOL_TRC_IEC61966_2_1
@ AVCOL_TRC_IEC61966_2_1
IEC 61966-2-1 (sRGB or sYCC)
Definition: pixfmt.h:572
AVCodecContext::thread_count
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition: avcodec.h:1502
AVCOL_TRC_GAMMA28
@ AVCOL_TRC_GAMMA28
also ITU-R BT470BG
Definition: pixfmt.h:564
libjxl_get_pix_fmt
static enum AVPixelFormat libjxl_get_pix_fmt(AVCodecContext *avctx, LibJxlDecodeContext *ctx)
Definition: libjxldec.c:99
AV_PIX_FMT_GRAY16
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:443
AVCOL_TRC_GAMMA22
@ AVCOL_TRC_GAMMA22
also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
Definition: pixfmt.h:563
avassert.h
LibJxlDecodeContext::events
JxlDecoderStatus events
Definition: libjxldec.c:53
AVCodecContext::color_primaries
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition: avcodec.h:988
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:306
av_csp_primaries_desc_from_id
const AVColorPrimariesDesc * av_csp_primaries_desc_from_id(enum AVColorPrimaries prm)
Retrieves a complete gamut description from an enum constant describing the color primaries.
Definition: csp.c:90
format
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
AV_CODEC_CAP_OTHER_THREADS
#define AV_CODEC_CAP_OTHER_THREADS
Codec supports multithreading through a method other than slice- or frame-level multithreading.
Definition: codec.h:121
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts_bsf.c:365
ff_libjxl_decoder
const FFCodec ff_libjxl_decoder
Definition: libjxldec.c:464
AVCodecContext::bits_per_raw_sample
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:1487
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
decode.h
av_csp_primaries_id_from_desc
enum AVColorPrimaries av_csp_primaries_id_from_desc(const AVColorPrimariesDesc *prm)
Detects which enum AVColorPrimaries constant corresponds to the given complete gamut description.
Definition: csp.c:110
libjxl_get_icc
static int libjxl_get_icc(AVCodecContext *avctx)
Definition: libjxldec.c:194
LibJxlDecodeContext::jxl_pixfmt
JxlPixelFormat jxl_pixfmt
Definition: libjxldec.c:49
AV_PIX_FMT_GRAYF32
#define AV_PIX_FMT_GRAYF32
Definition: pixfmt.h:491
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:536
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:272
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:93
AV_PIX_FMT_RGBA64
#define AV_PIX_FMT_RGBA64
Definition: pixfmt.h:449
NULL
#define NULL
Definition: coverity.c:32
AVCodecContext::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:1009
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
AVCOL_PRI_BT709
@ AVCOL_PRI_BT709
also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP 177 Annex B
Definition: pixfmt.h:535
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
AV_FRAME_DATA_ICC_PROFILE
@ AV_FRAME_DATA_ICC_PROFILE
The data contains an ICC profile as an opaque octet buffer following the format described by ISO 1507...
Definition: frame.h:144
av_frame_new_side_data_from_buf
AVFrameSideData * av_frame_new_side_data_from_buf(AVFrame *frame, enum AVFrameSideDataType type, AVBufferRef *buf)
Add a new side data to a frame from an existing AVBufferRef.
Definition: frame.c:638
libjxl_decode_frame
static int libjxl_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *avpkt)
Definition: libjxldec.c:331
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
error.h
AVCOL_PRI_BT2020
@ AVCOL_PRI_BT2020
ITU-R BT2020.
Definition: pixfmt.h:544
AVCOL_TRC_SMPTE2084
@ AVCOL_TRC_SMPTE2084
SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems.
Definition: pixfmt.h:575
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1473
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
AVPacket::size
int size
Definition: packet.h:375
codec_internal.h
LibJxlDecodeContext::iccp
AVBufferRef * iccp
Definition: libjxldec.c:54
AV_PIX_FMT_RGB48
#define AV_PIX_FMT_RGB48
Definition: pixfmt.h:445
frame.h
buffer.h
csp.h
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
av_buffer_alloc
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition: buffer.c:77
libjxl_get_primaries
static enum AVColorPrimaries libjxl_get_primaries(void *avctx, const JxlColorEncoding *jxl_color)
Definition: libjxldec.c:143
AVCOL_TRC_BT709
@ AVCOL_TRC_BT709
also ITU-R BT1361
Definition: pixfmt.h:560
AV_PIX_FMT_YA16
#define AV_PIX_FMT_YA16
Definition: pixfmt.h:444
common.h
AV_CODEC_ID_JPEGXL
@ AV_CODEC_ID_JPEGXL
Definition: codec_id.h:316
av_d2q
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition: rational.c:106
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:191
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:635
FF_CODEC_CAP_ICC_PROFILES
#define FF_CODEC_CAP_ICC_PROFILES
Codec supports embedded ICC profiles (AV_FRAME_DATA_ICC_PROFILE).
Definition: codec_internal.h:82
avcodec.h
ret
ret
Definition: filter_design.txt:187
pixfmt.h
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
AVCodecContext
main external API structure.
Definition: avcodec.h:426
AVCOL_TRC_ARIB_STD_B67
@ AVCOL_TRC_ARIB_STD_B67
ARIB STD-B67, known as "Hybrid log-gamma".
Definition: pixfmt.h:579
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
desc
const char * desc
Definition: libsvtav1.c:83
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
mem.h
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
FF_CODEC_CAP_AUTO_THREADS
#define FF_CODEC_CAP_AUTO_THREADS
Codec handles avctx->thread_count == 0 (auto) internally.
Definition: codec_internal.h:73
AVFrameSideData
Structure to hold side data for an AVFrame.
Definition: frame.h:236
LibJxlDecodeContext::runner
void * runner
Definition: libjxldec.c:46
libjxl_decode_close
static av_cold int libjxl_decode_close(AVCodecContext *avctx)
Definition: libjxldec.c:449
AVPacket
This structure stores compressed data.
Definition: packet.h:351
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:453
LibJxlDecodeContext
Definition: libjxldec.c:45
ff_libjxl_init_memory_manager
void ff_libjxl_init_memory_manager(JxlMemoryManager *manager)
Initialize and populate a JxlMemoryManager with av_malloc() and av_free() so libjxl will use these fu...
Definition: libjxl.c:65
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
AVCOL_TRC_SMPTE428
@ AVCOL_TRC_SMPTE428
SMPTE ST 428-1.
Definition: pixfmt.h:577
LibJxlDecodeContext::basic_info
JxlBasicInfo basic_info
Definition: libjxldec.c:48
libjxl_get_trc
static enum AVColorTransferCharacteristic libjxl_get_trc(void *avctx, const JxlColorEncoding *jxl_color)
Definition: libjxldec.c:170
libjxl_color_encoding_event
static int libjxl_color_encoding_event(AVCodecContext *avctx, AVFrame *frame)
Definition: libjxldec.c:235