29#define HEADER(name) do { \
30 ff_cbs_trace_header(ctx, name); \
33#define CHECK(call) do { \
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)
46#define SEI_FUNC(name, args) \
47static int FUNC_LCEVC(name) args; \
48static int FUNC_LCEVC(name ## _internal)(CodedBitstreamContext *ctx, \
49 RWContext *rw, void *cur, \
50 SEIMessageState *state) \
52 return FUNC_LCEVC(name)(ctx, rw, cur, state); \
54static int FUNC_LCEVC(name) args
56#define LCEVC_BLOCK_FUNC(name, args) \
57static int FUNC(name) args; \
58static int FUNC(name ## _internal)(CodedBitstreamContext *ctx, \
59 RWContext *rw, void *cur, \
60 LCEVCProcessBlockState *state, \
63 return FUNC(name)(ctx, rw, cur, state, nal_unit_type); \
65static int FUNC(name) args
67#define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : NULL)
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, )
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__)
96 xmb(name, current->name)
98#define fixed(width, name, value) do { \
99 av_unused uint32_t fixed_value = value; \
100 xu(width, name, fixed_value, value, value, 0, ); \
105 const char *
name, uint32_t *write_to)
114 for (
i = 0;
i < 10;
i++) {
117 "%s: bitstream ended.\n",
name);
126 if (
value > UINT32_MAX)
136#define READWRITE read
137#define RWContext GetBitContext
139#define ub(width, name) do { \
141 CHECK(ff_cbs_read_simple_unsigned(ctx, rw, width, #name, \
143 current->name = value; \
145#define xu(width, name, var, range_min, range_max, subs, ...) do { \
147 CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \
148 SUBSCRIPTS(subs, __VA_ARGS__), \
149 &value, range_min, range_max)); \
152#define xue(name, var, range_min, range_max, subs, ...) do { \
154 CHECK(ff_cbs_read_ue_golomb(ctx, rw, #name, \
155 SUBSCRIPTS(subs, __VA_ARGS__), \
156 &value, range_min, range_max)); \
159#define xi(width, name, var, range_min, range_max, subs, ...) do { \
161 CHECK(ff_cbs_read_signed(ctx, rw, width, #name, \
162 SUBSCRIPTS(subs, __VA_ARGS__), \
163 &value, range_min, range_max)); \
166#define xse(name, var, range_min, range_max, subs, ...) do { \
168 CHECK(ff_cbs_read_se_golomb(ctx, rw, #name, \
169 SUBSCRIPTS(subs, __VA_ARGS__), \
170 &value, range_min, range_max)); \
173#define xmb(name, var) do { \
175 CHECK(cbs_read_multi_byte(ctx, rw, #name, &value)); \
179#define infer(name, value) do { \
180 current->name = value; \
183#define more_rbsp_data(var) ((var) = ff_cbs_h2645_read_more_rbsp_data(rw))
185#define bit_position(rw) (get_bits_count(rw))
186#define byte_alignment(rw) (get_bits_count(rw) % 8)
190#define allocate(name, size) do { \
191 name = av_refstruct_allocz(size + \
192 AV_INPUT_BUFFER_PADDING_SIZE); \
194 return AVERROR(ENOMEM); \
197#define FUNC(name) FUNC_LCEVC(name)
228 for (
i =
len - 1;
i >= 0;
i--) {
232 byte =
value >> (7 *
i) & 0x7f;
245#define READWRITE write
246#define RWContext PutBitContext
248#define ub(width, name) do { \
249 uint32_t value = current->name; \
250 CHECK(ff_cbs_write_simple_unsigned(ctx, rw, width, #name, \
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)); \
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)); \
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)); \
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)); \
277#define xmb(name, var) do { \
278 uint32_t value = var; \
279 CHECK(cbs_write_multi_byte(ctx, rw, #name, value)); \
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; \
292#define more_rbsp_data(var) (var)
294#define bit_position(rw) (put_bits_count(rw))
295#define byte_alignment(rw) (put_bits_count(rw) % 8)
297#define allocate(name, size) do { \
299 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s must be set " \
300 "for writing.\n", #name); \
301 return AVERROR_INVALIDDATA; \
305#define FUNC(name) FUNC_LCEVC(name)
346 size_t size, start, end;
347 int i, j, nb_arrays, nal_unit_type, nb_nals,
version;
356 version = bytestream2_get_byte(&gbc);
367 nb_arrays = bytestream2_get_byte(&gbc);
369 for (
i = 0;
i < nb_arrays;
i++) {
370 nal_unit_type = bytestream2_get_byte(&gbc) & 0x3f;
371 nb_nals = bytestream2_get_be16(&gbc);
374 for (j = 0; j < nb_nals; j++) {
377 size = bytestream2_get_be16(&gbc);
385 frag->
data + start, end - start,
390 "LVCC array %d (%d NAL units of type %d).\n",
391 i, nb_nals, nal_unit_type);
428 err = ff_cbs_alloc_unit_content(
ctx, unit);
432 switch (unit->
type) {
444 block_list = &
nal->process_block_list;
452 slice =
block->payload;
473 switch (unit->
type) {
485 "NAL unit type %"PRIu32
".\n", unit->
type);
529 block->payload_type =
desc->payload_type;
542 if (!
block->payload_ref)
555 av_assert0(position >= 0 && position <= list->nb_blocks);
560 if (position < list->nb_blocks)
561 memmove(blocks + position + 1, blocks + position,
562 (list->
nb_blocks - position) *
sizeof(*blocks));
571 memcpy(blocks, list->
blocks, position *
sizeof(*blocks));
573 if (position < list->nb_blocks)
574 memcpy(blocks + position + 1, list->
blocks + position,
575 (list->
nb_blocks - position) *
sizeof(*blocks));
581 memset(blocks + position, 0,
sizeof(*blocks));
605 *list = &
nal->process_block_list;
613 uint32_t payload_type,
655 block->payload_type = payload_type;
656 block->payload = payload_data;
657 block->payload_ref = payload_ref;
664 uint32_t payload_type,
681 for (
int j = 0; j < list->
nb_blocks; j++) {
684 if (
block->payload_type == payload_type) {
685 if (!*iter || found) {
703 av_assert0(0 <= position && position < list->nb_blocks);
711 memmove(list->
blocks + position,
712 list->
blocks + position + 1,
719 uint32_t payload_type)
731 for (
int j = list->
nb_blocks - 1; j >= 0; j--) {
769#define LCEVC_PROCESS_BLOCK_RW(codec, name) \
770 .read = cbs_ ## codec ## _read_ ## name ## _internal, \
771 .write = cbs_ ## codec ## _write_ ## name ## _internal
static AVFormatContext * ctx
static av_cold void close(AVCodecParserContext *s)
#define av_assert0(cond)
assert() equivalent, that is always enabled.
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
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
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
static av_always_inline int bytestream2_tell(const GetByteContext *g)
int ff_cbs_h2645_fragment_add_nals(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, const H2645Packet *packet)
int ff_cbs_h2645_assemble_fragment(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag)
#define flags(name, subs,...)
#define i(width, name, range_min, range_max)
static int FUNC sei(CodedBitstreamContext *ctx, RWContext *rw, H264RawSEI *current)
#define CBS_UNIT_TYPE_END_OF_LIST
#define CBS_TRACE_WRITE_END_NO_SUBSCRIPTS()
#define CBS_TRACE_READ_START()
#define CBS_TRACE_READ_END_NO_SUBSCRIPTS()
#define CBS_UNIT_TYPES_COMPLEX(types, structure, free_func)
#define CBS_TRACE_WRITE_START()
const CodedBitstreamType ff_cbs_type_lcevc
static void free_picture_config(AVRefStructOpaque unused, void *obj)
static int cbs_lcevc_write_nal_unit(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit, PutBitContext *pbc)
static void cbs_lcevc_free_nal(AVRefStructOpaque unused, void *content)
int ff_cbs_lcevc_alloc_process_block_payload(LCEVCRawProcessBlock *block, const LCEVCProcessBlockTypeDescriptor *desc)
Allocate a new payload for the given 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.
static int cbs_lcevc_split_fragment(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, int header)
static const LCEVCProcessBlockTypeDescriptor cbs_lcevc_process_block_types[]
#define LCEVC_PROCESS_BLOCK_RW(codec, name)
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.
static void free_encoded_data(AVRefStructOpaque unused, void *obj)
static int cbs_lcevc_get_process_block_list(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit, LCEVCRawProcessBlockList **list)
static CodedBitstreamUnitTypeDescriptor cbs_lcevc_unit_types[]
static av_cold void cbs_lcevc_flush(CodedBitstreamContext *ctx)
const LCEVCProcessBlockTypeDescriptor * ff_cbs_lcevc_process_block_find_type(CodedBitstreamContext *ctx, int payload_type)
Find the type descriptor for the given payload type.
static int cbs_lcevc_read_nal_unit(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit)
static void free_additional_info(AVRefStructOpaque unused, void *obj)
static av_cold void cbs_lcevc_close(CodedBitstreamContext *ctx)
static void cbs_lcevc_delete_process_block(LCEVCRawProcessBlockList *list, int position)
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.
static int cbs_read_multi_byte(CodedBitstreamContext *ctx, GetBitContext *gbc, const char *name, uint32_t *write_to)
void ff_cbs_lcevc_free_process_block_list(LCEVCRawProcessBlockList *list)
Free all Process Block in a block list.
int ff_cbs_lcevc_list_add(LCEVCRawProcessBlockList *list, int position)
Allocate a new empty Process Block in a block list at a given position.
static int cbs_write_multi_byte(CodedBitstreamContext *ctx, PutBitContext *pbc, const char *name, uint32_t value)
#define LCEVC_PROCESS_BLOCK_TYPE_END
static int FUNC nal(CodedBitstreamContext *ctx, RWContext *rw, LCEVCRawNAL *current, int nal_unit_type)
void(* flush)(AVBSFContext *ctx)
bitstream reader API header.
static int get_bits_left(GetBitContext *gb)
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
AVCodecID
Identify the syntax and semantics of the bitstream.
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
@ H2645_FLAG_SMALL_PADDING
int(* filler)(InterplayACMContext *s, unsigned ind, unsigned col)
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
void ff_h2645_packet_uninit(H2645Packet *pkt)
Free all the allocated memory in the packet.
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.
@ LCEVC_PAYLOAD_TYPE_FILLER
@ LCEVC_PAYLOAD_TYPE_ADDITIONAL_INFO
@ LCEVC_PAYLOAD_TYPE_GLOBAL_CONFIG
@ LCEVC_PAYLOAD_TYPE_PICTURE_CONFIG
@ LCEVC_PAYLOAD_TYPE_ENCODED_DATA
@ LCEVC_PAYLOAD_TYPE_SEQUENCE_CONFIG
Memory handling functions.
static int put_bits_left(PutBitContext *s)
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
void * av_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
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.
static const uint8_t header[24]
Context structure for coded bitstream operations.
Coded bitstream fragment structure, combining one or more units.
CodedBitstreamUnit * units
Pointer to an array of units of length nb_units_allocated.
int nb_units
Number of units in this fragment.
size_t data_size
The number of bytes in the bitstream.
uint8_t * data
Pointer to the bitstream form of this fragment.
LCEVCRawGlobalConfig * gc
RefStruct references.
LCEVCRawSequenceConfig * sc
RefStruct references.
LCEVCRawPictureConfig * pc
RefStruct references.
CodedBitstreamH2645Context common
Coded bitstream unit structure.
void * content
Pointer to the decomposed form of this unit.
uint8_t * data
Pointer to the directly-parsable bitstream form of this unit.
CodedBitstreamUnitType type
Codec-specific type of this unit.
size_t data_size
The number of bytes in the bitstream (including any padding bits in the final byte).
AVBufferRef * data_ref
A reference to the buffer containing data.
void * payload_ref
RefStruct reference.
LCEVCRawPictureConfig * pc
RefStruct references.
LCEVCRawSequenceConfig * sc
RefStruct references.
LCEVCRawGlobalConfig * gc
RefStruct references.
LCEVCRawGlobalConfig * gc
RefStruct references.
LCEVCRawProcessBlock * blocks
#define av_malloc_array(a, b)
RefStruct is an API for creating reference-counted objects with minimal overhead.