From 9638f5b1a2369aa8ab32ffb68c928bb5343932fd Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt Date: Thu, 4 Aug 2022 11:02:14 +0200 Subject: avcodec/cbs_internal: Use unions to shrink size of descriptors Signed-off-by: Andreas Rheinhardt --- libavcodec/cbs.c | 26 +++++++++--------- libavcodec/cbs_internal.h | 69 ++++++++++++++++++++++++++--------------------- libavcodec/cbs_mpeg2.c | 10 +++---- 3 files changed, 57 insertions(+), 48 deletions(-) diff --git a/libavcodec/cbs.c b/libavcodec/cbs.c index c81297ec93..57b57238ed 100644 --- a/libavcodec/cbs.c +++ b/libavcodec/cbs.c @@ -857,8 +857,8 @@ static void cbs_default_free_unit_content(void *opaque, uint8_t *data) const CodedBitstreamUnitTypeDescriptor *desc = opaque; if (desc->content_type == CBS_CONTENT_TYPE_INTERNAL_REFS) { int i; - for (i = 0; i < desc->nb_ref_offsets; i++) { - void **ptr = (void**)(data + desc->ref_offsets[i]); + for (i = 0; i < desc->type.ref.nb_offsets; i++) { + void **ptr = (void**)(data + desc->type.ref.offsets[i]); av_buffer_unref((AVBufferRef**)(ptr + 1)); } } @@ -880,12 +880,12 @@ static const CodedBitstreamUnitTypeDescriptor if (desc->nb_unit_types == 0) break; if (desc->nb_unit_types == CBS_UNIT_TYPE_RANGE) { - if (unit->type >= desc->unit_type_range_start && - unit->type <= desc->unit_type_range_end) + if (unit->type >= desc->unit_type.range.start && + unit->type <= desc->unit_type.range.end) return desc; } else { for (j = 0; j < desc->nb_unit_types; j++) { - if (desc->unit_types[j] == unit->type) + if (desc->unit_type.list[j] == unit->type) return desc; } } @@ -910,7 +910,8 @@ int ff_cbs_alloc_unit_content2(CodedBitstreamContext *ctx, unit->content_ref = av_buffer_create(unit->content, desc->content_size, - desc->content_free ? desc->content_free + desc->content_type == CBS_CONTENT_TYPE_COMPLEX + ? desc->type.complex.content_free : cbs_default_free_unit_content, (void*)desc, 0); if (!unit->content_ref) { @@ -936,10 +937,10 @@ static int cbs_clone_internal_refs_unit_content(AVBufferRef **clone_ref, if (!copy) return AVERROR(ENOMEM); - for (i = 0; i < desc->nb_ref_offsets; i++) { - const uint8_t *const *src_ptr = (const uint8_t* const*)(src + desc->ref_offsets[i]); + for (i = 0; i < desc->type.ref.nb_offsets; i++) { + const uint8_t *const *src_ptr = (const uint8_t* const*)(src + desc->type.ref.offsets[i]); const AVBufferRef *src_buf = *(AVBufferRef**)(src_ptr + 1); - uint8_t **copy_ptr = (uint8_t**)(copy + desc->ref_offsets[i]); + uint8_t **copy_ptr = (uint8_t**)(copy + desc->type.ref.offsets[i]); AVBufferRef **copy_buf = (AVBufferRef**)(copy_ptr + 1); if (!*src_ptr) { @@ -962,7 +963,6 @@ static int cbs_clone_internal_refs_unit_content(AVBufferRef **clone_ref, } *clone_ref = av_buffer_create(copy, desc->content_size, - desc->content_free ? desc->content_free : cbs_default_free_unit_content, (void*)desc, 0); if (!*clone_ref) { @@ -974,7 +974,7 @@ static int cbs_clone_internal_refs_unit_content(AVBufferRef **clone_ref, fail: for (--i; i >= 0; i--) - av_buffer_unref((AVBufferRef**)(copy + desc->ref_offsets[i])); + av_buffer_unref((AVBufferRef**)(copy + desc->type.ref.offsets[i])); av_freep(©); *clone_ref = NULL; return err; @@ -1010,9 +1010,9 @@ static int cbs_clone_unit_content(CodedBitstreamContext *ctx, break; case CBS_CONTENT_TYPE_COMPLEX: - if (!desc->content_clone) + if (!desc->type.complex.content_clone) return AVERROR_PATCHWELCOME; - err = desc->content_clone(&ref, unit); + err = desc->type.complex.content_clone(&ref, unit); break; default: diff --git a/libavcodec/cbs_internal.h b/libavcodec/cbs_internal.h index 314d54daea..4030b76f1c 100644 --- a/libavcodec/cbs_internal.h +++ b/libavcodec/cbs_internal.h @@ -60,13 +60,16 @@ typedef const struct CodedBitstreamUnitTypeDescriptor { // used instead. int nb_unit_types; - // Array of unit types that this entry describes. - const CodedBitstreamUnitType unit_types[CBS_MAX_UNIT_TYPES]; - - // Start and end of unit type range, used if nb_unit_types is - // CBS_UNIT_TYPE_RANGE. - const CodedBitstreamUnitType unit_type_range_start; - const CodedBitstreamUnitType unit_type_range_end; + union { + // Array of unit types that this entry describes. + CodedBitstreamUnitType list[CBS_MAX_UNIT_TYPES]; + // Start and end of unit type range, used if nb_unit_types is + // CBS_UNIT_TYPE_RANGE. + struct { + CodedBitstreamUnitType start; + CodedBitstreamUnitType end; + } range; + } unit_type; // The type of content described. enum CBSContentType content_type; @@ -74,18 +77,24 @@ typedef const struct CodedBitstreamUnitTypeDescriptor { // the decomposed content of this type of unit. size_t content_size; - // Number of entries in the ref_offsets array. Only used if the - // content_type is CBS_CONTENT_TYPE_INTERNAL_REFS. - int nb_ref_offsets; - // The structure must contain two adjacent elements: - // type *field; - // AVBufferRef *field_ref; - // where field points to something in the buffer referred to by - // field_ref. This offset is then set to offsetof(struct, field). - size_t ref_offsets[CBS_MAX_REF_OFFSETS]; - - void (*content_free)(void *opaque, uint8_t *data); - int (*content_clone)(AVBufferRef **ref, CodedBitstreamUnit *unit); + union { + struct { + // Number of entries in the ref_offsets array. Only nonzero + // if the content_type is CBS_CONTENT_TYPE_INTERNAL_REFS. + int nb_offsets; + // The structure must contain two adjacent elements: + // type *field; + // AVBufferRef *field_ref; + // where field points to something in the buffer referred to by + // field_ref. This offset is then set to offsetof(struct, field). + size_t offsets[CBS_MAX_REF_OFFSETS]; + } ref; + + struct { + void (*content_free)(void *opaque, uint8_t *data); + int (*content_clone)(AVBufferRef **ref, CodedBitstreamUnit *unit); + } complex; + } type; } CodedBitstreamUnitTypeDescriptor; typedef struct CodedBitstreamType { @@ -184,38 +193,38 @@ int ff_cbs_write_signed(CodedBitstreamContext *ctx, PutBitContext *pbc, #define TYPE_LIST(...) { __VA_ARGS__ } #define CBS_UNIT_TYPE_POD(type, structure) { \ .nb_unit_types = 1, \ - .unit_types = { type }, \ + .unit_type.list = { type }, \ .content_type = CBS_CONTENT_TYPE_POD, \ .content_size = sizeof(structure), \ } #define CBS_UNIT_TYPES_INTERNAL_REF(types, structure, ref_field) { \ .nb_unit_types = FF_ARRAY_ELEMS((CodedBitstreamUnitType[])TYPE_LIST types), \ - .unit_types = TYPE_LIST types, \ + .unit_type.list = TYPE_LIST types, \ .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, \ .content_size = sizeof(structure), \ - .nb_ref_offsets = 1, \ - .ref_offsets = { offsetof(structure, ref_field) }, \ + .type.ref = { .nb_offsets = 1, \ + .offsets = { offsetof(structure, ref_field) } }, \ } #define CBS_UNIT_TYPE_INTERNAL_REF(type, structure, ref_field) \ CBS_UNIT_TYPES_INTERNAL_REF((type), structure, ref_field) #define CBS_UNIT_RANGE_INTERNAL_REF(range_start, range_end, structure, ref_field) { \ - .nb_unit_types = CBS_UNIT_TYPE_RANGE, \ - .unit_type_range_start = range_start, \ - .unit_type_range_end = range_end, \ + .nb_unit_types = CBS_UNIT_TYPE_RANGE, \ + .unit_type.range.start = range_start, \ + .unit_type.range.end = range_end, \ .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, \ .content_size = sizeof(structure), \ - .nb_ref_offsets = 1, \ - .ref_offsets = { offsetof(structure, ref_field) }, \ + .type.ref = { .nb_offsets = 1, \ + .offsets = { offsetof(structure, ref_field) } }, \ } #define CBS_UNIT_TYPES_COMPLEX(types, structure, free_func) { \ .nb_unit_types = FF_ARRAY_ELEMS((CodedBitstreamUnitType[])TYPE_LIST types), \ - .unit_types = TYPE_LIST types, \ + .unit_type.list = TYPE_LIST types, \ .content_type = CBS_CONTENT_TYPE_COMPLEX, \ .content_size = sizeof(structure), \ - .content_free = free_func, \ + .type.complex = { .content_free = free_func }, \ } #define CBS_UNIT_TYPE_COMPLEX(type, structure, free_func) \ CBS_UNIT_TYPES_COMPLEX((type), structure, free_func) diff --git a/libavcodec/cbs_mpeg2.c b/libavcodec/cbs_mpeg2.c index 33bd3e0998..1c9519cdaf 100644 --- a/libavcodec/cbs_mpeg2.c +++ b/libavcodec/cbs_mpeg2.c @@ -392,14 +392,14 @@ static const CodedBitstreamUnitTypeDescriptor cbs_mpeg2_unit_types[] = { { .nb_unit_types = CBS_UNIT_TYPE_RANGE, - .unit_type_range_start = 0x01, - .unit_type_range_end = 0xaf, + .unit_type.range.start = 0x01, + .unit_type.range.end = 0xaf, .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, .content_size = sizeof(MPEG2RawSlice), - .nb_ref_offsets = 2, - .ref_offsets = { offsetof(MPEG2RawSlice, header.extra_information_slice.extra_information), - offsetof(MPEG2RawSlice, data) }, + .type.ref = { .nb_offsets = 2, + .offsets = { offsetof(MPEG2RawSlice, header.extra_information_slice.extra_information), + offsetof(MPEG2RawSlice, data) } }, }, CBS_UNIT_TYPE_INTERNAL_REF(MPEG2_START_USER_DATA, MPEG2RawUserData, -- cgit v1.2.3