[FFmpeg-devel] [PATCH v4 03/21] cbs: Describe allocate/free methods in tabular form
Mark Thompson
sw at jkqxz.net
Tue Feb 25 00:31:35 EET 2020
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).
- Mark
More information about the ffmpeg-devel
mailing list