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
[] = {
39 int ff_cbs_init(CodedBitstreamContext
*ctx
,
40 enum AVCodecID codec_id
, void *log_ctx
)
42 const CodedBitstreamType
*type
;
46 for (i
= 0; i
< FF_ARRAY_ELEMS(cbs_type_table
); i
++) {
47 if (cbs_type_table
[i
]->codec_id
== codec_id
) {
48 type
= cbs_type_table
[i
];
53 return AVERROR(EINVAL
);
55 ctx
->log_ctx
= log_ctx
;
58 ctx
->priv_data
= av_mallocz(ctx
->codec
->priv_data_size
);
60 return AVERROR(ENOMEM
);
62 ctx
->decompose_unit_types
= NULL
;
64 ctx
->trace_enable
= 0;
65 ctx
->trace_level
= AV_LOG_TRACE
;
70 void ff_cbs_close(CodedBitstreamContext
*ctx
)
72 if (ctx
->codec
&& ctx
->codec
->close
)
73 ctx
->codec
->close(ctx
);
75 av_freep(&ctx
->priv_data
);
78 static void cbs_unit_uninit(CodedBitstreamContext
*ctx
,
79 CodedBitstreamUnit
*unit
)
81 if (ctx
->codec
->free_unit
&& unit
->content
&& !unit
->content_external
)
82 ctx
->codec
->free_unit(unit
);
84 av_freep(&unit
->data
);
86 unit
->data_bit_padding
= 0;
89 void ff_cbs_fragment_uninit(CodedBitstreamContext
*ctx
,
90 CodedBitstreamFragment
*frag
)
94 for (i
= 0; i
< frag
->nb_units
; i
++)
95 cbs_unit_uninit(ctx
, &frag
->units
[i
]);
96 av_freep(&frag
->units
);
99 av_freep(&frag
->data
);
101 frag
->data_bit_padding
= 0;
104 static int cbs_read_fragment_content(CodedBitstreamContext
*ctx
,
105 CodedBitstreamFragment
*frag
)
109 for (i
= 0; i
< frag
->nb_units
; i
++) {
110 if (ctx
->decompose_unit_types
) {
111 for (j
= 0; j
< ctx
->nb_decompose_unit_types
; j
++) {
112 if (ctx
->decompose_unit_types
[j
] == frag
->units
[i
].type
)
115 if (j
>= ctx
->nb_decompose_unit_types
)
119 err
= ctx
->codec
->read_unit(ctx
, &frag
->units
[i
]);
120 if (err
== AVERROR(ENOSYS
)) {
121 av_log(ctx
->log_ctx
, AV_LOG_WARNING
,
122 "Decomposition unimplemented for unit %d "
123 "(type %d).\n", i
, frag
->units
[i
].type
);
124 } else if (err
< 0) {
125 av_log(ctx
->log_ctx
, AV_LOG_ERROR
, "Failed to read unit %d "
126 "(type %d).\n", i
, frag
->units
[i
].type
);
134 int ff_cbs_read_extradata(CodedBitstreamContext
*ctx
,
135 CodedBitstreamFragment
*frag
,
136 const AVCodecParameters
*par
)
140 memset(frag
, 0, sizeof(*frag
));
142 frag
->data
= par
->extradata
;
143 frag
->data_size
= par
->extradata_size
;
145 err
= ctx
->codec
->split_fragment(ctx
, frag
, 1);
152 return cbs_read_fragment_content(ctx
, frag
);
155 int ff_cbs_read_packet(CodedBitstreamContext
*ctx
,
156 CodedBitstreamFragment
*frag
,
161 memset(frag
, 0, sizeof(*frag
));
163 frag
->data
= pkt
->data
;
164 frag
->data_size
= pkt
->size
;
166 err
= ctx
->codec
->split_fragment(ctx
, frag
, 0);
173 return cbs_read_fragment_content(ctx
, frag
);
176 int ff_cbs_read(CodedBitstreamContext
*ctx
,
177 CodedBitstreamFragment
*frag
,
178 const uint8_t *data
, size_t size
)
182 memset(frag
, 0, sizeof(*frag
));
184 // (We won't write to this during split.)
185 frag
->data
= (uint8_t*)data
;
186 frag
->data_size
= size
;
188 err
= ctx
->codec
->split_fragment(ctx
, frag
, 0);
195 return cbs_read_fragment_content(ctx
, frag
);
199 int ff_cbs_write_fragment_data(CodedBitstreamContext
*ctx
,
200 CodedBitstreamFragment
*frag
)
204 for (i
= 0; i
< frag
->nb_units
; i
++) {
205 if (!frag
->units
[i
].content
)
208 err
= ctx
->codec
->write_unit(ctx
, &frag
->units
[i
]);
210 av_log(ctx
->log_ctx
, AV_LOG_ERROR
, "Failed to write unit %d "
211 "(type %d).\n", i
, frag
->units
[i
].type
);
216 err
= ctx
->codec
->assemble_fragment(ctx
, frag
);
218 av_log(ctx
->log_ctx
, AV_LOG_ERROR
, "Failed to assemble fragment.\n");
225 int ff_cbs_write_extradata(CodedBitstreamContext
*ctx
,
226 AVCodecParameters
*par
,
227 CodedBitstreamFragment
*frag
)
231 err
= ff_cbs_write_fragment_data(ctx
, frag
);
235 av_freep(&par
->extradata
);
237 par
->extradata
= av_malloc(frag
->data_size
+
238 AV_INPUT_BUFFER_PADDING_SIZE
);
240 return AVERROR(ENOMEM
);
242 memcpy(par
->extradata
, frag
->data
, frag
->data_size
);
243 memset(par
->extradata
+ frag
->data_size
, 0,
244 AV_INPUT_BUFFER_PADDING_SIZE
);
245 par
->extradata_size
= frag
->data_size
;
250 int ff_cbs_write_packet(CodedBitstreamContext
*ctx
,
252 CodedBitstreamFragment
*frag
)
256 err
= ff_cbs_write_fragment_data(ctx
, frag
);
260 av_new_packet(pkt
, frag
->data_size
);
264 memcpy(pkt
->data
, frag
->data
, frag
->data_size
);
265 pkt
->size
= frag
->data_size
;
271 void ff_cbs_trace_header(CodedBitstreamContext
*ctx
,
274 if (!ctx
->trace_enable
)
277 av_log(ctx
->log_ctx
, ctx
->trace_level
, "%s\n", name
);
280 void ff_cbs_trace_syntax_element(CodedBitstreamContext
*ctx
, int position
,
281 const char *name
, const char *bits
,
284 size_t name_len
, bits_len
;
287 if (!ctx
->trace_enable
)
290 av_assert0(value
>= INT_MIN
&& value
<= UINT32_MAX
);
292 name_len
= strlen(name
);
293 bits_len
= strlen(bits
);
295 if (name_len
+ bits_len
> 60)
300 av_log(ctx
->log_ctx
, ctx
->trace_level
, "%-10d %s%*s = %"PRId64
"\n",
301 position
, name
, pad
, bits
, value
);
304 int ff_cbs_read_unsigned(CodedBitstreamContext
*ctx
, BitstreamContext
*bc
,
305 int width
, const char *name
, uint32_t *write_to
,
306 uint32_t range_min
, uint32_t range_max
)
311 av_assert0(width
<= 32);
313 if (ctx
->trace_enable
)
314 position
= bitstream_tell(bc
);
316 value
= bitstream_read(bc
, width
);
318 if (ctx
->trace_enable
) {
321 for (i
= 0; i
< width
; i
++)
322 bits
[i
] = value
>> (width
- i
- 1) & 1 ?
'1' : '0';
325 ff_cbs_trace_syntax_element(ctx
, position
, name
, bits
, value
);
328 if (value
< range_min
|| value
> range_max
) {
329 av_log(ctx
->log_ctx
, AV_LOG_ERROR
, "%s out of range: "
330 "%"PRIu32
", but must be in [%"PRIu32
",%"PRIu32
"].\n",
331 name
, value
, range_min
, range_max
);
332 return AVERROR_INVALIDDATA
;
339 int ff_cbs_write_unsigned(CodedBitstreamContext
*ctx
, PutBitContext
*pbc
,
340 int width
, const char *name
, uint32_t value
,
341 uint32_t range_min
, uint32_t range_max
)
343 av_assert0(width
<= 32);
345 if (value
< range_min
|| value
> range_max
) {
346 av_log(ctx
->log_ctx
, AV_LOG_ERROR
, "%s out of range: "
347 "%"PRIu32
", but must be in [%"PRIu32
",%"PRIu32
"].\n",
348 name
, value
, range_min
, range_max
);
349 return AVERROR_INVALIDDATA
;
352 if (put_bits_left(pbc
) < width
)
353 return AVERROR(ENOSPC
);
355 if (ctx
->trace_enable
) {
358 for (i
= 0; i
< width
; i
++)
359 bits
[i
] = value
>> (width
- i
- 1) & 1 ?
'1' : '0';
362 ff_cbs_trace_syntax_element(ctx
, put_bits_count(pbc
), name
, bits
, value
);
366 put_bits(pbc
, width
, value
);
368 put_bits32(pbc
, value
);
374 static int cbs_insert_unit(CodedBitstreamContext
*ctx
,
375 CodedBitstreamFragment
*frag
,
378 CodedBitstreamUnit
*units
;
380 units
= av_malloc_array(frag
->nb_units
+ 1, sizeof(*units
));
382 return AVERROR(ENOMEM
);
385 memcpy(units
, frag
->units
, position
* sizeof(*units
));
386 if (position
< frag
->nb_units
)
387 memcpy(units
+ position
+ 1, frag
->units
+ position
,
388 (frag
->nb_units
- position
) * sizeof(*units
));
390 memset(units
+ position
, 0, sizeof(*units
));
392 av_freep(&frag
->units
);
399 int ff_cbs_insert_unit_content(CodedBitstreamContext
*ctx
,
400 CodedBitstreamFragment
*frag
,
401 int position
, uint32_t type
,
407 position
= frag
->nb_units
;
408 av_assert0(position
>= 0 && position
<= frag
->nb_units
);
410 err
= cbs_insert_unit(ctx
, frag
, position
);
414 frag
->units
[position
].type
= type
;
415 frag
->units
[position
].content
= content
;
416 frag
->units
[position
].content_external
= 1;
421 int ff_cbs_insert_unit_data(CodedBitstreamContext
*ctx
,
422 CodedBitstreamFragment
*frag
,
423 int position
, uint32_t type
,
424 uint8_t *data
, size_t data_size
)
429 position
= frag
->nb_units
;
430 av_assert0(position
>= 0 && position
<= frag
->nb_units
);
432 err
= cbs_insert_unit(ctx
, frag
, position
);
436 frag
->units
[position
].type
= type
;
437 frag
->units
[position
].data
= data
;
438 frag
->units
[position
].data_size
= data_size
;
443 int ff_cbs_delete_unit(CodedBitstreamContext
*ctx
,
444 CodedBitstreamFragment
*frag
,
447 if (position
< 0 || position
>= frag
->nb_units
)
448 return AVERROR(EINVAL
);
450 cbs_unit_uninit(ctx
, &frag
->units
[position
]);
454 if (frag
->nb_units
== 0) {
455 av_freep(&frag
->units
);
458 memmove(frag
->units
+ position
,
459 frag
->units
+ position
+ 1,
460 (frag
->nb_units
- position
) * sizeof(*frag
->units
));
462 // Don't bother reallocating the unit array.