#include "put_bits.h"
+enum CBSContentType {
+ // 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 = 3,
+ // 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 const 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 is
+ // CBS_UNIT_TYPE_RANGE.
+ const CodedBitstreamUnitType unit_type_range_start;
+ const CodedBitstreamUnitType unit_type_range_end;
+
+ // The type of content described.
+ enum CBSContentType content_type;
+ // 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);
+ int (*content_clone)(AVBufferRef **ref, CodedBitstreamUnit *unit);
+} CodedBitstreamUnitTypeDescriptor;
+
typedef struct CodedBitstreamType {
enum AVCodecID codec_id;
+ // A class for the private data, used to declare private AVOptions.
+ // This field is NULL for types that do not declare any options.
+ // If this field is non-NULL, the first member of the filter private data
+ // must be a pointer to AVClass.
+ const AVClass *priv_class;
+
size_t priv_data_size;
+ // List of unit type descriptors for this codec.
+ // Terminated by a descriptor with nb_unit_types equal to zero.
+ const CodedBitstreamUnitTypeDescriptor *unit_types;
+
// Split frag->data into coded bitstream units, creating the
// frag->units array. Fill data but not content on each unit.
// The header argument should be set if the fragment came from
int (*read_unit)(CodedBitstreamContext *ctx,
CodedBitstreamUnit *unit);
- // Write the unit->data bitstream from unit->content.
+ // Write the data bitstream from unit->content into pbc.
+ // Return value AVERROR(ENOSPC) indicates that pbc was too small.
int (*write_unit)(CodedBitstreamContext *ctx,
- CodedBitstreamUnit *unit);
+ CodedBitstreamUnit *unit,
+ PutBitContext *pbc);
// Read the data from all of frag->units and assemble it into
// a bitstream for the whole fragment.
int (*assemble_fragment)(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag);
+ // Reset the codec internal state.
+ void (*flush)(CodedBitstreamContext *ctx);
+
// Free the codec internal state.
void (*close)(CodedBitstreamContext *ctx);
} CodedBitstreamType;
const int *subscripts, uint32_t value,
uint32_t range_min, uint32_t range_max);
-// The largest value representable in N bits, suitable for use as
+int ff_cbs_read_signed(CodedBitstreamContext *ctx, GetBitContext *gbc,
+ int width, const char *name,
+ const int *subscripts, int32_t *write_to,
+ int32_t range_min, int32_t range_max);
+
+int ff_cbs_write_signed(CodedBitstreamContext *ctx, PutBitContext *pbc,
+ int width, const char *name,
+ const int *subscripts, int32_t value,
+ int32_t range_min, int32_t range_max);
+
+// The largest unsigned value representable in N bits, suitable for use as
// range_max in the above functions.
#define MAX_UINT_BITS(length) ((UINT64_C(1) << (length)) - 1)
-
+// The largest signed value representable in N bits, suitable for use as
+// range_max in the above functions.
+#define MAX_INT_BITS(length) ((INT64_C(1) << ((length) - 1)) - 1)
+
+// The smallest signed value representable in N bits, suitable for use as
+// range_min in the above functions.
+#define MIN_INT_BITS(length) (-(INT64_C(1) << ((length) - 1)))
+
+
+#define CBS_UNIT_TYPE_POD(type, structure) { \
+ .nb_unit_types = 1, \
+ .unit_types = { type }, \
+ .content_type = CBS_CONTENT_TYPE_POD, \
+ .content_size = sizeof(structure), \
+ }
+#define CBS_UNIT_TYPE_INTERNAL_REF(type, structure, ref_field) { \
+ .nb_unit_types = 1, \
+ .unit_types = { type }, \
+ .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, \
+ .content_size = sizeof(structure), \
+ .nb_ref_offsets = 1, \
+ .ref_offsets = { offsetof(structure, ref_field) }, \
+ }
+#define CBS_UNIT_TYPE_COMPLEX(type, structure, free_func) { \
+ .nb_unit_types = 1, \
+ .unit_types = { type }, \
+ .content_type = CBS_CONTENT_TYPE_COMPLEX, \
+ .content_size = sizeof(structure), \
+ .content_free = free_func, \
+ }
+#define CBS_UNIT_TYPE_END_OF_LIST { .nb_unit_types = 0 }
+
+
+extern const CodedBitstreamType ff_cbs_type_av1;
extern const CodedBitstreamType ff_cbs_type_h264;
extern const CodedBitstreamType ff_cbs_type_h265;
+extern const CodedBitstreamType ff_cbs_type_jpeg;
extern const CodedBitstreamType ff_cbs_type_mpeg2;
extern const CodedBitstreamType ff_cbs_type_vp9;