FFmpeg
Loading...
Searching...
No Matches
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
50typedef struct LibJxlEncodeContext {
51 AVClass *class;
52 void *runner;
53 JxlEncoder *encoder;
54 JxlEncoderFrameSettings *options;
55 int effort;
56 float distance;
58 int xyb;
59 uint8_t *buffer;
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 */
84static 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 */
206static int libjxl_populate_primaries(void *avctx, JxlColorEncoding *jxl_color, enum AVColorPrimaries prm)
207{
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;
220 jxl_color->primaries = JXL_PRIMARIES_P3;
221 jxl_color->white_point = JXL_WHITE_POINT_DCI;
222 return 0;
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;
272 jxl_color.transfer_function = JXL_TRANSFER_FUNCTION_DCI;
273 break;
275 jxl_color.transfer_function = JXL_TRANSFER_FUNCTION_PQ;
276 break;
278 jxl_color.transfer_function = JXL_TRANSFER_FUNCTION_HLG;
279 break;
281 jxl_color.transfer_function = JXL_TRANSFER_FUNCTION_GAMMA;
282 jxl_color.gamma = 1/2.2f;
283 break;
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");
333 ret = AVERROR_EXTERNAL;
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");
343 ret = AVERROR_EXTERNAL;
344 goto end;
345 }
346
347end:
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 */
358static 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) {
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
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");
487 ret = AVERROR_EXTERNAL;
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");
500 ret = AVERROR_EXTERNAL;
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
532end:
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 */
548static 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 */
592static 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 */
637static 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
655 ret = libjxl_preprocess_frame(avctx, frame, &data);
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
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
809 .class_name = "libjxl",
810 .item_name = av_default_item_name,
811 .option = libjxl_encode_options,
812 .version = LIBAVUTIL_VERSION_INT,
813};
814
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,
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};
const FFCodec ff_libjxl_encoder
Definition libjxlenc.c:825
const FFCodec ff_libjxl_anim_encoder
Definition libjxlenc.c:846
#define VE
Definition amfenc_av1.c:30
static AVFormatContext * ctx
int32_t
Libavcodec external API header.
Convenience header that includes libavutil's core.
#define CODEC_PIXFMTS_ARRAY(array)
#define FF_CODEC_CAP_NOT_INIT_THREADSAFE
The codec is not known to be init-threadsafe (i.e.
#define FF_CODEC_RECEIVE_PACKET_CB(func)
#define FF_CODEC_CAP_ICC_PROFILES
Codec supports embedded ICC profiles (AV_FRAME_DATA_ICC_PROFILE).
#define FF_CODEC_ENCODE_CB(func)
#define CODEC_LONG_NAME(str)
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
#define FF_CODEC_CAP_AUTO_THREADS
Codec handles avctx->thread_count == 0 (auto) internally.
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
Colorspace value utility functions for libavutil.
static AVPacket * pkt
static AVFrame * frame
Display matrix.
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
Definition encode.c:106
int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame)
Called by encoders to get the next frame for encoding.
Definition encode.c:218
error code definitions
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:1174
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:883
void av_exif_free(AVExifMetadata *ifd)
Frees all resources associated with the given EXIF metadata struct.
Definition exif.c:660
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:1314
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:1327
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:1365
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:754
int32_t av_exif_get_tag_id(const char *name)
Retrieves the tag ID associated with the provided tag string name.
Definition exif.c:245
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:1273
@ AV_TIFF_SHORT
Definition exif.h:44
@ AV_EXIF_TIFF_HEADER
The TIFF header starts with 0x49492a00, or 0x4d4d002a.
Definition exif.h:62
@ AV_EXIF_T_OFF
The first four bytes point to the actual start, then it's AV_EXIF_TIFF_HEADER.
Definition exif.h:68
EXIF metadata parser - internal functions.
reference-counted frame API
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_FLOAT
Underlying C type is float.
Definition opt.h:270
#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:147
#define AV_CODEC_CAP_OTHER_THREADS
Codec supports multithreading through a method other than slice- or frame-level multithreading.
Definition codec.h:112
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
#define AV_CODEC_FLAG_QSCALE
Use fixed qscale.
Definition avcodec.h:213
@ AV_CODEC_ID_JPEGXL_ANIM
Definition codec_id.h:322
@ AV_CODEC_ID_JPEGXL
Definition codec_id.h:308
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
#define FF_QP2LAMBDA
factor to convert from H.263 QP to lambda
Definition avutil.h:226
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition error.h:59
#define AVERROR_EOF
End of file.
Definition error.h:57
#define AVERROR(e)
Definition error.h:45
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition frame.c:496
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition frame.c:659
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
Move everything contained in src to dst and reset src.
Definition frame.c:523
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition frame.c:52
@ AV_FRAME_DATA_EXIF
Exchangeable image file format metadata.
Definition frame.h:263
@ AV_FRAME_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition frame.h:85
@ 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
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
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
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition rational.h:104
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
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
#define av_cold
Definition attributes.h:117
Libavutil version macros.
size_t ff_libjxl_get_threadcount(int threads)
Transform threadcount in ffmpeg to one used by libjxl.
Definition libjxl.c:33
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
JPEG XL via libjxl common support header.
static const AVClass libjxl_encode_class
Definition libjxlenc.c:808
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
static int libjxl_populate_colorspace(AVCodecContext *avctx, const AVFrame *frame, const AVPixFmtDescriptor *pix_desc, const JxlBasicInfo *info)
Definition libjxlenc.c:253
static int libjxl_anim_encode_frame(AVCodecContext *avctx, AVPacket *pkt)
Encode one frame of the animation.
Definition libjxlenc.c:694
static int libjxl_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
Encode an entire frame.
Definition libjxlenc.c:637
static enum AVPixelFormat libjxl_supported_pixfmts[]
Definition libjxlenc.c:815
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
static const AVOption libjxl_encode_options[]
Definition libjxlenc.c:798
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
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
static av_cold int libjxl_anim_encode_init(AVCodecContext *avctx)
Initializer for the animation encoder.
Definition libjxlenc.c:182
static av_cold int libjxl_encode_close(AVCodecContext *avctx)
Definition libjxlenc.c:772
#define OFFSET(x)
Definition libjxlenc.c:795
static int libjxl_add_boxes(AVCodecContext *avctx)
Definition libjxlenc.c:320
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
static int libjxl_init_jxl_encoder(AVCodecContext *avctx)
Initialize the encoder on a per-file basis.
Definition libjxlenc.c:105
static av_cold int libjxl_encode_init(AVCodecContext *avctx)
Global encoder initialization.
Definition libjxlenc.c:132
Replacements for frequently missing libm functions.
const char * desc
Definition libsvtav1.c:83
Memory handling functions.
uint32_t tag
Definition movenc.c:2087
const char data[16]
Definition mxf.c:149
static float distance(float x, float y, int band)
#define av_realloc(p, s)
Definition ops_static.c:54
AVOptions.
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:3412
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3460
#define AV_PIX_FMT_FLAG_FLOAT
The pixel format contains IEEE-754 floating point values.
Definition pixdesc.h:158
pixel format definitions
#define AV_PIX_FMT_RGBF32
Definition pixfmt.h:632
#define AV_PIX_FMT_RGBAF32
Definition pixfmt.h:633
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition pixfmt.h:766
@ AVCOL_RANGE_UNSPECIFIED
Definition pixfmt.h:749
@ AVCOL_RANGE_JPEG
Full range content.
Definition pixfmt.h:783
#define AV_PIX_FMT_YA16
Definition pixfmt.h:530
@ AVALPHA_MODE_STRAIGHT
Alpha channel is independent of color values.
Definition pixfmt.h:819
@ AVALPHA_MODE_UNSPECIFIED
Unknown alpha handling, or no alpha channel.
Definition pixfmt.h:817
@ AVALPHA_MODE_PREMULTIPLIED
Alpha channel is multiplied into color values.
Definition pixfmt.h:818
#define AV_PIX_FMT_RGBA64
Definition pixfmt.h:535
#define AV_PIX_FMT_RGB48
Definition pixfmt.h:531
#define AV_PIX_FMT_GRAYF32
Definition pixfmt.h:588
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition pixfmt.h:75
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition pixfmt.h:81
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition pixfmt.h:100
@ AV_PIX_FMT_YA8
8 bits gray, 8 bits alpha
Definition pixfmt.h:140
#define AV_PIX_FMT_GRAY16
Definition pixfmt.h:528
AVColorPrimaries
Chromaticity coordinates of the source primaries.
Definition pixfmt.h:642
@ AVCOL_PRI_SMPTE432
SMPTE ST 432-1 (2010) / P3 D65 / Display P3.
Definition pixfmt.h:657
@ AVCOL_PRI_BT709
also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP 177 Annex B
Definition pixfmt.h:644
@ AVCOL_PRI_UNSPECIFIED
Definition pixfmt.h:645
@ AVCOL_PRI_SMPTE431
SMPTE ST 431-2 (2011) / DCI P3.
Definition pixfmt.h:656
@ AVCOL_PRI_BT2020
ITU-R BT2020.
Definition pixfmt.h:653
@ AVCOL_TRC_SMPTE2084
SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems.
Definition pixfmt.h:689
@ AVCOL_TRC_GAMMA22
also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
Definition pixfmt.h:677
@ AVCOL_TRC_LINEAR
"Linear transfer characteristics"
Definition pixfmt.h:681
@ AVCOL_TRC_GAMMA28
also ITU-R BT470BG
Definition pixfmt.h:678
@ AVCOL_TRC_ARIB_STD_B67
ARIB STD-B67, known as "Hybrid log-gamma".
Definition pixfmt.h:693
@ AVCOL_TRC_SMPTE428
SMPTE ST 428-1.
Definition pixfmt.h:691
@ AVCOL_TRC_IEC61966_2_1
IEC 61966-2-1 (sRGB or sYCC)
Definition pixfmt.h:686
@ AVCOL_TRC_UNSPECIFIED
Definition pixfmt.h:675
@ AVCOL_TRC_BT709
also ITU-R BT1361
Definition pixfmt.h:674
A reference to a data buffer.
Definition buffer.h:82
Describe the class of an AVClass context structure.
Definition log.h:76
main external API structure.
Definition avcodec.h:443
int global_quality
Global quality for codecs which cannot change it per frame.
Definition avcodec.h:1235
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition avcodec.h:681
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition avcodec.h:657
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition avcodec.h:1572
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition avcodec.h:1580
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition avcodec.h:664
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition avcodec.h:547
int flags
AV_CODEC_FLAG_*.
Definition avcodec.h:500
enum AVAlphaMode alpha_mode
Indicates how the alpha channel of the video is represented.
Definition avcodec.h:1938
void * priv_data
Definition avcodec.h:470
Struct that contains both white point location and primaries location, providing the complete descrip...
Definition csp.h:78
enum AVTiffDataType type
Definition exif.h:86
uint32_t count
Definition exif.h:87
union AVExifEntry::@325220332140161067313112036135003363017341144014 value
uint64_t * uint
Definition exif.h:108
Structure to hold side data for an AVFrame.
Definition frame.h:327
size_t size
Definition frame.h:330
uint8_t * data
Definition frame.h:329
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
AVOption.
Definition opt.h:428
This structure stores compressed data.
Definition packet.h:580
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
uint64_t flags
Combination of AV_PIX_FMT_FLAG_... flags.
Definition pixdesc.h:94
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition pixdesc.h:71
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
AVBufferRef * exif_buffer
Definition libjxlenc.c:62
JxlEncoder * encoder
Definition libjxlenc.c:53
JxlEncoderFrameSettings * options
Definition libjxlenc.c:54
JxlPixelFormat jxl_fmt
Definition libjxlenc.c:61
#define av_freep(p)
#define av_log(a,...)
else temp
Definition vf_mcdeint.c:275
static const uint8_t quality[]
Definition vmixdec.c:58