2 * This file is part of Libav.
4 * Libav 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.
9 * Libav 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.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with Libav; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "libavutil/avassert.h"
24 #include "libavutil/common.h"
27 #include "cbs_internal.h"
30 static const CodedBitstreamType
*cbs_type_table
[] = {
36 int ff_cbs_init(CodedBitstreamContext
*ctx
,
37 enum AVCodecID codec_id
, void *log_ctx
)
39 const CodedBitstreamType
*type
;
43 for (i
= 0; i
< FF_ARRAY_ELEMS(cbs_type_table
); i
++) {
44 if (cbs_type_table
[i
]->codec_id
== codec_id
) {
45 type
= cbs_type_table
[i
];
50 return AVERROR(EINVAL
);
52 ctx
->log_ctx
= log_ctx
;
55 ctx
->priv_data
= av_mallocz(ctx
->codec
->priv_data_size
);
57 return AVERROR(ENOMEM
);
59 ctx
->decompose_unit_types
= NULL
;
61 ctx
->trace_enable
= 0;
62 ctx
->trace_level
= AV_LOG_TRACE
;
67 void ff_cbs_close(CodedBitstreamContext
*ctx
)
69 if (ctx
->codec
&& ctx
->codec
->close
)
70 ctx
->codec
->close(ctx
);
72 av_freep(&ctx
->priv_data
);
75 static void cbs_unit_uninit(CodedBitstreamContext
*ctx
,
76 CodedBitstreamUnit
*unit
)
78 if (ctx
->codec
->free_unit
&& unit
->content
&& !unit
->content_external
)
79 ctx
->codec
->free_unit(unit
);
81 av_freep(&unit
->data
);
83 unit
->data_bit_padding
= 0;
86 void ff_cbs_fragment_uninit(CodedBitstreamContext
*ctx
,
87 CodedBitstreamFragment
*frag
)
91 for (i
= 0; i
< frag
->nb_units
; i
++)
92 cbs_unit_uninit(ctx
, &frag
->units
[i
]);
93 av_freep(&frag
->units
);
96 av_freep(&frag
->data
);
98 frag
->data_bit_padding
= 0;
101 static int cbs_read_fragment_content(CodedBitstreamContext
*ctx
,
102 CodedBitstreamFragment
*frag
)
106 for (i
= 0; i
< frag
->nb_units
; i
++) {
107 if (ctx
->decompose_unit_types
) {
108 for (j
= 0; j
< ctx
->nb_decompose_unit_types
; j
++) {
109 if (ctx
->decompose_unit_types
[j
] == frag
->units
[i
].type
)
112 if (j
>= ctx
->nb_decompose_unit_types
)
116 err
= ctx
->codec
->read_unit(ctx
, &frag
->units
[i
]);
117 if (err
== AVERROR(ENOSYS
)) {
118 av_log(ctx
->log_ctx
, AV_LOG_WARNING
,
119 "Decomposition unimplemented for unit %d "
120 "(type %d).\n", i
, frag
->units
[i
].type
);
121 } else if (err
< 0) {
122 av_log(ctx
->log_ctx
, AV_LOG_ERROR
, "Failed to read unit %d "
123 "(type %d).\n", i
, frag
->units
[i
].type
);
131 int ff_cbs_read_extradata(CodedBitstreamContext
*ctx
,
132 CodedBitstreamFragment
*frag
,
133 const AVCodecParameters
*par
)
137 memset(frag
, 0, sizeof(*frag
));
139 frag
->data
= par
->extradata
;
140 frag
->data_size
= par
->extradata_size
;
142 err
= ctx
->codec
->split_fragment(ctx
, frag
, 1);
149 return cbs_read_fragment_content(ctx
, frag
);
152 int ff_cbs_read_packet(CodedBitstreamContext
*ctx
,
153 CodedBitstreamFragment
*frag
,
158 memset(frag
, 0, sizeof(*frag
));
160 frag
->data
= pkt
->data
;
161 frag
->data_size
= pkt
->size
;
163 err
= ctx
->codec
->split_fragment(ctx
, frag
, 0);
170 return cbs_read_fragment_content(ctx
, frag
);
173 int ff_cbs_read(CodedBitstreamContext
*ctx
,
174 CodedBitstreamFragment
*frag
,
175 const uint8_t *data
, size_t size
)
179 memset(frag
, 0, sizeof(*frag
));
181 // (We won't write to this during split.)
182 frag
->data
= (uint8_t*)data
;
183 frag
->data_size
= size
;
185 err
= ctx
->codec
->split_fragment(ctx
, frag
, 0);
192 return cbs_read_fragment_content(ctx
, frag
);
196 int ff_cbs_write_fragment_data(CodedBitstreamContext
*ctx
,
197 CodedBitstreamFragment
*frag
)
201 for (i
= 0; i
< frag
->nb_units
; i
++) {
202 if (!frag
->units
[i
].content
)
205 err
= ctx
->codec
->write_unit(ctx
, &frag
->units
[i
]);
207 av_log(ctx
->log_ctx
, AV_LOG_ERROR
, "Failed to write unit %d "
208 "(type %d).\n", i
, frag
->units
[i
].type
);
213 err
= ctx
->codec
->assemble_fragment(ctx
, frag
);
215 av_log(ctx
->log_ctx
, AV_LOG_ERROR
, "Failed to assemble fragment.\n");
222 int ff_cbs_write_extradata(CodedBitstreamContext
*ctx
,
223 AVCodecParameters
*par
,
224 CodedBitstreamFragment
*frag
)
228 err
= ff_cbs_write_fragment_data(ctx
, frag
);
232 av_freep(&par
->extradata
);
234 par
->extradata
= av_malloc(frag
->data_size
+
235 AV_INPUT_BUFFER_PADDING_SIZE
);
237 return AVERROR(ENOMEM
);
239 memcpy(par
->extradata
, frag
->data
, frag
->data_size
);
240 memset(par
->extradata
+ frag
->data_size
, 0,
241 AV_INPUT_BUFFER_PADDING_SIZE
);
242 par
->extradata_size
= frag
->data_size
;
247 int ff_cbs_write_packet(CodedBitstreamContext
*ctx
,
249 CodedBitstreamFragment
*frag
)
253 err
= ff_cbs_write_fragment_data(ctx
, frag
);
257 av_new_packet(pkt
, frag
->data_size
);
261 memcpy(pkt
->data
, frag
->data
, frag
->data_size
);
262 pkt
->size
= frag
->data_size
;
268 void ff_cbs_trace_header(CodedBitstreamContext
*ctx
,
271 if (!ctx
->trace_enable
)
274 av_log(ctx
->log_ctx
, ctx
->trace_level
, "%s\n", name
);
277 void ff_cbs_trace_syntax_element(CodedBitstreamContext
*ctx
, int position
,
278 const char *name
, const char *bits
,
281 size_t name_len
, bits_len
;
284 if (!ctx
->trace_enable
)
287 av_assert0(value
>= INT_MIN
&& value
<= UINT32_MAX
);
289 name_len
= strlen(name
);
290 bits_len
= strlen(bits
);
292 if (name_len
+ bits_len
> 60)
297 av_log(ctx
->log_ctx
, ctx
->trace_level
, "%-10d %s%*s = %"PRId64
"\n",
298 position
, name
, pad
, bits
, value
);
301 int ff_cbs_read_unsigned(CodedBitstreamContext
*ctx
, BitstreamContext
*bc
,
302 int width
, const char *name
, uint32_t *write_to
,
303 uint32_t range_min
, uint32_t range_max
)
308 av_assert0(width
<= 32);
310 if (ctx
->trace_enable
)
311 position
= bitstream_tell(bc
);
313 value
= bitstream_read(bc
, width
);
315 if (ctx
->trace_enable
) {
318 for (i
= 0; i
< width
; i
++)
319 bits
[i
] = value
>> (width
- i
- 1) & 1 ?
'1' : '0';
322 ff_cbs_trace_syntax_element(ctx
, position
, name
, bits
, value
);
325 if (value
< range_min
|| value
> range_max
) {
326 av_log(ctx
->log_ctx
, AV_LOG_ERROR
, "%s out of range: "
327 "%"PRIu32
", but must be in [%"PRIu32
",%"PRIu32
"].\n",
328 name
, value
, range_min
, range_max
);
329 return AVERROR_INVALIDDATA
;
336 int ff_cbs_write_unsigned(CodedBitstreamContext
*ctx
, PutBitContext
*pbc
,
337 int width
, const char *name
, uint32_t value
,
338 uint32_t range_min
, uint32_t range_max
)
340 av_assert0(width
<= 32);
342 if (value
< range_min
|| value
> range_max
) {
343 av_log(ctx
->log_ctx
, AV_LOG_ERROR
, "%s out of range: "
344 "%"PRIu32
", but must be in [%"PRIu32
",%"PRIu32
"].\n",
345 name
, value
, range_min
, range_max
);
346 return AVERROR_INVALIDDATA
;
349 if (put_bits_left(pbc
) < width
)
350 return AVERROR(ENOSPC
);
352 if (ctx
->trace_enable
) {
355 for (i
= 0; i
< width
; i
++)
356 bits
[i
] = value
>> (width
- i
- 1) & 1 ?
'1' : '0';
359 ff_cbs_trace_syntax_element(ctx
, put_bits_count(pbc
), name
, bits
, value
);
363 put_bits(pbc
, width
, value
);
365 put_bits32(pbc
, value
);
371 static int cbs_insert_unit(CodedBitstreamContext
*ctx
,
372 CodedBitstreamFragment
*frag
,
375 CodedBitstreamUnit
*units
;
377 units
= av_malloc_array(frag
->nb_units
+ 1, sizeof(*units
));
379 return AVERROR(ENOMEM
);
382 memcpy(units
, frag
->units
, position
* sizeof(*units
));
383 if (position
< frag
->nb_units
)
384 memcpy(units
+ position
+ 1, frag
->units
+ position
,
385 (frag
->nb_units
- position
) * sizeof(*units
));
387 memset(units
+ position
, 0, sizeof(*units
));
389 av_freep(&frag
->units
);
396 int ff_cbs_insert_unit_content(CodedBitstreamContext
*ctx
,
397 CodedBitstreamFragment
*frag
,
398 int position
, uint32_t type
,
404 position
= frag
->nb_units
;
405 av_assert0(position
>= 0 && position
<= frag
->nb_units
);
407 err
= cbs_insert_unit(ctx
, frag
, position
);
411 frag
->units
[position
].type
= type
;
412 frag
->units
[position
].content
= content
;
413 frag
->units
[position
].content_external
= 1;
418 int ff_cbs_insert_unit_data(CodedBitstreamContext
*ctx
,
419 CodedBitstreamFragment
*frag
,
420 int position
, uint32_t type
,
421 uint8_t *data
, size_t data_size
)
426 position
= frag
->nb_units
;
427 av_assert0(position
>= 0 && position
<= frag
->nb_units
);
429 err
= cbs_insert_unit(ctx
, frag
, position
);
433 frag
->units
[position
].type
= type
;
434 frag
->units
[position
].data
= data
;
435 frag
->units
[position
].data_size
= data_size
;
440 int ff_cbs_delete_unit(CodedBitstreamContext
*ctx
,
441 CodedBitstreamFragment
*frag
,
444 if (position
< 0 || position
>= frag
->nb_units
)
445 return AVERROR(EINVAL
);
447 cbs_unit_uninit(ctx
, &frag
->units
[position
]);
451 if (frag
->nb_units
== 0) {
452 av_freep(&frag
->units
);
455 memmove(frag
->units
+ position
,
456 frag
->units
+ position
+ 1,
457 (frag
->nb_units
- position
) * sizeof(*frag
->units
));
459 // Don't bother reallocating the unit array.