FFmpeg
cbs_lcevc.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "libavutil/mem.h"
20 #include "libavutil/refstruct.h"
21 #include "bytestream.h"
22 #include "cbs.h"
23 #include "cbs_internal.h"
24 #include "cbs_h2645.h"
25 #include "cbs_lcevc.h"
26 #include "cbs_sei.h"
27 #include "get_bits.h"
28 
29 #define HEADER(name) do { \
30  ff_cbs_trace_header(ctx, name); \
31  } while (0)
32 
33 #define CHECK(call) do { \
34  err = (call); \
35  if (err < 0) \
36  return err; \
37  } while (0)
38 
39 #define FUNC_NAME2(rw, codec, name) cbs_ ## codec ## _ ## rw ## _ ## name
40 #define FUNC_NAME1(rw, codec, name) FUNC_NAME2(rw, codec, name)
41 #define FUNC_LCEVC(name) FUNC_NAME1(READWRITE, lcevc, name)
42 #define FUNC_NAME2_EXPORT(rw, codec, name) ff_cbs_ ## codec ## _ ## rw ## _ ## name
43 #define FUNC_NAME1_EXPORT(rw, codec, name) FUNC_NAME2_EXPORT(rw, codec, name)
44 #define FUNC_SEI(name) FUNC_NAME1_EXPORT(READWRITE, sei, name)
45 
46 #define SEI_FUNC(name, args) \
47 static int FUNC_LCEVC(name) args; \
48 static int FUNC_LCEVC(name ## _internal)(CodedBitstreamContext *ctx, \
49  RWContext *rw, void *cur, \
50  SEIMessageState *state) \
51 { \
52  return FUNC_LCEVC(name)(ctx, rw, cur, state); \
53 } \
54 static int FUNC_LCEVC(name) args
55 
56 #define LCEVC_BLOCK_FUNC(name, args) \
57 static int FUNC(name) args; \
58 static int FUNC(name ## _internal)(CodedBitstreamContext *ctx, \
59  RWContext *rw, void *cur, \
60  LCEVCProcessBlockState *state, \
61  int nal_unit_type) \
62 { \
63  return FUNC(name)(ctx, rw, cur, state, nal_unit_type); \
64 } \
65 static int FUNC(name) args
66 
67 #define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : NULL)
68 
69 #define u(width, name, range_min, range_max) \
70  xu(width, name, current->name, range_min, range_max, 0, )
71 #define flag(name) ub(1, name)
72 #define ue(name, range_min, range_max) \
73  xue(name, current->name, range_min, range_max, 0, )
74 #define i(width, name, range_min, range_max) \
75  xi(width, name, current->name, range_min, range_max, 0, )
76 #define ib(width, name) \
77  xi(width, name, current->name, MIN_INT_BITS(width), MAX_INT_BITS(width), 0, )
78 #define se(name, range_min, range_max) \
79  xse(name, current->name, range_min, range_max, 0, )
80 
81 #define us(width, name, range_min, range_max, subs, ...) \
82  xu(width, name, current->name, range_min, range_max, subs, __VA_ARGS__)
83 #define ubs(width, name, subs, ...) \
84  xu(width, name, current->name, 0, MAX_UINT_BITS(width), subs, __VA_ARGS__)
85 #define flags(name, subs, ...) \
86  xu(1, name, current->name, 0, 1, subs, __VA_ARGS__)
87 #define ues(name, range_min, range_max, subs, ...) \
88  xue(name, current->name, range_min, range_max, subs, __VA_ARGS__)
89 #define is(width, name, range_min, range_max, subs, ...) \
90  xi(width, name, current->name, range_min, range_max, subs, __VA_ARGS__)
91 #define ibs(width, name, subs, ...) \
92  xi(width, name, current->name, MIN_INT_BITS(width), MAX_INT_BITS(width), subs, __VA_ARGS__)
93 #define ses(name, range_min, range_max, subs, ...) \
94  xse(name, current->name, range_min, range_max, subs, __VA_ARGS__)
95 #define mb(name) \
96  xmb(name, current->name)
97 
98 #define fixed(width, name, value) do { \
99  av_unused uint32_t fixed_value = value; \
100  xu(width, name, fixed_value, value, value, 0, ); \
101  } while (0)
102 
103 
105  const char *name, uint32_t *write_to)
106 {
107  uint64_t value;
108  uint32_t byte;
109  int i;
110 
112 
113  value = 0;
114  for (i = 0; i < 10; i++) {
115  if (get_bits_left(gbc) < 8) {
116  av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid multi byte at "
117  "%s: bitstream ended.\n", name);
118  return AVERROR_INVALIDDATA;
119  }
120  byte = get_bits(gbc, 8);
121  value = (value << 7) | (byte & 0x7f);
122  if (!(byte & 0x80))
123  break;
124  }
125 
126  if (value > UINT32_MAX)
127  return AVERROR_INVALIDDATA;
128 
130 
131  *write_to = value;
132  return 0;
133 }
134 
135 #define READ
136 #define READWRITE read
137 #define RWContext GetBitContext
138 
139 #define ub(width, name) do { \
140  uint32_t value; \
141  CHECK(ff_cbs_read_simple_unsigned(ctx, rw, width, #name, \
142  &value)); \
143  current->name = value; \
144  } while (0)
145 #define xu(width, name, var, range_min, range_max, subs, ...) do { \
146  uint32_t value; \
147  CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \
148  SUBSCRIPTS(subs, __VA_ARGS__), \
149  &value, range_min, range_max)); \
150  var = value; \
151  } while (0)
152 #define xue(name, var, range_min, range_max, subs, ...) do { \
153  uint32_t value; \
154  CHECK(ff_cbs_read_ue_golomb(ctx, rw, #name, \
155  SUBSCRIPTS(subs, __VA_ARGS__), \
156  &value, range_min, range_max)); \
157  var = value; \
158  } while (0)
159 #define xi(width, name, var, range_min, range_max, subs, ...) do { \
160  int32_t value; \
161  CHECK(ff_cbs_read_signed(ctx, rw, width, #name, \
162  SUBSCRIPTS(subs, __VA_ARGS__), \
163  &value, range_min, range_max)); \
164  var = value; \
165  } while (0)
166 #define xse(name, var, range_min, range_max, subs, ...) do { \
167  int32_t value; \
168  CHECK(ff_cbs_read_se_golomb(ctx, rw, #name, \
169  SUBSCRIPTS(subs, __VA_ARGS__), \
170  &value, range_min, range_max)); \
171  var = value; \
172  } while (0)
173 #define xmb(name, var) do { \
174  uint32_t value; \
175  CHECK(cbs_read_multi_byte(ctx, rw, #name, &value)); \
176  var = value; \
177  } while (0)
178 
179 #define infer(name, value) do { \
180  current->name = value; \
181  } while (0)
182 
183 #define more_rbsp_data(var) ((var) = ff_cbs_h2645_read_more_rbsp_data(rw))
184 
185 #define bit_position(rw) (get_bits_count(rw))
186 #define byte_alignment(rw) (get_bits_count(rw) % 8)
187 
188 /* The CBS LCEVC code uses the refstruct API for the allocation
189  * of its child buffers. */
190 #define allocate(name, size) do { \
191  name = av_refstruct_allocz(size + \
192  AV_INPUT_BUFFER_PADDING_SIZE); \
193  if (!name) \
194  return AVERROR(ENOMEM); \
195  } while (0)
196 
197 #define FUNC(name) FUNC_LCEVC(name)
199 #undef FUNC
200 
201 
202 #undef READ
203 #undef READWRITE
204 #undef RWContext
205 #undef ub
206 #undef xu
207 #undef xi
208 #undef xue
209 #undef xse
210 #undef xmb
211 #undef infer
212 #undef more_rbsp_data
213 #undef bit_position
214 #undef byte_alignment
215 #undef allocate
216 
217 
219  const char *name, uint32_t value)
220 {
221  int len, i;
222  uint8_t byte;
223 
225 
226  len = (av_log2(value) + 7) / 7;
227 
228  for (i = len - 1; i >= 0; i--) {
229  if (put_bits_left(pbc) < 8)
230  return AVERROR(ENOSPC);
231 
232  byte = value >> (7 * i) & 0x7f;
233  if (i > 0)
234  byte |= 0x80;
235 
236  put_bits(pbc, 8, byte);
237  }
238 
240 
241  return 0;
242 }
243 
244 #define WRITE
245 #define READWRITE write
246 #define RWContext PutBitContext
247 
248 #define ub(width, name) do { \
249  uint32_t value = current->name; \
250  CHECK(ff_cbs_write_simple_unsigned(ctx, rw, width, #name, \
251  value)); \
252  } while (0)
253 #define xu(width, name, var, range_min, range_max, subs, ...) do { \
254  uint32_t value = var; \
255  CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, \
256  SUBSCRIPTS(subs, __VA_ARGS__), \
257  value, range_min, range_max)); \
258  } while (0)
259 #define xue(name, var, range_min, range_max, subs, ...) do { \
260  uint32_t value = var; \
261  CHECK(ff_cbs_write_ue_golomb(ctx, rw, #name, \
262  SUBSCRIPTS(subs, __VA_ARGS__), \
263  value, range_min, range_max)); \
264  } while (0)
265 #define xi(width, name, var, range_min, range_max, subs, ...) do { \
266  int32_t value = var; \
267  CHECK(ff_cbs_write_signed(ctx, rw, width, #name, \
268  SUBSCRIPTS(subs, __VA_ARGS__), \
269  value, range_min, range_max)); \
270  } while (0)
271 #define xse(name, var, range_min, range_max, subs, ...) do { \
272  int32_t value = var; \
273  CHECK(ff_cbs_write_se_golomb(ctx, rw, #name, \
274  SUBSCRIPTS(subs, __VA_ARGS__), \
275  value, range_min, range_max)); \
276  } while (0)
277 #define xmb(name, var) do { \
278  uint32_t value = var; \
279  CHECK(cbs_write_multi_byte(ctx, rw, #name, value)); \
280  } while (0)
281 
282 #define infer(name, value) do { \
283  if (current->name != (value)) { \
284  av_log(ctx->log_ctx, AV_LOG_ERROR, \
285  "%s does not match inferred value: " \
286  "%"PRId64", but should be %"PRId64".\n", \
287  #name, (int64_t)current->name, (int64_t)(value)); \
288  return AVERROR_INVALIDDATA; \
289  } \
290  } while (0)
291 
292 #define more_rbsp_data(var) (var)
293 
294 #define bit_position(rw) (put_bits_count(rw))
295 #define byte_alignment(rw) (put_bits_count(rw) % 8)
296 
297 #define allocate(name, size) do { \
298  if (!name) { \
299  av_log(ctx->log_ctx, AV_LOG_ERROR, "%s must be set " \
300  "for writing.\n", #name); \
301  return AVERROR_INVALIDDATA; \
302  } \
303  } while (0)
304 
305 #define FUNC(name) FUNC_LCEVC(name)
307 #undef FUNC
308 
309 #undef WRITE
310 #undef READWRITE
311 #undef RWContext
312 #undef ub
313 #undef xu
314 #undef xi
315 #undef xue
316 #undef xse
317 #undef xmb
318 #undef u
319 #undef i
320 #undef flag
321 #undef ue
322 #undef se
323 #undef infer
324 #undef more_rbsp_data
325 #undef bit_position
326 #undef byte_alignment
327 #undef allocate
328 
329 
332  int header)
333 {
334  enum AVCodecID codec_id = ctx->codec->codec_id;
336  CodedBitstreamH2645Context *h2645 = &priv->common;
337  GetByteContext gbc;
338  int err;
339 
340  av_assert0(frag->data && frag->nb_units == 0);
341  if (frag->data_size == 0)
342  return 0;
343 
344  if (header && frag->data[0]) {
345  // LVCC header.
346  size_t size, start, end;
347  int i, j, nb_arrays, nal_unit_type, nb_nals, version;
348 
349  h2645->mp4 = 1;
350 
351  bytestream2_init(&gbc, frag->data, frag->data_size);
352 
353  if (bytestream2_get_bytes_left(&gbc) < 14)
354  return AVERROR_INVALIDDATA;
355 
356  version = bytestream2_get_byte(&gbc);
357  if (version != 1) {
358  av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid LVCC header: "
359  "first byte %u.\n", version);
360  return AVERROR_INVALIDDATA;
361  }
362 
363  bytestream2_skip(&gbc, 3);
364  h2645->nal_length_size = (bytestream2_get_byte(&gbc) >> 6) + 1;
365 
366  bytestream2_skip(&gbc, 9);
367  nb_arrays = bytestream2_get_byte(&gbc);
368 
369  for (i = 0; i < nb_arrays; i++) {
370  nal_unit_type = bytestream2_get_byte(&gbc) & 0x3f;
371  nb_nals = bytestream2_get_be16(&gbc);
372 
373  start = bytestream2_tell(&gbc);
374  for (j = 0; j < nb_nals; j++) {
375  if (bytestream2_get_bytes_left(&gbc) < 2)
376  return AVERROR_INVALIDDATA;
377  size = bytestream2_get_be16(&gbc);
378  if (bytestream2_get_bytes_left(&gbc) < size)
379  return AVERROR_INVALIDDATA;
380  bytestream2_skip(&gbc, size);
381  }
382  end = bytestream2_tell(&gbc);
383 
384  err = ff_h2645_packet_split(&h2645->read_packet,
385  frag->data + start, end - start,
386  ctx->log_ctx, 2, AV_CODEC_ID_LCEVC,
388  if (err < 0) {
389  av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to split "
390  "LVCC array %d (%d NAL units of type %d).\n",
391  i, nb_nals, nal_unit_type);
392  return err;
393  }
394  err = ff_cbs_h2645_fragment_add_nals(ctx, frag, &h2645->read_packet);
395  if (err < 0)
396  return err;
397  }
398  } else {
400  // Annex B, or later MP4 with already-known parameters.
401 
402  err = ff_h2645_packet_split(&h2645->read_packet,
403  frag->data, frag->data_size,
404  ctx->log_ctx,
405  h2645->nal_length_size,
406  codec_id, flags);
407  if (err < 0)
408  return err;
409 
410  err = ff_cbs_h2645_fragment_add_nals(ctx, frag, &h2645->read_packet);
411  if (err < 0)
412  return err;
413  }
414 
415  return 0;
416 }
417 
419  CodedBitstreamUnit *unit)
420 {
421  GetBitContext gbc;
422  int err;
423 
424  err = init_get_bits8(&gbc, unit->data, unit->data_size);
425  if (err < 0)
426  return err;
427 
428  err = ff_cbs_alloc_unit_content(ctx, unit);
429  if (err < 0)
430  return err;
431 
432  switch (unit->type) {
433  case LCEVC_NON_IDR_NUT:
434  case LCEVC_IDR_NUT:
435  {
436  LCEVCRawNAL *nal = unit->content;
437  LCEVCRawProcessBlockList *block_list;
438 
439  err = cbs_lcevc_read_nal(ctx, &gbc, unit->content, unit->type);
440 
441  if (err < 0)
442  return err;
443 
444  block_list = &nal->process_block_list;
445  for (int i = 0; i < block_list->nb_blocks; i++) {
446  LCEVCRawProcessBlock *block = &block_list->blocks[i];
447  LCEVCRawEncodedData *slice;
448 
449  if (block->payload_type != LCEVC_PAYLOAD_TYPE_ENCODED_DATA)
450  continue;
451 
452  slice = block->payload;
453  slice->data_ref = av_buffer_ref(unit->data_ref);
454  if (!slice->data_ref)
455  return AVERROR(ENOMEM);
456  slice->data = unit->data + slice->header_size;
457  }
458 
459  if (err < 0)
460  return err;
461  }
462  break;
463  default:
464  return AVERROR(ENOSYS);
465  }
466 
467  return 0;
468 }
469 
471  CodedBitstreamUnit *unit,
472  PutBitContext *pbc)
473 {
474  int err;
475 
476  switch (unit->type) {
477  case LCEVC_NON_IDR_NUT:
478  case LCEVC_IDR_NUT:
479  {
480  err = cbs_lcevc_write_nal(ctx, pbc, unit->content, unit->type);
481 
482  if (err < 0)
483  return err;
484  }
485  break;
486  default:
487  av_log(ctx->log_ctx, AV_LOG_ERROR, "Write unimplemented for "
488  "NAL unit type %"PRIu32".\n", unit->type);
489  return AVERROR_PATCHWELCOME;
490  }
491 
492  return 0;
493 }
494 
495 static void free_picture_config(AVRefStructOpaque unused, void *obj)
496 {
497  LCEVCRawPictureConfig *picture_config = obj;
498 
499  av_refstruct_unref(&picture_config->gc);
500 }
501 
502 static void free_encoded_data(AVRefStructOpaque unused, void *obj)
503 {
504  LCEVCRawEncodedData *slice = obj;
505 
506  av_buffer_unref(&slice->data_ref);
507 
508  av_refstruct_unref(&slice->sc);
509  av_refstruct_unref(&slice->gc);
510  av_refstruct_unref(&slice->pc);
511 }
512 
513 static void free_additional_info(AVRefStructOpaque unused, void *obj)
514 {
515  LCEVCRawAdditionalInfo *additional_info = obj;
516  LCEVCRawSEI *sei = &additional_info->sei;
517  SEIRawMessage *message = &sei->message;
518 
519  av_refstruct_unref(&additional_info->payload_ref);
520  av_refstruct_unref(&sei->payload_ref);
521  av_refstruct_unref(&message->payload_ref);
522  av_refstruct_unref(&message->extension_data);
523 }
524 
527 {
528  void (*free_func)(AVRefStructOpaque, void*);
529 
530  av_assert0(block->payload == NULL &&
531  block->payload_ref == NULL);
532  block->payload_type = desc->payload_type;
533 
534  if (desc->payload_type == LCEVC_PAYLOAD_TYPE_PICTURE_CONFIG)
535  free_func = &free_picture_config;
536  else if (desc->payload_type == LCEVC_PAYLOAD_TYPE_ENCODED_DATA)
537  free_func = &free_encoded_data;
538  else if (desc->payload_type == LCEVC_PAYLOAD_TYPE_ADDITIONAL_INFO)
539  free_func = &free_additional_info;
540  else
541  free_func = NULL;
542 
543  block->payload_ref = av_refstruct_alloc_ext(desc->payload_size, 0,
544  NULL, free_func);
545  if (!block->payload_ref)
546  return AVERROR(ENOMEM);
547  block->payload = block->payload_ref;
548 
549  return 0;
550 }
551 
553 {
554  LCEVCRawProcessBlock *blocks;
555 
556  if (position == -1)
557  position = list->nb_blocks;
558  av_assert0(position >= 0 && position <= list->nb_blocks);
559 
560  if (list->nb_blocks < list->nb_blocks_allocated) {
561  blocks = list->blocks;
562 
563  if (position < list->nb_blocks)
564  memmove(blocks + position + 1, blocks + position,
565  (list->nb_blocks - position) * sizeof(*blocks));
566  } else {
567  blocks = av_malloc_array(list->nb_blocks*2 + 1, sizeof(*blocks));
568  if (!blocks)
569  return AVERROR(ENOMEM);
570 
571  list->nb_blocks_allocated = 2*list->nb_blocks_allocated + 1;
572 
573  if (position > 0)
574  memcpy(blocks, list->blocks, position * sizeof(*blocks));
575 
576  if (position < list->nb_blocks)
577  memcpy(blocks + position + 1, list->blocks + position,
578  (list->nb_blocks - position) * sizeof(*blocks));
579 
580  av_free(list->blocks);
581  list->blocks = blocks;
582  }
583 
584  memset(blocks + position, 0, sizeof(*blocks));
585 
586  ++list->nb_blocks;
587 
588  return 0;
589 }
590 
592 {
593  for (int i = 0; i < list->nb_blocks; i++) {
594  LCEVCRawProcessBlock *block = &list->blocks[i];
595  av_refstruct_unref(&block->payload_ref);
596  av_refstruct_unref(&block->extension_data);
597  }
598  av_free(list->blocks);
599 }
600 
602  CodedBitstreamUnit *unit,
604 {
605  LCEVCRawNAL *nal = unit->content;
606  if (unit->type != LCEVC_NON_IDR_NUT && unit->type != LCEVC_IDR_NUT)
607  return AVERROR(EINVAL);
608  *list = &nal->process_block_list;
609 
610  return 0;
611 }
612 
615  int position,
616  uint32_t payload_type,
617  void *payload_data,
618  void *payload_ref)
619 {
621  CodedBitstreamUnit *unit = NULL;
624  int err;
625 
627  if (!desc)
628  return AVERROR(EINVAL);
629 
630  for (int i = 0; i < au->nb_units; i++) {
631  if (au->units[i].type == LCEVC_NON_IDR_NUT ||
632  au->units[i].type == LCEVC_IDR_NUT) {
633  unit = &au->units[i];
634  break;
635  }
636  }
637  if (!unit)
638  return AVERROR(EINVAL);
639 
640  // Find the block list inside the codec-dependent unit.
642  if (err < 0)
643  return err;
644 
645  // Add a new block to the message list.
646  err = ff_cbs_lcevc_list_add(list, position);
647  if (err < 0)
648  return err;
649 
650  if (payload_ref) {
651  /* The following just increments payload_ref's refcount,
652  * so that payload_ref is now owned by us. */
653  payload_ref = av_refstruct_ref(payload_ref);
654  }
655 
656  block = &list->blocks[position];
657 
658  block->payload_type = payload_type;
659  block->payload = payload_data;
660  block->payload_ref = payload_ref;
661 
662  return 0;
663 }
664 
667  uint32_t payload_type,
668  LCEVCRawProcessBlock **iter)
669 {
670  int err, found;
671 
672  found = 0;
673  for (int i = 0; i < au->nb_units; i++) {
674  CodedBitstreamUnit *unit = &au->units[i];
676 
678  if (err < 0)
679  continue;
680 
681  for (int j = 0; j < list->nb_blocks; j++) {
682  LCEVCRawProcessBlock *block = &list->blocks[j];
683 
684  if (block->payload_type == payload_type) {
685  if (!*iter || found) {
686  *iter = block;
687  return j;
688  }
689  if (block == *iter)
690  found = 1;
691  }
692  }
693  }
694 
695  return AVERROR(ENOENT);
696 }
697 
699  int position)
700 {
702 
703  av_assert0(0 <= position && position < list->nb_blocks);
704 
705  block = &list->blocks[position];
706  av_refstruct_unref(&block->payload_ref);
707 
708  --list->nb_blocks;
709 
710  if (list->nb_blocks > 0) {
711  memmove(list->blocks + position,
712  list->blocks + position + 1,
713  (list->nb_blocks - position) * sizeof(*list->blocks));
714  }
715 }
716 
719  uint32_t payload_type)
720 {
721  int err;
722 
723  for (int i = 0; i < au->nb_units; i++) {
724  CodedBitstreamUnit *unit = &au->units[i];
726 
728  if (err < 0)
729  continue;
730 
731  for (int j = list->nb_blocks - 1; j >= 0; j--) {
732  if (list->blocks[j].payload_type == payload_type)
734  }
735  }
736 }
737 
739 {
741 
742  av_refstruct_unref(&lcevc->sc);
743  av_refstruct_unref(&lcevc->gc);
744  av_refstruct_unref(&lcevc->pc);
745 }
746 
748 {
750 
753 }
754 
755 static void cbs_lcevc_free_nal(AVRefStructOpaque unused, void *content)
756 {
757  LCEVCRawNAL *nal = content;
758  ff_cbs_lcevc_free_process_block_list(&nal->process_block_list);
759 }
760 
764 
766 };
767 
768 // Macro for the read/write pair.
769 #define LCEVC_PROCESS_BLOCK_RW(codec, name) \
770  .read = cbs_ ## codec ## _read_ ## name ## _internal, \
771  .write = cbs_ ## codec ## _write_ ## name ## _internal
772 
774  {
776  sizeof(LCEVCRawSequenceConfig),
777  LCEVC_PROCESS_BLOCK_RW(lcevc, sequence_config),
778  },
779  {
781  sizeof(LCEVCRawGlobalConfig),
782  LCEVC_PROCESS_BLOCK_RW(lcevc, global_config),
783  },
784  {
786  sizeof(LCEVCRawPictureConfig),
787  LCEVC_PROCESS_BLOCK_RW(lcevc, picture_config),
788  },
789  {
791  sizeof(LCEVCRawEncodedData),
792  LCEVC_PROCESS_BLOCK_RW(lcevc, encoded_data),
793  },
794  {
796  sizeof(LCEVCRawAdditionalInfo),
797  LCEVC_PROCESS_BLOCK_RW(lcevc, additional_info),
798  },
799  {
801  sizeof(LCEVCRawFiller),
803  },
805 };
806 
809  int payload_type)
810 {
811  for (int i = 0; cbs_lcevc_process_block_types[i].payload_type >= 0; i++) {
812  if (cbs_lcevc_process_block_types[i].payload_type == payload_type)
814  }
815 
816  return NULL;
817 }
818 
821 
822  .priv_data_size = sizeof(CodedBitstreamLCEVCContext),
823 
824  .unit_types = cbs_lcevc_unit_types,
825 
826  .split_fragment = &cbs_lcevc_split_fragment,
827  .read_unit = &cbs_lcevc_read_nal_unit,
828  .write_unit = &cbs_lcevc_write_nal_unit,
829  .assemble_fragment = &ff_cbs_h2645_assemble_fragment,
830 
833 };
cbs.h
name
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 minimum maximum flags name is the option name
Definition: writing_filters.txt:88
cbs_lcevc_close
static av_cold void cbs_lcevc_close(CodedBitstreamContext *ctx)
Definition: cbs_lcevc.c:747
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
bytestream2_get_bytes_left
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
Definition: bytestream.h:158
message
Definition: api-threadmessage-test.c:47
GetByteContext
Definition: bytestream.h:33
bytestream2_tell
static av_always_inline int bytestream2_tell(const GetByteContext *g)
Definition: bytestream.h:192
CodedBitstreamLCEVCContext::common
CodedBitstreamH2645Context common
Definition: cbs_lcevc.h:239
AVRefStructOpaque
RefStruct is an API for creating reference-counted objects with minimal overhead.
Definition: refstruct.h:58
CodedBitstreamUnit::content
void * content
Pointer to the decomposed form of this unit.
Definition: cbs.h:114
LCEVC_PROCESS_BLOCK_TYPE_END
#define LCEVC_PROCESS_BLOCK_TYPE_END
Definition: cbs_lcevc.h:235
SEIRawMessage
Definition: cbs_sei.h:142
cbs_lcevc_split_fragment
static int cbs_lcevc_split_fragment(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, int header)
Definition: cbs_lcevc.c:330
ff_cbs_lcevc_alloc_process_block_payload
int ff_cbs_lcevc_alloc_process_block_payload(LCEVCRawProcessBlock *block, const LCEVCProcessBlockTypeDescriptor *desc)
Allocate a new payload for the given Process Block.
Definition: cbs_lcevc.c:525
LCEVCRawEncodedData::header_size
size_t header_size
Definition: cbs_lcevc.h:124
put_bits
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition: j2kenc.c:154
CodedBitstreamContext
Context structure for coded bitstream operations.
Definition: cbs.h:226
ff_h2645_packet_uninit
void ff_h2645_packet_uninit(H2645Packet *pkt)
Free all the allocated memory in the packet.
Definition: h2645_parse.c:667
ff_cbs_h2645_fragment_add_nals
int ff_cbs_h2645_fragment_add_nals(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, const H2645Packet *packet)
Definition: cbs_h2645.c:229
CodedBitstreamUnit::type
CodedBitstreamUnitType type
Codec-specific type of this unit.
Definition: cbs.h:81
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
ff_cbs_type_lcevc
const CodedBitstreamType ff_cbs_type_lcevc
Definition: cbs_lcevc.c:819
cbs_lcevc_get_process_block_list
static int cbs_lcevc_get_process_block_list(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit, LCEVCRawProcessBlockList **list)
Definition: cbs_lcevc.c:601
LCEVCRawGlobalConfig
Definition: cbs_lcevc.h:49
CodedBitstreamUnit
Coded bitstream unit structure.
Definition: cbs.h:77
ff_cbs_h2645_assemble_fragment
int ff_cbs_h2645_assemble_fragment(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag)
Definition: cbs_h2645.c:341
LCEVCRawSEI
Definition: cbs_lcevc.h:151
close
static av_cold void close(AVCodecParserContext *s)
Definition: apv_parser.c:197
bytestream2_skip
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:168
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:337
cbs_lcevc_write_nal_unit
static int cbs_lcevc_write_nal_unit(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit, PutBitContext *pbc)
Definition: cbs_lcevc.c:470
cbs_lcevc.h
LCEVCRawEncodedData::pc
LCEVCRawPictureConfig * pc
RefStruct references.
Definition: cbs_lcevc.h:129
LCEVC_PAYLOAD_TYPE_SEQUENCE_CONFIG
@ LCEVC_PAYLOAD_TYPE_SEQUENCE_CONFIG
Definition: lcevc.h:70
GetBitContext
Definition: get_bits.h:109
put_bits_left
static int put_bits_left(PutBitContext *s)
Definition: put_bits.h:135
LCEVCRawEncodedData::gc
LCEVCRawGlobalConfig * gc
RefStruct references.
Definition: cbs_lcevc.h:128
CodedBitstreamUnit::data
uint8_t * data
Pointer to the directly-parsable bitstream form of this unit.
Definition: cbs.h:88
cbs_lcevc_flush
static av_cold void cbs_lcevc_flush(CodedBitstreamContext *ctx)
Definition: cbs_lcevc.c:738
refstruct.h
LCEVCRawSequenceConfig
Definition: cbs_lcevc.h:34
CodedBitstreamFragment::units
CodedBitstreamUnit * units
Pointer to an array of units of length nb_units_allocated.
Definition: cbs.h:175
CodedBitstreamUnitTypeDescriptor
Definition: cbs_internal.h:98
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
CodedBitstreamH2645Context
Definition: cbs_h2645.h:26
av_cold
#define av_cold
Definition: attributes.h:106
LCEVCRawFiller
Definition: cbs_lcevc.h:171
LCEVCRawPictureConfig
Definition: cbs_lcevc.h:87
init_get_bits8
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:544
LCEVC_PROCESS_BLOCK_RW
#define LCEVC_PROCESS_BLOCK_RW(codec, name)
Definition: cbs_lcevc.c:769
CodedBitstreamH2645Context::nal_length_size
int nal_length_size
Definition: cbs_h2645.h:31
CodedBitstreamFragment
Coded bitstream fragment structure, combining one or more units.
Definition: cbs.h:129
CodedBitstreamFragment::data_size
size_t data_size
The number of bytes in the bitstream.
Definition: cbs.h:142
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
av_refstruct_alloc_ext
static void * av_refstruct_alloc_ext(size_t size, unsigned flags, void *opaque, void(*free_cb)(AVRefStructOpaque opaque, void *obj))
A wrapper around av_refstruct_alloc_ext_c() for the common case of a non-const qualified opaque.
Definition: refstruct.h:94
CodedBitstreamLCEVCContext::gc
LCEVCRawGlobalConfig * gc
RefStruct references.
Definition: cbs_lcevc.h:246
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
get_bits.h
CodedBitstreamH2645Context::mp4
int mp4
Definition: cbs_h2645.h:29
cbs_internal.h
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:410
CodedBitstreamType::codec_id
enum AVCodecID codec_id
Definition: cbs_internal.h:145
PutBitContext
Definition: put_bits.h:50
LCEVC_IDR_NUT
@ LCEVC_IDR_NUT
Definition: lcevc.h:61
LCEVCRawNAL
Definition: cbs_lcevc.h:190
cbs_write_multi_byte
static int cbs_write_multi_byte(CodedBitstreamContext *ctx, PutBitContext *pbc, const char *name, uint32_t value)
Definition: cbs_lcevc.c:218
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
cbs_sei.h
LCEVC_PAYLOAD_TYPE_ADDITIONAL_INFO
@ LCEVC_PAYLOAD_TYPE_ADDITIONAL_INFO
Definition: lcevc.h:75
CBS_TRACE_READ_END_NO_SUBSCRIPTS
#define CBS_TRACE_READ_END_NO_SUBSCRIPTS()
Definition: cbs_internal.h:272
CodedBitstreamUnit::data_size
size_t data_size
The number of bytes in the bitstream (including any padding bits in the final byte).
Definition: cbs.h:93
list
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 list
Definition: filter_design.txt:25
flush
void(* flush)(AVBSFContext *ctx)
Definition: dts2pts.c:552
CodedBitstreamH2645Context::read_packet
H2645Packet read_packet
Definition: cbs_h2645.h:33
ff_cbs_lcevc_process_block_find_type
const LCEVCProcessBlockTypeDescriptor * ff_cbs_lcevc_process_block_find_type(CodedBitstreamContext *ctx, int payload_type)
Find the type descriptor for the given payload type.
Definition: cbs_lcevc.c:808
sei
static int FUNC() sei(CodedBitstreamContext *ctx, RWContext *rw, H264RawSEI *current)
Definition: cbs_h264_syntax_template.c:858
free_encoded_data
static void free_encoded_data(AVRefStructOpaque unused, void *obj)
Definition: cbs_lcevc.c:502
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
i
#define i(width, name, range_min, range_max)
Definition: cbs_lcevc.c:74
CodedBitstreamLCEVCContext
Definition: cbs_lcevc.h:237
LCEVCProcessBlockTypeDescriptor::payload_type
int payload_type
Definition: cbs_lcevc.h:225
byte
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_WB16 unsigned int_TMPL byte
Definition: bytestream.h:99
flags
#define flags(name, subs,...)
Definition: cbs_lcevc.c:85
size
int size
Definition: twinvq_data.h:10344
CodedBitstreamFragment::data
uint8_t * data
Pointer to the bitstream form of this fragment.
Definition: cbs.h:135
LCEVCRawEncodedData::sc
LCEVCRawSequenceConfig * sc
RefStruct references.
Definition: cbs_lcevc.h:127
LCEVCRawProcessBlockList::nb_blocks
int nb_blocks
Definition: cbs_lcevc.h:186
LCEVCRawProcessBlock
Definition: cbs_lcevc.h:175
header
static const uint8_t header[24]
Definition: sdr2.c:68
ff_cbs_lcevc_add_process_block
int ff_cbs_lcevc_add_process_block(CodedBitstreamContext *ctx, CodedBitstreamFragment *au, int position, uint32_t payload_type, void *payload_data, void *payload_ref)
Add a process block to an access unit.
Definition: cbs_lcevc.c:613
LCEVC_PAYLOAD_TYPE_GLOBAL_CONFIG
@ LCEVC_PAYLOAD_TYPE_GLOBAL_CONFIG
Definition: lcevc.h:71
av_refstruct_ref
void * av_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
Definition: refstruct.c:140
LCEVCRawPictureConfig::gc
LCEVCRawGlobalConfig * gc
RefStruct references.
Definition: cbs_lcevc.h:111
LCEVCRawAdditionalInfo::sei
LCEVCRawSEI sei
Definition: cbs_lcevc.h:163
ff_cbs_lcevc_free_process_block_list
void ff_cbs_lcevc_free_process_block_list(LCEVCRawProcessBlockList *list)
Free all Process Block in a block list.
Definition: cbs_lcevc.c:591
CodedBitstreamType
Definition: cbs_internal.h:144
cbs_lcevc_unit_types
static CodedBitstreamUnitTypeDescriptor cbs_lcevc_unit_types[]
Definition: cbs_lcevc.c:761
AV_CODEC_ID_LCEVC
@ AV_CODEC_ID_LCEVC
Definition: codec_id.h:615
version
version
Definition: libkvazaar.c:313
cbs_lcevc_delete_process_block
static void cbs_lcevc_delete_process_block(LCEVCRawProcessBlockList *list, int position)
Definition: cbs_lcevc.c:698
free_additional_info
static void free_additional_info(AVRefStructOpaque unused, void *obj)
Definition: cbs_lcevc.c:513
av_refstruct_unref
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
CBS_TRACE_WRITE_END_NO_SUBSCRIPTS
#define CBS_TRACE_WRITE_END_NO_SUBSCRIPTS()
Definition: cbs_internal.h:309
ff_cbs_lcevc_list_add
int ff_cbs_lcevc_list_add(LCEVCRawProcessBlockList *list, int position)
Allocate a new empty Process Block in a block list at a given position.
Definition: cbs_lcevc.c:552
H2645_FLAG_SMALL_PADDING
@ H2645_FLAG_SMALL_PADDING
Definition: h2645_parse.h:98
CodedBitstreamUnit::data_ref
AVBufferRef * data_ref
A reference to the buffer containing data.
Definition: cbs.h:105
CBS_UNIT_TYPES_COMPLEX
#define CBS_UNIT_TYPES_COMPLEX(types, structure, free_func)
Definition: cbs_internal.h:379
nal
static int FUNC() nal(CodedBitstreamContext *ctx, RWContext *rw, LCEVCRawNAL *current, int nal_unit_type)
Definition: cbs_lcevc_syntax_template.c:655
CodedBitstreamLCEVCContext::sc
LCEVCRawSequenceConfig * sc
RefStruct references.
Definition: cbs_lcevc.h:245
cbs_h2645.h
cbs_lcevc_syntax_template.c
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
cbs_lcevc_process_block_types
static const LCEVCProcessBlockTypeDescriptor cbs_lcevc_process_block_types[]
Definition: cbs_lcevc.c:773
CodedBitstreamLCEVCContext::pc
LCEVCRawPictureConfig * pc
RefStruct references.
Definition: cbs_lcevc.h:247
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
len
int len
Definition: vorbis_enc_data.h:426
CBS_UNIT_TYPE_END_OF_LIST
#define CBS_UNIT_TYPE_END_OF_LIST
Definition: cbs_internal.h:389
LCEVCRawEncodedData::data
uint8_t * data
Definition: cbs_lcevc.h:122
LCEVC_PAYLOAD_TYPE_PICTURE_CONFIG
@ LCEVC_PAYLOAD_TYPE_PICTURE_CONFIG
Definition: lcevc.h:72
cbs_read_multi_byte
static int cbs_read_multi_byte(CodedBitstreamContext *ctx, GetBitContext *gbc, const char *name, uint32_t *write_to)
Definition: cbs_lcevc.c:104
cbs_lcevc_read_nal_unit
static int cbs_lcevc_read_nal_unit(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit)
Definition: cbs_lcevc.c:418
LCEVCRawAdditionalInfo
Definition: cbs_lcevc.h:160
LCEVC_PAYLOAD_TYPE_FILLER
@ LCEVC_PAYLOAD_TYPE_FILLER
Definition: lcevc.h:76
H2645_FLAG_USE_REF
@ H2645_FLAG_USE_REF
Definition: h2645_parse.h:99
LCEVCRawProcessBlockList::blocks
LCEVCRawProcessBlock * blocks
Definition: cbs_lcevc.h:185
free_picture_config
static void free_picture_config(AVRefStructOpaque unused, void *obj)
Definition: cbs_lcevc.c:495
filler
int(* filler)(InterplayACMContext *s, unsigned ind, unsigned col)
Definition: interplayacm.c:421
ff_cbs_lcevc_delete_process_block_type
void ff_cbs_lcevc_delete_process_block_type(CodedBitstreamContext *ctx, CodedBitstreamFragment *au, uint32_t payload_type)
Delete all blocks with the given payload type from an access unit.
Definition: cbs_lcevc.c:717
LCEVCProcessBlockTypeDescriptor
Definition: cbs_lcevc.h:223
LCEVC_NON_IDR_NUT
@ LCEVC_NON_IDR_NUT
Definition: lcevc.h:60
desc
const char * desc
Definition: libsvtav1.c:82
mem.h
LCEVCRawProcessBlockList
Definition: cbs_lcevc.h:184
LCEVCRawEncodedData
Definition: cbs_lcevc.h:114
LCEVCRawEncodedData::data_ref
AVBufferRef * data_ref
Definition: cbs_lcevc.h:123
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
ff_cbs_lcevc_find_process_block
int ff_cbs_lcevc_find_process_block(CodedBitstreamContext *ctx, CodedBitstreamFragment *au, uint32_t payload_type, LCEVCRawProcessBlock **iter)
Iterate over blocks with the given payload type in an access unit.
Definition: cbs_lcevc.c:665
cbs_lcevc_free_nal
static void cbs_lcevc_free_nal(AVRefStructOpaque unused, void *content)
Definition: cbs_lcevc.c:755
bytestream.h
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
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
H2645_FLAG_IS_NALFF
@ H2645_FLAG_IS_NALFF
Definition: h2645_parse.h:97
ff_h2645_packet_split
int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length, void *logctx, int nal_length_size, enum AVCodecID codec_id, int flags)
Split an input packet into NAL units.
Definition: h2645_parse.c:527
LCEVC_PAYLOAD_TYPE_ENCODED_DATA
@ LCEVC_PAYLOAD_TYPE_ENCODED_DATA
Definition: lcevc.h:73
CBS_TRACE_READ_START
#define CBS_TRACE_READ_START()
Definition: cbs_internal.h:251
LCEVCRawAdditionalInfo::payload_ref
void * payload_ref
RefStruct reference.
Definition: cbs_lcevc.h:168
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1292
av_log2
int av_log2(unsigned v)
Definition: intmath.c:26
CodedBitstreamFragment::nb_units
int nb_units
Number of units in this fragment.
Definition: cbs.h:160
CBS_TRACE_WRITE_START
#define CBS_TRACE_WRITE_START()
Definition: cbs_internal.h:289