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 
30 enum {
33 };
34 
35 /**
36  * Private contents of vdr_ref.
37  */
38 typedef struct DOVIVdrRef {
41 } DOVIVdrRef;
42 
44 {
45  for (int i = 0; i < FF_ARRAY_ELEMS(s->vdr_ref); i++)
46  av_buffer_unref(&s->vdr_ref[i]);
47 
48  *s = (DOVIContext) {
49  .logctx = s->logctx,
50  };
51 }
52 
54 {
55  for (int i = 0; i < FF_ARRAY_ELEMS(s->vdr_ref); i++)
56  av_buffer_unref(&s->vdr_ref[i]);
57 
58  *s = (DOVIContext) {
59  .logctx = s->logctx,
60  .dv_profile = s->dv_profile,
61  };
62 }
63 
65 {
66  int ret;
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  if ((ret = av_buffer_replace(&s->vdr_ref[i], s0->vdr_ref[i])) < 0)
73  goto fail;
74  }
75 
76  return 0;
77 
78 fail:
80  return ret;
81 }
82 
84 {
85  if (!cfg)
86  return;
87 
88  s->dv_profile = cfg->dv_profile;
89 }
90 
92 {
93  AVFrameSideData *sd;
94  AVBufferRef *buf;
95  AVDOVIMetadata *dovi;
96  size_t dovi_size;
97 
98  if (!s->mapping || !s->color)
99  return 0; /* incomplete dovi metadata */
100 
101  dovi = av_dovi_metadata_alloc(&dovi_size);
102  if (!dovi)
103  return AVERROR(ENOMEM);
104 
105  buf = av_buffer_create((uint8_t *) dovi, dovi_size, NULL, NULL, 0);
106  if (!buf) {
107  av_free(dovi);
108  return AVERROR(ENOMEM);
109  }
110 
112  if (!sd) {
113  av_buffer_unref(&buf);
114  return AVERROR(ENOMEM);
115  }
116 
117  /* Copy only the parts of these structs known to us at compiler-time. */
118 #define COPY(t, a, b, last) memcpy(a, b, offsetof(t, last) + sizeof((b)->last))
119  COPY(AVDOVIRpuDataHeader, av_dovi_get_header(dovi), &s->header, disable_residual_flag);
120  COPY(AVDOVIDataMapping, av_dovi_get_mapping(dovi), s->mapping, nlq[2].linear_deadzone_threshold);
121  COPY(AVDOVIColorMetadata, av_dovi_get_color(dovi), s->color, source_diagonal);
122  return 0;
123 }
124 
125 static int guess_profile(const AVDOVIRpuDataHeader *hdr)
126 {
127  switch (hdr->vdr_rpu_profile) {
128  case 0:
129  if (hdr->bl_video_full_range_flag)
130  return 5;
131  break;
132  case 1:
134  if (hdr->vdr_bit_depth == 12) {
135  return 7;
136  } else {
137  return 4;
138  }
139  } else {
140  return 8;
141  }
142  }
143 
144  return 0; /* unknown */
145 }
146 
147 static inline uint64_t get_ue_coef(GetBitContext *gb, const AVDOVIRpuDataHeader *hdr)
148 {
149  uint64_t ipart;
150  union { uint32_t u32; float f32; } fpart;
151 
152  switch (hdr->coef_data_type) {
153  case RPU_COEFF_FIXED:
154  ipart = get_ue_golomb_long(gb);
155  fpart.u32 = get_bits_long(gb, hdr->coef_log2_denom);
156  return (ipart << hdr->coef_log2_denom) + fpart.u32;
157 
158  case RPU_COEFF_FLOAT:
159  fpart.u32 = get_bits_long(gb, 32);
160  return fpart.f32 * (1 << hdr->coef_log2_denom);
161  }
162 
163  return 0; /* unreachable */
164 }
165 
166 static inline int64_t get_se_coef(GetBitContext *gb, const AVDOVIRpuDataHeader *hdr)
167 {
168  int64_t ipart;
169  union { uint32_t u32; float f32; } fpart;
170 
171  switch (hdr->coef_data_type) {
172  case RPU_COEFF_FIXED:
173  ipart = get_se_golomb_long(gb);
174  fpart.u32 = get_bits_long(gb, hdr->coef_log2_denom);
175  return (ipart << hdr->coef_log2_denom) + fpart.u32;
176 
177  case RPU_COEFF_FLOAT:
178  fpart.u32 = get_bits_long(gb, 32);
179  return fpart.f32 * (1 << hdr->coef_log2_denom);
180  }
181 
182  return 0; /* unreachable */
183 }
184 
185 #define VALIDATE(VAR, MIN, MAX) \
186  do { \
187  if (VAR < MIN || VAR > MAX) { \
188  av_log(s->logctx, AV_LOG_ERROR, "RPU validation failed: " \
189  #MIN" <= "#VAR" = %d <= "#MAX"\n", (int) VAR); \
190  goto fail; \
191  } \
192  } while (0)
193 
194 int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size)
195 {
196  AVDOVIRpuDataHeader *hdr = &s->header;
197  GetBitContext *gb = &(GetBitContext){0};
198  DOVIVdrRef *vdr;
199  int ret;
200 
201  uint8_t nal_prefix;
202  uint8_t rpu_type;
203  uint8_t vdr_seq_info_present;
204  uint8_t vdr_dm_metadata_present;
205  uint8_t use_prev_vdr_rpu;
206  uint8_t use_nlq;
207  uint8_t profile;
208  if ((ret = init_get_bits8(gb, rpu, rpu_size)) < 0)
209  return ret;
210 
211  /* RPU header, common values */
212  nal_prefix = get_bits(gb, 8);
213  VALIDATE(nal_prefix, 25, 25);
214  rpu_type = get_bits(gb, 6);
215  if (rpu_type != 2) {
216  av_log(s->logctx, AV_LOG_WARNING, "Unrecognized RPU type "
217  "%"PRIu8", ignoring\n", rpu_type);
218  return 0;
219  }
220 
221  hdr->rpu_type = rpu_type;
222  hdr->rpu_format = get_bits(gb, 11);
223 
224  /* Values specific to RPU type 2 */
225  hdr->vdr_rpu_profile = get_bits(gb, 4);
226  hdr->vdr_rpu_level = get_bits(gb, 4);
227 
228  vdr_seq_info_present = get_bits1(gb);
229  if (vdr_seq_info_present) {
231  hdr->coef_data_type = get_bits(gb, 2);
233  switch (hdr->coef_data_type) {
234  case RPU_COEFF_FIXED:
235  hdr->coef_log2_denom = get_ue_golomb(gb);
236  VALIDATE(hdr->coef_log2_denom, 13, 32);
237  break;
238  case RPU_COEFF_FLOAT:
239  hdr->coef_log2_denom = 32; /* arbitrary, choose maximum precision */
240  break;
241  }
242 
243  hdr->vdr_rpu_normalized_idc = get_bits(gb, 2);
245 
246  if ((hdr->rpu_format & 0x700) == 0) {
247  int bl_bit_depth_minus8 = get_ue_golomb_31(gb);
248  int el_bit_depth_minus8 = get_ue_golomb_31(gb);
249  int vdr_bit_depth_minus8 = get_ue_golomb_31(gb);
250  VALIDATE(bl_bit_depth_minus8, 0, 8);
251  VALIDATE(el_bit_depth_minus8, 0, 8);
252  VALIDATE(vdr_bit_depth_minus8, 0, 8);
253  hdr->bl_bit_depth = bl_bit_depth_minus8 + 8;
254  hdr->el_bit_depth = el_bit_depth_minus8 + 8;
255  hdr->vdr_bit_depth = vdr_bit_depth_minus8 + 8;
257  skip_bits(gb, 3); /* reserved_zero_3bits */
259  hdr->disable_residual_flag = get_bits1(gb);
260  }
261  }
262 
263  if (!hdr->bl_bit_depth) {
264  av_log(s->logctx, AV_LOG_ERROR, "Missing RPU VDR sequence info?\n");
265  goto fail;
266  }
267 
268  vdr_dm_metadata_present = get_bits1(gb);
269  use_prev_vdr_rpu = get_bits1(gb);
270  use_nlq = (hdr->rpu_format & 0x700) == 0 && !hdr->disable_residual_flag;
271 
272  profile = s->dv_profile ? s->dv_profile : guess_profile(hdr);
273  if (profile == 5 && use_nlq) {
274  av_log(s->logctx, AV_LOG_ERROR, "Profile 5 RPUs should not use NLQ\n");
275  goto fail;
276  }
277 
278  if (use_prev_vdr_rpu) {
279  int prev_vdr_rpu_id = get_ue_golomb_31(gb);
280  VALIDATE(prev_vdr_rpu_id, 0, DOVI_MAX_DM_ID);
281  if (!s->vdr_ref[prev_vdr_rpu_id]) {
282  av_log(s->logctx, AV_LOG_ERROR, "Unknown previous RPU ID: %u\n",
283  prev_vdr_rpu_id);
284  goto fail;
285  }
286  vdr = (DOVIVdrRef *) s->vdr_ref[prev_vdr_rpu_id]->data;
287  s->mapping = &vdr->mapping;
288  } else {
289  int vdr_rpu_id = get_ue_golomb_31(gb);
290  VALIDATE(vdr_rpu_id, 0, DOVI_MAX_DM_ID);
291  if (!s->vdr_ref[vdr_rpu_id]) {
292  s->vdr_ref[vdr_rpu_id] = av_buffer_allocz(sizeof(DOVIVdrRef));
293  if (!s->vdr_ref[vdr_rpu_id])
294  return AVERROR(ENOMEM);
295  }
296 
297  vdr = (DOVIVdrRef *) s->vdr_ref[vdr_rpu_id]->data;
298  s->mapping = &vdr->mapping;
299 
300  vdr->mapping.vdr_rpu_id = vdr_rpu_id;
303 
304  for (int c = 0; c < 3; c++) {
305  AVDOVIReshapingCurve *curve = &vdr->mapping.curves[c];
306  int num_pivots_minus_2 = get_ue_golomb_31(gb);
307  int pivot = 0;
308 
309  VALIDATE(num_pivots_minus_2, 0, AV_DOVI_MAX_PIECES - 1);
310  curve->num_pivots = num_pivots_minus_2 + 2;
311  for (int i = 0; i < curve->num_pivots; i++) {
312  pivot += get_bits(gb, hdr->bl_bit_depth);
313  curve->pivots[i] = av_clip_uint16(pivot);
314  }
315  }
316 
317  if (use_nlq) {
318  vdr->mapping.nlq_method_idc = get_bits(gb, 3);
319  /**
320  * The patent mentions another legal value, NLQ_MU_LAW, but it's
321  * not documented anywhere how to parse or apply that type of NLQ.
322  */
324  } else {
326  }
327 
330  /* End of rpu_data_header(), start of vdr_rpu_data_payload() */
331 
332  for (int c = 0; c < 3; c++) {
333  AVDOVIReshapingCurve *curve = &vdr->mapping.curves[c];
334  for (int i = 0; i < curve->num_pivots - 1; i++) {
335  int mapping_idc = get_ue_golomb_31(gb);
336  VALIDATE(mapping_idc, 0, 1);
337  curve->mapping_idc[i] = mapping_idc;
338  switch (mapping_idc) {
340  int poly_order_minus1 = get_ue_golomb_31(gb);
341  VALIDATE(poly_order_minus1, 0, 1);
342  curve->poly_order[i] = poly_order_minus1 + 1;
343  if (poly_order_minus1 == 0) {
344  int linear_interp_flag = get_bits1(gb);
345  if (linear_interp_flag) {
346  /* lack of documentation/samples */
347  avpriv_request_sample(s->logctx, "Dolby Vision "
348  "linear interpolation");
350  return AVERROR_PATCHWELCOME;
351  }
352  }
353  for (int k = 0; k <= curve->poly_order[i]; k++)
354  curve->poly_coef[i][k] = get_se_coef(gb, hdr);
355  break;
356  }
357  case AV_DOVI_MAPPING_MMR: {
358  int mmr_order_minus1 = get_bits(gb, 2);
359  VALIDATE(mmr_order_minus1, 0, 2);
360  curve->mmr_order[i] = mmr_order_minus1 + 1;
361  curve->mmr_constant[i] = get_se_coef(gb, hdr);
362  for (int j = 0; j < curve->mmr_order[i]; j++) {
363  for (int k = 0; k < 7; k++)
364  curve->mmr_coef[i][j][k] = get_se_coef(gb, hdr);
365  }
366  break;
367  }
368  }
369  }
370  }
371 
372  if (use_nlq) {
373  for (int c = 0; c < 3; c++) {
374  AVDOVINLQParams *nlq = &vdr->mapping.nlq[c];
375  nlq->nlq_offset = get_bits(gb, hdr->el_bit_depth);
376  nlq->vdr_in_max = get_ue_coef(gb, hdr);
377  switch (vdr->mapping.nlq_method_idc) {
379  nlq->linear_deadzone_slope = get_ue_coef(gb, hdr);
380  nlq->linear_deadzone_threshold = get_ue_coef(gb, hdr);
381  break;
382  }
383  }
384  }
385  }
386 
387  if (vdr_dm_metadata_present) {
389  int affected_dm_id = get_ue_golomb_31(gb);
390  int current_dm_id = get_ue_golomb_31(gb);
391  VALIDATE(affected_dm_id, 0, DOVI_MAX_DM_ID);
392  VALIDATE(current_dm_id, 0, DOVI_MAX_DM_ID);
393  if (!s->vdr_ref[affected_dm_id]) {
394  s->vdr_ref[affected_dm_id] = av_buffer_allocz(sizeof(DOVIVdrRef));
395  if (!s->vdr_ref[affected_dm_id])
396  return AVERROR(ENOMEM);
397  }
398 
399  if (!s->vdr_ref[current_dm_id]) {
400  av_log(s->logctx, AV_LOG_ERROR, "Unknown previous RPU DM ID: %u\n",
401  current_dm_id);
402  goto fail;
403  }
404 
405  /* Update current pointer based on current_dm_id */
406  vdr = (DOVIVdrRef *) s->vdr_ref[current_dm_id]->data;
407  s->color = &vdr->color;
408 
409  /* Update values of affected_dm_id */
410  vdr = (DOVIVdrRef *) s->vdr_ref[affected_dm_id]->data;
411  color = &vdr->color;
412  color->dm_metadata_id = affected_dm_id;
413  color->scene_refresh_flag = get_ue_golomb_31(gb);
414  for (int i = 0; i < 9; i++)
415  color->ycc_to_rgb_matrix[i] = av_make_q(get_sbits(gb, 16), 1 << 13);
416  for (int i = 0; i < 3; i++) {
417  int denom = profile == 4 ? (1 << 30) : (1 << 28);
418  unsigned offset = get_bits_long(gb, 32);
419  if (offset > INT_MAX) {
420  /* Ensure the result fits inside AVRational */
421  offset >>= 1;
422  denom >>= 1;
423  }
424  color->ycc_to_rgb_offset[i] = av_make_q(offset, denom);
425  }
426  for (int i = 0; i < 9; i++)
427  color->rgb_to_lms_matrix[i] = av_make_q(get_sbits(gb, 16), 1 << 14);
428 
429  color->signal_eotf = get_bits(gb, 16);
430  color->signal_eotf_param0 = get_bits(gb, 16);
431  color->signal_eotf_param1 = get_bits(gb, 16);
432  color->signal_eotf_param2 = get_bits_long(gb, 32);
433  color->signal_bit_depth = get_bits(gb, 5);
434  VALIDATE(color->signal_bit_depth, 8, 16);
435  color->signal_color_space = get_bits(gb, 2);
436  color->signal_chroma_format = get_bits(gb, 2);
437  color->signal_full_range_flag = get_bits(gb, 2);
438  color->source_min_pq = get_bits(gb, 12);
439  color->source_max_pq = get_bits(gb, 12);
440  color->source_diagonal = get_bits(gb, 10);
441  }
442 
443  /* FIXME: verify CRC32, requires implementation of AV_CRC_32_MPEG_2 */
444  return 0;
445 
446 fail:
447  ff_dovi_ctx_unref(s); /* don't leak potentially invalid state */
448  return AVERROR(EINVAL);
449 }
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
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:43
DOVI_MAX_DM_ID
#define DOVI_MAX_DM_ID
Definition: dovi_rpu.h:30
color
Definition: vf_paletteuse.c:600
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:547
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
DOVIVdrRef::mapping
AVDOVIDataMapping mapping
Definition: dovi_rpu.c:39
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:325
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:185
AVDOVIRpuDataHeader::rpu_format
uint16_t rpu_format
Definition: dovi_meta.h:78
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
ff_dovi_ctx_replace
int ff_dovi_ctx_replace(DOVIContext *s, const DOVIContext *s0)
Definition: dovi_rpu.c:64
DOVIVdrRef::color
AVDOVIColorMetadata color
Definition: dovi_rpu.c:40
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:468
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:380
DOVIContext
Definition: dovi_rpu.h:31
fail
#define fail()
Definition: checkasm.h:130
AVDOVIRpuDataHeader::el_bit_depth
uint8_t el_bit_depth
Definition: dovi_meta.h:87
GetBitContext
Definition: get_bits.h:62
dovi_rpu.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:678
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:256
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:360
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
get_se_coef
static int64_t get_se_coef(GetBitContext *gb, const AVDOVIRpuDataHeader *hdr)
Definition: dovi_rpu.c:166
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:499
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:83
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:640
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:53
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:125
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
RPU_COEFF_FIXED
@ RPU_COEFF_FIXED
Definition: dovi_rpu.c:31
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:147
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:271
AVDOVIDataMapping::num_y_partitions
uint32_t num_y_partitions
Definition: dovi_meta.h:148
av_buffer_replace
int av_buffer_replace(AVBufferRef **pdst, const AVBufferRef *src)
Ensure dst refers to the same data as src.
Definition: buffer.c:233
profile
int profile
Definition: mxfenc.c:2005
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:194
AVDOVINLQParams::linear_deadzone_slope
uint64_t linear_deadzone_slope
Definition: dovi_meta.h:130
AVDOVIReshapingCurve
Definition: dovi_meta.h:104
av_buffer_allocz
AVBufferRef * av_buffer_allocz(size_t size)
Same as av_buffer_alloc(), except the returned buffer will be initialized to zero.
Definition: buffer.c:93
ret
ret
Definition: filter_design.txt:187
RPU_COEFF_FLOAT
@ RPU_COEFF_FLOAT
Definition: dovi_rpu.c:32
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
AVDOVINLQParams::vdr_in_max
uint64_t vdr_in_max
Definition: dovi_meta.h:128
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
av_clip_uint16
#define av_clip_uint16
Definition: common.h:107
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:231
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
DOVIVdrRef
Private contents of vdr_ref.
Definition: dovi_rpu.c:38
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
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_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:91
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
AVDOVIDecoderConfigurationRecord
Definition: dovi_meta.h:52