FFmpeg
dovi_rpu.c
Go to the documentation of this file.
1 /*
2  * Dolby Vision RPU decoder
3  *
4  * Copyright (C) 2021 Jan Ekström
5  * Copyright (C) 2021 Niklas Haas
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include "libavutil/buffer.h"
25 
26 #include "dovi_rpu.h"
27 #include "golomb.h"
28 #include "get_bits.h"
29 #include "refstruct.h"
30 
31 enum {
34 };
35 
36 /**
37  * Private contents of vdr.
38  */
39 typedef struct DOVIVdr {
42 } DOVIVdr;
43 
45 {
46  for (int i = 0; i < FF_ARRAY_ELEMS(s->vdr); i++)
47  ff_refstruct_unref(&s->vdr[i]);
48 
49  *s = (DOVIContext) {
50  .logctx = s->logctx,
51  };
52 }
53 
55 {
56  for (int i = 0; i < FF_ARRAY_ELEMS(s->vdr); i++)
57  ff_refstruct_unref(&s->vdr[i]);
58 
59  *s = (DOVIContext) {
60  .logctx = s->logctx,
61  .dv_profile = s->dv_profile,
62  };
63 }
64 
66 {
67  s->logctx = s0->logctx;
68  s->mapping = s0->mapping;
69  s->color = s0->color;
70  s->dv_profile = s0->dv_profile;
71  for (int i = 0; i < DOVI_MAX_DM_ID; i++)
72  ff_refstruct_replace(&s->vdr[i], s0->vdr[i]);
73 }
74 
76 {
77  if (!cfg)
78  return;
79 
80  s->dv_profile = cfg->dv_profile;
81 }
82 
84 {
85  AVFrameSideData *sd;
86  AVBufferRef *buf;
87  AVDOVIMetadata *dovi;
88  size_t dovi_size;
89 
90  if (!s->mapping || !s->color)
91  return 0; /* incomplete dovi metadata */
92 
93  dovi = av_dovi_metadata_alloc(&dovi_size);
94  if (!dovi)
95  return AVERROR(ENOMEM);
96 
97  buf = av_buffer_create((uint8_t *) dovi, dovi_size, NULL, NULL, 0);
98  if (!buf) {
99  av_free(dovi);
100  return AVERROR(ENOMEM);
101  }
102 
104  if (!sd) {
105  av_buffer_unref(&buf);
106  return AVERROR(ENOMEM);
107  }
108 
109  /* Copy only the parts of these structs known to us at compiler-time. */
110 #define COPY(t, a, b, last) memcpy(a, b, offsetof(t, last) + sizeof((b)->last))
111  COPY(AVDOVIRpuDataHeader, av_dovi_get_header(dovi), &s->header, disable_residual_flag);
112  COPY(AVDOVIDataMapping, av_dovi_get_mapping(dovi), s->mapping, nlq[2].linear_deadzone_threshold);
113  COPY(AVDOVIColorMetadata, av_dovi_get_color(dovi), s->color, source_diagonal);
114  return 0;
115 }
116 
117 static int guess_profile(const AVDOVIRpuDataHeader *hdr)
118 {
119  switch (hdr->vdr_rpu_profile) {
120  case 0:
121  if (hdr->bl_video_full_range_flag)
122  return 5;
123  break;
124  case 1:
126  if (hdr->vdr_bit_depth == 12) {
127  return 7;
128  } else {
129  return 4;
130  }
131  } else {
132  return 8;
133  }
134  }
135 
136  return 0; /* unknown */
137 }
138 
139 static inline uint64_t get_ue_coef(GetBitContext *gb, const AVDOVIRpuDataHeader *hdr)
140 {
141  uint64_t ipart;
142  union { uint32_t u32; float f32; } fpart;
143 
144  switch (hdr->coef_data_type) {
145  case RPU_COEFF_FIXED:
146  ipart = get_ue_golomb_long(gb);
147  fpart.u32 = get_bits_long(gb, hdr->coef_log2_denom);
148  return (ipart << hdr->coef_log2_denom) + fpart.u32;
149 
150  case RPU_COEFF_FLOAT:
151  fpart.u32 = get_bits_long(gb, 32);
152  return fpart.f32 * (1LL << hdr->coef_log2_denom);
153  }
154 
155  return 0; /* unreachable */
156 }
157 
158 static inline int64_t get_se_coef(GetBitContext *gb, const AVDOVIRpuDataHeader *hdr)
159 {
160  int64_t ipart;
161  union { uint32_t u32; float f32; } fpart;
162 
163  switch (hdr->coef_data_type) {
164  case RPU_COEFF_FIXED:
165  ipart = get_se_golomb_long(gb);
166  fpart.u32 = get_bits_long(gb, hdr->coef_log2_denom);
167  return ipart * (1LL << hdr->coef_log2_denom) + fpart.u32;
168 
169  case RPU_COEFF_FLOAT:
170  fpart.u32 = get_bits_long(gb, 32);
171  return fpart.f32 * (1LL << hdr->coef_log2_denom);
172  }
173 
174  return 0; /* unreachable */
175 }
176 
177 static inline unsigned get_variable_bits(GetBitContext *gb, int n)
178 {
179  unsigned int value = get_bits(gb, n);
180  int read_more = get_bits1(gb);
181  while (read_more) {
182  value = (value + 1) << n;
183  value |= get_bits(gb, n);
184  read_more = get_bits1(gb);
185  }
186  return value;
187 }
188 
189 #define VALIDATE(VAR, MIN, MAX) \
190  do { \
191  if (VAR < MIN || VAR > MAX) { \
192  av_log(s->logctx, AV_LOG_ERROR, "RPU validation failed: " \
193  #MIN" <= "#VAR" = %d <= "#MAX"\n", (int) VAR); \
194  goto fail; \
195  } \
196  } while (0)
197 
198 int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size)
199 {
200  AVDOVIRpuDataHeader *hdr = &s->header;
201  GetBitContext *gb = &(GetBitContext){0};
202  DOVIVdr *vdr;
203  int ret;
204 
205  uint8_t nal_prefix;
206  uint8_t rpu_type;
207  uint8_t vdr_seq_info_present;
208  uint8_t vdr_dm_metadata_present;
209  uint8_t use_prev_vdr_rpu;
210  uint8_t use_nlq;
211  uint8_t profile;
212  if ((ret = init_get_bits8(gb, rpu, rpu_size)) < 0)
213  return ret;
214 
215  /* Container header */
216  if (s->dv_profile == 10 /* dav1.10 */) {
217  /* DV inside AV1 re-uses an EMDF container skeleton, but with fixed
218  * values - so we can effectively treat this as a magic byte sequence.
219  *
220  * The exact fields are, as follows:
221  * emdf_version : f(2) = 0
222  * key_id : f(3) = 6
223  * emdf_payload_id : f(5) = 31
224  * emdf_payload_id_ext : var(5) = 225
225  * smploffste : f(1) = 0
226  * duratione : f(1) = 0
227  * groupide : f(1) = 0
228  * codecdatae : f(1) = 0
229  * discard_unknown_payload : f(1) = 1
230  */
231  const unsigned header_magic = 0x01be6841u;
232  unsigned header, emdf_payload_size;
233  header = get_bits_long(gb, 27);
234  VALIDATE(header, header_magic, header_magic);
235  emdf_payload_size = get_variable_bits(gb, 8);
236  VALIDATE(emdf_payload_size, 6, 512);
237  if (emdf_payload_size * 8 > get_bits_left(gb))
238  return AVERROR_INVALIDDATA;
239  } else {
240  nal_prefix = get_bits(gb, 8);
241  VALIDATE(nal_prefix, 25, 25);
242  }
243 
244  /* RPU header */
245  rpu_type = get_bits(gb, 6);
246  if (rpu_type != 2) {
247  av_log(s->logctx, AV_LOG_WARNING, "Unrecognized RPU type "
248  "%"PRIu8", ignoring\n", rpu_type);
249  return 0;
250  }
251 
252  hdr->rpu_type = rpu_type;
253  hdr->rpu_format = get_bits(gb, 11);
254 
255  /* Values specific to RPU type 2 */
256  hdr->vdr_rpu_profile = get_bits(gb, 4);
257  hdr->vdr_rpu_level = get_bits(gb, 4);
258 
259  vdr_seq_info_present = get_bits1(gb);
260  if (vdr_seq_info_present) {
262  hdr->coef_data_type = get_bits(gb, 2);
264  switch (hdr->coef_data_type) {
265  case RPU_COEFF_FIXED:
266  hdr->coef_log2_denom = get_ue_golomb(gb);
267  VALIDATE(hdr->coef_log2_denom, 13, 32);
268  break;
269  case RPU_COEFF_FLOAT:
270  hdr->coef_log2_denom = 32; /* arbitrary, choose maximum precision */
271  break;
272  }
273 
274  hdr->vdr_rpu_normalized_idc = get_bits(gb, 2);
276 
277  if ((hdr->rpu_format & 0x700) == 0) {
278  int bl_bit_depth_minus8 = get_ue_golomb_31(gb);
279  int el_bit_depth_minus8 = get_ue_golomb_31(gb);
280  int vdr_bit_depth_minus8 = get_ue_golomb_31(gb);
281  VALIDATE(bl_bit_depth_minus8, 0, 8);
282  VALIDATE(el_bit_depth_minus8, 0, 8);
283  VALIDATE(vdr_bit_depth_minus8, 0, 8);
284  hdr->bl_bit_depth = bl_bit_depth_minus8 + 8;
285  hdr->el_bit_depth = el_bit_depth_minus8 + 8;
286  hdr->vdr_bit_depth = vdr_bit_depth_minus8 + 8;
288  skip_bits(gb, 3); /* reserved_zero_3bits */
290  hdr->disable_residual_flag = get_bits1(gb);
291  }
292  }
293 
294  if (!hdr->bl_bit_depth) {
295  av_log(s->logctx, AV_LOG_ERROR, "Missing RPU VDR sequence info?\n");
296  goto fail;
297  }
298 
299  vdr_dm_metadata_present = get_bits1(gb);
300  use_prev_vdr_rpu = get_bits1(gb);
301  use_nlq = (hdr->rpu_format & 0x700) == 0 && !hdr->disable_residual_flag;
302 
303  profile = s->dv_profile ? s->dv_profile : guess_profile(hdr);
304  if (profile == 5 && use_nlq) {
305  av_log(s->logctx, AV_LOG_ERROR, "Profile 5 RPUs should not use NLQ\n");
306  goto fail;
307  }
308 
309  if (use_prev_vdr_rpu) {
310  int prev_vdr_rpu_id = get_ue_golomb_31(gb);
311  VALIDATE(prev_vdr_rpu_id, 0, DOVI_MAX_DM_ID);
312  if (!s->vdr[prev_vdr_rpu_id]) {
313  av_log(s->logctx, AV_LOG_ERROR, "Unknown previous RPU ID: %u\n",
314  prev_vdr_rpu_id);
315  goto fail;
316  }
317  vdr = s->vdr[prev_vdr_rpu_id];
318  s->mapping = &vdr->mapping;
319  } else {
320  int vdr_rpu_id = get_ue_golomb_31(gb);
321  VALIDATE(vdr_rpu_id, 0, DOVI_MAX_DM_ID);
322  if (!s->vdr[vdr_rpu_id]) {
323  s->vdr[vdr_rpu_id] = ff_refstruct_allocz(sizeof(DOVIVdr));
324  if (!s->vdr[vdr_rpu_id])
325  return AVERROR(ENOMEM);
326  }
327 
328  vdr = s->vdr[vdr_rpu_id];
329  s->mapping = &vdr->mapping;
330 
331  vdr->mapping.vdr_rpu_id = vdr_rpu_id;
334 
335  for (int c = 0; c < 3; c++) {
336  AVDOVIReshapingCurve *curve = &vdr->mapping.curves[c];
337  int num_pivots_minus_2 = get_ue_golomb_31(gb);
338  int pivot = 0;
339 
340  VALIDATE(num_pivots_minus_2, 0, AV_DOVI_MAX_PIECES - 1);
341  curve->num_pivots = num_pivots_minus_2 + 2;
342  for (int i = 0; i < curve->num_pivots; i++) {
343  pivot += get_bits(gb, hdr->bl_bit_depth);
344  curve->pivots[i] = av_clip_uint16(pivot);
345  }
346  }
347 
348  if (use_nlq) {
349  vdr->mapping.nlq_method_idc = get_bits(gb, 3);
350  /**
351  * The patent mentions another legal value, NLQ_MU_LAW, but it's
352  * not documented anywhere how to parse or apply that type of NLQ.
353  */
355  } else {
357  }
358 
361  /* End of rpu_data_header(), start of vdr_rpu_data_payload() */
362 
363  for (int c = 0; c < 3; c++) {
364  AVDOVIReshapingCurve *curve = &vdr->mapping.curves[c];
365  for (int i = 0; i < curve->num_pivots - 1; i++) {
366  int mapping_idc = get_ue_golomb_31(gb);
367  VALIDATE(mapping_idc, 0, 1);
368  curve->mapping_idc[i] = mapping_idc;
369  switch (mapping_idc) {
371  int poly_order_minus1 = get_ue_golomb_31(gb);
372  VALIDATE(poly_order_minus1, 0, 1);
373  curve->poly_order[i] = poly_order_minus1 + 1;
374  if (poly_order_minus1 == 0) {
375  int linear_interp_flag = get_bits1(gb);
376  if (linear_interp_flag) {
377  /* lack of documentation/samples */
378  avpriv_request_sample(s->logctx, "Dolby Vision "
379  "linear interpolation");
381  return AVERROR_PATCHWELCOME;
382  }
383  }
384  for (int k = 0; k <= curve->poly_order[i]; k++)
385  curve->poly_coef[i][k] = get_se_coef(gb, hdr);
386  break;
387  }
388  case AV_DOVI_MAPPING_MMR: {
389  int mmr_order_minus1 = get_bits(gb, 2);
390  VALIDATE(mmr_order_minus1, 0, 2);
391  curve->mmr_order[i] = mmr_order_minus1 + 1;
392  curve->mmr_constant[i] = get_se_coef(gb, hdr);
393  for (int j = 0; j < curve->mmr_order[i]; j++) {
394  for (int k = 0; k < 7; k++)
395  curve->mmr_coef[i][j][k] = get_se_coef(gb, hdr);
396  }
397  break;
398  }
399  }
400  }
401  }
402 
403  if (use_nlq) {
404  for (int c = 0; c < 3; c++) {
405  AVDOVINLQParams *nlq = &vdr->mapping.nlq[c];
406  nlq->nlq_offset = get_bits(gb, hdr->el_bit_depth);
407  nlq->vdr_in_max = get_ue_coef(gb, hdr);
408  switch (vdr->mapping.nlq_method_idc) {
410  nlq->linear_deadzone_slope = get_ue_coef(gb, hdr);
411  nlq->linear_deadzone_threshold = get_ue_coef(gb, hdr);
412  break;
413  }
414  }
415  }
416  }
417 
418  if (vdr_dm_metadata_present) {
420  int affected_dm_id = get_ue_golomb_31(gb);
421  int current_dm_id = get_ue_golomb_31(gb);
422  VALIDATE(affected_dm_id, 0, DOVI_MAX_DM_ID);
423  VALIDATE(current_dm_id, 0, DOVI_MAX_DM_ID);
424  if (!s->vdr[affected_dm_id]) {
425  s->vdr[affected_dm_id] = ff_refstruct_allocz(sizeof(DOVIVdr));
426  if (!s->vdr[affected_dm_id])
427  return AVERROR(ENOMEM);
428  }
429 
430  if (!s->vdr[current_dm_id]) {
431  av_log(s->logctx, AV_LOG_ERROR, "Unknown previous RPU DM ID: %u\n",
432  current_dm_id);
433  goto fail;
434  }
435 
436  /* Update current pointer based on current_dm_id */
437  vdr = s->vdr[current_dm_id];
438  s->color = &vdr->color;
439 
440  /* Update values of affected_dm_id */
441  vdr = s->vdr[affected_dm_id];
442  color = &vdr->color;
443  color->dm_metadata_id = affected_dm_id;
444  color->scene_refresh_flag = get_ue_golomb_31(gb);
445  for (int i = 0; i < 9; i++)
446  color->ycc_to_rgb_matrix[i] = av_make_q(get_sbits(gb, 16), 1 << 13);
447  for (int i = 0; i < 3; i++) {
448  int denom = profile == 4 ? (1 << 30) : (1 << 28);
449  unsigned offset = get_bits_long(gb, 32);
450  if (offset > INT_MAX) {
451  /* Ensure the result fits inside AVRational */
452  offset >>= 1;
453  denom >>= 1;
454  }
455  color->ycc_to_rgb_offset[i] = av_make_q(offset, denom);
456  }
457  for (int i = 0; i < 9; i++)
458  color->rgb_to_lms_matrix[i] = av_make_q(get_sbits(gb, 16), 1 << 14);
459 
460  color->signal_eotf = get_bits(gb, 16);
461  color->signal_eotf_param0 = get_bits(gb, 16);
462  color->signal_eotf_param1 = get_bits(gb, 16);
463  color->signal_eotf_param2 = get_bits_long(gb, 32);
464  color->signal_bit_depth = get_bits(gb, 5);
465  VALIDATE(color->signal_bit_depth, 8, 16);
466  color->signal_color_space = get_bits(gb, 2);
467  color->signal_chroma_format = get_bits(gb, 2);
468  color->signal_full_range_flag = get_bits(gb, 2);
469  color->source_min_pq = get_bits(gb, 12);
470  color->source_max_pq = get_bits(gb, 12);
471  color->source_diagonal = get_bits(gb, 10);
472  }
473 
474  /* FIXME: verify CRC32, requires implementation of AV_CRC_32_MPEG_2 */
475  return 0;
476 
477 fail:
478  ff_dovi_ctx_unref(s); /* don't leak potentially invalid state */
479  return AVERROR(EINVAL);
480 }
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
AVDOVIDataMapping::nlq_method_idc
enum AVDOVINLQMethod nlq_method_idc
Definition: dovi_meta.h:146
get_bits_left
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:694
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
ff_dovi_ctx_unref
void ff_dovi_ctx_unref(DOVIContext *s)
Completely reset a DOVIContext, preserving only logctx.
Definition: dovi_rpu.c:44
DOVI_MAX_DM_ID
#define DOVI_MAX_DM_ID
Definition: dovi_rpu.h:30
color
Definition: vf_paletteuse.c:511
u
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:250
get_se_golomb_long
static int get_se_golomb_long(GetBitContext *gb)
Definition: golomb.h:294
get_bits_long
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:421
AV_FRAME_DATA_DOVI_METADATA
@ AV_FRAME_DATA_DOVI_METADATA
Parsed Dolby Vision metadata, suitable for passing to a software implementation.
Definition: frame.h:204
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:340
get_ue_golomb
static int get_ue_golomb(GetBitContext *gb)
Read an unsigned Exp-Golomb code in the range 0 to 8190.
Definition: golomb.h:53
AVDOVIReshapingCurve::mmr_coef
int64_t mmr_coef[AV_DOVI_MAX_PIECES][3][7]
Definition: dovi_meta.h:114
AV_DOVI_NLQ_NONE
@ AV_DOVI_NLQ_NONE
Definition: dovi_meta.h:118
AVDOVIReshapingCurve::mapping_idc
enum AVDOVIMappingMethod mapping_idc[AV_DOVI_MAX_PIECES]
Definition: dovi_meta.h:107
VALIDATE
#define VALIDATE(VAR, MIN, MAX)
Definition: dovi_rpu.c:189
AVDOVIRpuDataHeader::rpu_format
uint16_t rpu_format
Definition: dovi_meta.h:78
RPU_COEFF_FIXED
@ RPU_COEFF_FIXED
Definition: dovi_rpu.c:32
AVDOVIDataMapping::mapping_color_space
uint8_t mapping_color_space
Definition: dovi_meta.h:141
AVDOVIRpuDataHeader
Dolby Vision RPU data header.
Definition: dovi_meta.h:76
AVDOVIRpuDataHeader::coef_data_type
uint8_t coef_data_type
Definition: dovi_meta.h:82
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:381
golomb.h
exp golomb vlc stuff
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:335
DOVIContext
Definition: dovi_rpu.h:31
fail
#define fail()
Definition: checkasm.h:179
AVDOVIRpuDataHeader::el_bit_depth
uint8_t el_bit_depth
Definition: dovi_meta.h:87
GetBitContext
Definition: get_bits.h:108
RPU_COEFF_FLOAT
@ RPU_COEFF_FLOAT
Definition: dovi_rpu.c:33
dovi_rpu.h
refstruct.h
AVDOVIRpuDataHeader::vdr_rpu_normalized_idc
uint8_t vdr_rpu_normalized_idc
Definition: dovi_meta.h:84
AVDOVIRpuDataHeader::el_spatial_resampling_filter_flag
uint8_t el_spatial_resampling_filter_flag
Definition: dovi_meta.h:90
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
AVDOVIRpuDataHeader::chroma_resampling_explicit_filter_flag
uint8_t chroma_resampling_explicit_filter_flag
Definition: dovi_meta.h:81
init_get_bits8
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:545
AVDOVIRpuDataHeader::vdr_bit_depth
uint8_t vdr_bit_depth
Definition: dovi_meta.h:88
AVDOVIRpuDataHeader::rpu_type
uint8_t rpu_type
Definition: dovi_meta.h:77
AVDOVIMetadata
Combined struct representing a combination of header, mapping and color metadata, for attaching to fr...
Definition: dovi_meta.h:197
s
#define s(width, name)
Definition: cbs_vp9.c:198
AVDOVIReshapingCurve::mmr_order
uint8_t mmr_order[AV_DOVI_MAX_PIECES]
Definition: dovi_meta.h:112
AVDOVIRpuDataHeader::spatial_resampling_filter_flag
uint8_t spatial_resampling_filter_flag
Definition: dovi_meta.h:89
get_sbits
static int get_sbits(GetBitContext *s, int n)
Definition: get_bits.h:320
AVDOVIDecoderConfigurationRecord::dv_profile
uint8_t dv_profile
Definition: dovi_meta.h:55
get_bits.h
AV_DOVI_MAPPING_POLYNOMIAL
@ AV_DOVI_MAPPING_POLYNOMIAL
Definition: dovi_meta.h:95
av_dovi_get_header
static av_always_inline AVDOVIRpuDataHeader * av_dovi_get_header(const AVDOVIMetadata *data)
Definition: dovi_meta.h:208
AVDOVIReshapingCurve::poly_order
uint8_t poly_order[AV_DOVI_MAX_PIECES]
Definition: dovi_meta.h:109
frame
static AVFrame * frame
Definition: demux_decode.c:54
get_se_coef
static int64_t get_se_coef(GetBitContext *gb, const AVDOVIRpuDataHeader *hdr)
Definition: dovi_rpu.c:158
AVDOVINLQParams::linear_deadzone_threshold
uint64_t linear_deadzone_threshold
Definition: dovi_meta.h:131
NULL
#define NULL
Definition: coverity.c:32
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
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_DOVI_MAPPING_MMR
@ AV_DOVI_MAPPING_MMR
Definition: dovi_meta.h:96
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:388
ff_dovi_update_cfg
void ff_dovi_update_cfg(DOVIContext *s, const AVDOVIDecoderConfigurationRecord *cfg)
Read the contents of an AVDOVIDecoderConfigurationRecord (usually provided by stream side data) and u...
Definition: dovi_rpu.c:75
ff_refstruct_allocz
static void * ff_refstruct_allocz(size_t size)
Equivalent to ff_refstruct_alloc_ext(size, 0, NULL, NULL)
Definition: refstruct.h:105
av_frame_new_side_data_from_buf
AVFrameSideData * av_frame_new_side_data_from_buf(AVFrame *frame, enum AVFrameSideDataType type, AVBufferRef *buf)
Add a new side data to a frame from an existing AVBufferRef.
Definition: frame.c:672
AVDOVIReshapingCurve::mmr_constant
int64_t mmr_constant[AV_DOVI_MAX_PIECES]
Definition: dovi_meta.h:113
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
av_buffer_create
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition: buffer.c:55
ff_dovi_ctx_flush
void ff_dovi_ctx_flush(DOVIContext *s)
Partially reset the internal state.
Definition: dovi_rpu.c:54
DOVIVdr::mapping
AVDOVIDataMapping mapping
Definition: dovi_rpu.c:40
AV_DOVI_NLQ_LINEAR_DZ
@ AV_DOVI_NLQ_LINEAR_DZ
Definition: dovi_meta.h:119
guess_profile
static int guess_profile(const AVDOVIRpuDataHeader *hdr)
Definition: dovi_rpu.c:117
AVDOVIRpuDataHeader::vdr_rpu_profile
uint8_t vdr_rpu_profile
Definition: dovi_meta.h:79
color
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:94
av_make_q
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
av_dovi_metadata_alloc
AVDOVIMetadata * av_dovi_metadata_alloc(size_t *size)
Allocate an AVDOVIMetadata structure and initialize its fields to default values.
Definition: dovi_meta.c:44
COPY
#define COPY(t, a, b, last)
get_ue_coef
static uint64_t get_ue_coef(GetBitContext *gb, const AVDOVIRpuDataHeader *hdr)
Definition: dovi_rpu.c:139
header
static const uint8_t header[24]
Definition: sdr2.c:68
buffer.h
AVDOVIRpuDataHeader::coef_log2_denom
uint8_t coef_log2_denom
Definition: dovi_meta.h:83
AVDOVIRpuDataHeader::bl_video_full_range_flag
uint8_t bl_video_full_range_flag
Definition: dovi_meta.h:85
AVDOVIReshapingCurve::poly_coef
int64_t poly_coef[AV_DOVI_MAX_PIECES][3]
Definition: dovi_meta.h:110
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
AVDOVIDataMapping::num_y_partitions
uint32_t num_y_partitions
Definition: dovi_meta.h:148
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
get_variable_bits
static unsigned get_variable_bits(GetBitContext *gb, int n)
Definition: dovi_rpu.c:177
profile
int profile
Definition: mxfenc.c:2226
AVDOVINLQParams
Coefficients of the non-linear inverse quantization.
Definition: dovi_meta.h:126
AVDOVIDataMapping::curves
AVDOVIReshapingCurve curves[3]
Definition: dovi_meta.h:143
ff_dovi_rpu_parse
int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size)
Parse the contents of a Dovi RPU NAL and update the parsed values in the DOVIContext struct.
Definition: dovi_rpu.c:198
AVDOVINLQParams::linear_deadzone_slope
uint64_t linear_deadzone_slope
Definition: dovi_meta.h:130
AVDOVIReshapingCurve
Definition: dovi_meta.h:104
ret
ret
Definition: filter_design.txt:187
DOVIVdr
Private contents of vdr.
Definition: dovi_rpu.c:39
AVDOVINLQParams::vdr_in_max
uint64_t vdr_in_max
Definition: dovi_meta.h:128
ff_refstruct_replace
void ff_refstruct_replace(void *dstp, const void *src)
Ensure *dstp refers to the same object as src.
Definition: refstruct.c:160
AVDOVIReshapingCurve::num_pivots
uint8_t num_pivots
Definition: dovi_meta.h:105
AVDOVIRpuDataHeader::vdr_rpu_level
uint8_t vdr_rpu_level
Definition: dovi_meta.h:80
av_dovi_get_color
static av_always_inline AVDOVIColorMetadata * av_dovi_get_color(const AVDOVIMetadata *data)
Definition: dovi_meta.h:220
get_ue_golomb_31
static int get_ue_golomb_31(GetBitContext *gb)
read unsigned exp golomb code, constraint to a max of 31.
Definition: golomb.h:120
AVDOVIDataMapping::mapping_chroma_format_idc
uint8_t mapping_chroma_format_idc
Definition: dovi_meta.h:142
AVDOVIRpuDataHeader::bl_bit_depth
uint8_t bl_bit_depth
Definition: dovi_meta.h:86
AVDOVIColorMetadata
Dolby Vision RPU colorspace metadata parameters.
Definition: dovi_meta.h:157
DOVIVdr::color
AVDOVIColorMetadata color
Definition: dovi_rpu.c:41
av_clip_uint16
#define av_clip_uint16
Definition: common.h:110
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
get_ue_golomb_long
static unsigned get_ue_golomb_long(GetBitContext *gb)
Read an unsigned Exp-Golomb code in the range 0 to UINT32_MAX-1.
Definition: golomb.h:104
av_dovi_get_mapping
static av_always_inline AVDOVIDataMapping * av_dovi_get_mapping(const AVDOVIMetadata *data)
Definition: dovi_meta.h:214
s0
#define s0
Definition: regdef.h:37
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:36
AVFrameSideData
Structure to hold side data for an AVFrame.
Definition: frame.h:246
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVDOVIReshapingCurve::pivots
uint16_t pivots[AV_DOVI_MAX_PIECES+1]
Definition: dovi_meta.h:106
AVDOVINLQParams::nlq_offset
uint16_t nlq_offset
Definition: dovi_meta.h:127
AVDOVIDataMapping::vdr_rpu_id
uint8_t vdr_rpu_id
Definition: dovi_meta.h:140
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
AVDOVIRpuDataHeader::disable_residual_flag
uint8_t disable_residual_flag
Definition: dovi_meta.h:91
AVDOVIDataMapping::nlq
AVDOVINLQParams nlq[3]
Definition: dovi_meta.h:149
AVDOVIDataMapping
Dolby Vision RPU data mapping parameters.
Definition: dovi_meta.h:139
ff_refstruct_unref
void ff_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition: refstruct.c:120
ff_dovi_attach_side_data
int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame)
Attach the decoded AVDOVIMetadata as side data to an AVFrame.
Definition: dovi_rpu.c:83
AV_DOVI_MAX_PIECES
#define AV_DOVI_MAX_PIECES
Coefficients of a piece-wise function.
Definition: dovi_meta.h:103
AVDOVIDataMapping::num_x_partitions
uint32_t num_x_partitions
Definition: dovi_meta.h:147
ff_dovi_ctx_replace
void ff_dovi_ctx_replace(DOVIContext *s, const DOVIContext *s0)
Definition: dovi_rpu.c:65
AVDOVIDecoderConfigurationRecord
Definition: dovi_meta.h:52