]> git.sesse.net Git - ffmpeg/blob - libavcodec/cbs.c
avcodec/dvbsubdec: prefer to use variable instead of type for sizeof
[ffmpeg] / libavcodec / cbs.c
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 <string.h>
20
21 #include "config.h"
22
23 #include "libavutil/avassert.h"
24 #include "libavutil/buffer.h"
25 #include "libavutil/common.h"
26
27 #include "cbs.h"
28 #include "cbs_internal.h"
29
30
31 static const CodedBitstreamType *cbs_type_table[] = {
32 #if CONFIG_CBS_AV1
33     &ff_cbs_type_av1,
34 #endif
35 #if CONFIG_CBS_H264
36     &ff_cbs_type_h264,
37 #endif
38 #if CONFIG_CBS_H265
39     &ff_cbs_type_h265,
40 #endif
41 #if CONFIG_CBS_JPEG
42     &ff_cbs_type_jpeg,
43 #endif
44 #if CONFIG_CBS_MPEG2
45     &ff_cbs_type_mpeg2,
46 #endif
47 #if CONFIG_CBS_VP9
48     &ff_cbs_type_vp9,
49 #endif
50 };
51
52 const enum AVCodecID ff_cbs_all_codec_ids[] = {
53 #if CONFIG_CBS_AV1
54     AV_CODEC_ID_AV1,
55 #endif
56 #if CONFIG_CBS_H264
57     AV_CODEC_ID_H264,
58 #endif
59 #if CONFIG_CBS_H265
60     AV_CODEC_ID_H265,
61 #endif
62 #if CONFIG_CBS_JPEG
63     AV_CODEC_ID_MJPEG,
64 #endif
65 #if CONFIG_CBS_MPEG2
66     AV_CODEC_ID_MPEG2VIDEO,
67 #endif
68 #if CONFIG_CBS_VP9
69     AV_CODEC_ID_VP9,
70 #endif
71     AV_CODEC_ID_NONE
72 };
73
74 int ff_cbs_init(CodedBitstreamContext **ctx_ptr,
75                 enum AVCodecID codec_id, void *log_ctx)
76 {
77     CodedBitstreamContext *ctx;
78     const CodedBitstreamType *type;
79     int i;
80
81     type = NULL;
82     for (i = 0; i < FF_ARRAY_ELEMS(cbs_type_table); i++) {
83         if (cbs_type_table[i]->codec_id == codec_id) {
84             type = cbs_type_table[i];
85             break;
86         }
87     }
88     if (!type)
89         return AVERROR(EINVAL);
90
91     ctx = av_mallocz(sizeof(*ctx));
92     if (!ctx)
93         return AVERROR(ENOMEM);
94
95     ctx->log_ctx = log_ctx;
96     ctx->codec   = type;
97
98     if (type->priv_data_size) {
99         ctx->priv_data = av_mallocz(ctx->codec->priv_data_size);
100         if (!ctx->priv_data) {
101             av_freep(&ctx);
102             return AVERROR(ENOMEM);
103         }
104     }
105
106     ctx->decompose_unit_types = NULL;
107
108     ctx->trace_enable = 0;
109     ctx->trace_level  = AV_LOG_TRACE;
110
111     *ctx_ptr = ctx;
112     return 0;
113 }
114
115 void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
116 {
117     CodedBitstreamContext *ctx = *ctx_ptr;
118
119     if (!ctx)
120         return;
121
122     if (ctx->codec && ctx->codec->close)
123         ctx->codec->close(ctx);
124
125     av_freep(&ctx->write_buffer);
126     av_freep(&ctx->priv_data);
127     av_freep(ctx_ptr);
128 }
129
130 static void cbs_unit_uninit(CodedBitstreamUnit *unit)
131 {
132     av_buffer_unref(&unit->content_ref);
133     unit->content = NULL;
134
135     av_buffer_unref(&unit->data_ref);
136     unit->data             = NULL;
137     unit->data_size        = 0;
138     unit->data_bit_padding = 0;
139 }
140
141 void ff_cbs_fragment_reset(CodedBitstreamFragment *frag)
142 {
143     int i;
144
145     for (i = 0; i < frag->nb_units; i++)
146         cbs_unit_uninit(&frag->units[i]);
147     frag->nb_units = 0;
148
149     av_buffer_unref(&frag->data_ref);
150     frag->data             = NULL;
151     frag->data_size        = 0;
152     frag->data_bit_padding = 0;
153 }
154
155 void ff_cbs_fragment_free(CodedBitstreamFragment *frag)
156 {
157     ff_cbs_fragment_reset(frag);
158
159     av_freep(&frag->units);
160     frag->nb_units_allocated = 0;
161 }
162
163 static int cbs_read_fragment_content(CodedBitstreamContext *ctx,
164                                      CodedBitstreamFragment *frag)
165 {
166     int err, i, j;
167
168     for (i = 0; i < frag->nb_units; i++) {
169         CodedBitstreamUnit *unit = &frag->units[i];
170
171         if (ctx->decompose_unit_types) {
172             for (j = 0; j < ctx->nb_decompose_unit_types; j++) {
173                 if (ctx->decompose_unit_types[j] == unit->type)
174                     break;
175             }
176             if (j >= ctx->nb_decompose_unit_types)
177                 continue;
178         }
179
180         av_buffer_unref(&unit->content_ref);
181         unit->content = NULL;
182
183         av_assert0(unit->data && unit->data_ref);
184
185         err = ctx->codec->read_unit(ctx, unit);
186         if (err == AVERROR(ENOSYS)) {
187             av_log(ctx->log_ctx, AV_LOG_VERBOSE,
188                    "Decomposition unimplemented for unit %d "
189                    "(type %"PRIu32").\n", i, unit->type);
190         } else if (err < 0) {
191             av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to read unit %d "
192                    "(type %"PRIu32").\n", i, unit->type);
193             return err;
194         }
195     }
196
197     return 0;
198 }
199
200 static int cbs_fill_fragment_data(CodedBitstreamFragment *frag,
201                                   const uint8_t *data, size_t size)
202 {
203     av_assert0(!frag->data && !frag->data_ref);
204
205     frag->data_ref =
206         av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
207     if (!frag->data_ref)
208         return AVERROR(ENOMEM);
209
210     frag->data      = frag->data_ref->data;
211     frag->data_size = size;
212
213     memcpy(frag->data, data, size);
214     memset(frag->data + size, 0,
215            AV_INPUT_BUFFER_PADDING_SIZE);
216
217     return 0;
218 }
219
220 int ff_cbs_read_extradata(CodedBitstreamContext *ctx,
221                           CodedBitstreamFragment *frag,
222                           const AVCodecParameters *par)
223 {
224     int err;
225
226     err = cbs_fill_fragment_data(frag, par->extradata,
227                                  par->extradata_size);
228     if (err < 0)
229         return err;
230
231     err = ctx->codec->split_fragment(ctx, frag, 1);
232     if (err < 0)
233         return err;
234
235     return cbs_read_fragment_content(ctx, frag);
236 }
237
238 int ff_cbs_read_packet(CodedBitstreamContext *ctx,
239                        CodedBitstreamFragment *frag,
240                        const AVPacket *pkt)
241 {
242     int err;
243
244     if (pkt->buf) {
245         frag->data_ref = av_buffer_ref(pkt->buf);
246         if (!frag->data_ref)
247             return AVERROR(ENOMEM);
248
249         frag->data      = pkt->data;
250         frag->data_size = pkt->size;
251
252     } else {
253         err = cbs_fill_fragment_data(frag, pkt->data, pkt->size);
254         if (err < 0)
255             return err;
256     }
257
258     err = ctx->codec->split_fragment(ctx, frag, 0);
259     if (err < 0)
260         return err;
261
262     return cbs_read_fragment_content(ctx, frag);
263 }
264
265 int ff_cbs_read(CodedBitstreamContext *ctx,
266                 CodedBitstreamFragment *frag,
267                 const uint8_t *data, size_t size)
268 {
269     int err;
270
271     err = cbs_fill_fragment_data(frag, data, size);
272     if (err < 0)
273         return err;
274
275     err = ctx->codec->split_fragment(ctx, frag, 0);
276     if (err < 0)
277         return err;
278
279     return cbs_read_fragment_content(ctx, frag);
280 }
281
282 static int cbs_write_unit_data(CodedBitstreamContext *ctx,
283                                CodedBitstreamUnit *unit)
284 {
285     PutBitContext pbc;
286     int ret;
287
288     if (!ctx->write_buffer) {
289         // Initial write buffer size is 1MB.
290         ctx->write_buffer_size = 1024 * 1024;
291
292     reallocate_and_try_again:
293         ret = av_reallocp(&ctx->write_buffer, ctx->write_buffer_size);
294         if (ret < 0) {
295             av_log(ctx->log_ctx, AV_LOG_ERROR, "Unable to allocate a "
296                    "sufficiently large write buffer (last attempt "
297                    "%"SIZE_SPECIFIER" bytes).\n", ctx->write_buffer_size);
298             return ret;
299         }
300     }
301
302     init_put_bits(&pbc, ctx->write_buffer, ctx->write_buffer_size);
303
304     ret = ctx->codec->write_unit(ctx, unit, &pbc);
305     if (ret < 0) {
306         if (ret == AVERROR(ENOSPC)) {
307             // Overflow.
308             if (ctx->write_buffer_size == INT_MAX / 8)
309                 return AVERROR(ENOMEM);
310             ctx->write_buffer_size = FFMIN(2 * ctx->write_buffer_size, INT_MAX / 8);
311             goto reallocate_and_try_again;
312         }
313         // Write failed for some other reason.
314         return ret;
315     }
316
317     // Overflow but we didn't notice.
318     av_assert0(put_bits_count(&pbc) <= 8 * ctx->write_buffer_size);
319
320     if (put_bits_count(&pbc) % 8)
321         unit->data_bit_padding = 8 - put_bits_count(&pbc) % 8;
322     else
323         unit->data_bit_padding = 0;
324
325     flush_put_bits(&pbc);
326
327     ret = ff_cbs_alloc_unit_data(unit, put_bits_count(&pbc) / 8);
328     if (ret < 0)
329         return ret;
330
331     memcpy(unit->data, ctx->write_buffer, unit->data_size);
332
333     return 0;
334 }
335
336 int ff_cbs_write_fragment_data(CodedBitstreamContext *ctx,
337                                CodedBitstreamFragment *frag)
338 {
339     int err, i;
340
341     for (i = 0; i < frag->nb_units; i++) {
342         CodedBitstreamUnit *unit = &frag->units[i];
343
344         if (!unit->content)
345             continue;
346
347         av_buffer_unref(&unit->data_ref);
348         unit->data = NULL;
349
350         err = cbs_write_unit_data(ctx, unit);
351         if (err < 0) {
352             av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to write unit %d "
353                    "(type %"PRIu32").\n", i, unit->type);
354             return err;
355         }
356         av_assert0(unit->data && unit->data_ref);
357     }
358
359     av_buffer_unref(&frag->data_ref);
360     frag->data = NULL;
361
362     err = ctx->codec->assemble_fragment(ctx, frag);
363     if (err < 0) {
364         av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to assemble fragment.\n");
365         return err;
366     }
367     av_assert0(frag->data && frag->data_ref);
368
369     return 0;
370 }
371
372 int ff_cbs_write_extradata(CodedBitstreamContext *ctx,
373                            AVCodecParameters *par,
374                            CodedBitstreamFragment *frag)
375 {
376     int err;
377
378     err = ff_cbs_write_fragment_data(ctx, frag);
379     if (err < 0)
380         return err;
381
382     av_freep(&par->extradata);
383
384     par->extradata = av_malloc(frag->data_size +
385                                AV_INPUT_BUFFER_PADDING_SIZE);
386     if (!par->extradata)
387         return AVERROR(ENOMEM);
388
389     memcpy(par->extradata, frag->data, frag->data_size);
390     memset(par->extradata + frag->data_size, 0,
391            AV_INPUT_BUFFER_PADDING_SIZE);
392     par->extradata_size = frag->data_size;
393
394     return 0;
395 }
396
397 int ff_cbs_write_packet(CodedBitstreamContext *ctx,
398                         AVPacket *pkt,
399                         CodedBitstreamFragment *frag)
400 {
401     AVBufferRef *buf;
402     int err;
403
404     err = ff_cbs_write_fragment_data(ctx, frag);
405     if (err < 0)
406         return err;
407
408     buf = av_buffer_ref(frag->data_ref);
409     if (!buf)
410         return AVERROR(ENOMEM);
411
412     av_buffer_unref(&pkt->buf);
413
414     pkt->buf  = buf;
415     pkt->data = frag->data;
416     pkt->size = frag->data_size;
417
418     return 0;
419 }
420
421
422 void ff_cbs_trace_header(CodedBitstreamContext *ctx,
423                          const char *name)
424 {
425     if (!ctx->trace_enable)
426         return;
427
428     av_log(ctx->log_ctx, ctx->trace_level, "%s\n", name);
429 }
430
431 void ff_cbs_trace_syntax_element(CodedBitstreamContext *ctx, int position,
432                                  const char *str, const int *subscripts,
433                                  const char *bits, int64_t value)
434 {
435     char name[256];
436     size_t name_len, bits_len;
437     int pad, subs, i, j, k, n;
438
439     if (!ctx->trace_enable)
440         return;
441
442     av_assert0(value >= INT_MIN && value <= UINT32_MAX);
443
444     subs = subscripts ? subscripts[0] : 0;
445     n = 0;
446     for (i = j = 0; str[i];) {
447         if (str[i] == '[') {
448             if (n < subs) {
449                 ++n;
450                 k = snprintf(name + j, sizeof(name) - j, "[%d", subscripts[n]);
451                 av_assert0(k > 0 && j + k < sizeof(name));
452                 j += k;
453                 for (++i; str[i] && str[i] != ']'; i++);
454                 av_assert0(str[i] == ']');
455             } else {
456                 while (str[i] && str[i] != ']')
457                     name[j++] = str[i++];
458                 av_assert0(str[i] == ']');
459             }
460         } else {
461             av_assert0(j + 1 < sizeof(name));
462             name[j++] = str[i++];
463         }
464     }
465     av_assert0(j + 1 < sizeof(name));
466     name[j] = 0;
467     av_assert0(n == subs);
468
469     name_len = strlen(name);
470     bits_len = strlen(bits);
471
472     if (name_len + bits_len > 60)
473         pad = bits_len + 2;
474     else
475         pad = 61 - name_len;
476
477     av_log(ctx->log_ctx, ctx->trace_level, "%-10d  %s%*s = %"PRId64"\n",
478            position, name, pad, bits, value);
479 }
480
481 int ff_cbs_read_unsigned(CodedBitstreamContext *ctx, GetBitContext *gbc,
482                          int width, const char *name,
483                          const int *subscripts, uint32_t *write_to,
484                          uint32_t range_min, uint32_t range_max)
485 {
486     uint32_t value;
487     int position;
488
489     av_assert0(width > 0 && width <= 32);
490
491     if (get_bits_left(gbc) < width) {
492         av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value at "
493                "%s: bitstream ended.\n", name);
494         return AVERROR_INVALIDDATA;
495     }
496
497     if (ctx->trace_enable)
498         position = get_bits_count(gbc);
499
500     value = get_bits_long(gbc, width);
501
502     if (ctx->trace_enable) {
503         char bits[33];
504         int i;
505         for (i = 0; i < width; i++)
506             bits[i] = value >> (width - i - 1) & 1 ? '1' : '0';
507         bits[i] = 0;
508
509         ff_cbs_trace_syntax_element(ctx, position, name, subscripts,
510                                     bits, value);
511     }
512
513     if (value < range_min || value > range_max) {
514         av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
515                "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
516                name, value, range_min, range_max);
517         return AVERROR_INVALIDDATA;
518     }
519
520     *write_to = value;
521     return 0;
522 }
523
524 int ff_cbs_write_unsigned(CodedBitstreamContext *ctx, PutBitContext *pbc,
525                           int width, const char *name,
526                           const int *subscripts, uint32_t value,
527                           uint32_t range_min, uint32_t range_max)
528 {
529     av_assert0(width > 0 && width <= 32);
530
531     if (value < range_min || value > range_max) {
532         av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
533                "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n",
534                name, value, range_min, range_max);
535         return AVERROR_INVALIDDATA;
536     }
537
538     if (put_bits_left(pbc) < width)
539         return AVERROR(ENOSPC);
540
541     if (ctx->trace_enable) {
542         char bits[33];
543         int i;
544         for (i = 0; i < width; i++)
545             bits[i] = value >> (width - i - 1) & 1 ? '1' : '0';
546         bits[i] = 0;
547
548         ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc),
549                                     name, subscripts, bits, value);
550     }
551
552     if (width < 32)
553         put_bits(pbc, width, value);
554     else
555         put_bits32(pbc, value);
556
557     return 0;
558 }
559
560 int ff_cbs_read_signed(CodedBitstreamContext *ctx, GetBitContext *gbc,
561                        int width, const char *name,
562                        const int *subscripts, int32_t *write_to,
563                        int32_t range_min, int32_t range_max)
564 {
565     int32_t value;
566     int position;
567
568     av_assert0(width > 0 && width <= 32);
569
570     if (get_bits_left(gbc) < width) {
571         av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value at "
572                "%s: bitstream ended.\n", name);
573         return AVERROR_INVALIDDATA;
574     }
575
576     if (ctx->trace_enable)
577         position = get_bits_count(gbc);
578
579     value = get_sbits_long(gbc, width);
580
581     if (ctx->trace_enable) {
582         char bits[33];
583         int i;
584         for (i = 0; i < width; i++)
585             bits[i] = value & (1U << (width - i - 1)) ? '1' : '0';
586         bits[i] = 0;
587
588         ff_cbs_trace_syntax_element(ctx, position, name, subscripts,
589                                     bits, value);
590     }
591
592     if (value < range_min || value > range_max) {
593         av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
594                "%"PRId32", but must be in [%"PRId32",%"PRId32"].\n",
595                name, value, range_min, range_max);
596         return AVERROR_INVALIDDATA;
597     }
598
599     *write_to = value;
600     return 0;
601 }
602
603 int ff_cbs_write_signed(CodedBitstreamContext *ctx, PutBitContext *pbc,
604                         int width, const char *name,
605                         const int *subscripts, int32_t value,
606                         int32_t range_min, int32_t range_max)
607 {
608     av_assert0(width > 0 && width <= 32);
609
610     if (value < range_min || value > range_max) {
611         av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
612                "%"PRId32", but must be in [%"PRId32",%"PRId32"].\n",
613                name, value, range_min, range_max);
614         return AVERROR_INVALIDDATA;
615     }
616
617     if (put_bits_left(pbc) < width)
618         return AVERROR(ENOSPC);
619
620     if (ctx->trace_enable) {
621         char bits[33];
622         int i;
623         for (i = 0; i < width; i++)
624             bits[i] = value & (1U << (width - i - 1)) ? '1' : '0';
625         bits[i] = 0;
626
627         ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc),
628                                     name, subscripts, bits, value);
629     }
630
631     if (width < 32)
632         put_sbits(pbc, width, value);
633     else
634         put_bits32(pbc, value);
635
636     return 0;
637 }
638
639
640 int ff_cbs_alloc_unit_content(CodedBitstreamUnit *unit,
641                               size_t size,
642                               void (*free)(void *opaque, uint8_t *data))
643 {
644     av_assert0(!unit->content && !unit->content_ref);
645
646     unit->content = av_mallocz(size);
647     if (!unit->content)
648         return AVERROR(ENOMEM);
649
650     unit->content_ref = av_buffer_create(unit->content, size,
651                                          free, NULL, 0);
652     if (!unit->content_ref) {
653         av_freep(&unit->content);
654         return AVERROR(ENOMEM);
655     }
656
657     return 0;
658 }
659
660 int ff_cbs_alloc_unit_data(CodedBitstreamUnit *unit,
661                            size_t size)
662 {
663     av_assert0(!unit->data && !unit->data_ref);
664
665     unit->data_ref = av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
666     if (!unit->data_ref)
667         return AVERROR(ENOMEM);
668
669     unit->data      = unit->data_ref->data;
670     unit->data_size = size;
671
672     memset(unit->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
673
674     return 0;
675 }
676
677 static int cbs_insert_unit(CodedBitstreamFragment *frag,
678                            int position)
679 {
680     CodedBitstreamUnit *units;
681
682     if (frag->nb_units < frag->nb_units_allocated) {
683         units = frag->units;
684
685         if (position < frag->nb_units)
686             memmove(units + position + 1, units + position,
687                     (frag->nb_units - position) * sizeof(*units));
688     } else {
689         units = av_malloc_array(frag->nb_units*2 + 1, sizeof(*units));
690         if (!units)
691             return AVERROR(ENOMEM);
692
693         frag->nb_units_allocated = 2*frag->nb_units_allocated + 1;
694
695         if (position > 0)
696             memcpy(units, frag->units, position * sizeof(*units));
697
698         if (position < frag->nb_units)
699             memcpy(units + position + 1, frag->units + position,
700                    (frag->nb_units - position) * sizeof(*units));
701     }
702
703     memset(units + position, 0, sizeof(*units));
704
705     if (units != frag->units) {
706         av_free(frag->units);
707         frag->units = units;
708     }
709
710     ++frag->nb_units;
711
712     return 0;
713 }
714
715 int ff_cbs_insert_unit_content(CodedBitstreamFragment *frag,
716                                int position,
717                                CodedBitstreamUnitType type,
718                                void *content,
719                                AVBufferRef *content_buf)
720 {
721     CodedBitstreamUnit *unit;
722     AVBufferRef *content_ref;
723     int err;
724
725     if (position == -1)
726         position = frag->nb_units;
727     av_assert0(position >= 0 && position <= frag->nb_units);
728
729     if (content_buf) {
730         content_ref = av_buffer_ref(content_buf);
731         if (!content_ref)
732             return AVERROR(ENOMEM);
733     } else {
734         content_ref = NULL;
735     }
736
737     err = cbs_insert_unit(frag, position);
738     if (err < 0) {
739         av_buffer_unref(&content_ref);
740         return err;
741     }
742
743     unit = &frag->units[position];
744     unit->type        = type;
745     unit->content     = content;
746     unit->content_ref = content_ref;
747
748     return 0;
749 }
750
751 int ff_cbs_insert_unit_data(CodedBitstreamFragment *frag,
752                             int position,
753                             CodedBitstreamUnitType type,
754                             uint8_t *data, size_t data_size,
755                             AVBufferRef *data_buf)
756 {
757     CodedBitstreamUnit *unit;
758     AVBufferRef *data_ref;
759     int err;
760
761     if (position == -1)
762         position = frag->nb_units;
763     av_assert0(position >= 0 && position <= frag->nb_units);
764
765     if (data_buf)
766         data_ref = av_buffer_ref(data_buf);
767     else
768         data_ref = av_buffer_create(data, data_size, NULL, NULL, 0);
769     if (!data_ref) {
770         if (!data_buf)
771             av_free(data);
772         return AVERROR(ENOMEM);
773     }
774
775     err = cbs_insert_unit(frag, position);
776     if (err < 0) {
777         av_buffer_unref(&data_ref);
778         return err;
779     }
780
781     unit = &frag->units[position];
782     unit->type      = type;
783     unit->data      = data;
784     unit->data_size = data_size;
785     unit->data_ref  = data_ref;
786
787     return 0;
788 }
789
790 void ff_cbs_delete_unit(CodedBitstreamFragment *frag,
791                         int position)
792 {
793     av_assert0(0 <= position && position < frag->nb_units
794                              && "Unit to be deleted not in fragment.");
795
796     cbs_unit_uninit(&frag->units[position]);
797
798     --frag->nb_units;
799
800     if (frag->nb_units > 0)
801         memmove(frag->units + position,
802                 frag->units + position + 1,
803                 (frag->nb_units - position) * sizeof(*frag->units));
804 }