FFmpeg
Loading...
Searching...
No Matches
dovi_rpuenc.c
Go to the documentation of this file.
1/*
2 * Dolby Vision RPU encoder
3 *
4 * Copyright (C) 2024 Niklas Haas
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
24#include "libavutil/avassert.h"
25#include "libavutil/crc.h"
26#include "libavutil/mem.h"
27#include "libavutil/refstruct.h"
28
29#include "avcodec.h"
30#include "dovi_rpu.h"
31#include "itut35.h"
32#include "put_bits.h"
33#include "put_golomb.h"
34
35static const struct {
36 uint64_t pps; // maximum pixels per second
37 int width; // maximum width
38 int main; // maximum bitrate in main tier
39 int high; // maximum bitrate in high tier
40} dv_levels[] = {
41 [1] = {1280*720*24, 1280, 20, 50},
42 [2] = {1280*720*30, 1280, 20, 50},
43 [3] = {1920*1080*24, 1920, 20, 70},
44 [4] = {1920*1080*30, 2560, 20, 70},
45 [5] = {1920*1080*60, 3840, 20, 70},
46 [6] = {3840*2160*24, 3840, 25, 130},
47 [7] = {3840*2160*30, 3840, 25, 130},
48 [8] = {3840*2160*48, 3840, 40, 130},
49 [9] = {3840*2160*60, 3840, 40, 130},
50 [10] = {3840*2160*120, 3840, 60, 240},
51 [11] = {3840*2160*120, 7680, 60, 240},
52 [12] = {7680*4320*60, 7680, 120, 450},
53 [13] = {7680*4320*120u, 7680, 240, 800},
54};
55
58 enum AVDOVICompression compression,
59 int strict_std_compliance,
60 int width, int height,
62 enum AVPixelFormat pix_format,
63 enum AVColorSpace color_space,
65 enum AVColorTransferCharacteristic color_trc,
66 AVPacketSideData **coded_side_data,
67 int *nb_coded_side_data)
68{
70 const AVDOVIRpuDataHeader *hdr = NULL;
71 int dv_profile, dv_level, bl_compat_id = -1;
72 size_t cfg_size;
73 uint64_t pps;
74
75 if (!s->enable)
76 goto skip;
77
78 if (metadata)
80
81 if (s->enable == FF_DOVI_AUTOMATIC && !hdr)
82 goto skip;
83
84 if (compression == AV_DOVI_COMPRESSION_RESERVED ||
85 compression > AV_DOVI_COMPRESSION_EXTENDED)
86 return AVERROR(EINVAL);
87
88 switch (codec_id) {
89 case AV_CODEC_ID_AV1: dv_profile = 10; break;
90 case AV_CODEC_ID_H264: dv_profile = 9; break;
92 if (hdr) {
93 dv_profile = ff_dovi_guess_profile_hevc(hdr);
94 break;
95 }
96
97 /* This is likely to be proprietary IPTPQc2 */
98 if (color_space == AVCOL_SPC_IPT_C2 ||
99 (color_space == AVCOL_SPC_UNSPECIFIED &&
100 color_trc == AVCOL_TRC_UNSPECIFIED))
101 dv_profile = 5;
102 else
103 dv_profile = 8;
104 break;
105 default:
106 av_unreachable("ff_dovi_configure only used with AV1, H.264 and HEVC");
107 }
108
109 if (strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
110 if (dv_profile == 9) {
111 if (pix_format != AV_PIX_FMT_YUV420P)
112 dv_profile = 0;
113 } else {
114 if (pix_format != AV_PIX_FMT_YUV420P10)
115 dv_profile = 0;
116 }
117 }
118
119 switch (dv_profile) {
120 case 4: /* HEVC with enhancement layer */
121 case 7:
122 if (s->enable > 0) {
123 av_log(s->logctx, AV_LOG_ERROR, "Coding of Dolby Vision enhancement "
124 "layers is currently unsupported.");
126 } else {
127 goto skip;
128 }
129 case 5: /* HEVC with proprietary IPTPQc2 */
130 bl_compat_id = 0;
131 break;
132 case 10:
133 /* FIXME: check for proper H.273 tags once those are added */
134 if (hdr && hdr->bl_video_full_range_flag) {
135 /* AV1 with proprietary IPTPQc2 */
136 bl_compat_id = 0;
137 break;
138 }
140 case 8: /* HEVC (or AV1) with BL compatibility */
141 if (color_space == AVCOL_SPC_BT2020_NCL &&
143 color_trc == AVCOL_TRC_SMPTE2084) {
144 bl_compat_id = 1;
145 } else if (color_space == AVCOL_SPC_BT2020_NCL &&
147 color_trc == AVCOL_TRC_ARIB_STD_B67) {
148 bl_compat_id = 4;
149 } else if (color_space == AVCOL_SPC_BT709 &&
151 color_trc == AVCOL_TRC_BT709) {
152 bl_compat_id = 2;
153 }
154 }
155
156 if (!dv_profile || bl_compat_id < 0) {
157 if (s->enable > 0) {
158 av_log(s->logctx, AV_LOG_ERROR, "Dolby Vision enabled, but could "
159 "not determine profile and compatibility mode. Double-check "
160 "colorspace and format settings for compatibility?\n");
161 return AVERROR(EINVAL);
162 }
163 goto skip;
164 }
165
166 if (compression != AV_DOVI_COMPRESSION_NONE) {
167 if (dv_profile < 8 && strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
168 av_log(s->logctx, AV_LOG_ERROR, "Dolby Vision metadata compression "
169 "is not permitted for profiles 7 and earlier. (dv_profile: %d, "
170 "compression: %d)\n", dv_profile, compression);
171 return AVERROR(EINVAL);
172 } else if (compression == AV_DOVI_COMPRESSION_EXTENDED &&
173 strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
174 av_log(s->logctx, AV_LOG_ERROR, "Dolby Vision extended metadata "
175 "compression is experimental and not supported by "
176 "devices.");
177 return AVERROR(EINVAL);
178 } else if (dv_profile == 8) {
179 av_log(s->logctx, AV_LOG_WARNING, "Dolby Vision metadata compression "
180 "for profile 8 is known to be unsupported by many devices, "
181 "use with caution.\n");
182 }
183 }
184
185 pps = width * height;
186 if (framerate.num) {
187 pps = pps * framerate.num / framerate.den;
188 } else {
189 pps *= 25; /* sanity fallback */
190 }
191
192 dv_level = 0;
193 for (int i = 1; i < FF_ARRAY_ELEMS(dv_levels); i++) {
194 if (pps > dv_levels[i].pps)
195 continue;
196 if (width > dv_levels[i].width)
197 continue;
198 /* In theory, we should also test the bitrate when known, and
199 * distinguish between main and high tier. In practice, just ignore
200 * the bitrate constraints and hope they work out. This would ideally
201 * be handled by either the encoder or muxer directly. */
202 dv_level = i;
203 break;
204 }
205
206 if (!dv_level) {
207 if (strict_std_compliance >= FF_COMPLIANCE_STRICT) {
208 av_log(s->logctx, AV_LOG_ERROR, "Coded PPS (%"PRIu64") and width (%d) "
209 "exceed Dolby Vision limitations\n", pps, width);
210 return AVERROR(EINVAL);
211 } else {
212 av_log(s->logctx, AV_LOG_WARNING, "Coded PPS (%"PRIu64") and width (%d) "
213 "exceed Dolby Vision limitations. Ignoring, resulting file "
214 "may be non-conforming.\n", pps, width);
215 dv_level = FF_ARRAY_ELEMS(dv_levels) - 1;
216 }
217 }
218
219 cfg = av_dovi_alloc(&cfg_size);
220 if (!cfg)
221 return AVERROR(ENOMEM);
222
223 if (!av_packet_side_data_add(coded_side_data,
224 nb_coded_side_data,
225 AV_PKT_DATA_DOVI_CONF, cfg, cfg_size, 0)) {
226 av_free(cfg);
227 return AVERROR(ENOMEM);
228 }
229
230 cfg->dv_version_major = 1;
231 cfg->dv_version_minor = 0;
232 cfg->dv_profile = dv_profile;
233 cfg->dv_level = dv_level;
234 cfg->rpu_present_flag = 1;
235 cfg->el_present_flag = 0;
236 cfg->bl_present_flag = 1;
237 cfg->dv_bl_signal_compatibility_id = bl_compat_id;
238 cfg->dv_md_compression = compression;
239
240 s->cfg = *cfg;
241 return 0;
242
243skip:
245 return 0;
246}
247
250 enum AVDOVICompression compression,
251 int strict_std_compliance)
252{
253 return dovi_configure_ext(s, par->codec_id, metadata, compression,
254 strict_std_compliance, par->width, par->height,
255 par->framerate, par->format, par->color_space,
256 par->color_primaries, par->color_trc,
258}
259
261{
263 const AVFrameSideData *sd;
267 if (sd)
268 metadata = (const AVDOVIMetadata *) sd->data;
269
270 /* Current encoders cannot handle metadata compression during encoding */
272 avctx->strict_std_compliance, avctx->width,
273 avctx->height, avctx->framerate, avctx->pix_fmt,
274 avctx->colorspace, avctx->color_primaries, avctx->color_trc,
275 &avctx->coded_side_data, &avctx->nb_coded_side_data);
276}
277
278/* Compares only the static DM metadata parts of AVDOVIColorMetadata (excluding
279 * dm_metadata_id and scene_refresh_flag) */
280static int cmp_dm_level0(const AVDOVIColorMetadata *dm1,
281 const AVDOVIColorMetadata *dm2)
282{
283 int ret;
284 for (int i = 0; i < FF_ARRAY_ELEMS(dm1->ycc_to_rgb_matrix); i++) {
285 if ((ret = av_cmp_q(dm1->ycc_to_rgb_matrix[i], dm2->ycc_to_rgb_matrix[i])))
286 return ret;
287 }
288
289 for (int i = 0; i < FF_ARRAY_ELEMS(dm1->ycc_to_rgb_offset); i++) {
290 if ((ret = av_cmp_q(dm1->ycc_to_rgb_offset[i], dm2->ycc_to_rgb_offset[i])))
291 return ret;
292 }
293
294 for (int i = 0; i < FF_ARRAY_ELEMS(dm1->rgb_to_lms_matrix); i++) {
295 if ((ret = av_cmp_q(dm1->rgb_to_lms_matrix[i], dm2->rgb_to_lms_matrix[i])))
296 return ret;
297 }
298
299 return memcmp(&dm1->signal_eotf, &dm2->signal_eotf,
300 sizeof(AVDOVIColorMetadata) -offsetof(AVDOVIColorMetadata, signal_eotf));
301}
302
303/* Tries to reuse the static ext blocks. May reorder `ext->dm_static` */
305{
306 int i, j, idx = 0;
307
308 for (i = 0; i < metadata->num_ext_blocks; i++) {
311 continue;
312
313 /* Find the first matching ext block and move it to [idx] */
314 for (j = idx; j < ext->num_static; j++) {
315 if (!memcmp(&ext->dm_static[j], dm, sizeof(*dm))) {
316 if (j != idx)
317 FFSWAP(AVDOVIDmData, ext->dm_static[j], ext->dm_static[idx]);
318 idx++;
319 break;
320 }
321 }
322
323 if (j == ext->num_static) {
324 /* Found no matching ext block */
325 return 0;
326 }
327 }
328
329 /* If idx is less than ext->num_static, then there are extra unmatched
330 * ext blocks inside ext->dm_static */
331 return idx == ext->num_static;
332}
333
334static inline void put_ue_coef(PutBitContext *pb, const AVDOVIRpuDataHeader *hdr,
335 uint64_t coef)
336{
337 union { uint32_t u32; float f32; } fpart;
338
339 switch (hdr->coef_data_type) {
340 case RPU_COEFF_FIXED:
341 set_ue_golomb(pb, coef >> hdr->coef_log2_denom);
343 coef & ((1LL << hdr->coef_log2_denom) - 1));
344 break;
345 case RPU_COEFF_FLOAT:
346 fpart.f32 = coef / (float) (1LL << hdr->coef_log2_denom);
347 put_bits63(pb, hdr->coef_log2_denom, fpart.u32);
348 break;
349 }
350}
351
352static inline void put_se_coef(PutBitContext *pb, const AVDOVIRpuDataHeader *hdr,
353 uint64_t coef)
354{
355 union { uint32_t u32; float f32; } fpart;
356
357 switch (hdr->coef_data_type) {
358 case RPU_COEFF_FIXED:
359 set_se_golomb(pb, coef >> hdr->coef_log2_denom);
361 coef & ((1LL << hdr->coef_log2_denom) - 1));
362 break;
363 case RPU_COEFF_FLOAT:
364 fpart.f32 = coef / (float) (1LL << hdr->coef_log2_denom);
365 put_bits63(pb, hdr->coef_log2_denom, fpart.u32);
366 break;
367 }
368}
369
370static int validate_ue_golomb_value(uint64_t value)
371{
372 return value <= 0xFFFE;
373}
374
376{
377 return value >= -0x7FFF && value <= 0x7FFF;
378}
379
380static int validate_ue_coef(const AVDOVIRpuDataHeader *hdr, uint64_t coef)
381{
382 if (hdr->coef_log2_denom >= 63)
383 return 0;
384 return validate_ue_golomb_value(coef >> hdr->coef_log2_denom);
385}
386
387static int validate_se_coef(const AVDOVIRpuDataHeader *hdr, int64_t coef)
388{
389 if (hdr->coef_log2_denom >= 63)
390 return 0;
391 return validate_se_golomb_value(coef >> hdr->coef_log2_denom);
392}
393
395 const AVDOVIDataMapping *mapping)
396{
397 if (!mapping->num_x_partitions || mapping->num_x_partitions > 0xFFFF ||
398 !mapping->num_y_partitions || mapping->num_y_partitions > 0xFFFF)
399 return 0;
400
401 for (int c = 0; c < 3; c++) {
402 const AVDOVIReshapingCurve *curve = &mapping->curves[c];
403
404 if (curve->num_pivots < 2 || curve->num_pivots > AV_DOVI_MAX_PIECES + 1)
405 return 0;
406
407 for (int i = 1; i < curve->num_pivots; i++)
408 if (curve->pivots[i] < curve->pivots[i - 1])
409 return 0;
410
411 for (int i = 0; i < curve->num_pivots - 1; i++) {
412 switch (curve->mapping_idc[i]) {
414 if (curve->poly_order[i] < 1 || curve->poly_order[i] > 2)
415 return 0;
416 for (int k = 0; k <= curve->poly_order[i]; k++)
417 if (!validate_se_coef(hdr, curve->poly_coef[i][k]))
418 return 0;
419 break;
421 if (curve->mmr_order[i] < 1 || curve->mmr_order[i] > 3)
422 return 0;
423 if (!validate_se_coef(hdr, curve->mmr_constant[i]))
424 return 0;
425 for (int j = 0; j < curve->mmr_order[i]; j++)
426 for (int k = 0; k < 7; k++)
427 if (!validate_se_coef(hdr, curve->mmr_coef[i][j][k]))
428 return 0;
429 break;
430 default:
431 return 0;
432 }
433 }
434 }
435
436 if (mapping->nlq_method_idc != AV_DOVI_NLQ_NONE) {
438 return 0;
439 for (int c = 0; c < 3; c++) {
440 const AVDOVINLQParams *nlq = &mapping->nlq[c];
441 if (!validate_ue_coef(hdr, nlq->vdr_in_max) ||
444 return 0;
445 }
446 }
447
448 return 1;
449}
450
451static int av_q2den(AVRational q, int den)
452{
453 if (!q.den || q.den == den)
454 return q.num;
455 q = av_mul_q(q, av_make_q(den, 1));
456 return (q.num + (q.den >> 1)) / q.den;
457}
458
459static void generate_ext_v1(PutBitContext *pb, const AVDOVIDmData *dm)
460{
461 int ext_block_length, start_pos, pad_bits;
462
463 switch (dm->level) {
464 case 1: ext_block_length = 5; break;
465 case 2: ext_block_length = 11; break;
466 case 4: ext_block_length = 3; break;
467 case 5: ext_block_length = 7; break;
468 case 6: ext_block_length = 8; break;
469 case 255: ext_block_length = 6; break;
470 default: return;
471 }
472
473 set_ue_golomb(pb, ext_block_length);
474 put_bits(pb, 8, dm->level);
475 start_pos = put_bits_count(pb);
476
477 switch (dm->level) {
478 case 1:
479 put_bits(pb, 12, dm->l1.min_pq);
480 put_bits(pb, 12, dm->l1.max_pq);
481 put_bits(pb, 12, dm->l1.avg_pq);
482 break;
483 case 2:
484 put_bits(pb, 12, dm->l2.target_max_pq);
485 put_bits(pb, 12, dm->l2.trim_slope);
486 put_bits(pb, 12, dm->l2.trim_offset);
487 put_bits(pb, 12, dm->l2.trim_power);
488 put_bits(pb, 12, dm->l2.trim_chroma_weight);
489 put_bits(pb, 12, dm->l2.trim_saturation_gain);
490 put_sbits(pb, 13, dm->l2.ms_weight);
491 break;
492 case 4:
493 put_bits(pb, 12, dm->l4.anchor_pq);
494 put_bits(pb, 12, dm->l4.anchor_power);
495 break;
496 case 5:
497 put_bits(pb, 13, dm->l5.left_offset);
498 put_bits(pb, 13, dm->l5.right_offset);
499 put_bits(pb, 13, dm->l5.top_offset);
500 put_bits(pb, 13, dm->l5.bottom_offset);
501 break;
502 case 6:
503 put_bits(pb, 16, dm->l6.max_luminance);
504 put_bits(pb, 16, dm->l6.min_luminance);
505 put_bits(pb, 16, dm->l6.max_cll);
506 put_bits(pb, 16, dm->l6.max_fall);
507 break;
508 case 255:
509 put_bits(pb, 8, dm->l255.dm_run_mode);
510 put_bits(pb, 8, dm->l255.dm_run_version);
511 for (int i = 0; i < 4; i++)
512 put_bits(pb, 8, dm->l255.dm_debug[i]);
513 break;
514 }
515
516 pad_bits = ext_block_length * 8 - (put_bits_count(pb) - start_pos);
517 av_assert1(pad_bits >= 0);
518 put_bits(pb, pad_bits, 0);
519}
520
521static void put_cie_xy(PutBitContext *pb, AVCIExy xy)
522{
523 const int denom = 32767;
524 put_sbits(pb, 16, av_q2den(xy.x, denom));
525 put_sbits(pb, 16, av_q2den(xy.y, denom));
526}
527
528#define ANY6(arr) (arr[0] || arr[1] || arr[2] || arr[3] || arr[4] || arr[5])
529#define ANY_XY(xy) (xy.x.num || xy.y.num)
530#define ANY_CSP(csp) (ANY_XY(csp.prim.r) || ANY_XY(csp.prim.g) || \
531 ANY_XY(csp.prim.b) || ANY_XY(csp.wp))
532
533static void generate_ext_v2(PutBitContext *pb, const AVDOVIDmData *dm)
534{
535 int ext_block_length, start_pos, pad_bits;
536
537 switch (dm->level) {
538 case 3: ext_block_length = 5; break;
539 case 8:
540 if (ANY6(dm->l8.hue_vector_field)) {
541 ext_block_length = 25;
542 } else if (ANY6(dm->l8.saturation_vector_field)) {
543 ext_block_length = 19;
544 } else if (dm->l8.clip_trim) {
545 ext_block_length = 13;
546 } else if (dm->l8.target_mid_contrast) {
547 ext_block_length = 12;
548 } else {
549 ext_block_length = 10;
550 }
551 break;
552 case 9:
554 ext_block_length = 17;
555 } else {
556 ext_block_length = 1;
557 }
558 break;
559 case 10:
561 ext_block_length = 21;
562 } else {
563 ext_block_length = 5;
564 }
565 break;
566 case 11: ext_block_length = 4; break;
567 case 254: ext_block_length = 2; break;
568 default: return;
569 }
570
571 set_ue_golomb(pb, ext_block_length);
572 put_bits(pb, 8, dm->level);
573 start_pos = put_bits_count(pb);
574
575 switch (dm->level) {
576 case 3:
577 put_bits(pb, 12, dm->l3.min_pq_offset);
578 put_bits(pb, 12, dm->l3.max_pq_offset);
579 put_bits(pb, 12, dm->l3.avg_pq_offset);
580 break;
581 case 8:
582 put_bits(pb, 8, dm->l8.target_display_index);
583 put_bits(pb, 12, dm->l8.trim_slope);
584 put_bits(pb, 12, dm->l8.trim_offset);
585 put_bits(pb, 12, dm->l8.trim_power);
586 put_bits(pb, 12, dm->l8.trim_chroma_weight);
587 put_bits(pb, 12, dm->l8.trim_saturation_gain);
588 put_bits(pb, 12, dm->l8.ms_weight);
589 if (ext_block_length < 12)
590 break;
591 put_bits(pb, 12, dm->l8.target_mid_contrast);
592 if (ext_block_length < 13)
593 break;
594 put_bits(pb, 12, dm->l8.clip_trim);
595 if (ext_block_length < 19)
596 break;
597 for (int i = 0; i < 6; i++)
599 if (ext_block_length < 25)
600 break;
601 for (int i = 0; i < 6; i++)
602 put_bits(pb, 8, dm->l8.hue_vector_field[i]);
603 break;
604 case 9:
605 put_bits(pb, 8, dm->l9.source_primary_index);
606 if (ext_block_length < 17)
607 break;
612 break;
613 case 10:
615 put_bits(pb, 12, dm->l10.target_max_pq);
616 put_bits(pb, 12, dm->l10.target_min_pq);
618 if (ext_block_length < 21)
619 break;
624 break;
625 case 11:
626 put_bits(pb, 8, dm->l11.content_type);
627 put_bits(pb, 4, dm->l11.whitepoint);
628 put_bits(pb, 1, dm->l11.reference_mode_flag);
629 put_bits(pb, 3, 0); /* reserved */
630 put_bits(pb, 8, 0); /* reserved */
631 put_bits(pb, 8, 0); /* reserved */
632 break;
633 case 254:
634 put_bits(pb, 8, dm->l254.dm_mode);
635 put_bits(pb, 8, dm->l254.dm_version_index);
636 break;
637 }
638
639 pad_bits = ext_block_length * 8 - (put_bits_count(pb) - start_pos);
640 av_assert1(pad_bits >= 0);
641 put_bits(pb, pad_bits, 0);
642}
643
645 int flags, uint8_t **out_rpu, int *out_size)
646{
647 PutBitContext *pb = &(PutBitContext){0};
648 const AVDOVIRpuDataHeader *hdr;
649 const AVDOVIDataMapping *mapping;
651 int vdr_dm_metadata_present, vdr_rpu_id, use_prev_vdr_rpu, profile,
652 buffer_size, rpu_size, pad, zero_run, dm_compression;
653 int num_ext_blocks_v1, num_ext_blocks_v2;
654 int dv_md_compression = s->cfg.dv_md_compression;
655 uint32_t crc;
656 uint8_t *dst;
657 if (!metadata) {
658 *out_rpu = NULL;
659 *out_size = 0;
660 return 0;
661 }
662
664 mapping = av_dovi_get_mapping(metadata);
666 av_assert0(s->cfg.dv_profile);
667
669 dv_md_compression = AV_DOVI_COMPRESSION_NONE;
670 else if (dv_md_compression == AV_DOVI_COMPRESSION_RESERVED)
671 return AVERROR(EINVAL);
672
673 if (hdr->rpu_type != 2) {
674 av_log(s->logctx, AV_LOG_ERROR, "Unhandled RPU type %"PRIu8"\n",
675 hdr->rpu_type);
676 return AVERROR_INVALIDDATA;
677 }
678
679 if (!validate_mapping_for_generation(hdr, mapping)) {
680 av_log(s->logctx, AV_LOG_ERROR, "Coefficient out of range for RPU\n");
681 return AVERROR_INVALIDDATA;
682 }
683
685 dv_md_compression = AV_DOVI_COMPRESSION_NONE;
686
687 vdr_rpu_id = mapping->vdr_rpu_id;
688 if (vdr_rpu_id < 0 || vdr_rpu_id > DOVI_MAX_DM_ID) {
689 av_log(s->logctx, AV_LOG_ERROR, "Invalid VDR RPU id %d\n", vdr_rpu_id);
690 return AVERROR_INVALIDDATA;
691 }
692 use_prev_vdr_rpu = 0;
693
694 if (!s->vdr[vdr_rpu_id]) {
695 s->vdr[vdr_rpu_id] = av_refstruct_allocz(sizeof(AVDOVIDataMapping));
696 if (!s->vdr[vdr_rpu_id])
697 return AVERROR(ENOMEM);
698 }
699
700 switch (dv_md_compression) {
702 /* Limited metadata compression requires vdr_rpi_id == 0 */
703 if (vdr_rpu_id != 0)
704 break;
707 if (s->vdr[vdr_rpu_id])
708 use_prev_vdr_rpu = !memcmp(s->vdr[vdr_rpu_id], mapping, sizeof(*mapping));
709 break;
711 return AVERROR(EINVAL);
712 }
713
714 if (s->cfg.dv_md_compression != AV_DOVI_COMPRESSION_EXTENDED) {
715 /* Flush VDRs to avoid leaking old state; maintaining multiple VDR
716 * references requires extended compression */
717 for (int i = 0; i <= DOVI_MAX_DM_ID; i++) {
718 if (i != vdr_rpu_id)
719 av_refstruct_unref(&s->vdr[i]);
720 }
721 }
722
723 if (metadata->num_ext_blocks && !s->ext_blocks) {
724 s->ext_blocks = av_refstruct_allocz(sizeof(*s->ext_blocks));
725 if (!s->ext_blocks)
726 return AVERROR(ENOMEM);
727 }
728
729 vdr_dm_metadata_present = !!memcmp(color, &ff_dovi_color_default, sizeof(*color));
730 if (metadata->num_ext_blocks)
731 vdr_dm_metadata_present = 1;
732
733 if (vdr_dm_metadata_present && !s->dm) {
735 if (!s->dm)
736 return AVERROR(ENOMEM);
737 }
738
739 dm_compression = 0;
740 if (dv_md_compression != AV_DOVI_COMPRESSION_NONE) {
741 if (!cmp_dm_level0(s->dm, color) && try_reuse_ext(s->ext_blocks, metadata))
742 dm_compression = 1;
743 }
744
745 num_ext_blocks_v1 = num_ext_blocks_v2 = 0;
746 for (int i = 0; i < metadata->num_ext_blocks; i++) {
748 if (dm_compression && ff_dovi_rpu_extension_is_static(dm->level))
749 continue;
750
751 switch (dm->level) {
752 case 1:
753 case 2:
754 case 4:
755 case 5:
756 case 6:
757 case 255:
758 num_ext_blocks_v1++;
759 break;
760 case 3:
761 case 8:
762 case 9:
763 case 10:
764 case 11:
765 case 254:
766 num_ext_blocks_v2++;
767 break;
768 default:
769 av_log(s->logctx, AV_LOG_ERROR, "Invalid ext block level %d\n",
770 dm->level);
771 return AVERROR_INVALIDDATA;
772 }
773 }
774
775 buffer_size = 12 /* vdr seq info */ + 5 /* CRC32 + terminator */;
776 buffer_size += num_ext_blocks_v1 * 13;
777 buffer_size += num_ext_blocks_v2 * 28;
778 if (!use_prev_vdr_rpu) {
779 buffer_size += 160;
780 for (int c = 0; c < 3; c++) {
781 for (int i = 0; i < mapping->curves[c].num_pivots - 1; i++) {
782 switch (mapping->curves[c].mapping_idc[i]) {
783 case AV_DOVI_MAPPING_POLYNOMIAL: buffer_size += 26; break;
784 case AV_DOVI_MAPPING_MMR: buffer_size += 177; break;
785 }
786 }
787 }
788 }
789 if (vdr_dm_metadata_present)
790 buffer_size += 67;
791
792 av_fast_padded_malloc(&s->rpu_buf, &s->rpu_buf_sz, buffer_size);
793 if (!s->rpu_buf)
794 return AVERROR(ENOMEM);
795 init_put_bits(pb, s->rpu_buf, s->rpu_buf_sz);
796
797 /* RPU header */
798 put_bits(pb, 6, hdr->rpu_type);
799 put_bits(pb, 11, hdr->rpu_format);
800 put_bits(pb, 4, hdr->vdr_rpu_profile);
801 put_bits(pb, 4, hdr->vdr_rpu_level);
802 put_bits(pb, 1, 1); /* vdr_seq_info_present */
804 put_bits(pb, 2, hdr->coef_data_type);
807 put_bits(pb, 2, hdr->vdr_rpu_normalized_idc);
809 if ((hdr->rpu_format & 0x700) == 0) {
810 int ext_mapping_idc = (hdr->ext_mapping_idc_5_7 << 5) | hdr->ext_mapping_idc_0_4;
811 set_ue_golomb(pb, hdr->bl_bit_depth - 8);
812 set_ue_golomb(pb, (ext_mapping_idc << 8) | (hdr->el_bit_depth - 8));
813 set_ue_golomb(pb, hdr->vdr_bit_depth - 8);
815 put_bits(pb, 3, dm_compression);
817 put_bits(pb, 1, hdr->disable_residual_flag);
818 }
819 s->header = *hdr;
820
821 put_bits(pb, 1, vdr_dm_metadata_present);
822 put_bits(pb, 1, use_prev_vdr_rpu);
823 set_ue_golomb(pb, vdr_rpu_id);
824 s->mapping = s->vdr[vdr_rpu_id];
825
826 profile = s->cfg.dv_profile ? s->cfg.dv_profile : ff_dovi_guess_profile_hevc(hdr);
827
828 if (!use_prev_vdr_rpu) {
831 for (int c = 0; c < 3; c++) {
832 const AVDOVIReshapingCurve *curve = &mapping->curves[c];
833 int prev = 0;
834 set_ue_golomb(pb, curve->num_pivots - 2);
835 for (int i = 0; i < curve->num_pivots; i++) {
836 put_bits(pb, hdr->bl_bit_depth, curve->pivots[i] - prev);
837 prev = curve->pivots[i];
838 }
839 }
840
841 if (mapping->nlq_method_idc != AV_DOVI_NLQ_NONE) {
842 put_bits(pb, 3, mapping->nlq_method_idc);
843 put_bits(pb, hdr->bl_bit_depth, mapping->nlq_pivots[0]);
844 put_bits(pb, hdr->bl_bit_depth, mapping->nlq_pivots[1] - mapping->nlq_pivots[0]);
845 }
846
847 set_ue_golomb(pb, mapping->num_x_partitions - 1);
848 set_ue_golomb(pb, mapping->num_y_partitions - 1);
849
850 for (int c = 0; c < 3; c++) {
851 const AVDOVIReshapingCurve *curve = &mapping->curves[c];
852 for (int i = 0; i < curve->num_pivots - 1; i++) {
853 set_ue_golomb(pb, curve->mapping_idc[i]);
854 switch (curve->mapping_idc[i]) {
856 set_ue_golomb(pb, curve->poly_order[i] - 1);
857 if (curve->poly_order[i] == 1)
858 put_bits(pb, 1, 0); /* linear_interp_flag */
859 for (int k = 0; k <= curve->poly_order[i]; k++)
860 put_se_coef(pb, hdr, curve->poly_coef[i][k]);
861 break;
862 }
863 case AV_DOVI_MAPPING_MMR: {
864 put_bits(pb, 2, curve->mmr_order[i] - 1);
865 put_se_coef(pb, hdr, curve->mmr_constant[i]);
866 for (int j = 0; j < curve->mmr_order[i]; j++) {
867 for (int k = 0; k < 7; k++)
868 put_se_coef(pb, hdr, curve->mmr_coef[i][j][k]);
869 }
870 break;
871 }
872 }
873 }
874 }
875
876 if (mapping->nlq_method_idc != AV_DOVI_NLQ_NONE) {
877 for (int c = 0; c < 3; c++) {
878 const AVDOVINLQParams *nlq = &mapping->nlq[c];
879 put_bits(pb, hdr->el_bit_depth, nlq->nlq_offset);
880 put_ue_coef(pb, hdr, nlq->vdr_in_max);
881 switch (mapping->nlq_method_idc) {
883 put_ue_coef(pb, hdr, nlq->linear_deadzone_slope);
885 break;
886 }
887 }
888 }
889
890 memcpy(s->vdr[vdr_rpu_id], mapping, sizeof(*mapping));
891 }
892
893 if (vdr_dm_metadata_present) {
894 DOVIExt *ext = s->ext_blocks;
895 const int denom = profile == 4 ? (1 << 30) : (1 << 28);
896 set_ue_golomb(pb, color->dm_metadata_id); /* affected_dm_id */
897 set_ue_golomb(pb, color->dm_metadata_id); /* current_dm_id */
898 set_ue_golomb(pb, color->scene_refresh_flag);
899 if (!dm_compression) {
900 for (int i = 0; i < 9; i++)
901 put_sbits(pb, 16, av_q2den(color->ycc_to_rgb_matrix[i], 1 << 13));
902 for (int i = 0; i < 3; i++)
903 put_bits32(pb, av_q2den(color->ycc_to_rgb_offset[i], denom));
904 for (int i = 0; i < 9; i++)
905 put_sbits(pb, 16, av_q2den(color->rgb_to_lms_matrix[i], 1 << 14));
906 put_bits(pb, 16, color->signal_eotf);
907 put_bits(pb, 16, color->signal_eotf_param0);
908 put_bits(pb, 16, color->signal_eotf_param1);
909 put_bits32(pb, color->signal_eotf_param2);
910 put_bits(pb, 5, color->signal_bit_depth);
911 put_bits(pb, 2, color->signal_color_space);
912 put_bits(pb, 2, color->signal_chroma_format);
913 put_bits(pb, 2, color->signal_full_range_flag);
914 put_bits(pb, 12, color->source_min_pq);
915 put_bits(pb, 12, color->source_max_pq);
916 put_bits(pb, 10, color->source_diagonal);
917 }
918
919 memcpy(s->dm, color, sizeof(*color));
920 s->color = s->dm;
921
922 /* Extension blocks */
923 set_ue_golomb(pb, num_ext_blocks_v1);
924 align_put_bits(pb);
925 for (int i = 0; i < metadata->num_ext_blocks; i++) {
927 if (dm_compression && ff_dovi_rpu_extension_is_static(dm->level))
928 continue;
929 generate_ext_v1(pb, dm);
930 }
931
932 if (num_ext_blocks_v2) {
933 set_ue_golomb(pb, num_ext_blocks_v2);
934 align_put_bits(pb);
935 for (int i = 0; i < metadata->num_ext_blocks; i++) {
937 if (dm_compression && ff_dovi_rpu_extension_is_static(dm->level))
938 continue;
940 }
941 }
942
943 if (ext) {
944 size_t ext_sz = FFMIN(sizeof(AVDOVIDmData), metadata->ext_block_size);
945 ext->num_dynamic = 0;
946 if (!dm_compression)
947 ext->num_static = 0;
948 for (int i = 0; i < metadata->num_ext_blocks; i++) {
951 memcpy(&ext->dm_dynamic[ext->num_dynamic++], dm, ext_sz);
952 else if (!dm_compression)
953 memcpy(&ext->dm_static[ext->num_static++], dm, ext_sz);
954 }
955 }
956 } else {
957 s->color = &ff_dovi_color_default;
958 av_refstruct_unref(&s->ext_blocks);
959 }
960
961 flush_put_bits(pb);
963 s->rpu_buf, put_bytes_output(pb)));
964 put_bits32(pb, crc);
965 put_bits(pb, 8, 0x80); /* terminator */
966 flush_put_bits(pb);
967
968 rpu_size = put_bytes_output(pb);
969 if (flags & FF_DOVI_WRAP_T35) {
970 *out_rpu = av_malloc(rpu_size + 15);
971 if (!*out_rpu)
972 return AVERROR(ENOMEM);
973 init_put_bits(pb, *out_rpu, rpu_size + 15);
976 put_bits32(pb, 0x800); /* provider_oriented_code */
977 put_bits(pb, 27, 0x01be6841u); /* fixed EMDF header, see above */
978 if (rpu_size > 0xFF) {
979 av_assert2(rpu_size <= 0x10000);
980 put_bits(pb, 8, (rpu_size >> 8) - 1);
981 put_bits(pb, 1, 1); /* read_more */
982 put_bits(pb, 8, rpu_size & 0xFF);
983 put_bits(pb, 1, 0);
984 } else {
985 put_bits(pb, 8, rpu_size);
986 put_bits(pb, 1, 0);
987 }
988 ff_copy_bits(pb, s->rpu_buf, rpu_size * 8);
989 put_bits(pb, 17, 0x400); /* emdf payload id + emdf_protection */
990
991 pad = pb->bit_left & 7;
992 put_bits(pb, pad, (1 << pad) - 1); /* pad to next byte with 1 bits */
993 flush_put_bits(pb);
995 return 0;
996 } else if (flags & FF_DOVI_WRAP_NAL) {
997 *out_rpu = dst = av_malloc(4 + rpu_size * 3 / 2); /* worst case */
998 if (!*out_rpu)
999 return AVERROR(ENOMEM);
1000 *dst++ = 25; /* NAL prefix */
1001 zero_run = 0;
1002 for (int i = 0; i < rpu_size; i++) {
1003 if (zero_run < 2) {
1004 if (s->rpu_buf[i] == 0) {
1005 zero_run++;
1006 } else {
1007 zero_run = 0;
1008 }
1009 } else {
1010 if ((s->rpu_buf[i] & ~3) == 0) {
1011 /* emulation prevention */
1012 *dst++ = 3;
1013 }
1014 zero_run = s->rpu_buf[i] == 0;
1015 }
1016 *dst++ = s->rpu_buf[i];
1017 }
1018 *out_size = dst - *out_rpu;
1019 return 0;
1020 } else {
1021 /* Return intermediate buffer directly */
1022 *out_rpu = s->rpu_buf;
1023 *out_size = rpu_size;
1024 s->rpu_buf = NULL;
1025 s->rpu_buf_sz = 0;
1026 return 0;
1027 }
1028}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition avassert.h:68
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition avassert.h:58
#define av_unreachable(msg)
Asserts that are used as compiler optimization hints depending upon ASSERT_LEVEL and NBDEBUG.
Definition avassert.h:109
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
Libavcodec external API header.
void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length)
Copy the content of src to the bitstream.
Definition bitstream.c:49
static void BS_FUNC skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
static int FUNC metadata(CodedBitstreamContext *ctx, RWContext *rw, APVRawMetadata *current)
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
Public header for CRC hash function implementation.
static const AVColorPrimariesDesc color_primaries[AVCOL_PRI_NB]
Definition csp.c:76
#define FF_COMPLIANCE_UNOFFICIAL
Allow unofficial extensions.
Definition defs.h:61
#define FF_COMPLIANCE_EXPERIMENTAL
Allow nonstandardized experimental things.
Definition defs.h:62
#define FF_COMPLIANCE_STRICT
Strictly conform to all the things in the spec no matter what consequences.
Definition defs.h:59
AVDOVIDecoderConfigurationRecord * av_dovi_alloc(size_t *size)
Allocate a AVDOVIDecoderConfigurationRecord structure and initialize its fields to default values.
Definition dovi_meta.c:26
static av_always_inline AVDOVIColorMetadata * av_dovi_get_color(const AVDOVIMetadata *data)
Definition dovi_meta.h:375
static av_always_inline AVDOVIRpuDataHeader * av_dovi_get_header(const AVDOVIMetadata *data)
Definition dovi_meta.h:363
AVDOVICompression
Definition dovi_meta.h:67
@ AV_DOVI_COMPRESSION_EXTENDED
Definition dovi_meta.h:71
@ AV_DOVI_COMPRESSION_LIMITED
Definition dovi_meta.h:69
@ AV_DOVI_COMPRESSION_NONE
Definition dovi_meta.h:68
@ AV_DOVI_COMPRESSION_RESERVED
Definition dovi_meta.h:70
static av_always_inline AVDOVIDmData * av_dovi_get_ext(const AVDOVIMetadata *data, int index)
Gets the specified Dolby Vision Display Management (DM) metadata.
Definition dovi_meta.h:385
@ AV_DOVI_MAPPING_MMR
Definition dovi_meta.h:109
@ AV_DOVI_MAPPING_POLYNOMIAL
Definition dovi_meta.h:108
@ AV_DOVI_NLQ_NONE
Definition dovi_meta.h:131
@ AV_DOVI_NLQ_LINEAR_DZ
Definition dovi_meta.h:132
static av_always_inline AVDOVIDataMapping * av_dovi_get_mapping(const AVDOVIMetadata *data)
Definition dovi_meta.h:369
#define AV_DOVI_MAX_PIECES
Coefficients of a piece-wise function.
Definition dovi_meta.h:116
const AVDOVIColorMetadata ff_dovi_color_default
Definition dovi_rpu.c:94
int ff_dovi_guess_profile_hevc(const AVDOVIRpuDataHeader *hdr)
Internal helper function to guess the correct DV profile for HEVC.
Definition dovi_rpu.c:72
#define FF_DOVI_AUTOMATIC
Enable tri-state.
Definition dovi_rpu.h:49
@ FF_DOVI_WRAP_NAL
wrap inside NAL RBSP
Definition dovi_rpu.h:159
@ FF_DOVI_WRAP_T35
wrap inside T.35+EMDF
Definition dovi_rpu.h:160
@ FF_DOVI_COMPRESS_RPU
enable compression for this RPU
Definition dovi_rpu.h:161
@ RPU_COEFF_FIXED
Definition dovi_rpu.h:183
@ RPU_COEFF_FLOAT
Definition dovi_rpu.h:184
static int ff_dovi_rpu_extension_is_static(int level)
Definition dovi_rpu.h:197
#define DOVI_MAX_DM_ID
Definition dovi_rpu.h:33
static void put_se_coef(PutBitContext *pb, const AVDOVIRpuDataHeader *hdr, uint64_t coef)
int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata, int flags, uint8_t **out_rpu, int *out_size)
Synthesize a Dolby Vision RPU reflecting the current state.
uint64_t pps
Definition dovi_rpuenc.c:36
static int validate_ue_coef(const AVDOVIRpuDataHeader *hdr, uint64_t coef)
#define ANY_CSP(csp)
static void generate_ext_v2(PutBitContext *pb, const AVDOVIDmData *dm)
static int av_q2den(AVRational q, int den)
static void put_ue_coef(PutBitContext *pb, const AVDOVIRpuDataHeader *hdr, uint64_t coef)
static int validate_se_coef(const AVDOVIRpuDataHeader *hdr, int64_t coef)
#define ANY6(arr)
static av_cold int dovi_configure_ext(DOVIContext *s, enum AVCodecID codec_id, const AVDOVIMetadata *metadata, enum AVDOVICompression compression, int strict_std_compliance, int width, int height, AVRational framerate, enum AVPixelFormat pix_format, enum AVColorSpace color_space, enum AVColorPrimaries color_primaries, enum AVColorTransferCharacteristic color_trc, AVPacketSideData **coded_side_data, int *nb_coded_side_data)
Definition dovi_rpuenc.c:56
static int validate_se_golomb_value(int64_t value)
static void generate_ext_v1(PutBitContext *pb, const AVDOVIDmData *dm)
av_cold int ff_dovi_configure(DOVIContext *s, AVCodecContext *avctx)
Variant of ff_dovi_configure_from_codedpar which infers the codec parameters from an AVCodecContext.
static const struct @236203243050001075351004153163043221076053071107 dv_levels[]
static int validate_mapping_for_generation(const AVDOVIRpuDataHeader *hdr, const AVDOVIDataMapping *mapping)
static int cmp_dm_level0(const AVDOVIColorMetadata *dm1, const AVDOVIColorMetadata *dm2)
int high
Definition dovi_rpuenc.c:39
av_cold int ff_dovi_configure_from_codedpar(DOVIContext *s, AVCodecParameters *par, const AVDOVIMetadata *metadata, enum AVDOVICompression compression, int strict_std_compliance)
Configure the encoder for Dolby Vision encoding.
static int try_reuse_ext(DOVIExt *ext, const AVDOVIMetadata *metadata)
static int validate_ue_golomb_value(uint64_t value)
static void put_cie_xy(PutBitContext *pb, AVCIExy xy)
int main
Definition dovi_rpuenc.c:38
double value
Definition eval.c:102
static CheckasmConfig cfg
Definition checkasm.c:74
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition codec_id.h:47
@ AV_CODEC_ID_H264
Definition codec_id.h:77
@ AV_CODEC_ID_AV1
Definition codec_id.h:275
@ AV_CODEC_ID_HEVC
Definition codec_id.h:223
void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size)
Same behaviour av_fast_malloc but the buffer has additional AV_INPUT_BUFFER_PADDING_SIZE at the end w...
Definition utils.c:53
AVPacketSideData * av_packet_side_data_add(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, void *data, size_t size, int flags)
Wrap existing data as packet side data.
Definition packet.c:613
@ AV_PKT_DATA_DOVI_CONF
DOVI configuration ref: dolby-vision-bitstreams-within-the-iso-base-media-file-format-v2....
Definition packet.h:280
const AVCRC * av_crc_get_table(AVCRCId crc_id)
Get an initialized standard CRC table.
Definition crc.c:389
uint32_t av_crc(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer, size_t length)
Calculate the CRC of a block.
Definition crc.c:421
@ AV_CRC_32_IEEE
Definition crc.h:52
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
static const AVFrameSideData * av_frame_side_data_get(AVFrameSideData *const *sd, const int nb_sd, enum AVFrameSideDataType type)
Wrapper around av_frame_side_data_get_c() to workaround the limitation that for any type T the conver...
Definition frame.h:1196
@ AV_FRAME_DATA_DOVI_METADATA
Parsed Dolby Vision metadata, suitable for passing to a software implementation.
Definition frame.h:208
#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
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition rational.c:80
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition rational.h:71
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition rational.h:89
#define ITU_T_T35_PROVIDER_CODE_DOLBY
Definition itut35.h:45
#define ITU_T_T35_COUNTRY_CODE_US
Definition itut35.h:32
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition j2kenc.c:154
Macro definitions for various function/variable attributes.
#define av_fallthrough
Definition attributes.h:67
#define av_cold
Definition attributes.h:117
#define FFSWAP(type, a, b)
Definition macros.h:52
#define FFMIN(a, b)
Definition macros.h:49
Memory handling functions.
int profile
Definition mxfenc.c:2299
#define av_malloc(s)
Definition ops_static.c:52
#define AV_PIX_FMT_YUV420P10
Definition pixfmt.h:545
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
AVColorPrimaries
Chromaticity coordinates of the source primaries.
Definition pixfmt.h:642
@ AVCOL_PRI_BT709
also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP 177 Annex B
Definition pixfmt.h:644
@ AVCOL_PRI_BT2020
ITU-R BT2020.
Definition pixfmt.h:653
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition pixfmt.h:672
@ AVCOL_TRC_SMPTE2084
SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems.
Definition pixfmt.h:689
@ AVCOL_TRC_ARIB_STD_B67
ARIB STD-B67, known as "Hybrid log-gamma".
Definition pixfmt.h:693
@ AVCOL_TRC_UNSPECIFIED
Definition pixfmt.h:675
@ AVCOL_TRC_BT709
also ITU-R BT1361
Definition pixfmt.h:674
AVColorSpace
YUV colorspace type.
Definition pixfmt.h:706
@ AVCOL_SPC_BT709
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / derived in SMPTE RP 177 Annex B
Definition pixfmt.h:708
@ AVCOL_SPC_BT2020_NCL
ITU-R BT2020 non-constant luminance system.
Definition pixfmt.h:717
@ AVCOL_SPC_UNSPECIFIED
Definition pixfmt.h:709
@ AVCOL_SPC_IPT_C2
SMPTE ST 2128, IPT-C2.
Definition pixfmt.h:723
bitstream writer API
static void put_sbits(PutBitContext *pb, int n, int32_t value)
Definition put_bits.h:291
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition put_bits.h:62
static int put_bits_count(PutBitContext *s)
Definition put_bits.h:90
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition put_bits.h:153
static void put_bits63(PutBitContext *s, int n, uint64_t value)
Write up to 63 bits into a bitstream.
Definition put_bits.h:344
static int put_bytes_output(const PutBitContext *s)
Definition put_bits.h:99
static av_unused void put_bits32(PutBitContext *s, uint32_t value)
Write exactly 32 bits into a bitstream.
Definition put_bits.h:301
static void align_put_bits(PutBitContext *s)
Pad the bitstream with zeros up to the next byte boundary.
Definition put_bits.h:445
exp golomb vlc writing stuff
static void set_ue_golomb(PutBitContext *pb, int i)
write unsigned exp golomb code.
Definition put_golomb.h:41
static void set_se_golomb(PutBitContext *pb, int i)
write signed exp golomb code.
Definition put_golomb.h:86
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition refstruct.c:120
static void * av_refstruct_allocz(size_t size)
Equivalent to av_refstruct_alloc_ext(size, 0, NULL, NULL)
Definition refstruct.h:105
#define av_bswap32
Definition bswap.h:47
#define FF_ARRAY_ELEMS(a)
Struct containing chromaticity x and y values for the standard CIE 1931 chromaticity definition.
Definition csp.h:56
AVRational x
Definition csp.h:57
AVRational y
Definition csp.h:57
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:643
int width
picture width / height.
Definition avcodec.h:604
AVPacketSideData * coded_side_data
Additional data associated with the entire coded stream.
Definition avcodec.h:1768
int strict_std_compliance
strictly follow the standard (MPEG-4, ...).
Definition avcodec.h:1375
int nb_coded_side_data
Definition avcodec.h:1769
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition avcodec.h:657
AVRational framerate
Definition avcodec.h:563
int nb_decoded_side_data
Definition avcodec.h:1930
enum AVColorSpace colorspace
YUV colorspace type.
Definition avcodec.h:671
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition avcodec.h:664
AVFrameSideData ** decoded_side_data
Array containing static side data, such as HDR10 CLL / MDCV structures.
Definition avcodec.h:1929
enum AVCodecID codec_id
Definition avcodec.h:453
This struct describes the properties of an encoded stream.
Definition codec_par.h:49
enum AVColorSpace color_space
Definition codec_par.h:192
int height
The height of the video frame in pixels.
Definition codec_par.h:150
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition codec_par.h:88
int width
The width of the video frame in pixels.
Definition codec_par.h:143
AVRational framerate
Number of frames per second, for streams with constant frame durations.
Definition codec_par.h:175
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition codec_par.h:57
enum AVColorPrimaries color_primaries
Definition codec_par.h:190
enum AVColorTransferCharacteristic color_trc
Definition codec_par.h:191
AVPacketSideData * coded_side_data
Additional data associated with the entire stream.
Definition codec_par.h:83
AVWhitepointCoefficients wp
Definition csp.h:79
AVPrimaryCoefficients prim
Definition csp.h:80
Dolby Vision RPU colorspace metadata parameters.
Definition dovi_meta.h:171
uint16_t signal_eotf
Extra signal metadata (see Dolby patents for more info).
Definition dovi_meta.h:190
AVRational rgb_to_lms_matrix[9]
Definition dovi_meta.h:185
AVRational ycc_to_rgb_matrix[9]
Coefficients of the custom Dolby Vision IPT-PQ matrices.
Definition dovi_meta.h:183
AVRational ycc_to_rgb_offset[3]
Definition dovi_meta.h:184
Dolby Vision RPU data mapping parameters.
Definition dovi_meta.h:152
uint32_t num_x_partitions
Definition dovi_meta.h:160
AVDOVINLQParams nlq[3]
Definition dovi_meta.h:162
uint8_t mapping_color_space
Definition dovi_meta.h:154
uint8_t mapping_chroma_format_idc
Definition dovi_meta.h:155
uint16_t nlq_pivots[2]
Definition dovi_meta.h:163
AVDOVIReshapingCurve curves[3]
Definition dovi_meta.h:156
enum AVDOVINLQMethod nlq_method_idc
Definition dovi_meta.h:159
uint32_t num_y_partitions
Definition dovi_meta.h:161
Dolby Vision metadata extension block.
Definition dovi_meta.h:318
AVDOVIDmLevel9 l9
Definition dovi_meta.h:329
AVDOVIDmLevel3 l3
Definition dovi_meta.h:323
uint8_t level
Definition dovi_meta.h:319
AVDOVIDmLevel8 l8
Definition dovi_meta.h:328
AVDOVIDmLevel254 l254
Definition dovi_meta.h:332
AVDOVIDmLevel6 l6
Definition dovi_meta.h:326
AVDOVIDmLevel4 l4
Definition dovi_meta.h:324
AVDOVIDmLevel1 l1
Definition dovi_meta.h:321
AVDOVIDmLevel11 l11
Definition dovi_meta.h:331
AVDOVIDmLevel5 l5
Definition dovi_meta.h:325
AVDOVIDmLevel10 l10
Definition dovi_meta.h:330
AVDOVIDmLevel255 l255
Definition dovi_meta.h:333
AVDOVIDmLevel2 l2
Definition dovi_meta.h:322
uint16_t target_min_pq
Definition dovi_meta.h:273
uint16_t target_max_pq
Definition dovi_meta.h:272
uint8_t target_primary_index
Definition dovi_meta.h:274
AVColorPrimariesDesc target_display_primaries
Definition dovi_meta.h:275
uint8_t target_display_index
Definition dovi_meta.h:271
uint8_t content_type
Definition dovi_meta.h:279
uint8_t whitepoint
Definition dovi_meta.h:280
uint8_t reference_mode_flag
Definition dovi_meta.h:281
uint16_t avg_pq
Definition dovi_meta.h:207
uint16_t min_pq
Definition dovi_meta.h:205
uint16_t max_pq
Definition dovi_meta.h:206
uint8_t dm_version_index
Definition dovi_meta.h:301
uint8_t dm_debug[4]
Definition dovi_meta.h:308
uint8_t dm_run_version
Definition dovi_meta.h:307
uint8_t dm_run_mode
Definition dovi_meta.h:306
int16_t ms_weight
Definition dovi_meta.h:218
uint16_t target_max_pq
Definition dovi_meta.h:212
uint16_t trim_slope
Definition dovi_meta.h:213
uint16_t trim_chroma_weight
Definition dovi_meta.h:216
uint16_t trim_saturation_gain
Definition dovi_meta.h:217
uint16_t trim_offset
Definition dovi_meta.h:214
uint16_t trim_power
Definition dovi_meta.h:215
uint16_t max_pq_offset
Definition dovi_meta.h:223
uint16_t avg_pq_offset
Definition dovi_meta.h:224
uint16_t min_pq_offset
Definition dovi_meta.h:222
uint16_t anchor_pq
Definition dovi_meta.h:228
uint16_t anchor_power
Definition dovi_meta.h:229
uint16_t bottom_offset
Definition dovi_meta.h:237
uint16_t top_offset
Definition dovi_meta.h:236
uint16_t left_offset
Definition dovi_meta.h:234
uint16_t right_offset
Definition dovi_meta.h:235
uint16_t min_luminance
Definition dovi_meta.h:243
uint16_t max_luminance
Definition dovi_meta.h:242
uint16_t max_fall
Definition dovi_meta.h:245
uint16_t max_cll
Definition dovi_meta.h:244
uint16_t trim_offset
Definition dovi_meta.h:252
uint8_t target_display_index
Definition dovi_meta.h:250
uint16_t target_mid_contrast
Definition dovi_meta.h:257
uint8_t saturation_vector_field[6]
Definition dovi_meta.h:259
uint16_t trim_power
Definition dovi_meta.h:253
uint8_t hue_vector_field[6]
Definition dovi_meta.h:260
uint16_t trim_saturation_gain
Definition dovi_meta.h:255
uint16_t trim_chroma_weight
Definition dovi_meta.h:254
uint16_t ms_weight
Definition dovi_meta.h:256
uint16_t clip_trim
Definition dovi_meta.h:258
uint16_t trim_slope
Definition dovi_meta.h:251
AVColorPrimariesDesc source_display_primaries
Definition dovi_meta.h:266
uint8_t source_primary_index
Definition dovi_meta.h:265
Combined struct representing a combination of header, mapping and color metadata, for attaching to fr...
Definition dovi_meta.h:345
Coefficients of the non-linear inverse quantization.
Definition dovi_meta.h:139
uint64_t linear_deadzone_slope
Definition dovi_meta.h:143
uint64_t linear_deadzone_threshold
Definition dovi_meta.h:144
uint16_t nlq_offset
Definition dovi_meta.h:140
uint64_t vdr_in_max
Definition dovi_meta.h:141
uint8_t poly_order[AV_DOVI_MAX_PIECES]
Definition dovi_meta.h:122
enum AVDOVIMappingMethod mapping_idc[AV_DOVI_MAX_PIECES]
Definition dovi_meta.h:120
int64_t mmr_constant[AV_DOVI_MAX_PIECES]
Definition dovi_meta.h:126
int64_t mmr_coef[AV_DOVI_MAX_PIECES][3][7]
Definition dovi_meta.h:127
int64_t poly_coef[AV_DOVI_MAX_PIECES][3]
Definition dovi_meta.h:123
uint16_t pivots[AV_DOVI_MAX_PIECES+1]
Definition dovi_meta.h:119
uint8_t mmr_order[AV_DOVI_MAX_PIECES]
Definition dovi_meta.h:125
Dolby Vision RPU data header.
Definition dovi_meta.h:87
uint8_t vdr_rpu_profile
Definition dovi_meta.h:90
uint8_t ext_mapping_idc_0_4
Definition dovi_meta.h:103
uint8_t spatial_resampling_filter_flag
Definition dovi_meta.h:100
uint8_t vdr_bit_depth
Definition dovi_meta.h:99
uint8_t el_spatial_resampling_filter_flag
Definition dovi_meta.h:101
uint8_t bl_video_full_range_flag
Definition dovi_meta.h:96
uint16_t rpu_format
Definition dovi_meta.h:89
uint8_t disable_residual_flag
Definition dovi_meta.h:102
uint8_t vdr_rpu_normalized_idc
Definition dovi_meta.h:95
uint8_t coef_log2_denom
Definition dovi_meta.h:94
uint8_t chroma_resampling_explicit_filter_flag
Definition dovi_meta.h:92
uint8_t coef_data_type
Definition dovi_meta.h:93
uint8_t ext_mapping_idc_5_7
Definition dovi_meta.h:104
uint8_t vdr_rpu_level
Definition dovi_meta.h:91
Structure to hold side data for an AVFrame.
Definition frame.h:327
uint8_t * data
Definition frame.h:329
This structure stores auxiliary information for decoding, presenting, or otherwise processing the cod...
Definition packet.h:424
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
int num_dynamic
Definition dovi_rpu.h:39
AVDOVIDmData dm_static[7]
static extension blocks
Definition dovi_rpu.h:36
int num_static
Definition dovi_rpu.h:38
AVDOVIDmData dm_dynamic[25]
dynamic extension blocks
Definition dovi_rpu.h:37
#define av_free(p)
#define av_log(a,...)
float framerate
Definition av1_levels.c:29
static int out_size
Definition movenc.c:56
#define height
Definition dsp.h:89
#define width
Definition dsp.h:89
enum AVCodecID codec_id
static double c[64]