[FFmpeg-cvslog] avcodec/cbs_internal: Use unions to shrink size of descriptors

Andreas Rheinhardt git at videolan.org
Mon Aug 8 12:45:30 EEST 2022


ffmpeg | branch: master | Andreas Rheinhardt <andreas.rheinhardt at outlook.com> | Thu Aug  4 11:02:14 2022 +0200| [9638f5b1a2369aa8ab32ffb68c928bb5343932fd] | committer: Andreas Rheinhardt

avcodec/cbs_internal: Use unions to shrink size of descriptors

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=9638f5b1a2369aa8ab32ffb68c928bb5343932fd
---

 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(&copy);
     *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,



More information about the ffmpeg-cvslog mailing list