FFmpeg
libjxlenc.c
Go to the documentation of this file.
1 /*
2  * JPEG XL encoding 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 encoder using libjxl
25  */
26 
27 #include <string.h>
28 
29 #include "libavutil/avutil.h"
30 #include "libavutil/csp.h"
31 #include "libavutil/display.h"
32 #include "libavutil/error.h"
33 #include "libavutil/frame.h"
34 #include "libavutil/libm.h"
35 #include "libavutil/mem.h"
36 #include "libavutil/opt.h"
37 #include "libavutil/pixdesc.h"
38 #include "libavutil/pixfmt.h"
39 #include "libavutil/version.h"
40 
41 #include "avcodec.h"
42 #include "encode.h"
43 #include "codec_internal.h"
44 #include "exif_internal.h"
45 
46 #include <jxl/encode.h>
47 #include <jxl/thread_parallel_runner.h>
48 #include "libjxl.h"
49 
50 typedef struct LibJxlEncodeContext {
51  AVClass *class;
52  void *runner;
53  JxlEncoder *encoder;
54  JxlEncoderFrameSettings *options;
55  int effort;
56  float distance;
57  int modular;
58  int xyb;
59  uint8_t *buffer;
60  size_t buffer_size;
61  JxlPixelFormat jxl_fmt;
63 
64  /* animation stuff */
69 
70 /**
71  * Map a quality setting for -qscale roughly from libjpeg
72  * quality numbers to libjxl's butteraugli distance for
73  * photographic content.
74  *
75  * Setting distance explicitly is preferred, but this will
76  * allow qscale to be used as a fallback.
77  *
78  * This function is continuous and injective on [0, 100] which
79  * makes it monotonic.
80  *
81  * @param quality 0.0 to 100.0 quality setting, libjpeg quality
82  * @return Butteraugli distance between 0.0 and 15.0
83  */
84 static float quality_to_distance(float quality)
85 {
86  if (quality >= 100.0)
87  return 0.0;
88  else if (quality >= 90.0)
89  return (100.0 - quality) * 0.10;
90  else if (quality >= 30.0)
91  return 0.1 + (100.0 - quality) * 0.09;
92  else if (quality > 0.0)
93  return 15.0 + (59.0 * quality - 4350.0) * quality / 9000.0;
94  else
95  return 15.0;
96 }
97 
98 /**
99  * Initialize the encoder on a per-file basis. All of these need to be set
100  * once each time the encoder is reset, which is each frame for still
101  * images, to make the image2 muxer work. For animation this is run once.
102  *
103  * @return 0 upon success, negative on failure.
104  */
106 {
108 
109  /* reset the encoder every frame for image2 muxer */
110  JxlEncoderReset(ctx->encoder);
111 
112  /* This needs to be set each time the encoder is reset */
113  if (JxlEncoderSetParallelRunner(ctx->encoder, JxlThreadParallelRunner, ctx->runner)
114  != JXL_ENC_SUCCESS) {
115  av_log(avctx, AV_LOG_ERROR, "Failed to set JxlThreadParallelRunner\n");
116  return AVERROR_EXTERNAL;
117  }
118 
119  ctx->options = JxlEncoderFrameSettingsCreate(ctx->encoder, NULL);
120  if (!ctx->options) {
121  av_log(avctx, AV_LOG_ERROR, "Failed to create JxlEncoderOptions\n");
122  return AVERROR_EXTERNAL;
123  }
124 
125  return 0;
126 }
127 
128 /**
129  * Global encoder initialization. This only needs to be run once,
130  * not every frame.
131  */
133 {
135  JxlMemoryManager manager;
136 
138  ctx->encoder = JxlEncoderCreate(&manager);
139  if (!ctx->encoder) {
140  av_log(avctx, AV_LOG_ERROR, "Failed to create JxlEncoder\n");
141  return AVERROR_EXTERNAL;
142  }
143 
144  ctx->runner = JxlThreadParallelRunnerCreate(&manager, ff_libjxl_get_threadcount(avctx->thread_count));
145  if (!ctx->runner) {
146  av_log(avctx, AV_LOG_ERROR, "Failed to create JxlThreadParallelRunner\n");
147  return AVERROR_EXTERNAL;
148  }
149 
150  ctx->buffer_size = 4096;
151  ctx->buffer = av_realloc(NULL, ctx->buffer_size);
152 
153  if (!ctx->buffer) {
154  av_log(avctx, AV_LOG_ERROR, "Could not allocate encoding buffer\n");
155  return AVERROR(ENOMEM);
156  }
157 
158  /* check for negative, our default */
159  if (ctx->distance < 0.0) {
160  /* use ffmpeg.c -q option if passed */
161  if (avctx->flags & AV_CODEC_FLAG_QSCALE)
162  ctx->distance = quality_to_distance((float)avctx->global_quality / FF_QP2LAMBDA);
163  else
164  /* default 1.0 matches cjxl */
165  ctx->distance = 1.0;
166  }
167  /*
168  * 0.01 is the minimum distance accepted for lossy
169  * interpreting any positive value less than this as minimum
170  */
171  if (ctx->distance > 0.0 && ctx->distance < 0.01)
172  ctx->distance = 0.01;
173 
174  return 0;
175 }
176 
177 /**
178  * Initializer for the animation encoder. This calls the other initializers
179  * to prevent code duplication and also allocates the prev-frame used in the
180  * encoder.
181  */
183 {
184  int ret;
186 
187  ret = libjxl_encode_init(avctx);
188  if (ret < 0)
189  return ret;
190 
191  ret = libjxl_init_jxl_encoder(avctx);
192  if (ret < 0)
193  return ret;
194 
195  ctx->frame = av_frame_alloc();
196  if (!ctx->frame)
197  return AVERROR(ENOMEM);
198 
199  return 0;
200 }
201 
202 /**
203  * Populate a JxlColorEncoding with the given enum AVColorPrimaries.
204  * @return < 0 upon failure, >= 0 upon success
205  */
206 static int libjxl_populate_primaries(void *avctx, JxlColorEncoding *jxl_color, enum AVColorPrimaries prm)
207 {
208  const AVColorPrimariesDesc *desc;
209 
210  switch (prm) {
211  case AVCOL_PRI_BT709:
212  jxl_color->primaries = JXL_PRIMARIES_SRGB;
213  jxl_color->white_point = JXL_WHITE_POINT_D65;
214  return 0;
215  case AVCOL_PRI_BT2020:
216  jxl_color->primaries = JXL_PRIMARIES_2100;
217  jxl_color->white_point = JXL_WHITE_POINT_D65;
218  return 0;
219  case AVCOL_PRI_SMPTE431:
220  jxl_color->primaries = JXL_PRIMARIES_P3;
221  jxl_color->white_point = JXL_WHITE_POINT_DCI;
222  return 0;
223  case AVCOL_PRI_SMPTE432:
224  jxl_color->primaries = JXL_PRIMARIES_P3;
225  jxl_color->white_point = JXL_WHITE_POINT_D65;
226  return 0;
228  av_log(avctx, AV_LOG_WARNING, "Unknown primaries, assuming BT.709/sRGB. Colors may be wrong.\n");
229  jxl_color->primaries = JXL_PRIMARIES_SRGB;
230  jxl_color->white_point = JXL_WHITE_POINT_D65;
231  return 0;
232  }
233 
235  if (!desc)
236  return AVERROR(EINVAL);
237 
238  jxl_color->primaries = JXL_PRIMARIES_CUSTOM;
239  jxl_color->white_point = JXL_WHITE_POINT_CUSTOM;
240 
241  jxl_color->primaries_red_xy[0] = av_q2d(desc->prim.r.x);
242  jxl_color->primaries_red_xy[1] = av_q2d(desc->prim.r.y);
243  jxl_color->primaries_green_xy[0] = av_q2d(desc->prim.g.x);
244  jxl_color->primaries_green_xy[1] = av_q2d(desc->prim.g.y);
245  jxl_color->primaries_blue_xy[0] = av_q2d(desc->prim.b.x);
246  jxl_color->primaries_blue_xy[1] = av_q2d(desc->prim.b.y);
247  jxl_color->white_point_xy[0] = av_q2d(desc->wp.x);
248  jxl_color->white_point_xy[1] = av_q2d(desc->wp.y);
249 
250  return 0;
251 }
252 
254  const AVPixFmtDescriptor *pix_desc, const JxlBasicInfo *info)
255 {
256  JxlColorEncoding jxl_color;
258  int ret;
259 
260  switch (frame->color_trc && frame->color_trc != AVCOL_TRC_UNSPECIFIED
261  ? frame->color_trc : avctx->color_trc) {
262  case AVCOL_TRC_BT709:
263  jxl_color.transfer_function = JXL_TRANSFER_FUNCTION_709;
264  break;
265  case AVCOL_TRC_LINEAR:
266  jxl_color.transfer_function = JXL_TRANSFER_FUNCTION_LINEAR;
267  break;
269  jxl_color.transfer_function = JXL_TRANSFER_FUNCTION_SRGB;
270  break;
271  case AVCOL_TRC_SMPTE428:
272  jxl_color.transfer_function = JXL_TRANSFER_FUNCTION_DCI;
273  break;
274  case AVCOL_TRC_SMPTE2084:
275  jxl_color.transfer_function = JXL_TRANSFER_FUNCTION_PQ;
276  break;
278  jxl_color.transfer_function = JXL_TRANSFER_FUNCTION_HLG;
279  break;
280  case AVCOL_TRC_GAMMA22:
281  jxl_color.transfer_function = JXL_TRANSFER_FUNCTION_GAMMA;
282  jxl_color.gamma = 1/2.2f;
283  break;
284  case AVCOL_TRC_GAMMA28:
285  jxl_color.transfer_function = JXL_TRANSFER_FUNCTION_GAMMA;
286  jxl_color.gamma = 1/2.8f;
287  break;
288  default:
289  if (pix_desc->flags & AV_PIX_FMT_FLAG_FLOAT) {
290  av_log(avctx, AV_LOG_WARNING,
291  "Unknown transfer function, assuming Linear Light. Colors may be wrong.\n");
292  jxl_color.transfer_function = JXL_TRANSFER_FUNCTION_LINEAR;
293  } else {
294  av_log(avctx, AV_LOG_WARNING,
295  "Unknown transfer function, assuming IEC61966-2-1/sRGB. Colors may be wrong.\n");
296  jxl_color.transfer_function = JXL_TRANSFER_FUNCTION_SRGB;
297  }
298  }
299 
300  jxl_color.rendering_intent = JXL_RENDERING_INTENT_RELATIVE;
301  if (info->num_color_channels == 1)
302  jxl_color.color_space = JXL_COLOR_SPACE_GRAY;
303  else
304  jxl_color.color_space = JXL_COLOR_SPACE_RGB;
305 
306  ret = libjxl_populate_primaries(avctx, &jxl_color,
307  frame->color_primaries && frame->color_primaries != AVCOL_PRI_UNSPECIFIED
308  ? frame->color_primaries : avctx->color_primaries);
309  if (ret < 0)
310  return ret;
311 
312  if (JxlEncoderSetColorEncoding(ctx->encoder, &jxl_color) != JXL_ENC_SUCCESS) {
313  av_log(avctx, AV_LOG_WARNING, "Failed to set JxlColorEncoding\n");
314  return AVERROR_EXTERNAL;
315  }
316 
317  return 0;
318 }
319 
321 {
323  JxlEncoderStatus jret = JXL_ENC_SUCCESS;
324  int ret = 0, opened = 0;
325 
326  /* no boxes need to be added */
327  if (!ctx->exif_buffer)
328  goto end;
329 
330  jret = JxlEncoderUseBoxes(ctx->encoder);
331  if (jret != JXL_ENC_SUCCESS) {
332  av_log(avctx, AV_LOG_WARNING, "Could not enable UseBoxes\n");
334  goto end;
335  }
336  opened = 1;
337 
338  jret = JxlEncoderAddBox(ctx->encoder, "Exif", ctx->exif_buffer->data, ctx->exif_buffer->size, JXL_TRUE);
339  if (jret != JXL_ENC_SUCCESS)
340  jret = JxlEncoderAddBox(ctx->encoder, "Exif", ctx->exif_buffer->data, ctx->exif_buffer->size, JXL_FALSE);
341  if (jret != JXL_ENC_SUCCESS) {
342  av_log(avctx, AV_LOG_WARNING, "Failed to add Exif box\n");
344  goto end;
345  }
346 
347 end:
348  if (opened)
349  JxlEncoderCloseBoxes(ctx->encoder);
350 
351  return ret;
352 }
353 
354 /**
355  * Sends metadata to libjxl based on the first frame of the stream, such as pixel format,
356  * orientation, bit depth, and that sort of thing.
357  */
358 static int libjxl_preprocess_stream(AVCodecContext *avctx, const AVFrame *frame, int animated)
359 {
361  AVFrameSideData *sd;
362  int32_t *matrix = (int32_t[9]){ 0 };
363  int ret = 0, have_matrix = 0;
364  JxlEncoderStatus jret = JXL_ENC_SUCCESS;
365  const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(frame->format);
366  JxlBasicInfo info;
367  JxlPixelFormat *jxl_fmt = &ctx->jxl_fmt;
368  int bits_per_sample;
369  int orientation;
370 #if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
371  JxlBitDepth jxl_bit_depth;
372 #endif
373 
374  /* populate the basic info settings */
375  JxlEncoderInitBasicInfo(&info);
376  jxl_fmt->num_channels = pix_desc->nb_components;
377  info.xsize = frame->width;
378  info.ysize = frame->height;
379  info.num_extra_channels = (jxl_fmt->num_channels + 1) & 0x1;
380  info.num_color_channels = jxl_fmt->num_channels - info.num_extra_channels;
381  bits_per_sample = av_get_bits_per_pixel(pix_desc) / jxl_fmt->num_channels;
382  info.bits_per_sample = avctx->bits_per_raw_sample > 0 && !(pix_desc->flags & AV_PIX_FMT_FLAG_FLOAT)
383  ? avctx->bits_per_raw_sample : bits_per_sample;
384  info.alpha_bits = (info.num_extra_channels > 0) * info.bits_per_sample;
385  if (pix_desc->flags & AV_PIX_FMT_FLAG_FLOAT) {
386  info.exponent_bits_per_sample = info.bits_per_sample > 16 ? 8 : 5;
387  info.alpha_exponent_bits = info.alpha_bits ? info.exponent_bits_per_sample : 0;
388  jxl_fmt->data_type = info.bits_per_sample > 16 ? JXL_TYPE_FLOAT : JXL_TYPE_FLOAT16;
389  } else {
390  info.exponent_bits_per_sample = 0;
391  info.alpha_exponent_bits = 0;
392  jxl_fmt->data_type = info.bits_per_sample <= 8 ? JXL_TYPE_UINT8 : JXL_TYPE_UINT16;
393  }
394 
395  if (info.alpha_bits) {
396  if (avctx->alpha_mode == AVALPHA_MODE_PREMULTIPLIED ||
398  info.alpha_premultiplied = 1;
399  } else if (avctx->alpha_mode != AVALPHA_MODE_STRAIGHT && frame->alpha_mode != AVALPHA_MODE_STRAIGHT) {
400  av_log(avctx, AV_LOG_WARNING, "Unknown alpha mode, assuming straight (independent)\n");
401  }
402  }
403 
404 #if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
405  jxl_bit_depth.bits_per_sample = bits_per_sample;
406  jxl_bit_depth.type = JXL_BIT_DEPTH_FROM_PIXEL_FORMAT;
407  jxl_bit_depth.exponent_bits_per_sample = pix_desc->flags & AV_PIX_FMT_FLAG_FLOAT ?
408  info.exponent_bits_per_sample : 0;
409 #endif
410 
411  /* JPEG XL format itself does not support limited range */
412  if (avctx->color_range == AVCOL_RANGE_MPEG ||
413  avctx->color_range == AVCOL_RANGE_UNSPECIFIED && frame->color_range == AVCOL_RANGE_MPEG)
414  av_log(avctx, AV_LOG_WARNING, "This encoder does not support limited (tv) range, colors will be wrong!\n");
415  else if (avctx->color_range != AVCOL_RANGE_JPEG && frame->color_range != AVCOL_RANGE_JPEG)
416  av_log(avctx, AV_LOG_WARNING, "Unknown color range, assuming full (pc)\n");
417 
418  /* bitexact lossless requires there to be no XYB transform */
419  info.uses_original_profile = ctx->distance == 0.0 || !ctx->xyb;
420 
422  if (sd) {
423  matrix = (int32_t *) sd->data;
424  have_matrix = 1;
425  }
427  if (sd) {
428  AVExifMetadata ifd = { 0 };
429  AVExifEntry *orient = NULL;
430  uint16_t tag = av_exif_get_tag_id("Orientation");
431  ret = av_exif_parse_buffer(avctx, sd->data, sd->size, &ifd, AV_EXIF_TIFF_HEADER);
432  if (ret >= 0)
433  ret = ff_exif_sanitize_ifd(avctx, frame, &ifd);
434  if (ret >= 0)
435  ret = av_exif_get_entry(avctx, &ifd, tag, 0, &orient);
436  if (ret >= 0 && orient) {
437  if (!have_matrix && orient->type == AV_TIFF_SHORT && orient->count
438  && orient->value.uint[0] >= 1 && orient->value.uint[0] <= 8) {
440  have_matrix = 1;
441  }
442  /* pop the orientation tag anyway, because it only creates */
443  /* ambiguity with the codestream orientation taking precdence */
444  ret = av_exif_remove_entry(avctx, &ifd, tag, 0);
445  }
446  if (ret >= 0)
447  ret = av_exif_write(avctx, &ifd, &ctx->exif_buffer, AV_EXIF_T_OFF);
448  if (ret < 0)
449  av_log(avctx, AV_LOG_WARNING, "unable to process EXIF frame data\n");
450  av_exif_free(&ifd);
451  }
452 
453  /* use identity matrix as default */
454  if (!have_matrix)
456 
457  /* av_display_matrix_flip is a right-multipilcation */
458  /* i.e. flip is applied before the previous matrix */
459  if (frame->linesize[0] < 0)
461 
462  orientation = av_exif_matrix_to_orientation(matrix);
463  /* JPEG XL orientation flag agrees with EXIF for values 1-8 */
464  if (orientation) {
465  info.orientation = orientation;
466  } else {
467  av_log(avctx, AV_LOG_WARNING, "singular displaymatrix data\n");
468  info.orientation = frame->linesize[0] >= 0 ? JXL_ORIENT_IDENTITY : JXL_ORIENT_FLIP_VERTICAL;
469  }
470 
471  /* restore the previous value */
472  if (frame->linesize[0] < 0)
474 
475  if (animated) {
476  info.have_animation = 1;
477  info.animation.have_timecodes = 0;
478  info.animation.num_loops = 0;
479  /* avctx->timebase is in seconds per tick, so we take the reciprocol */
480  info.animation.tps_numerator = avctx->time_base.den;
481  info.animation.tps_denominator = avctx->time_base.num;
482  }
483 
484  jret = JxlEncoderSetBasicInfo(ctx->encoder, &info);
485  if (jret != JXL_ENC_SUCCESS) {
486  av_log(avctx, AV_LOG_ERROR, "Failed to set JxlBasicInfo\n");
488  goto end;
489  }
490 
491  if (info.alpha_bits) {
492  JxlExtraChannelInfo extra_info;
493  JxlEncoderInitExtraChannelInfo(JXL_CHANNEL_ALPHA, &extra_info);
494  extra_info.bits_per_sample = info.alpha_bits;
495  extra_info.exponent_bits_per_sample = info.alpha_exponent_bits;
496  extra_info.alpha_premultiplied = info.alpha_premultiplied;
497  jret = JxlEncoderSetExtraChannelInfo(ctx->encoder, 0, &extra_info);
498  if (jret != JXL_ENC_SUCCESS) {
499  av_log(avctx, AV_LOG_ERROR, "Failed to set JxlExtraChannelInfo for alpha!\n");
501  goto end;
502  }
503  }
504 
506  if (sd && sd->size) {
507  jret = JxlEncoderSetICCProfile(ctx->encoder, sd->data, sd->size);
508  if (jret != JXL_ENC_SUCCESS)
509  av_log(avctx, AV_LOG_WARNING, "Could not set ICC Profile\n");
510  }
511 
512  /* jret != JXL_ENC_SUCCESS means fallthrough from above */
513  if (!sd || !sd->size || jret != JXL_ENC_SUCCESS)
514  libjxl_populate_colorspace(avctx, frame, pix_desc, &info);
515 
516 #if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
517  jret = JxlEncoderSetFrameBitDepth(ctx->options, &jxl_bit_depth);
518  if (jret != JXL_ENC_SUCCESS)
519  av_log(avctx, AV_LOG_WARNING, "Failed to set JxlBitDepth\n");
520 #endif
521 
522  /* depending on basic info, level 10 might
523  * be required instead of level 5 */
524  if (JxlEncoderGetRequiredCodestreamLevel(ctx->encoder) > 5) {
525  jret = JxlEncoderSetCodestreamLevel(ctx->encoder, 10);
526  if (jret != JXL_ENC_SUCCESS)
527  av_log(avctx, AV_LOG_WARNING, "Could not increase codestream level\n");
528  }
529 
530  libjxl_add_boxes(avctx);
531 
532 end:
533  av_buffer_unref(&ctx->exif_buffer);
534  return ret;
535 }
536 
537 /**
538  * Sends frame information to libjxl on a per-frame basis. If this is a still image,
539  * this is evaluated once per output file. If this is an animated JPEG XL encode, it
540  * is called once per frame.
541  *
542  * This returns a buffer to the data that should be passed to libjxl (via the
543  * argument **data). If the linesize is nonnegative, this will be frame->data[0],
544  * although if the linesize is negative, it will be the start of the buffer
545  * instead. *data is just a pointer to a location in frame->data so it should not be
546  * freed directly.
547  */
548 static int libjxl_preprocess_frame(AVCodecContext *avctx, const AVFrame *frame, const uint8_t **data)
549 {
551  JxlPixelFormat *jxl_fmt = &ctx->jxl_fmt;
552 
553  /* these shouldn't fail, libjxl bug notwithstanding */
554  if (JxlEncoderFrameSettingsSetOption(ctx->options, JXL_ENC_FRAME_SETTING_EFFORT, ctx->effort)
555  != JXL_ENC_SUCCESS) {
556  av_log(avctx, AV_LOG_ERROR, "Failed to set effort to: %d\n", ctx->effort);
557  return AVERROR_EXTERNAL;
558  }
559 
560  if (JxlEncoderSetFrameDistance(ctx->options, ctx->distance) != JXL_ENC_SUCCESS) {
561  av_log(avctx, AV_LOG_ERROR, "Failed to set distance: %f\n", ctx->distance);
562  return AVERROR_EXTERNAL;
563  }
564 
565  /*
566  * In theory the library should automatically enable modular if necessary,
567  * but it appears it won't at the moment due to a bug. This will still
568  * work even if that is patched.
569  */
570  if (JxlEncoderFrameSettingsSetOption(ctx->options, JXL_ENC_FRAME_SETTING_MODULAR,
571  ctx->modular || ctx->distance <= 0.0 ? 1 : -1) != JXL_ENC_SUCCESS) {
572  av_log(avctx, AV_LOG_ERROR, "Failed to set modular\n");
573  return AVERROR_EXTERNAL;
574  }
575 
576  jxl_fmt->endianness = JXL_NATIVE_ENDIAN;
577  if (frame->linesize[0] >= 0) {
578  jxl_fmt->align = frame->linesize[0];
579  *data = frame->data[0];
580  } else {
581  jxl_fmt->align = -frame->linesize[0];
582  *data = frame->data[0] + frame->linesize[0] * (frame->height - 1);
583  }
584 
585  return 0;
586 }
587 
588 /**
589  * Run libjxl's output processing loop, reallocating the packet as necessary
590  * if libjxl needs more space to work with.
591  */
592 static int libjxl_process_output(AVCodecContext *avctx, size_t *bytes_written)
593 {
595  JxlEncoderStatus jret;
596  size_t available = ctx->buffer_size;
597  uint8_t *next_out = ctx->buffer;
598 
599  while (1) {
600  jret = JxlEncoderProcessOutput(ctx->encoder, &next_out, &available);
601  if (jret == JXL_ENC_ERROR) {
602  av_log(avctx, AV_LOG_ERROR, "Unspecified libjxl error occurred\n");
603  return AVERROR_EXTERNAL;
604  }
605  *bytes_written = ctx->buffer_size - available;
606  /* all data passed has been encoded */
607  if (jret == JXL_ENC_SUCCESS)
608  break;
609  if (jret == JXL_ENC_NEED_MORE_OUTPUT) {
610  /*
611  * at the moment, libjxl has no way to
612  * tell us how much space it actually needs
613  * so we need to malloc loop
614  */
615  uint8_t *temp;
616  size_t new_size = ctx->buffer_size * 2;
617  temp = av_realloc(ctx->buffer, new_size);
618  if (!temp)
619  return AVERROR(ENOMEM);
620  ctx->buffer = temp;
621  ctx->buffer_size = new_size;
622  next_out = ctx->buffer + *bytes_written;
623  available = new_size - *bytes_written;
624  continue;
625  }
626  av_log(avctx, AV_LOG_ERROR, "Bad libjxl event: %d\n", jret);
627  return AVERROR_EXTERNAL;
628  }
629 
630  return 0;
631 }
632 
633 /**
634  * Encode an entire frame. This will always reinitialize a new still image
635  * and encode a one-frame image (for image2 and image2pipe).
636  */
637 static int libjxl_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
638 {
639 
641  int ret;
642  size_t bytes_written = 0;
643  const uint8_t *data;
644 
645  ret = libjxl_init_jxl_encoder(avctx);
646  if (ret < 0) {
647  av_log(avctx, AV_LOG_ERROR, "Error frame-initializing JxlEncoder\n");
648  return ret;
649  }
650 
651  ret = libjxl_preprocess_stream(avctx, frame, 0);
652  if (ret < 0)
653  return ret;
654 
656  if (ret < 0)
657  return ret;
658 
659  if (JxlEncoderAddImageFrame(ctx->options, &ctx->jxl_fmt, data, ctx->jxl_fmt.align * frame->height)
660  != JXL_ENC_SUCCESS) {
661  av_log(avctx, AV_LOG_ERROR, "Failed to add Image Frame\n");
662  return AVERROR_EXTERNAL;
663  }
664 
665  /*
666  * Run this after the last frame in the image has been passed.
667  */
668  JxlEncoderCloseInput(ctx->encoder);
669 
670  ret = libjxl_process_output(avctx, &bytes_written);
671  if (ret < 0)
672  return ret;
673 
674  ret = ff_get_encode_buffer(avctx, pkt, bytes_written, 0);
675  if (ret < 0)
676  return ret;
677 
678  memcpy(pkt->data, ctx->buffer, bytes_written);
679  *got_packet = 1;
680 
681  return 0;
682 }
683 
684 /**
685  * Encode one frame of the animation. libjxl requires us to set duration of the frame
686  * but we're only promised the PTS, not the duration. As a result we have to buffer
687  * a frame and subtract the PTS from the last PTS. The last frame uses the previous
688  * frame's calculated duration as a fallback if its duration field is unset.
689  *
690  * We also need to tell libjxl if our frame is the last one, which we won't know upon
691  * receiving a single frame, so we have to buffer a frame as well and send the "last frame"
692  * upon receiving the special EOF frame.
693  */
695 {
697  int ret = 0;
698  JxlFrameHeader frame_header;
699  size_t bytes_written = 0;
700  const uint8_t *data;
701 
702  if (!ctx->prev) {
703  ctx->prev = av_frame_alloc();
704  if (!ctx->prev)
705  return AVERROR(ENOMEM);
706  ret = ff_encode_get_frame(avctx, ctx->prev);
707  if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
708  return ret;
709  ret = libjxl_preprocess_stream(avctx, ctx->prev, 1);
710  if (ret < 0)
711  return ret;
712  }
713 
714  ret = ff_encode_get_frame(avctx, ctx->frame);
715  if (ret == AVERROR_EOF) {
716  av_frame_free(&ctx->frame);
717  ret = 0;
718  }
719  if (ret == AVERROR(EAGAIN))
720  return ret;
721 
722  JxlEncoderInitFrameHeader(&frame_header);
723 
724  ctx->duration = ctx->prev->duration ? ctx->prev->duration :
725  ctx->frame ? ctx->frame->pts - ctx->prev->pts :
726  ctx->duration ? ctx->duration :
727  1;
728 
729  frame_header.duration = ctx->duration;
730  pkt->duration = ctx->duration;
731  pkt->pts = ctx->prev->pts;
732  pkt->dts = pkt->pts;
733 
734  if (JxlEncoderSetFrameHeader(ctx->options, &frame_header) != JXL_ENC_SUCCESS) {
735  av_log(avctx, AV_LOG_ERROR, "Failed to set JxlFrameHeader\n");
736  return AVERROR_EXTERNAL;
737  }
738 
739  ret = libjxl_preprocess_frame(avctx, ctx->prev, &data);
740  if (ret < 0)
741  return ret;
742 
743  if (JxlEncoderAddImageFrame(ctx->options, &ctx->jxl_fmt, data, ctx->jxl_fmt.align * ctx->prev->height)
744  != JXL_ENC_SUCCESS) {
745  av_log(avctx, AV_LOG_ERROR, "Failed to add Image Frame\n");
746  return AVERROR_EXTERNAL;
747  }
748 
749  if (!ctx->frame)
750  JxlEncoderCloseInput(ctx->encoder);
751 
752  ret = libjxl_process_output(avctx, &bytes_written);
753  if (ret < 0)
754  return ret;
755 
756  ret = ff_get_encode_buffer(avctx, pkt, bytes_written, 0);
757  if (ret < 0)
758  return ret;
759 
760  memcpy(pkt->data, ctx->buffer, bytes_written);
761 
762  if (ctx->frame) {
763  av_frame_unref(ctx->prev);
764  av_frame_move_ref(ctx->prev, ctx->frame);
765  } else {
766  av_frame_free(&ctx->prev);
767  }
768 
769  return ret;
770 }
771 
773 {
775 
776  if (ctx->runner)
777  JxlThreadParallelRunnerDestroy(ctx->runner);
778  ctx->runner = NULL;
779 
780  /*
781  * destroying the encoder also frees
782  * ctx->options so we don't need to
783  */
784  if (ctx->encoder)
785  JxlEncoderDestroy(ctx->encoder);
786  ctx->encoder = NULL;
787 
788  av_freep(&ctx->buffer);
789  av_frame_free(&ctx->prev);
790  av_frame_free(&ctx->frame);
791 
792  return 0;
793 }
794 
795 #define OFFSET(x) offsetof(LibJxlEncodeContext, x)
796 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
797 
798 static const AVOption libjxl_encode_options[] = {
799  { "effort", "Encoding effort", OFFSET(effort), AV_OPT_TYPE_INT, { .i64 = 7 }, 1, 9, VE },
800  { "distance", "Maximum Butteraugli distance (quality setting, "
801  "lower = better, zero = lossless, default 1.0)", OFFSET(distance), AV_OPT_TYPE_FLOAT, { .dbl = -1.0 }, -1.0, 15.0, VE },
802  { "modular", "Force modular mode", OFFSET(modular), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
803  { "xyb", "Use XYB-encoding for lossy images", OFFSET(xyb),
804  AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE },
805  { NULL },
806 };
807 
808 static const AVClass libjxl_encode_class = {
809  .class_name = "libjxl",
810  .item_name = av_default_item_name,
811  .option = libjxl_encode_options,
812  .version = LIBAVUTIL_VERSION_INT,
813 };
814 
823 };
824 
826  .p.name = "libjxl",
827  CODEC_LONG_NAME("libjxl JPEG XL"),
828  .p.type = AVMEDIA_TYPE_VIDEO,
829  .p.id = AV_CODEC_ID_JPEGXL,
830  .priv_data_size = sizeof(LibJxlEncodeContext),
833  .close = libjxl_encode_close,
834  .p.capabilities = AV_CODEC_CAP_OTHER_THREADS |
837  .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
842  .p.priv_class = &libjxl_encode_class,
843  .p.wrapper_name = "libjxl",
844 };
845 
847  .p.name = "libjxl_anim",
848  CODEC_LONG_NAME("libjxl JPEG XL animated"),
849  .p.type = AVMEDIA_TYPE_VIDEO,
850  .p.id = AV_CODEC_ID_JPEGXL_ANIM,
851  .priv_data_size = sizeof(LibJxlEncodeContext),
854  .close = libjxl_encode_close,
855  .p.capabilities = AV_CODEC_CAP_OTHER_THREADS |
858  .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
863  .p.priv_class = &libjxl_encode_class,
864  .p.wrapper_name = "libjxl",
865 };
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
LibJxlEncodeContext::effort
int effort
Definition: libjxlenc.c:55
LibJxlEncodeContext::options
JxlEncoderFrameSettings * options
Definition: libjxlenc.c:54
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
AV_CODEC_ID_JPEGXL_ANIM
@ AV_CODEC_ID_JPEGXL_ANIM
Definition: codec_id.h:331
LibJxlEncodeContext::buffer_size
size_t buffer_size
Definition: libjxlenc.c:60
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:1944
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:43
libjxl_process_output
static int libjxl_process_output(AVCodecContext *avctx, size_t *bytes_written)
Run libjxl's output processing loop, reallocating the packet as necessary if libjxl needs more space ...
Definition: libjxlenc.c:592
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
opt.h
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:813
AVALPHA_MODE_PREMULTIPLIED
@ AVALPHA_MODE_PREMULTIPLIED
Alpha channel is multiplied into color values.
Definition: pixfmt.h:812
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:882
libm.h
av_frame_get_side_data
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition: frame.c:659
VE
#define VE
Definition: libjxlenc.c:796
AVExifEntry
Definition: exif.h:85
av_exif_write
int av_exif_write(void *logctx, const AVExifMetadata *ifd, AVBufferRef **buffer, enum AVExifHeaderMode header_mode)
Allocates a buffer using av_malloc of an appropriate size and writes the EXIF data represented by ifd...
Definition: exif.c:753
AVExifMetadata
Definition: exif.h:76
AVColorPrimariesDesc
Struct that contains both white point location and primaries location, providing the complete descrip...
Definition: csp.h:78
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3456
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
LibJxlEncodeContext::runner
void * runner
Definition: libjxlenc.c:52
AVCOL_TRC_LINEAR
@ AVCOL_TRC_LINEAR
"Linear transfer characteristics"
Definition: pixfmt.h:675
frame_header
static int FUNC() frame_header(CodedBitstreamContext *ctx, RWContext *rw, APVRawFrameHeader *current)
Definition: cbs_apv_syntax_template.c:142
matrix
Definition: vc1dsp.c:43
AV_CODEC_FLAG_QSCALE
#define AV_CODEC_FLAG_QSCALE
Use fixed qscale.
Definition: avcodec.h:213
int64_t
long long int64_t
Definition: coverity.c:34
av_exif_orientation_to_matrix
int av_exif_orientation_to_matrix(int32_t *matrix, int orientation)
Convert an orientation constant used by EXIF's orientation tag into a display matrix used by AV_FRAME...
Definition: exif.c:1343
AV_PIX_FMT_FLAG_FLOAT
#define AV_PIX_FMT_FLAG_FLOAT
The pixel format contains IEEE-754 floating point values.
Definition: pixdesc.h:158
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:435
pixdesc.h
AVCodecContext::color_trc
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition: avcodec.h:660
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:777
av_display_matrix_flip
void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip)
Flip the input matrix horizontally and/or vertically.
Definition: display.c:66
AVPacket::data
uint8_t * data
Definition: packet.h:595
AVOption
AVOption.
Definition: opt.h:429
encode.h
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:669
data
const char data[16]
Definition: mxf.c:149
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:35
FFCodec
Definition: codec_internal.h:127
libjxl.h
AV_FRAME_DATA_DISPLAYMATRIX
@ AV_FRAME_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition: frame.h:85
av_get_bits_per_pixel
int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc)
Return the number of bits per pixel used by the pixel format described by pixdesc.
Definition: pixdesc.c:3408
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:613
AVColorPrimaries
AVColorPrimaries
Chromaticity coordinates of the source primaries.
Definition: pixfmt.h:636
quality
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about quality
Definition: rate_distortion.txt:12
libjxl_anim_encode_init
static av_cold int libjxl_anim_encode_init(AVCodecContext *avctx)
Initializer for the animation encoder.
Definition: libjxlenc.c:182
AV_TIFF_SHORT
@ AV_TIFF_SHORT
Definition: exif.h:45
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:680
libjxl_anim_encode_frame
static int libjxl_anim_encode_frame(AVCodecContext *avctx, AVPacket *pkt)
Encode one frame of the animation.
Definition: libjxlenc.c:694
OFFSET
#define OFFSET(x)
Definition: libjxlenc.c:795
LibJxlEncodeContext::prev
AVFrame * prev
Definition: libjxlenc.c:66
AVCodecContext::thread_count
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition: avcodec.h:1573
AVCOL_TRC_GAMMA28
@ AVCOL_TRC_GAMMA28
also ITU-R BT470BG
Definition: pixfmt.h:672
av_exif_free
void av_exif_free(AVExifMetadata *ifd)
Frees all resources associated with the given EXIF metadata struct.
Definition: exif.c:659
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:496
LibJxlEncodeContext::xyb
int xyb
Definition: libjxlenc.c:58
AV_PIX_FMT_GRAY16
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:522
FF_CODEC_ENCODE_CB
#define FF_CODEC_ENCODE_CB(func)
Definition: codec_internal.h:359
AVRational::num
int num
Numerator.
Definition: rational.h:59
libjxl_populate_colorspace
static int libjxl_populate_colorspace(AVCodecContext *avctx, const AVFrame *frame, const AVPixFmtDescriptor *pix_desc, const JxlBasicInfo *info)
Definition: libjxlenc.c:253
LibJxlEncodeContext::modular
int modular
Definition: libjxlenc.c:57
AVCOL_TRC_GAMMA22
@ AVCOL_TRC_GAMMA22
also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
Definition: pixfmt.h:671
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:52
AVCodecContext::color_primaries
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition: avcodec.h:653
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
AVFrameSideData::size
size_t size
Definition: frame.h:293
av_cold
#define av_cold
Definition: attributes.h:119
AVCodecContext::global_quality
int global_quality
Global quality for codecs which cannot change it per frame.
Definition: avcodec.h:1229
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:95
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
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
info
MIPS optimizations info
Definition: mips.txt:2
AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
This encoder can reorder user opaque values from input AVFrames and return them with corresponding ou...
Definition: codec.h:144
AVCodecContext::bits_per_raw_sample
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:1565
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
AV_PIX_FMT_RGBF32
#define AV_PIX_FMT_RGBF32
Definition: pixfmt.h:626
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:332
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
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
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:244
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
NULL
#define NULL
Definition: coverity.c:32
exif_internal.h
AVCodecContext::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:677
CODEC_PIXFMTS_ARRAY
#define CODEC_PIXFMTS_ARRAY(array)
Definition: codec_internal.h:393
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
AV_EXIF_TIFF_HEADER
@ AV_EXIF_TIFF_HEADER
The TIFF header starts with 0x49492a00, or 0x4d4d002a.
Definition: exif.h:63
AVPixFmtDescriptor::nb_components
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:71
LibJxlEncodeContext::buffer
uint8_t * buffer
Definition: libjxlenc.c:59
FF_CODEC_RECEIVE_PACKET_CB
#define FF_CODEC_RECEIVE_PACKET_CB(func)
Definition: codec_internal.h:367
AVCOL_PRI_BT709
@ AVCOL_PRI_BT709
also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP 177 Annex B
Definition: pixfmt.h:638
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:242
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
libjxl_init_jxl_encoder
static int libjxl_init_jxl_encoder(AVCodecContext *avctx)
Initialize the encoder on a per-file basis.
Definition: libjxlenc.c:105
AVExifEntry::count
uint32_t count
Definition: exif.h:88
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:81
AVPixFmtDescriptor::flags
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
Definition: pixdesc.h:94
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:1289
AVCOL_RANGE_UNSPECIFIED
@ AVCOL_RANGE_UNSPECIFIED
Definition: pixfmt.h:743
LibJxlEncodeContext
Definition: libjxlenc.c:50
error.h
AVCOL_PRI_BT2020
@ AVCOL_PRI_BT2020
ITU-R BT2020.
Definition: pixfmt.h:647
AVCodecContext::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avcodec.h:543
AVCOL_TRC_SMPTE2084
@ AVCOL_TRC_SMPTE2084
SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems.
Definition: pixfmt.h:683
AVCOL_PRI_SMPTE431
@ AVCOL_PRI_SMPTE431
SMPTE ST 431-2 (2011) / DCI P3.
Definition: pixfmt.h:650
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:551
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
libjxl_preprocess_stream
static int libjxl_preprocess_stream(AVCodecContext *avctx, const AVFrame *frame, int animated)
Sends metadata to libjxl based on the first frame of the stream, such as pixel format,...
Definition: libjxlenc.c:358
codec_internal.h
libjxl_encode_frame
static int libjxl_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
Encode an entire frame.
Definition: libjxlenc.c:637
AV_PIX_FMT_RGB48
#define AV_PIX_FMT_RGB48
Definition: pixfmt.h:525
AVFrameSideData::data
uint8_t * data
Definition: frame.h:292
libjxl_preprocess_frame
static int libjxl_preprocess_frame(AVCodecContext *avctx, const AVFrame *frame, const uint8_t **data)
Sends frame information to libjxl on a per-frame basis.
Definition: libjxlenc.c:548
ff_libjxl_encoder
const FFCodec ff_libjxl_encoder
Definition: libjxlenc.c:825
frame.h
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:594
csp.h
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
quality_to_distance
static float quality_to_distance(float quality)
Map a quality setting for -qscale roughly from libjpeg quality numbers to libjxl's butteraugli distan...
Definition: libjxlenc.c:84
AVCOL_TRC_BT709
@ AVCOL_TRC_BT709
also ITU-R BT1361
Definition: pixfmt.h:668
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Underlying C type is float.
Definition: opt.h:271
LibJxlEncodeContext::distance
float distance
Definition: libjxlenc.c:56
libjxl_populate_primaries
static int libjxl_populate_primaries(void *avctx, JxlColorEncoding *jxl_color, enum AVColorPrimaries prm)
Populate a JxlColorEncoding with the given enum AVColorPrimaries.
Definition: libjxlenc.c:206
AVExifEntry::value
union AVExifEntry::@124 value
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:588
libjxl_encode_init
static av_cold int libjxl_encode_init(AVCodecContext *avctx)
Global encoder initialization.
Definition: libjxlenc.c:132
ff_libjxl_anim_encoder
const FFCodec ff_libjxl_anim_encoder
Definition: libjxlenc.c:846
available
if no frame is available
Definition: filter_design.txt:166
display.h
AV_CODEC_ID_JPEGXL
@ AV_CODEC_ID_JPEGXL
Definition: codec_id.h:317
libjxl_encode_close
static av_cold int libjxl_encode_close(AVCodecContext *avctx)
Definition: libjxlenc.c:772
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_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:496
LibJxlEncodeContext::jxl_fmt
JxlPixelFormat jxl_fmt
Definition: libjxlenc.c:61
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:179
libjxl_supported_pixfmts
static enum AVPixelFormat libjxl_supported_pixfmts[]
Definition: libjxlenc.c:815
AVExifEntry::uint
uint64_t * uint
Definition: exif.h:109
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:760
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
libjxl_encode_class
static const AVClass libjxl_encode_class
Definition: libjxlenc.c:808
avcodec.h
version.h
tag
uint32_t tag
Definition: movenc.c:2046
ret
ret
Definition: filter_design.txt:187
pixfmt.h
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:81
AVALPHA_MODE_UNSPECIFIED
@ AVALPHA_MODE_UNSPECIFIED
Unknown alpha handling, or no alpha channel.
Definition: pixfmt.h:811
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
libjxl_add_boxes
static int libjxl_add_boxes(AVCodecContext *avctx)
Definition: libjxlenc.c:320
LibJxlEncodeContext::exif_buffer
AVBufferRef * exif_buffer
Definition: libjxlenc.c:62
AVCodecContext
main external API structure.
Definition: avcodec.h:439
AVCOL_TRC_ARIB_STD_B67
@ AVCOL_TRC_ARIB_STD_B67
ARIB STD-B67, known as "Hybrid log-gamma".
Definition: pixfmt.h:687
frame_header
Definition: truemotion1.c:88
ff_get_encode_buffer
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
Definition: encode.c:105
libjxl_encode_options
static const AVOption libjxl_encode_options[]
Definition: libjxlenc.c:798
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
AVExifEntry::type
enum AVTiffDataType type
Definition: exif.h:87
temp
else temp
Definition: vf_mcdeint.c:271
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:1398
ff_exif_sanitize_ifd
int ff_exif_sanitize_ifd(void *logctx, const AVFrame *frame, AVExifMetadata *ifd)
Compares values in the IFD with data in the provided AVFrame and sets the values in that IFD to match...
Definition: exif.c:1381
LibJxlEncodeContext::frame
AVFrame * frame
Definition: libjxlenc.c:65
av_realloc
#define av_realloc(p, s)
Definition: ops_asmgen.c:46
desc
const char * desc
Definition: libsvtav1.c:83
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
avutil.h
mem.h
ff_encode_get_frame
int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame)
Called by encoders to get the next frame for encoding.
Definition: encode.c:204
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:290
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
AVCOL_PRI_SMPTE432
@ AVCOL_PRI_SMPTE432
SMPTE ST 432-1 (2010) / P3 D65 / Display P3.
Definition: pixfmt.h:651
AVPacket
This structure stores compressed data.
Definition: packet.h:572
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:466
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
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_exif_get_entry
int av_exif_get_entry(void *logctx, AVExifMetadata *ifd, uint16_t id, int flags, AVExifEntry **value)
Get an entry with the tagged ID from the EXIF metadata struct.
Definition: exif.c:1190
AV_FRAME_DATA_EXIF
@ AV_FRAME_DATA_EXIF
Exchangeable image file format metadata.
Definition: frame.h:263
int32_t
int32_t
Definition: audioconvert.c:56
distance
static float distance(float x, float y, int band)
Definition: nellymoserenc.c:231
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVCOL_TRC_SMPTE428
@ AVCOL_TRC_SMPTE428
SMPTE ST 428-1.
Definition: pixfmt.h:685
LibJxlEncodeContext::encoder
JxlEncoder * encoder
Definition: libjxlenc.c:53
pkt
static AVPacket * pkt
Definition: demux_decode.c:55
FF_QP2LAMBDA
#define FF_QP2LAMBDA
factor to convert from H.263 QP to lambda
Definition: avutil.h:226
av_exif_matrix_to_orientation
int av_exif_matrix_to_orientation(const int32_t *matrix)
Convert a display matrix used by AV_FRAME_DATA_DISPLAYMATRIX into an orientation constant used by EXI...
Definition: exif.c:1330
LibJxlEncodeContext::duration
int64_t duration
Definition: libjxlenc.c:67