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  break;
460  default:
461  return AVERROR(ENOSYS);
462  }
463 
464  return 0;
465 }
466 
468  CodedBitstreamUnit *unit,
469  PutBitContext *pbc)
470 {
471  int err;
472 
473  switch (unit->type) {
474  case LCEVC_NON_IDR_NUT:
475  case LCEVC_IDR_NUT:
476  {
477  err = cbs_lcevc_write_nal(ctx, pbc, unit->content, unit->type);
478 
479  if (err < 0)
480  return err;
481  }
482  break;
483  default:
484  av_log(ctx->log_ctx, AV_LOG_ERROR, "Write unimplemented for "
485  "NAL unit type %"PRIu32".\n", unit->type);
486  return AVERROR_PATCHWELCOME;
487  }
488 
489  return 0;
490 }
491 
492 static void free_picture_config(AVRefStructOpaque unused, void *obj)
493 {
494  LCEVCRawPictureConfig *picture_config = obj;
495 
496  av_refstruct_unref(&picture_config->gc);
497 }
498 
499 static void free_encoded_data(AVRefStructOpaque unused, void *obj)
500 {
501  LCEVCRawEncodedData *slice = obj;
502 
503  av_buffer_unref(&slice->data_ref);
504 
505  av_refstruct_unref(&slice->sc);
506  av_refstruct_unref(&slice->gc);
507  av_refstruct_unref(&slice->pc);
508 }
509 
510 static void free_additional_info(AVRefStructOpaque unused, void *obj)
511 {
512  LCEVCRawAdditionalInfo *additional_info = obj;
513  LCEVCRawSEI *sei = &additional_info->sei;
514  SEIRawMessage *message = &sei->message;
515 
516  av_refstruct_unref(&additional_info->payload_ref);
517  av_refstruct_unref(&sei->payload_ref);
518  av_refstruct_unref(&message->payload_ref);
519  av_refstruct_unref(&message->extension_data);
520 }
521 
524 {
525  void (*free_func)(AVRefStructOpaque, void*);
526 
527  av_assert0(block->payload == NULL &&
528  block->payload_ref == NULL);
529  block->payload_type = desc->payload_type;
530 
531  if (desc->payload_type == LCEVC_PAYLOAD_TYPE_PICTURE_CONFIG)
532  free_func = &free_picture_config;
533  else if (desc->payload_type == LCEVC_PAYLOAD_TYPE_ENCODED_DATA)
534  free_func = &free_encoded_data;
535  else if (desc->payload_type == LCEVC_PAYLOAD_TYPE_ADDITIONAL_INFO)
536  free_func = &free_additional_info;
537  else
538  free_func = NULL;
539 
540  block->payload_ref = av_refstruct_alloc_ext(desc->payload_size, 0,
541  NULL, free_func);
542  if (!block->payload_ref)
543  return AVERROR(ENOMEM);
544  block->payload = block->payload_ref;
545 
546  return 0;
547 }
548 
550 {
551  LCEVCRawProcessBlock *blocks;
552 
553  if (position == -1)
554  position = list->nb_blocks;
555  av_assert0(position >= 0 && position <= list->nb_blocks);
556 
557  if (list->nb_blocks < list->nb_blocks_allocated) {
558  blocks = list->blocks;
559 
560  if (position < list->nb_blocks)
561  memmove(blocks + position + 1, blocks + position,
562  (list->nb_blocks - position) * sizeof(*blocks));
563  } else {
564  blocks = av_malloc_array(list->nb_blocks*2 + 1, sizeof(*blocks));
565  if (!blocks)
566  return AVERROR(ENOMEM);
567 
568  list->nb_blocks_allocated = 2*list->nb_blocks_allocated + 1;
569 
570  if (position > 0)
571  memcpy(blocks, list->blocks, position * sizeof(*blocks));
572 
573  if (position < list->nb_blocks)
574  memcpy(blocks + position + 1, list->blocks + position,
575  (list->nb_blocks - position) * sizeof(*blocks));
576 
577  av_free(list->blocks);
578  list->blocks = blocks;
579  }
580 
581  memset(blocks + position, 0, sizeof(*blocks));
582 
583  ++list->nb_blocks;
584 
585  return 0;
586 }
587 
589 {
590  for (int i = 0; i < list->nb_blocks; i++) {
591  LCEVCRawProcessBlock *block = &list->blocks[i];
592  av_refstruct_unref(&block->payload_ref);
593  av_refstruct_unref(&block->extension_data);
594  }
595  av_free(list->blocks);
596 }
597 
599  CodedBitstreamUnit *unit,
601 {
602  LCEVCRawNAL *nal = unit->content;
603  if (unit->type != LCEVC_NON_IDR_NUT && unit->type != LCEVC_IDR_NUT)
604  return AVERROR(EINVAL);
605  *list = &nal->process_block_list;
606 
607  return 0;
608 }
609 
612  int position,
613  uint32_t payload_type,
614  void *payload_data,
615  void *payload_ref)
616 {
618  CodedBitstreamUnit *unit = NULL;
621  int err;
622 
624  if (!desc)
625  return AVERROR(EINVAL);
626 
627  for (int i = 0; i < au->nb_units; i++) {
628  if (au->units[i].type == LCEVC_NON_IDR_NUT ||
629  au->units[i].type == LCEVC_IDR_NUT) {
630  unit = &au->units[i];
631  break;
632  }
633  }
634  if (!unit)
635  return AVERROR(EINVAL);
636 
637  // Find the block list inside the codec-dependent unit.
639  if (err < 0)
640  return err;
641 
642  // Add a new block to the message list.
643  err = ff_cbs_lcevc_list_add(list, position);
644  if (err < 0)
645  return err;
646 
647  if (payload_ref) {
648  /* The following just increments payload_ref's refcount,
649  * so that payload_ref is now owned by us. */
650  payload_ref = av_refstruct_ref(payload_ref);
651  }
652 
653  block = &list->blocks[position];
654 
655  block->payload_type = payload_type;
656  block->payload = payload_data;
657  block->payload_ref = payload_ref;
658 
659  return 0;
660 }
661 
664  uint32_t payload_type,
665  LCEVCRawProcessBlock **iter)
666 {
667  int err, found;
668 
669  found = 0;
670  for (int i = 0; i < au->nb_units; i++) {
671  CodedBitstreamUnit *unit = &au->units[i];
673 
674  if (!unit->content)
675  continue;
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:688
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
LCEVC_PAYLOAD_TYPE_ADDITIONAL_INFO
@ LCEVC_PAYLOAD_TYPE_ADDITIONAL_INFO
Definition: lcevc.h:75
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
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
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:522
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_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:598
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:323
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:467
cbs_lcevc.h
LCEVCRawEncodedData::pc
LCEVCRawPictureConfig * pc
RefStruct references.
Definition: cbs_lcevc.h:129
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
LCEVC_PAYLOAD_TYPE_FILLER
@ LCEVC_PAYLOAD_TYPE_FILLER
Definition: lcevc.h:76
CodedBitstreamUnit::data
uint8_t * data
Pointer to the directly-parsable bitstream form of this unit.
Definition: cbs.h:88
LCEVC_NON_IDR_NUT
@ LCEVC_NON_IDR_NUT
Definition: lcevc.h:60
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
ff_h2645_packet_uninit
void ff_h2645_packet_uninit(H2645Packet *pkt)
Free all the allocated memory in the packet.
Definition: h2645_parse.c:685
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:119
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
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
LCEVC_PAYLOAD_TYPE_ENCODED_DATA
@ LCEVC_PAYLOAD_TYPE_ENCODED_DATA
Definition: lcevc.h:73
cbs_sei.h
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:553
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:499
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:610
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:588
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:510
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:549
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
LCEVC_PAYLOAD_TYPE_PICTURE_CONFIG
@ LCEVC_PAYLOAD_TYPE_PICTURE_CONFIG
Definition: lcevc.h:72
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:657
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
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
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:492
LCEVC_PAYLOAD_TYPE_SEQUENCE_CONFIG
@ LCEVC_PAYLOAD_TYPE_SEQUENCE_CONFIG
Definition: lcevc.h:70
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
desc
const char * desc
Definition: libsvtav1.c:83
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:662
cbs_lcevc_free_nal
static void cbs_lcevc_free_nal(AVRefStructOpaque unused, void *content)
Definition: cbs_lcevc.c:755
LCEVC_PAYLOAD_TYPE_GLOBAL_CONFIG
@ LCEVC_PAYLOAD_TYPE_GLOBAL_CONFIG
Definition: lcevc.h:71
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
LCEVC_IDR_NUT
@ LCEVC_IDR_NUT
Definition: lcevc.h:61
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:1291
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