[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:10:00 EET 2020
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().
>>> +
>>> + // 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.
- Andreas
More information about the ffmpeg-devel
mailing list