30#define HEADER(name) do { \
31 ff_cbs_trace_header(ctx, name); \
34#define CHECK(call) do { \
40#define FUNC_NAME2(rw, codec, name) cbs_ ## codec ## _ ## rw ## _ ## name
41#define FUNC_NAME1(rw, codec, name) FUNC_NAME2(rw, codec, name)
42#define FUNC_H266(name) FUNC_NAME1(READWRITE, h266, name)
43#define FUNC_NAME2_EXPORT(rw, codec, name) ff_cbs_ ## codec ## _ ## rw ## _ ## name
44#define FUNC_NAME1_EXPORT(rw, codec, name) FUNC_NAME2_EXPORT(rw, codec, name)
45#define FUNC_SEI(name) FUNC_NAME1_EXPORT(READWRITE, sei, name)
47#define SEI_FUNC(name, args) \
48static int FUNC_H266(name) args; \
49static int FUNC_H266(name ## _internal)(CodedBitstreamContext *ctx, \
50 RWContext *rw, void *cur, \
51 SEIMessageState *state) \
53 return FUNC_H266(name)(ctx, rw, cur, state); \
55static int FUNC_H266(name) args
57#define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : NULL)
59#define u(width, name, range_min, range_max) \
60 xu(width, name, current->name, range_min, range_max, 0, )
61#define flag(name) ub(1, name)
62#define ue(name, range_min, range_max) \
63 xue(name, current->name, range_min, range_max, 0, )
64#define i(width, name, range_min, range_max) \
65 xi(width, name, current->name, range_min, range_max, 0, )
66#define ib(width, name) \
67 xi(width, name, current->name, MIN_INT_BITS(width), MAX_INT_BITS(width), 0, )
68#define se(name, range_min, range_max) \
69 xse(name, current->name, range_min, range_max, 0, )
71#define us(width, name, range_min, range_max, subs, ...) \
72 xu(width, name, current->name, range_min, range_max, subs, __VA_ARGS__)
73#define ubs(width, name, subs, ...) \
74 xu(width, name, current->name, 0, MAX_UINT_BITS(width), subs, __VA_ARGS__)
75#define flags(name, subs, ...) \
76 xu(1, name, current->name, 0, 1, subs, __VA_ARGS__)
77#define ues(name, range_min, range_max, subs, ...) \
78 xue(name, current->name, range_min, range_max, subs, __VA_ARGS__)
79#define is(width, name, range_min, range_max, subs, ...) \
80 xi(width, name, current->name, range_min, range_max, subs, __VA_ARGS__)
81#define ibs(width, name, subs, ...) \
82 xi(width, name, current->name, MIN_INT_BITS(width), MAX_INT_BITS(width), subs, __VA_ARGS__)
83#define ses(name, range_min, range_max, subs, ...) \
84 xse(name, current->name, range_min, range_max, subs, __VA_ARGS__)
86#define fixed(width, name, value) do { \
87 av_unused uint32_t fixed_value = value; \
88 xu(width, name, fixed_value, value, value, 0, ); \
94#define RWContext GetBitContext
96#define ub(width, name) do { \
98 CHECK(ff_cbs_read_simple_unsigned(ctx, rw, width, #name, \
100 current->name = value; \
102#define xu(width, name, var, range_min, range_max, subs, ...) do { \
104 CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \
105 SUBSCRIPTS(subs, __VA_ARGS__), \
106 &value, range_min, range_max)); \
109#define xue(name, var, range_min, range_max, subs, ...) do { \
111 CHECK(ff_cbs_read_ue_golomb(ctx, rw, #name, \
112 SUBSCRIPTS(subs, __VA_ARGS__), \
113 &value, range_min, range_max)); \
116#define xi(width, name, var, range_min, range_max, subs, ...) do { \
118 CHECK(ff_cbs_read_signed(ctx, rw, width, #name, \
119 SUBSCRIPTS(subs, __VA_ARGS__), \
120 &value, range_min, range_max)); \
123#define xse(name, var, range_min, range_max, subs, ...) do { \
125 CHECK(ff_cbs_read_se_golomb(ctx, rw, #name, \
126 SUBSCRIPTS(subs, __VA_ARGS__), \
127 &value, range_min, range_max)); \
132#define infer(name, value) do { \
133 current->name = value; \
136#define more_rbsp_data(var) ((var) = ff_cbs_h2645_read_more_rbsp_data(rw))
138#define bit_position(rw) (get_bits_count(rw))
139#define byte_alignment(rw) (get_bits_count(rw) % 8)
141#define allocate(name, size) do { \
142 name ## _ref = av_buffer_allocz(size + \
143 AV_INPUT_BUFFER_PADDING_SIZE); \
145 return AVERROR(ENOMEM); \
146 name = name ## _ref->data; \
149#define FUNC(name) FUNC_H266(name)
167#undef allocate_struct
171#define READWRITE write
172#define RWContext PutBitContext
174#define ub(width, name) do { \
175 uint32_t value = current->name; \
176 CHECK(ff_cbs_write_simple_unsigned(ctx, rw, width, #name, \
179#define xu(width, name, var, range_min, range_max, subs, ...) do { \
180 uint32_t value = var; \
181 CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, \
182 SUBSCRIPTS(subs, __VA_ARGS__), \
183 value, range_min, range_max)); \
185#define xue(name, var, range_min, range_max, subs, ...) do { \
186 uint32_t value = var; \
187 CHECK(ff_cbs_write_ue_golomb(ctx, rw, #name, \
188 SUBSCRIPTS(subs, __VA_ARGS__), \
189 value, range_min, range_max)); \
191#define xi(width, name, var, range_min, range_max, subs, ...) do { \
192 int32_t value = var; \
193 CHECK(ff_cbs_write_signed(ctx, rw, width, #name, \
194 SUBSCRIPTS(subs, __VA_ARGS__), \
195 value, range_min, range_max)); \
197#define xse(name, var, range_min, range_max, subs, ...) do { \
198 int32_t value = var; \
199 CHECK(ff_cbs_write_se_golomb(ctx, rw, #name, \
200 SUBSCRIPTS(subs, __VA_ARGS__), \
201 value, range_min, range_max)); \
204#define infer(name, value) do { \
205 if (current->name != (value)) { \
206 av_log(ctx->log_ctx, AV_LOG_ERROR, \
207 "%s does not match inferred value: " \
208 "%"PRId64", but should be %"PRId64".\n", \
209 #name, (int64_t)current->name, (int64_t)(value)); \
210 return AVERROR_INVALIDDATA; \
214#define more_rbsp_data(var) (var)
216#define bit_position(rw) (put_bits_count(rw))
217#define byte_alignment(rw) (put_bits_count(rw) % 8)
219#define allocate(name, size) do { \
221 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s must be set " \
222 "for writing.\n", #name); \
223 return AVERROR_INVALIDDATA; \
227#define FUNC(name) FUNC_H266(name)
268 int ptl_present_flag, num_arrays;
275 b = bytestream2_get_byte(&gbc);
277 ptl_present_flag =
b & 1;
279 if(ptl_present_flag) {
280 int num_sublayers, num_bytes_constraint_info, num_sub_profiles;
281 num_sublayers = (bytestream2_get_be16u(&gbc) >> 4) & 7;
285 num_bytes_constraint_info = bytestream2_get_byte(&gbc) & 0x3f;
287 if(num_sublayers > 1) {
288 int count_present_flags = 0;
289 b = bytestream2_get_byte(&gbc);
290 for(
i = num_sublayers - 2;
i >= 0;
i--) {
291 if((
b >> (7 - (num_sublayers - 2 -
i))) & 0x01)
292 count_present_flags++;
296 num_sub_profiles = bytestream2_get_byte(&gbc);
303 num_arrays = bytestream2_get_byte(&gbc);
304 for(j = 0; j < num_arrays; j++) {
305 size_t start, end,
size;
306 int nal_unit_type = bytestream2_get_byte(&gbc) & 0x1f;
307 unsigned int num_nalus = 1;
309 num_nalus = bytestream2_get_be16(&gbc);
312 for(
i = 0;
i < num_nalus;
i++) {
315 size = bytestream2_get_be16(&gbc);
323 frag->
data + start, end - start,
328 "VVCC array %d (%d NAL units of type %d).\n",
329 i, num_nalus, nal_unit_type);
356#define cbs_h266_replace_ps(ps_name, ps_var, id_element) \
357static int cbs_h266_replace_ ## ps_var(CodedBitstreamContext *ctx, \
358 CodedBitstreamUnit *unit) \
360 CodedBitstreamH266Context *priv = ctx->priv_data; \
361 H266Raw ## ps_name *ps_var = unit->content; \
362 unsigned int id = ps_var->id_element; \
363 int err = ff_cbs_make_unit_refcounted(ctx, unit); \
366 av_assert0(unit->content_ref); \
367 av_refstruct_replace(&priv->ps_var[id], unit->content_ref); \
379 unsigned int id =
sps->sps_seq_parameter_set_id;
380 int err = ff_cbs_make_unit_refcounted(
ctx, unit);
401 err = ff_cbs_make_unit_refcounted(
ctx, unit);
421 err = ff_cbs_alloc_unit_content(
ctx, unit);
425 switch (unit->
type) {
428 err = cbs_h266_read_dci(
ctx, &gbc, unit->
content);
436 err = cbs_h266_read_opi(
ctx, &gbc, unit->
content);
446 err = cbs_h266_read_vps(
ctx, &gbc,
vps);
450 err = cbs_h266_replace_vps(
ctx, unit);
459 err = cbs_h266_read_sps(
ctx, &gbc,
sps);
463 err = cbs_h266_replace_sps(
ctx, unit);
473 err = cbs_h266_read_pps(
ctx, &gbc,
pps);
477 err = cbs_h266_replace_pps(
ctx, unit);
486 err = cbs_h266_read_aps(
ctx, &gbc, unit->
content,
496 err = cbs_h266_read_ph(
ctx, &gbc,
ph);
517 err = cbs_h266_read_slice_header(
ctx, &gbc, &slice->
header);
535 slice->
ph = h266->
ph;
551 err = cbs_h266_read_aud(
ctx, &gbc, unit->
content);
560 err = cbs_h266_read_sei(
ctx, &gbc, unit->
content,
580 switch (unit->
type) {
585 err = cbs_h266_write_dci(
ctx, pbc,
dci);
594 err = cbs_h266_write_opi(
ctx, pbc,
opi);
603 err = cbs_h266_write_vps(
ctx, pbc,
vps);
607 err = cbs_h266_replace_vps(
ctx, unit);
616 err = cbs_h266_write_sps(
ctx, pbc,
sps);
620 err = cbs_h266_replace_sps(
ctx, unit);
630 err = cbs_h266_write_pps(
ctx, pbc,
pps);
634 err = cbs_h266_replace_pps(
ctx, unit);
643 err = cbs_h266_write_aps(
ctx, pbc, unit->
content,
652 err = cbs_h266_write_ph(
ctx, pbc,
ph);
673 err = cbs_h266_write_slice_header(
ctx, pbc, &slice->
header);
697 err = cbs_h266_write_aud(
ctx, pbc, unit->
content);
706 err = cbs_h266_write_sei(
ctx, pbc, unit->
content,
716 "NAL unit type %"PRIu32
".\n", unit->
type);
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)
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_write_slice_data(CodedBitstreamContext *ctx, PutBitContext *pbc, const uint8_t *data, size_t data_size, int data_bit_start)
int ff_cbs_h2645_read_more_rbsp_data(GetBitContext *gbc)
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)
static int FUNC sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
static int FUNC vps(CodedBitstreamContext *ctx, RWContext *rw, H265RawVPS *current)
static int FUNC extension_data(CodedBitstreamContext *ctx, RWContext *rw, H265RawExtensionData *current)
static CodedBitstreamUnitTypeDescriptor cbs_h266_unit_types[]
static int cbs_h266_replace_ph(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit, H266RawPictureHeader *ph)
static av_cold void cbs_h266_flush(CodedBitstreamContext *ctx)
static int cbs_h266_split_fragment(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, int header)
const CodedBitstreamType ff_cbs_type_h266
static void cbs_h266_free_sei(AVRefStructOpaque unused, void *content)
#define cbs_h266_replace_ps(ps_name, ps_var, id_element)
static int cbs_h266_read_nal_unit(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit)
static int cbs_h266_write_nal_unit(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit, PutBitContext *pbc)
static void cbs_h266_free_slice(AVRefStructOpaque unused, void *content)
static av_cold void cbs_h266_close(CodedBitstreamContext *ctx)
static int FUNC ph(CodedBitstreamContext *ctx, RWContext *rw, H266RawPH *current)
static int FUNC opi(CodedBitstreamContext *ctx, RWContext *rw, H266RawOPI *current)
static int FUNC dci(CodedBitstreamContext *ctx, RWContext *rw, H266RawDCI *current)
#define CBS_UNIT_TYPE_POD(type_, structure)
#define CBS_UNIT_TYPE_END_OF_LIST
#define CBS_UNIT_TYPE_INTERNAL_REF(type, structure, ref_field)
@ CBS_CONTENT_TYPE_INTERNAL_REFS
#define CBS_UNIT_TYPES_COMPLEX(types, structure, free_func)
void ff_cbs_sei_free_message_list(SEIRawMessageList *list)
Free all SEI messages in a message list.
void(* flush)(AVBSFContext *ctx)
bitstream reader API header.
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
static int get_bits_count(const GetBitContext *s)
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
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.
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_replace(void *dstp, const void *src)
Ensure *dstp refers to the same object as src.
void * av_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
static const uint8_t header[24]
#define FF_ARRAY_ELEMS(a)
Context structure for coded bitstream operations.
Coded bitstream fragment structure, combining one or more units.
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.
H266RawSPS * sps[VVC_MAX_SPS_COUNT]
RefStruct references.
void * ph_ref
RefStruct reference backing ph above.
H266RawPPS * pps[VVC_MAX_PPS_COUNT]
RefStruct references.
H266RawPictureHeader * ph
H266RawVPS * vps[VVC_MAX_VPS_COUNT]
RefStruct references.
CodedBitstreamH2645Context common
Coded bitstream unit structure.
void * content
Pointer to the decomposed form of this unit.
void * content_ref
If content is reference counted, a RefStruct reference backing content.
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.
uint8_t pps_seq_parameter_set_id
H266RawExtensionData extension_data
H266RawSliceHeader header
void * ph_ref
RefStruct reference backing referred-to PH above.
H266RawPictureHeader * ph
H266RawPPS * pps
RefStruct reference to referred-to PPS.
H266RawSPS * sps
RefStruct reference to referred-to SPS.
static AVFormatContext * ctx
RefStruct is an API for creating reference-counted objects with minimal overhead.