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/intreadwrite.h"
33 #include "libavutil/mem.h"
34 #include "libavutil/pixdesc.h"
35 #include "libavutil/pixfmt.h"
36 #include "libavutil/frame.h"
37 
38 #include "avcodec.h"
39 #include "codec_internal.h"
40 #include "decode.h"
41 #include "exif_internal.h"
42 #include "internal.h"
43 
44 #include <jxl/decode.h>
45 #include <jxl/thread_parallel_runner.h>
46 #include "libjxl.h"
47 
48 typedef struct LibJxlDecodeContext {
49  void *runner;
50  JxlDecoder *decoder;
51  JxlBasicInfo basic_info;
52  JxlPixelFormat jxl_pixfmt;
53 #if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
54  JxlBitDepth jxl_bit_depth;
55 #endif
56  JxlDecoderStatus events;
65  JxlDecoderStatus jret;
67  size_t exif_pos;
68  int exif_box;
70 
72 {
74 
75  ctx->events = JXL_DEC_BASIC_INFO | JXL_DEC_FULL_IMAGE
76  | JXL_DEC_COLOR_ENCODING | JXL_DEC_FRAME
77  | JXL_DEC_BOX;
78  if (JxlDecoderSubscribeEvents(ctx->decoder, ctx->events) != JXL_DEC_SUCCESS) {
79  av_log(avctx, AV_LOG_ERROR, "Error subscribing to JXL events\n");
80  return AVERROR_EXTERNAL;
81  }
82 
83  if (JxlDecoderSetDecompressBoxes(ctx->decoder, JXL_TRUE) != JXL_DEC_SUCCESS) {
84  av_log(avctx, AV_LOG_ERROR, "Error setting compress box mode\n");
85  return AVERROR_EXTERNAL;
86  }
87 
88  if (JxlDecoderSetParallelRunner(ctx->decoder, JxlThreadParallelRunner, ctx->runner) != JXL_DEC_SUCCESS) {
89  av_log(avctx, AV_LOG_ERROR, "Failed to set JxlThreadParallelRunner\n");
90  return AVERROR_EXTERNAL;
91  }
92 
93  av_buffer_unref(&ctx->exif);
94  memset(&ctx->basic_info, 0, sizeof(JxlBasicInfo));
95  memset(&ctx->jxl_pixfmt, 0, sizeof(JxlPixelFormat));
96  ctx->prev_is_last = 1;
97 
98  return 0;
99 }
100 
102 {
104  JxlMemoryManager manager;
105 
107  ctx->decoder = JxlDecoderCreate(&manager);
108  if (!ctx->decoder) {
109  av_log(avctx, AV_LOG_ERROR, "Failed to create JxlDecoder\n");
110  return AVERROR_EXTERNAL;
111  }
112 
113  ctx->runner = JxlThreadParallelRunnerCreate(&manager, ff_libjxl_get_threadcount(avctx->thread_count));
114  if (!ctx->runner) {
115  av_log(avctx, AV_LOG_ERROR, "Failed to create JxlThreadParallelRunner\n");
116  return AVERROR_EXTERNAL;
117  }
118 
119  ctx->avpkt = avctx->internal->in_pkt;
120  ctx->frame = av_frame_alloc();
121  if (!ctx->frame)
122  return AVERROR(ENOMEM);
123 
124  return libjxl_init_jxl_decoder(avctx);
125 }
126 
128 {
129  const JxlBasicInfo *basic_info = &ctx->basic_info;
130  JxlPixelFormat *format = &ctx->jxl_pixfmt;
131  format->endianness = JXL_NATIVE_ENDIAN;
132  format->num_channels = basic_info->num_color_channels + (basic_info->alpha_bits > 0);
133 #if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
134  ctx->jxl_bit_depth.bits_per_sample = avctx->bits_per_raw_sample = basic_info->bits_per_sample;
135  ctx->jxl_bit_depth.type = JXL_BIT_DEPTH_FROM_PIXEL_FORMAT;
136  ctx->jxl_bit_depth.exponent_bits_per_sample = basic_info->exponent_bits_per_sample;
137 #endif
138  /* Gray */
139  if (basic_info->num_color_channels == 1) {
140  if (basic_info->bits_per_sample <= 8) {
141  format->data_type = JXL_TYPE_UINT8;
142  return basic_info->alpha_bits ? AV_PIX_FMT_YA8 : AV_PIX_FMT_GRAY8;
143  }
144  if (basic_info->exponent_bits_per_sample || basic_info->bits_per_sample > 16) {
145  if (!basic_info->alpha_bits) {
146  format->data_type = JXL_TYPE_FLOAT;
147  return AV_PIX_FMT_GRAYF32;
148  }
149  av_log(avctx, AV_LOG_WARNING, "Downsampling gray+alpha float to 16-bit integer via libjxl\n");
150  }
151  format->data_type = JXL_TYPE_UINT16;
152  return basic_info->alpha_bits ? AV_PIX_FMT_YA16 : AV_PIX_FMT_GRAY16;
153  }
154  /* rgb only */
155  /* libjxl only supports packed RGB and gray output at the moment */
156  if (basic_info->num_color_channels == 3) {
157  if (basic_info->bits_per_sample <= 8) {
158  format->data_type = JXL_TYPE_UINT8;
159  return basic_info->alpha_bits ? AV_PIX_FMT_RGBA : AV_PIX_FMT_RGB24;
160  }
161  if (basic_info->exponent_bits_per_sample || basic_info->bits_per_sample > 16) {
162  format->data_type = JXL_TYPE_FLOAT;
163  return basic_info->alpha_bits ? AV_PIX_FMT_RGBAF32 : AV_PIX_FMT_RGBF32;
164  }
165  format->data_type = JXL_TYPE_UINT16;
166  return basic_info->alpha_bits ? AV_PIX_FMT_RGBA64 : AV_PIX_FMT_RGB48;
167  }
168 
169  return AV_PIX_FMT_NONE;
170 }
171 
172 static enum AVColorPrimaries libjxl_get_primaries(void *avctx, const JxlColorEncoding *jxl_color)
173 {
175  enum AVColorPrimaries prim;
176 
177  /* libjxl populates these double values even if it uses an enum space */
178  desc.prim.r.x = av_d2q(jxl_color->primaries_red_xy[0], 300000);
179  desc.prim.r.y = av_d2q(jxl_color->primaries_red_xy[1], 300000);
180  desc.prim.g.x = av_d2q(jxl_color->primaries_green_xy[0], 300000);
181  desc.prim.g.y = av_d2q(jxl_color->primaries_green_xy[1], 300000);
182  desc.prim.b.x = av_d2q(jxl_color->primaries_blue_xy[0], 300000);
183  desc.prim.b.y = av_d2q(jxl_color->primaries_blue_xy[1], 300000);
184  desc.wp.x = av_d2q(jxl_color->white_point_xy[0], 300000);
185  desc.wp.y = av_d2q(jxl_color->white_point_xy[1], 300000);
186 
188  if (prim == AVCOL_PRI_UNSPECIFIED) {
189  /* try D65 with the same primaries */
190  /* BT.709 uses D65 white point */
192  av_log(avctx, AV_LOG_WARNING, "Changing unknown white point to D65\n");
194  }
195 
196  return prim;
197 }
198 
199 static enum AVColorTransferCharacteristic libjxl_get_trc(void *avctx, const JxlColorEncoding *jxl_color)
200 {
201  switch (jxl_color->transfer_function) {
202  case JXL_TRANSFER_FUNCTION_709: return AVCOL_TRC_BT709;
203  case JXL_TRANSFER_FUNCTION_LINEAR: return AVCOL_TRC_LINEAR;
204  case JXL_TRANSFER_FUNCTION_SRGB: return AVCOL_TRC_IEC61966_2_1;
205  case JXL_TRANSFER_FUNCTION_PQ: return AVCOL_TRC_SMPTE2084;
206  case JXL_TRANSFER_FUNCTION_DCI: return AVCOL_TRC_SMPTE428;
207  case JXL_TRANSFER_FUNCTION_HLG: return AVCOL_TRC_ARIB_STD_B67;
208  case JXL_TRANSFER_FUNCTION_GAMMA:
209  if (jxl_color->gamma > 0.45355 && jxl_color->gamma < 0.45555)
210  return AVCOL_TRC_GAMMA22;
211  else if (jxl_color->gamma > 0.35614 && jxl_color->gamma < 0.35814)
212  return AVCOL_TRC_GAMMA28;
213  else
214  av_log(avctx, AV_LOG_WARNING, "Unsupported gamma transfer: %f\n", jxl_color->gamma);
215  break;
216  default:
217  av_log(avctx, AV_LOG_WARNING, "Unknown transfer function: %d\n", jxl_color->transfer_function);
218  }
219 
220  return AVCOL_TRC_UNSPECIFIED;
221 }
222 
223 static int libjxl_get_icc(AVCodecContext *avctx)
224 {
226  size_t icc_len;
227  JxlDecoderStatus jret;
228  /* an ICC profile is present, and we can meaningfully get it,
229  * because the pixel data is not XYB-encoded */
230 #if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0, 9, 0)
231  jret = JxlDecoderGetICCProfileSize(ctx->decoder, &ctx->jxl_pixfmt, JXL_COLOR_PROFILE_TARGET_DATA, &icc_len);
232 #else
233  jret = JxlDecoderGetICCProfileSize(ctx->decoder, JXL_COLOR_PROFILE_TARGET_DATA, &icc_len);
234 #endif
235  if (jret == JXL_DEC_SUCCESS && icc_len > 0) {
236  av_buffer_unref(&ctx->iccp);
237  ctx->iccp = av_buffer_alloc(icc_len);
238  if (!ctx->iccp)
239  return AVERROR(ENOMEM);
240 #if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0, 9, 0)
241  jret = JxlDecoderGetColorAsICCProfile(ctx->decoder, &ctx->jxl_pixfmt, JXL_COLOR_PROFILE_TARGET_DATA,
242  ctx->iccp->data, icc_len);
243 #else
244  jret = JxlDecoderGetColorAsICCProfile(ctx->decoder, JXL_COLOR_PROFILE_TARGET_DATA, ctx->iccp->data, icc_len);
245 #endif
246  if (jret != JXL_DEC_SUCCESS) {
247  av_log(avctx, AV_LOG_WARNING, "Unable to obtain ICC Profile\n");
248  av_buffer_unref(&ctx->iccp);
249  }
250  }
251 
252  return 0;
253 }
254 
255 /*
256  * There's generally four cases when it comes to decoding a libjxl image
257  * with regard to color encoding:
258  * (a) There is an embedded ICC profile in the image, and the image is XYB-encoded.
259  * (b) There is an embedded ICC profile in the image, and the image is not XYB-encoded.
260  * (c) There is no embedded ICC profile, and FFmpeg supports the tagged colorspace.
261  * (d) There is no embedded ICC profile, and FFmpeg does not support the tagged colorspace.
262  *
263  * In case (b), we forward the pixel data as is and forward the ICC Profile as-is.
264  * In case (c), we request the pixel data in the space it's tagged as,
265  * and tag the space accordingly.
266  * In case (a), libjxl does not support getting the pixel data in the space described by the ICC
267  * profile, so instead we request the pixel data in BT.2020/PQ as it is the widest
268  * space that FFmpeg supports.
269  * In case (d), we also request wide-gamut pixel data as a fallback since FFmpeg doesn't support
270  * the custom primaries tagged in the space.
271  */
273 {
275  JxlDecoderStatus jret;
276  int ret;
277  JxlColorEncoding jxl_color;
278  /* set this flag if we need to fall back on wide gamut */
279  int fallback = 0;
280 
281 #if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0, 9, 0)
282  jret = JxlDecoderGetColorAsEncodedProfile(ctx->decoder, NULL, JXL_COLOR_PROFILE_TARGET_ORIGINAL, &jxl_color);
283 #else
284  jret = JxlDecoderGetColorAsEncodedProfile(ctx->decoder, JXL_COLOR_PROFILE_TARGET_ORIGINAL, &jxl_color);
285 #endif
286  if (jret == JXL_DEC_SUCCESS) {
287  /* enum values describe the colors of this image */
288  jret = JxlDecoderSetPreferredColorProfile(ctx->decoder, &jxl_color);
289  if (jret == JXL_DEC_SUCCESS)
290 #if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0, 9, 0)
291  jret = JxlDecoderGetColorAsEncodedProfile(ctx->decoder, &ctx->jxl_pixfmt,
292  JXL_COLOR_PROFILE_TARGET_DATA, &jxl_color);
293 #else
294  jret = JxlDecoderGetColorAsEncodedProfile(ctx->decoder, JXL_COLOR_PROFILE_TARGET_DATA, &jxl_color);
295 #endif
296  /* if we couldn't successfully request the pixel data space, we fall back on wide gamut */
297  /* this code path is very unlikely to happen in practice */
298  if (jret != JXL_DEC_SUCCESS)
299  fallback = 1;
300  } else {
301  /* an ICC Profile is present in the stream */
302  if (ctx->basic_info.uses_original_profile) {
303  /* uses_original_profile is the same as !xyb_encoded */
304  av_log(avctx, AV_LOG_VERBOSE, "Using embedded ICC Profile\n");
305  if ((ret = libjxl_get_icc(avctx)) < 0)
306  return ret;
307  } else {
308  /*
309  * an XYB-encoded image with an embedded ICC profile can't always have the
310  * pixel data requested in the original space, so libjxl has no feature
311  * to allow this to happen, so we fall back on wide gamut
312  */
313  fallback = 1;
314  }
315  }
316 
317  avctx->color_range = frame->color_range = AVCOL_RANGE_JPEG;
318  if (ctx->basic_info.num_color_channels > 1)
319  avctx->colorspace = AVCOL_SPC_RGB;
322 
323  if (!ctx->iccp) {
324  /* checking enum values */
325  if (!fallback) {
326  if (avctx->colorspace == AVCOL_SPC_RGB)
327  avctx->color_primaries = libjxl_get_primaries(avctx, &jxl_color);
328  avctx->color_trc = libjxl_get_trc(avctx, &jxl_color);
329  }
330  /* fall back on wide gamut if enum values fail */
331  if (avctx->color_primaries == AVCOL_PRI_UNSPECIFIED) {
332  if (avctx->colorspace == AVCOL_SPC_RGB) {
333  av_log(avctx, AV_LOG_WARNING, "Falling back on wide gamut output\n");
334  jxl_color.primaries = JXL_PRIMARIES_2100;
336  }
337  /* libjxl requires this set even for grayscale */
338  jxl_color.white_point = JXL_WHITE_POINT_D65;
339  }
340  if (avctx->color_trc == AVCOL_TRC_UNSPECIFIED) {
341  if (ctx->jxl_pixfmt.data_type == JXL_TYPE_FLOAT
342  || ctx->jxl_pixfmt.data_type == JXL_TYPE_FLOAT16) {
343  av_log(avctx, AV_LOG_WARNING, "Falling back on Linear Light transfer\n");
344  jxl_color.transfer_function = JXL_TRANSFER_FUNCTION_LINEAR;
345  avctx->color_trc = AVCOL_TRC_LINEAR;
346  } else {
347  av_log(avctx, AV_LOG_WARNING, "Falling back on iec61966-2-1/sRGB transfer\n");
348  jxl_color.transfer_function = JXL_TRANSFER_FUNCTION_SRGB;
350  }
351  }
352  /* all colors will be in-gamut so we want accurate colors */
353  jxl_color.rendering_intent = JXL_RENDERING_INTENT_RELATIVE;
354  jxl_color.color_space = ctx->basic_info.num_color_channels > 1 ? JXL_COLOR_SPACE_RGB : JXL_COLOR_SPACE_GRAY;
355  jret = JxlDecoderSetPreferredColorProfile(ctx->decoder, &jxl_color);
356  if (jret != JXL_DEC_SUCCESS) {
357  av_log(avctx, AV_LOG_WARNING, "Unable to set fallback color encoding\n");
358  /*
359  * This should only happen if there's a non-XYB encoded image with custom primaries
360  * embedded as enums and no embedded ICC Profile.
361  * In this case, libjxl will synthesize an ICC Profile for us.
362  */
365  if ((ret = libjxl_get_icc(avctx)) < 0)
366  return ret;
367  }
368  }
369 
370  frame->color_trc = avctx->color_trc;
371  frame->color_primaries = avctx->color_primaries;
372  frame->colorspace = avctx->colorspace;
373 
374  return 0;
375 }
376 
378 {
380  int ret = 0;
381 
382  if (ctx->iccp) {
384  if (ret < 0)
385  return ret;
386  }
387 
388  if (ctx->exif) {
389  AVExifMetadata ifd = { 0 };
390  /* size may be larger than exif_pos due to the realloc loop */
391  ret = av_exif_parse_buffer(avctx, ctx->exif->data, ctx->exif_pos, &ifd, AV_EXIF_T_OFF);
392  av_buffer_unref(&ctx->exif);
393  if (ret < 0) {
394  av_log(avctx, AV_LOG_ERROR, "Unable to parse EXIF buffer: %s\n", av_err2str(ret));
395  return ret;
396  }
397  /*
398  * JPEG XL Codestream orientation overrides EXIF orientation in all cases.
399  * As a result, we remove the EXIF Orientation tag rather than just zeroing it
400  * in order to prevent any ambiguity. libjxl autorotates the image for us so we
401  * do not need to worry about that.
402  */
403  ret = av_exif_remove_entry(avctx, &ifd, av_exif_get_tag_id("Orientation"), 0);
404  if (ret < 0)
405  av_log(avctx, AV_LOG_WARNING, "Unable to remove orientation from EXIF buffer: %s\n", av_err2str(ret));
406  ret = ff_decode_exif_attach_ifd(avctx, ctx->frame, &ifd);
407  if (ret < 0)
408  av_log(avctx, AV_LOG_ERROR, "Unable to attach EXIF ifd: %s\n", av_err2str(ret));
409  av_exif_free(&ifd);
410  }
411 
412  return ret;
413 }
414 
416 {
418  if (ctx->exif_box) {
419  /* last box was Exif */
420  size_t remainder = JxlDecoderReleaseBoxBuffer(ctx->decoder);
421  ctx->exif_pos = ctx->exif->size - remainder;
422  ctx->exif_box = 0;
423  }
424  int ret = libjxl_attach_sidedata(avctx);
426  ctx->frame_complete = 0;
427  return ret;
428 }
429 
431 {
433  int ret;
434  AVPacket *pkt = ctx->avpkt;
435 
436  while (1) {
437  size_t remaining;
438  JxlFrameHeader header;
439 
440  if (!pkt->size) {
442  ret = ff_decode_get_packet(avctx, pkt);
443  if (ret < 0 && ret != AVERROR_EOF)
444  return ret;
445  ctx->accumulated_pts = 0;
446  ctx->frame_duration = 0;
447  if (!pkt->size) {
448  /* jret set by the last iteration of the loop */
449  if (ctx->jret == JXL_DEC_NEED_MORE_INPUT && !ctx->frame_complete) {
450  av_log(avctx, AV_LOG_ERROR, "Unexpected end of JXL codestream\n");
451  return AVERROR_INVALIDDATA;
452  } else if (ctx->frame_complete) {
453  libjxl_finalize_frame(avctx, frame, ctx->frame);
454  ctx->jret = JXL_DEC_SUCCESS;
455  return 0;
456  }
457  return AVERROR_EOF;
458  }
459  }
460 
461  ctx->jret = JxlDecoderSetInput(ctx->decoder, pkt->data, pkt->size);
462  if (ctx->jret == JXL_DEC_ERROR) {
463  /* this should never happen here unless there's a bug in libjxl */
464  av_log(avctx, AV_LOG_ERROR, "Unknown libjxl decode error\n");
465  return AVERROR_EXTERNAL;
466  }
467 
468  ctx->jret = JxlDecoderProcessInput(ctx->decoder);
469  /*
470  * JxlDecoderReleaseInput returns the number
471  * of bytes remaining to be read, rather than
472  * the number of bytes that it did read
473  */
474  remaining = JxlDecoderReleaseInput(ctx->decoder);
475  size_t consumed = pkt->size - remaining;
476  pkt->data += consumed;
477  pkt->size = remaining;
478 
479  switch(ctx->jret) {
480  case JXL_DEC_ERROR:
481  av_log(avctx, AV_LOG_ERROR, "Unknown libjxl decode error\n");
482  /*
483  * we consume all remaining input on error, if nothing was consumed
484  * this prevents libjxl from consuming nothing forever
485  * and just dumping the last error over and over
486  */
487  if (!consumed)
489  return AVERROR_INVALIDDATA;
490  case JXL_DEC_NEED_MORE_INPUT:
491  av_log(avctx, AV_LOG_DEBUG, "NEED_MORE_INPUT event emitted\n");
492  continue;
493  case JXL_DEC_BASIC_INFO:
494  av_log(avctx, AV_LOG_DEBUG, "BASIC_INFO event emitted\n");
495  if (JxlDecoderGetBasicInfo(ctx->decoder, &ctx->basic_info) != JXL_DEC_SUCCESS) {
496  /*
497  * this should never happen
498  * if it does it is likely a libjxl decoder bug
499  */
500  av_log(avctx, AV_LOG_ERROR, "Bad libjxl basic info event\n");
501  return AVERROR_EXTERNAL;
502  }
503  avctx->pix_fmt = libjxl_get_pix_fmt(avctx, ctx);
504  if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
505  av_log(avctx, AV_LOG_ERROR, "Bad libjxl pixel format\n");
506  return AVERROR_EXTERNAL;
507  }
508  if ((ret = ff_set_dimensions(avctx, ctx->basic_info.xsize, ctx->basic_info.ysize)) < 0)
509  return ret;
510  if (ctx->basic_info.have_animation)
511  ctx->anim_timebase = av_make_q(ctx->basic_info.animation.tps_denominator,
512  ctx->basic_info.animation.tps_numerator);
513  if (ctx->basic_info.alpha_bits) {
514  if (ctx->basic_info.alpha_premultiplied)
516  else
518  }
519  continue;
520  case JXL_DEC_COLOR_ENCODING:
521  av_log(avctx, AV_LOG_DEBUG, "COLOR_ENCODING event emitted\n");
522  ret = libjxl_color_encoding_event(avctx, ctx->frame);
523  if (ret < 0)
524  return ret;
525  continue;
526  case JXL_DEC_NEED_IMAGE_OUT_BUFFER:
527  av_log(avctx, AV_LOG_DEBUG, "NEED_IMAGE_OUT_BUFFER event emitted\n");
528  ret = ff_get_buffer(avctx, ctx->frame, 0);
529  if (ret < 0)
530  return ret;
531  ctx->jxl_pixfmt.align = ctx->frame->linesize[0];
532  if (JxlDecoderSetImageOutBuffer(ctx->decoder, &ctx->jxl_pixfmt,
533  ctx->frame->data[0], ctx->frame->buf[0]->size)
534  != JXL_DEC_SUCCESS) {
535  av_log(avctx, AV_LOG_ERROR, "Bad libjxl dec need image out buffer event\n");
536  return AVERROR_EXTERNAL;
537  }
538 #if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
539  if (JxlDecoderSetImageOutBitDepth(ctx->decoder, &ctx->jxl_bit_depth) != JXL_DEC_SUCCESS) {
540  av_log(avctx, AV_LOG_ERROR, "Error setting output bit depth\n");
541  return AVERROR_EXTERNAL;
542  }
543 #endif
544  continue;
545  case JXL_DEC_FRAME:
546  /* Frame here refers to the Frame bundle, not a decoded picture */
547  av_log(avctx, AV_LOG_DEBUG, "FRAME event emitted\n");
548  if (ctx->prev_is_last) {
549  /*
550  * The last frame sent was tagged as "is_last" which
551  * means this is a new image file altogether.
552  */
553  ctx->frame->pict_type = AV_PICTURE_TYPE_I;
554  ctx->frame->flags |= AV_FRAME_FLAG_KEY;
555  }
556  if (JxlDecoderGetFrameHeader(ctx->decoder, &header) != JXL_DEC_SUCCESS) {
557  av_log(avctx, AV_LOG_ERROR, "Bad libjxl dec frame event\n");
558  return AVERROR_EXTERNAL;
559  }
560  ctx->prev_is_last = header.is_last;
561  /* zero duration for animation means the frame is not presented */
562  if (ctx->basic_info.have_animation && header.duration)
563  ctx->frame_duration = header.duration;
564  continue;
565  case JXL_DEC_FULL_IMAGE:
566  /* full image is one frame, even if animated */
567  av_log(avctx, AV_LOG_DEBUG, "FULL_IMAGE event emitted\n");
568  if (ctx->basic_info.have_animation) {
569  ctx->frame->pts = av_rescale_q(ctx->accumulated_pts, ctx->anim_timebase, avctx->pkt_timebase);
570  ctx->frame->duration = av_rescale_q(ctx->frame_duration, ctx->anim_timebase, avctx->pkt_timebase);
571  } else {
572  ctx->frame->pts = 0;
573  ctx->frame->duration = pkt->duration;
574  }
575  if (pkt->pts != AV_NOPTS_VALUE)
576  ctx->frame->pts += pkt->pts;
577  ctx->accumulated_pts += ctx->frame_duration;
578  ctx->frame->pkt_dts = pkt->dts;
579  if (ctx->basic_info.have_animation && !ctx->prev_is_last) {
580  libjxl_finalize_frame(avctx, frame, ctx->frame);
581  return 0;
582  } else {
583  ctx->frame_complete = 1;
584  continue;
585  }
586  case JXL_DEC_SUCCESS:
587  av_log(avctx, AV_LOG_DEBUG, "SUCCESS event emitted\n");
588  /*
589  * this event will be fired when the zero-length EOF
590  * packet is sent to the decoder by the client,
591  * but it will also be fired when the next image of
592  * an image2pipe sequence is loaded up
593  */
594  libjxl_finalize_frame(avctx, frame, ctx->frame);
595  JxlDecoderReset(ctx->decoder);
597  return 0;
598  case JXL_DEC_BOX: {
599  char type[4];
600  av_log(avctx, AV_LOG_DEBUG, "BOX event emitted\n");
601  if (ctx->exif_box) {
602  /* last box was Exif */
603  size_t remainder = JxlDecoderReleaseBoxBuffer(ctx->decoder);
604  ctx->exif_pos = ctx->exif->size - remainder;
605  }
606  if (JxlDecoderGetBoxType(ctx->decoder, type, JXL_TRUE) != JXL_DEC_SUCCESS) {
607  av_log(avctx, AV_LOG_ERROR, "Error getting box type\n");
608  return AVERROR_EXTERNAL;
609  }
610  if (AV_RL32(type) != MKTAG('E','x','i','f')) {
611  ctx->exif_box = 0;
612  continue;
613  }
614  ctx->exif_box = 1;
615  av_buffer_unref(&ctx->exif);
616  ctx->exif_pos = 0;
617  // 4k buffer should usually be enough
618  ret = av_buffer_realloc(&ctx->exif, 4096);
619  if (ret < 0)
620  return AVERROR(ENOMEM);
621  if (JxlDecoderSetBoxBuffer(ctx->decoder, ctx->exif->data, ctx->exif->size) != JXL_DEC_SUCCESS) {
622  av_log(avctx, AV_LOG_ERROR, "Error setting box buffer\n");
623  return AVERROR_EXTERNAL;
624  }
625  continue;
626  }
627  case JXL_DEC_BOX_NEED_MORE_OUTPUT: {
628  av_log(avctx, AV_LOG_DEBUG, "BOX_NEED_MORE_OUTPUT event emitted\n");
629  size_t remainder = JxlDecoderReleaseBoxBuffer(ctx->decoder);
630  ctx->exif_pos = ctx->exif->size - remainder;
631  size_t new_size = ctx->exif->size << 1;
632  ret = av_buffer_realloc(&ctx->exif, new_size);
633  if (ret < 0)
634  return AVERROR(ENOMEM);
635  if (JxlDecoderSetBoxBuffer(ctx->decoder, ctx->exif->data + ctx->exif_pos,
636  ctx->exif->size - ctx->exif_pos) != JXL_DEC_SUCCESS) {
637  av_log(avctx, AV_LOG_ERROR, "Error setting box buffer\n");
638  return AVERROR_EXTERNAL;
639  }
640  continue;
641  }
642  default:
643  av_log(avctx, AV_LOG_ERROR, "Bad libjxl event: %d\n", ctx->jret);
644  return AVERROR_EXTERNAL;
645  }
646  }
647 }
648 
650 {
652 
653  if (ctx->runner)
654  JxlThreadParallelRunnerDestroy(ctx->runner);
655  ctx->runner = NULL;
656  if (ctx->decoder)
657  JxlDecoderDestroy(ctx->decoder);
658  ctx->decoder = NULL;
659  av_buffer_unref(&ctx->exif);
660  av_buffer_unref(&ctx->iccp);
661  av_frame_free(&ctx->frame);
662 
663  return 0;
664 }
665 
667  .p.name = "libjxl",
668  CODEC_LONG_NAME("libjxl JPEG XL"),
669  .p.type = AVMEDIA_TYPE_VIDEO,
670  .p.id = AV_CODEC_ID_JPEGXL,
671  .priv_data_size = sizeof(LibJxlDecodeContext),
674  .close = libjxl_decode_close,
675  .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_OTHER_THREADS,
676  .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
679  .p.wrapper_name = "libjxl",
680 };
681 
683  .p.name = "libjxl_anim",
684  CODEC_LONG_NAME("libjxl JPEG XL animated"),
685  .p.type = AVMEDIA_TYPE_VIDEO,
686  .p.id = AV_CODEC_ID_JPEGXL_ANIM,
687  .priv_data_size = sizeof(LibJxlDecodeContext),
690  .close = libjxl_decode_close,
691  .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_OTHER_THREADS,
692  .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
695  .p.wrapper_name = "libjxl",
696 };
AV_EXIF_T_OFF
@ AV_EXIF_T_OFF
The first four bytes point to the actual start, then it's AV_EXIF_TIFF_HEADER.
Definition: exif.h:69
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:433
ff_decode_get_packet
int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
Called by decoders to get the next packet for decoding.
Definition: decode.c:245
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
libjxl_init_jxl_decoder
static int libjxl_init_jxl_decoder(AVCodecContext *avctx)
Definition: libjxldec.c:71
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
AV_CODEC_ID_JPEGXL_ANIM
@ AV_CODEC_ID_JPEGXL_ANIM
Definition: codec_id.h:331
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
AVCodecContext::alpha_mode
enum AVAlphaMode alpha_mode
Indicates how the alpha channel of the video is represented.
Definition: avcodec.h:1932
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:140
AVALPHA_MODE_STRAIGHT
@ AVALPHA_MODE_STRAIGHT
Alpha channel is independent of color values.
Definition: pixfmt.h:803
AVALPHA_MODE_PREMULTIPLIED
@ AVALPHA_MODE_PREMULTIPLIED
Alpha channel is multiplied into color values.
Definition: pixfmt.h:802
av_exif_parse_buffer
int av_exif_parse_buffer(void *logctx, const uint8_t *buf, size_t size, AVExifMetadata *ifd, enum AVExifHeaderMode header_mode)
Decodes the EXIF data provided in the buffer and writes it into the struct *ifd.
Definition: exif.c:767
AVCodecContext::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:659
AVColorTransferCharacteristic
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition: pixfmt.h:661
AVColorPrimariesDesc::wp
AVWhitepointCoefficients wp
Definition: csp.h:79
AVExifMetadata
Definition: exif.h:76
AVColorPrimariesDesc
Struct that contains both white point location and primaries location, providing the complete descrip...
Definition: csp.h:78
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
LibJxlDecodeContext::decoder
JxlDecoder * decoder
Definition: libjxldec.c:50
AVCOL_TRC_LINEAR
@ AVCOL_TRC_LINEAR
"Linear transfer characteristics"
Definition: pixfmt.h:670
int64_t
long long int64_t
Definition: coverity.c:34
LibJxlDecodeContext::avpkt
AVPacket * avpkt
Definition: libjxldec.c:58
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:64
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:427
pixdesc.h
AVCodecContext::color_trc
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition: avcodec.h:652
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:767
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:558
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:664
libjxl_decode_init
static av_cold int libjxl_decode_init(AVCodecContext *avctx)
Definition: libjxldec.c:101
libjxl_finalize_frame
static int libjxl_finalize_frame(AVCodecContext *avctx, AVFrame *dst, AVFrame *src)
Definition: libjxldec.c:415
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:226
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:691
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:576
LibJxlDecodeContext::exif
AVBufferRef * exif
Definition: libjxldec.c:66
LibJxlDecodeContext::accumulated_pts
int64_t accumulated_pts
Definition: libjxldec.c:59
AVColorPrimaries
AVColorPrimaries
Chromaticity coordinates of the source primaries.
Definition: pixfmt.h:636
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:675
AVCodecContext::thread_count
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition: avcodec.h:1561
AVCOL_TRC_GAMMA28
@ AVCOL_TRC_GAMMA28
also ITU-R BT470BG
Definition: pixfmt.h:667
libjxl_get_pix_fmt
static enum AVPixelFormat libjxl_get_pix_fmt(AVCodecContext *avctx, LibJxlDecodeContext *ctx)
Definition: libjxldec.c:127
av_exif_free
void av_exif_free(AVExifMetadata *ifd)
Frees all resources associated with the given EXIF metadata struct.
Definition: exif.c:612
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
AV_PIX_FMT_GRAY16
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:522
AVCOL_TRC_GAMMA22
@ AVCOL_TRC_GAMMA22
also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
Definition: pixfmt.h:666
ff_frame_new_side_data_from_buf
int ff_frame_new_side_data_from_buf(const AVCodecContext *avctx, AVFrame *frame, enum AVFrameSideDataType type, AVBufferRef **buf)
Similar to ff_frame_new_side_data, but using an existing buffer ref.
Definition: decode.c:2152
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:52
avassert.h
LibJxlDecodeContext::events
JxlDecoderStatus events
Definition: libjxldec.c:56
AVCodecContext::color_primaries
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition: avcodec.h:645
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
av_cold
#define av_cold
Definition: attributes.h:106
AV_FRAME_FLAG_KEY
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition: frame.h:642
intreadwrite.h
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
libjxl_attach_sidedata
static int libjxl_attach_sidedata(AVCodecContext *avctx)
Definition: libjxldec.c:377
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1415
LibJxlDecodeContext::jxl_bit_depth
JxlBitDepth jxl_bit_depth
Definition: libjxldec.c:54
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:109
ff_libjxl_decoder
const FFCodec ff_libjxl_decoder
Definition: libjxldec.c:666
AVCodecContext::bits_per_raw_sample
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:1553
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
ctx
AVFormatContext * ctx
Definition: movenc.c:49
decode.h
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
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:223
AV_PIX_FMT_RGBF32
#define AV_PIX_FMT_RGBF32
Definition: pixfmt.h:626
LibJxlDecodeContext::jxl_pixfmt
JxlPixelFormat jxl_pixfmt
Definition: libjxldec.c:52
AV_PIX_FMT_GRAYF32
#define AV_PIX_FMT_GRAYF32
Definition: pixfmt.h:582
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:639
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:331
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:100
AV_PIX_FMT_RGBA64
#define AV_PIX_FMT_RGBA64
Definition: pixfmt.h:529
av_exif_get_tag_id
int32_t av_exif_get_tag_id(const char *name)
Retrieves the tag ID associated with the provided tag string name.
Definition: exif.c:225
ff_decode_exif_attach_ifd
int ff_decode_exif_attach_ifd(AVCodecContext *avctx, AVFrame *frame, const AVExifMetadata *ifd)
Definition: decode.c:2412
NULL
#define NULL
Definition: coverity.c:32
exif_internal.h
format
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion and so on Or we could have separate passes for the vertical and horizontal scaling In between each SwsPass lies a fully allocated image buffer Graph passes may have different levels of e g we can have a single threaded error diffusion pass following a multi threaded scaling pass SwsGraph is internally recreated whenever the image format
Definition: swscale-v2.txt:14
AVCodecContext::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:669
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
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AVCodecContext::internal
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:466
AVCOL_PRI_BT709
@ AVCOL_PRI_BT709
also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP 177 Annex B
Definition: pixfmt.h:638
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:278
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_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:81
av_exif_remove_entry
int av_exif_remove_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags)
Remove an entry from the provided EXIF metadata struct.
Definition: exif.c:1143
error.h
AVCOL_PRI_BT2020
@ AVCOL_PRI_BT2020
ITU-R BT2020.
Definition: pixfmt.h:647
LibJxlDecodeContext::exif_pos
size_t exif_pos
Definition: libjxldec.c:67
AVCOL_TRC_SMPTE2084
@ AVCOL_TRC_SMPTE2084
SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems.
Definition: pixfmt.h:678
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1720
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:368
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:75
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:559
codec_internal.h
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
LibJxlDecodeContext::iccp
AVBufferRef * iccp
Definition: libjxldec.c:57
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
AVCodecContext::pkt_timebase
AVRational pkt_timebase
Timebase in which pkt_dts/pts and AVPacket.dts/pts are expressed.
Definition: avcodec.h:542
AV_PIX_FMT_RGB48
#define AV_PIX_FMT_RGB48
Definition: pixfmt.h:525
av_make_q
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:247
frame.h
header
static const uint8_t header[24]
Definition: sdr2.c:68
buffer.h
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:557
csp.h
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
LibJxlDecodeContext::frame_duration
int64_t frame_duration
Definition: libjxldec.c:60
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:172
AVCOL_TRC_BT709
@ AVCOL_TRC_BT709
also ITU-R BT1361
Definition: pixfmt.h:663
AV_PIX_FMT_YA16
#define AV_PIX_FMT_YA16
Definition: pixfmt.h:524
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:551
common.h
AVCodecInternal::in_pkt
AVPacket * in_pkt
This packet is used to hold the packet given to decoders implementing the .decode API; it is unused b...
Definition: internal.h:83
LibJxlDecodeContext::anim_timebase
AVRational anim_timebase
Definition: libjxldec.c:62
AV_CODEC_ID_JPEGXL
@ AV_CODEC_ID_JPEGXL
Definition: codec_id.h:317
av_frame_move_ref
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
Move everything contained in src to dst and reset src.
Definition: frame.c:523
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:179
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:631
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:81
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:265
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
libjxl_receive_frame
static int libjxl_receive_frame(AVCodecContext *avctx, AVFrame *frame)
Definition: libjxldec.c:430
AVCodecContext
main external API structure.
Definition: avcodec.h:431
AVCOL_TRC_ARIB_STD_B67
@ AVCOL_TRC_ARIB_STD_B67
ARIB STD-B67, known as "Hybrid log-gamma".
Definition: pixfmt.h:682
FF_CODEC_RECEIVE_FRAME_CB
#define FF_CODEC_RECEIVE_FRAME_CB(func)
Definition: codec_internal.h:354
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
LibJxlDecodeContext::exif_box
int exif_box
Definition: libjxldec.c:68
LibJxlDecodeContext::jret
JxlDecoderStatus jret
Definition: libjxldec.c:65
AV_PIX_FMT_RGBAF32
#define AV_PIX_FMT_RGBAF32
Definition: pixfmt.h:627
AVFormatContext::duration
int64_t duration
Duration of the stream, in AV_TIME_BASE fractional seconds.
Definition: avformat.h:1399
av_buffer_realloc
int av_buffer_realloc(AVBufferRef **pbuf, size_t size)
Reallocate a given buffer.
Definition: buffer.c:183
desc
const char * desc
Definition: libsvtav1.c:79
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
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:72
LibJxlDecodeContext::frame
AVFrame * frame
Definition: libjxldec.c:63
LibJxlDecodeContext::runner
void * runner
Definition: libjxldec.c:49
libjxl_decode_close
static av_cold int libjxl_decode_close(AVCodecContext *avctx)
Definition: libjxldec.c:649
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:458
AVPacket
This structure stores compressed data.
Definition: packet.h:535
LibJxlDecodeContext
Definition: libjxldec.c:48
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:680
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
LibJxlDecodeContext::prev_is_last
int prev_is_last
Definition: libjxldec.c:61
ff_libjxl_anim_decoder
const FFCodec ff_libjxl_anim_decoder
Definition: libjxldec.c:682
LibJxlDecodeContext::basic_info
JxlBasicInfo basic_info
Definition: libjxldec.c:51
libjxl_get_trc
static enum AVColorTransferCharacteristic libjxl_get_trc(void *avctx, const JxlColorEncoding *jxl_color)
Definition: libjxldec.c:199
LibJxlDecodeContext::frame_complete
int frame_complete
Definition: libjxldec.c:64
libjxl_color_encoding_event
static int libjxl_color_encoding_event(AVCodecContext *avctx, AVFrame *frame)
Definition: libjxldec.c:272
src
#define src
Definition: vp8dsp.c:248