28#define HEADER(name) do { \
29 ff_cbs_trace_header(ctx, name); \
32#define CHECK(call) do { \
38#define FUNC_NAME2(rw, codec, name) cbs_ ## codec ## _ ## rw ## _ ## name
39#define FUNC_NAME1(rw, codec, name) FUNC_NAME2(rw, codec, name)
40#define FUNC_NAME2_EXPORT(rw, codec, name) ff_cbs_ ## codec ## _ ## rw ## _ ## name
41#define FUNC_NAME1_EXPORT(rw, codec, name) FUNC_NAME2_EXPORT(rw, codec, name)
42#define FUNC_SEI(name) FUNC_NAME1(READWRITE, sei, name)
43#define FUNC_SEI_EXPORT(name) FUNC_NAME1_EXPORT(READWRITE, sei, name)
45#define SEI_FUNC(name, args) \
46static int FUNC_SEI(name) args; \
47static int FUNC_SEI(name ## _internal)(CodedBitstreamContext *ctx, \
48 RWContext *rw, void *cur, \
49 SEIMessageState *state) \
51 return FUNC_SEI(name)(ctx, rw, cur, state); \
53static int FUNC_SEI(name) args
55#define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : NULL)
57#define u(width, name, range_min, range_max) \
58 xu(width, name, current->name, range_min, range_max, 0, )
59#define flag(name) ub(1, name)
60#define ue(name, range_min, range_max) \
61 xue(name, current->name, range_min, range_max, 0, )
62#define i(width, name, range_min, range_max) \
63 xi(width, name, current->name, range_min, range_max, 0, )
64#define ib(width, name) \
65 xi(width, name, current->name, MIN_INT_BITS(width), MAX_INT_BITS(width), 0, )
66#define se(name, range_min, range_max) \
67 xse(name, current->name, range_min, range_max, 0, )
69#define us(width, name, range_min, range_max, subs, ...) \
70 xu(width, name, current->name, range_min, range_max, subs, __VA_ARGS__)
71#define ubs(width, name, subs, ...) \
72 xu(width, name, current->name, 0, MAX_UINT_BITS(width), subs, __VA_ARGS__)
73#define flags(name, subs, ...) \
74 xu(1, name, current->name, 0, 1, subs, __VA_ARGS__)
75#define ues(name, range_min, range_max, subs, ...) \
76 xue(name, current->name, range_min, range_max, subs, __VA_ARGS__)
77#define is(width, name, range_min, range_max, subs, ...) \
78 xi(width, name, current->name, range_min, range_max, subs, __VA_ARGS__)
79#define ibs(width, name, subs, ...) \
80 xi(width, name, current->name, MIN_INT_BITS(width), MAX_INT_BITS(width), subs, __VA_ARGS__)
81#define ses(name, range_min, range_max, subs, ...) \
82 xse(name, current->name, range_min, range_max, subs, __VA_ARGS__)
84#define fixed(width, name, value) do { \
85 av_unused uint32_t fixed_value = value; \
86 xu(width, name, fixed_value, value, value, 0, ); \
92#define RWContext GetBitContext
94#define ub(width, name) do { \
96 CHECK(ff_cbs_read_simple_unsigned(ctx, rw, width, #name, \
98 current->name = value; \
100#define xu(width, name, var, range_min, range_max, subs, ...) do { \
102 CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \
103 SUBSCRIPTS(subs, __VA_ARGS__), \
104 &value, range_min, range_max)); \
107#define xue(name, var, range_min, range_max, subs, ...) do { \
109 CHECK(ff_cbs_read_ue_golomb(ctx, rw, #name, \
110 SUBSCRIPTS(subs, __VA_ARGS__), \
111 &value, range_min, range_max)); \
114#define xi(width, name, var, range_min, range_max, subs, ...) do { \
116 CHECK(ff_cbs_read_signed(ctx, rw, width, #name, \
117 SUBSCRIPTS(subs, __VA_ARGS__), \
118 &value, range_min, range_max)); \
121#define xse(name, var, range_min, range_max, subs, ...) do { \
123 CHECK(ff_cbs_read_se_golomb(ctx, rw, #name, \
124 SUBSCRIPTS(subs, __VA_ARGS__), \
125 &value, range_min, range_max)); \
130#define infer(name, value) do { \
131 current->name = value; \
134#define more_rbsp_data(var) ((var) = ff_cbs_h2645_read_more_rbsp_data(rw))
136#define bit_position(rw) (get_bits_count(rw))
137#define byte_alignment(rw) (get_bits_count(rw) % 8)
141#define allocate(name, size) do { \
142 name = av_refstruct_allocz(size + \
143 AV_INPUT_BUFFER_PADDING_SIZE); \
145 return AVERROR(ENOMEM); \
148#define FUNC(name) FUNC_SEI_EXPORT(name)
168#define READWRITE write
169#define RWContext PutBitContext
171#define ub(width, name) do { \
172 uint32_t value = current->name; \
173 CHECK(ff_cbs_write_simple_unsigned(ctx, rw, width, #name, \
176#define xu(width, name, var, range_min, range_max, subs, ...) do { \
177 uint32_t value = var; \
178 CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, \
179 SUBSCRIPTS(subs, __VA_ARGS__), \
180 value, range_min, range_max)); \
182#define xue(name, var, range_min, range_max, subs, ...) do { \
183 uint32_t value = var; \
184 CHECK(ff_cbs_write_ue_golomb(ctx, rw, #name, \
185 SUBSCRIPTS(subs, __VA_ARGS__), \
186 value, range_min, range_max)); \
188#define xi(width, name, var, range_min, range_max, subs, ...) do { \
189 int32_t value = var; \
190 CHECK(ff_cbs_write_signed(ctx, rw, width, #name, \
191 SUBSCRIPTS(subs, __VA_ARGS__), \
192 value, range_min, range_max)); \
194#define xse(name, var, range_min, range_max, subs, ...) do { \
195 int32_t value = var; \
196 CHECK(ff_cbs_write_se_golomb(ctx, rw, #name, \
197 SUBSCRIPTS(subs, __VA_ARGS__), \
198 value, range_min, range_max)); \
201#define infer(name, value) do { \
202 if (current->name != (value)) { \
203 av_log(ctx->log_ctx, AV_LOG_ERROR, \
204 "%s does not match inferred value: " \
205 "%"PRId64", but should be %"PRId64".\n", \
206 #name, (int64_t)current->name, (int64_t)(value)); \
207 return AVERROR_INVALIDDATA; \
211#define more_rbsp_data(var) (var)
213#define bit_position(rw) (put_bits_count(rw))
214#define byte_alignment(rw) (put_bits_count(rw) % 8)
216#define allocate(name, size) do { \
218 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s must be set " \
219 "for writing.\n", #name); \
220 return AVERROR_INVALIDDATA; \
224#define FUNC(name) FUNC_SEI_EXPORT(name)
273 int new_count = 2 * old_count + 1;
276 new_count,
sizeof(*list->
messages));
284 memset(list->
messages + old_count, 0,
285 (new_count - old_count) *
sizeof(*list->
messages));
307 int sei_type, highest_vcl_type, err,
i, position;
309 switch (
ctx->codec->codec_id) {
374 err = ff_cbs_insert_unit_content(au, position, sei_type,
378 unit = &au->
units[position];
379 unit->
type = sei_type;
381 err = ff_cbs_alloc_unit_content(
ctx, unit);
385 switch (
ctx->codec->codec_id) {
391 .nal_unit_type = sei_type,
401 .nal_unit_type = sei_type,
403 .nuh_temporal_id_plus1 = 1,
413 .nal_unit_type = sei_type,
415 .nuh_temporal_id_plus1 = 1,
433 switch (
ctx->codec->codec_id) {
439 *list = &
sei->message_list;
448 *list = &
sei->message_list;
457 *list = &
sei->message_list;
470 uint32_t payload_type,
507 message->payload_type = payload_type;
508 message->payload = payload_data;
509 message->payload_ref = payload_ref;
516 uint32_t payload_type,
519 int err,
i, j, found;
533 if (
message->payload_type == payload_type) {
534 if (!*iter || found) {
552 av_assert0(0 <= position && position < list->nb_messages);
569 uint32_t payload_type)
589#define SEI_MESSAGE_RW(codec, name) \
590 .read = cbs_ ## codec ## _read_ ## name ## _internal, \
591 .write = cbs_ ## codec ## _write_ ## name ## _internal
679 switch (
ctx->codec->codec_id) {
#define av_assert0(cond)
assert() equivalent, that is always enabled.
const SEIMessageTypeDescriptor ff_cbs_sei_h264_types[]
#define i(width, name, range_min, range_max)
static int FUNC sei(CodedBitstreamContext *ctx, RWContext *rw, H264RawSEI *current)
const SEIMessageTypeDescriptor ff_cbs_sei_h265_types[]
static void cbs_sei_delete_message(SEIRawMessageList *list, int position)
#define SEI_MESSAGE_RW(codec, name)
void ff_cbs_sei_free_message_list(SEIRawMessageList *list)
Free all SEI messages in a message list.
int ff_cbs_sei_alloc_message_payload(SEIRawMessage *message, const SEIMessageTypeDescriptor *desc)
Allocate a new payload for the given SEI message.
void ff_cbs_sei_delete_message_type(CodedBitstreamContext *ctx, CodedBitstreamFragment *au, uint32_t payload_type)
Delete all messages with the given payload type from an access unit.
static const SEIMessageTypeDescriptor cbs_sei_h274_types[]
static int cbs_sei_get_message_list(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit, SEIRawMessageList **list)
int ff_cbs_sei_list_add(SEIRawMessageList *list)
Allocate a new empty SEI message in a message list.
static void cbs_free_user_data_registered(AVRefStructOpaque unused, void *obj)
static void cbs_free_user_data_unregistered(AVRefStructOpaque unused, void *obj)
int ff_cbs_sei_add_message(CodedBitstreamContext *ctx, CodedBitstreamFragment *au, int prefix, uint32_t payload_type, void *payload_data, void *payload_ref)
Add an SEI message to an access unit.
static int cbs_sei_get_unit(CodedBitstreamContext *ctx, CodedBitstreamFragment *au, int prefix, CodedBitstreamUnit **sei_unit)
const SEIMessageTypeDescriptor * ff_cbs_sei_find_type(CodedBitstreamContext *ctx, int payload_type)
Find the type descriptor for the given payload type.
static const SEIMessageTypeDescriptor cbs_sei_common_types[]
int ff_cbs_sei_find_message(CodedBitstreamContext *ctx, CodedBitstreamFragment *au, uint32_t payload_type, SEIRawMessage **iter)
Iterate over messages with the given payload type in an access unit.
#define SEI_MESSAGE_TYPE_END
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Memory handling functions.
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.
@ SEI_TYPE_DECODED_PICTURE_HASH
@ SEI_TYPE_FILLER_PAYLOAD
@ SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35
@ SEI_TYPE_DISPLAY_ORIENTATION
@ SEI_TYPE_ALTERNATIVE_TRANSFER_CHARACTERISTICS
@ SEI_TYPE_FRAME_PACKING_ARRANGEMENT
@ SEI_TYPE_FRAME_FIELD_INFO
@ SEI_TYPE_USER_DATA_UNREGISTERED
@ SEI_TYPE_FILM_GRAIN_CHARACTERISTICS
@ SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO
@ SEI_TYPE_AMBIENT_VIEWING_ENVIRONMENT
@ SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME
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.
Coded bitstream unit structure.
void * content
Pointer to the decomposed form of this unit.
CodedBitstreamUnitType type
Codec-specific type of this unit.
int nb_messages_allocated
uint8_t * data_ref
RefStruct reference.
uint8_t * data_ref
RefStruct reference.
const FFCodec * codec_list[]
static AVFormatContext * ctx
RefStruct is an API for creating reference-counted objects with minimal overhead.