[FFmpeg-devel] [PATCH v4 03/21] cbs: Describe allocate/free methods in tabular form

Andreas Rheinhardt andreas.rheinhardt at gmail.com
Tue Feb 25 00:42:00 EET 2020


Mark Thompson:
> On 24/02/2020 22:10, Andreas Rheinhardt wrote:
>> Mark Thompson:
>>> On 24/02/2020 17:19, Andreas Rheinhardt wrote:
>>>> Mark Thompson:
>>>>> Unit types are split into three categories, depending on how their
>>>>> content is managed:
>>>>> * POD structure - these require no special treatment.
>>>>> * Structure containing references to refcounted buffers - these can use
>>>>>   a common free function when the offsets of all the internal references
>>>>>   are known.
>>>>> * More complex structures - these still require ad-hoc treatment.
>>>>>
>>>>> For each codec we can then maintain a table of descriptors for each set of
>>>>> equivalent unit types, defining the mechanism needed to allocate/free that
>>>>> unit content.  This is not required to be used immediately - a new alloc
>>>>> function supports this, but does not replace the old one which works without
>>>>> referring to these tables.
>>>>> ---
>>>>>  libavcodec/cbs.c          | 69 +++++++++++++++++++++++++++++++++++++++
>>>>>  libavcodec/cbs.h          |  9 +++++
>>>>>  libavcodec/cbs_internal.h | 60 ++++++++++++++++++++++++++++++++++
>>>>>  3 files changed, 138 insertions(+)
>>>>>
>>>>> ...
>>>>> diff --git a/libavcodec/cbs_internal.h b/libavcodec/cbs_internal.h
>>>>> index 4c5a535ca6..615f514a85 100644
>>>>> --- a/libavcodec/cbs_internal.h
>>>>> +++ b/libavcodec/cbs_internal.h
>>>>> @@ -25,11 +25,71 @@
>>>>>  #include "put_bits.h"
>>>>>  
>>>>>  
>>>>> +enum {
>>>>> +    // Unit content is a simple structure.
>>>>> +    CBS_CONTENT_TYPE_POD,
>>>>> +    // Unit content contains some references to other structures, but all
>>>>> +    // managed via buffer reference counting.  The descriptor defines the
>>>>> +    // structure offsets of every buffer reference.
>>>>> +    CBS_CONTENT_TYPE_INTERNAL_REFS,
>>>>> +    // Unit content is something more complex.  The descriptor defines
>>>>> +    // special functions to manage the content.
>>>>> +    CBS_CONTENT_TYPE_COMPLEX,
>>>>> +};
>>>>> +
>>>>> +enum {
>>>>> +      // Maximum number of unit types described by the same unit type
>>>>> +      // descriptor.
>>>>> +      CBS_MAX_UNIT_TYPES = 16,
>>>>
>>>> This is quite big and I wonder whether it would not be better to
>>>> simply split the HEVC-slices into two range descriptors in order to
>>>> reduce this to three.
>>>
>>> As-written, the range case is only covering the one actual range case (MPEG-2 slices).  I think it's preferable to leave the HEVC slice headers as-is, because having the full list there explicitly is much clearer.
>>>
>>> As an alternative, would you prefer the array here to be a pointer + compound literal array?  It would avoid this constant and save few bytes of space on average, at the cost of the definitions being slightly more complex.
>>>
>> No.
>>
>>>>> +      // Maximum number of reference buffer offsets in any one unit.
>>>>> +      CBS_MAX_REF_OFFSETS = 2,
>>>>> +      // Special value used in a unit type descriptor to indicate that it
>>>>> +      // applies to a large range of types rather than a set of discrete
>>>>> +      // values.
>>>>> +      CBS_UNIT_TYPE_RANGE = -1,
>>>>> +};
>>>>> +
>>>>> +typedef struct CodedBitstreamUnitTypeDescriptor {
>>>>> +    // Number of entries in the unit_types array, or the special value
>>>>> +    // CBS_UNIT_TYPE_RANGE to indicate that the range fields should be
>>>>> +    // 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 == 0.
>>>>
>>>> nb_unit_types == 0 is actually used for the sentinel in the
>>>> CodedBitstreamUnitTypeDescriptor-array. nb_unit_types ==
>>>> CBS_UNIT_TYPE_RANGE indicates that this descriptor uses ranges.
>>>
>>> Fixed.
>>>
>>>>> +    const CodedBitstreamUnitType unit_type_range_start;
>>>>> +    const CodedBitstreamUnitType unit_type_range_end;
>>>>
>>>> The ranges could be free (size-wise) if you used a union with unit_types.
>>>
>>> Anonymous unions are still not allowed in FFmpeg, unfortunately (they are C11, though many compilers supported them before that).
>>>
>> What about a non-anonymous union? It would only be used in
>> cbs_find_unit_type_desc().
> 
> Mildly against because it would be ugly to bunch together the unrelated fields, but I could be pushed into it.
> 
>>>>> +
>>>>> +    // The type of content described, from CBS_CONTENT_TYPE_*.
>>>>> +    int    content_type;
>>>>
>>>> Maybe make a proper type out of the CBS_CONTENT_TYPE_*-enum and use it
>>>> here?
>>>
>>> That's a good idea; done.
>>>
>>>>> +    // The size of the structure which should be allocated to contain
>>>>> +    // 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);
>>>>
>>>> Is there a usecase for a dedicated free-function different for a unit
>>>> of type CBS_CONTENT_TYPE_INTERNAL_REFS? If not, then one could use a
>>>> union for this and the ref_offset stuff.
>>>
>>> Yes, but the same anonymous union problem.
>>>
>>>>> +} CodedBitstreamUnitTypeDescriptor;
>>>>
>>>> I wonder whether you should add const to the typedef in order to omit
>>>> it everywhere else. After all, no CodedBitstreamUnitTypeDescriptor
>>>> will ever be assembled during runtime.
>>>
>>> It definitely makes sense to add it to reduce errors.  Not so sure about the removing it from everywhere else - the fact that it looks wrong at the point of use probably causes more confusion.
>>>
>>> So, I've done the first part but not the second (helpfully, redundant type qualifiers have no effect).
>>
>> MSVC emits a warning (or just a note or so) for this.
> Urgh.  Is that definitely intended or is it a bug in the compiler?  The C standard is very clear that this is fine (C11 6.7.3).
> 
This is also the way it is in C99, but given that [1] says that it
leads to an error with MSVC in ANSI-C mode (which means C90), I looked
at C90 and found:
"The same type qualifier shall not appear more than once in the same
specifier list or qualifier list, either directly or via one or more
typedefs."

- Andreas

[1]:
https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-1-c4114?view=vs-2019


More information about the ffmpeg-devel mailing list