#include <stddef.h>
#include <stdint.h>
+
#include "libavutil/buffer.h"
+#include "cbs.h"
+#include "sei.h"
+
+
+typedef struct SEIRawFillerPayload {
+ uint32_t payload_size;
+} SEIRawFillerPayload;
typedef struct SEIRawUserDataRegistered {
uint8_t itu_t_t35_country_code;
uint8_t preferred_transfer_characteristics;
} SEIRawAlternativeTransferCharacteristics;
+typedef struct SEIRawMessage {
+ uint32_t payload_type;
+ uint32_t payload_size;
+ void *payload;
+ AVBufferRef *payload_ref;
+ uint8_t *extension_data;
+ AVBufferRef *extension_data_ref;
+ size_t extension_bit_length;
+} SEIRawMessage;
+
+typedef struct SEIRawMessageList {
+ SEIRawMessage *messages;
+ int nb_messages;
+ int nb_messages_allocated;
+} SEIRawMessageList;
+
+
+typedef struct SEIMessageState {
+ // The type of the payload being written.
+ uint32_t payload_type;
+ // When reading, contains the size of the payload to allow finding the
+ // end of variable-length fields (such as user_data_payload_byte[]).
+ // (When writing, the size will be derived from the total number of
+ // bytes actually written.)
+ uint32_t payload_size;
+ // When writing, indicates that payload extension data is present so
+ // all extended fields must be written. May be updated by the writer
+ // to indicate that extended fields have been written, so the extension
+ // end bits must be written too.
+ uint8_t extension_present;
+} SEIMessageState;
+
+struct GetBitContext;
+struct PutBitContext;
+
+typedef int (*SEIMessageReadFunction)(CodedBitstreamContext *ctx,
+ struct GetBitContext *rw,
+ void *current,
+ SEIMessageState *sei);
+
+typedef int (*SEIMessageWriteFunction)(CodedBitstreamContext *ctx,
+ struct PutBitContext *rw,
+ void *current,
+ SEIMessageState *sei);
+
+typedef struct SEIMessageTypeDescriptor {
+ // Payload type for the message. (-1 in this field ends a list.)
+ int type;
+ // Valid in a prefix SEI NAL unit (always for H.264).
+ uint8_t prefix;
+ // Valid in a suffix SEI NAL unit (never for H.264).
+ uint8_t suffix;
+ // Size of the decomposed structure.
+ size_t size;
+ // Read bitstream into SEI message.
+ SEIMessageReadFunction read;
+ // Write bitstream from SEI message.
+ SEIMessageWriteFunction write;
+} SEIMessageTypeDescriptor;
+
+// Macro for the read/write pair. The clumsy cast is needed because the
+// current pointer is typed in all of the read/write functions but has to
+// be void here to fit all cases.
+#define SEI_MESSAGE_RW(codec, name) \
+ .read = (SEIMessageReadFunction) cbs_ ## codec ## _read_ ## name, \
+ .write = (SEIMessageWriteFunction)cbs_ ## codec ## _write_ ## name
+
+// End-of-list sentinel element.
+#define SEI_MESSAGE_TYPE_END { .type = -1 }
+
+
+/**
+ * Find the type descriptor for the given payload type.
+ *
+ * Returns NULL if the payload type is not known.
+ */
+const SEIMessageTypeDescriptor *ff_cbs_sei_find_type(CodedBitstreamContext *ctx,
+ int payload_type);
+
+/**
+ * Allocate a new payload for the given SEI message.
+ */
+int ff_cbs_sei_alloc_message_payload(SEIRawMessage *message,
+ const SEIMessageTypeDescriptor *desc);
+
+/**
+ * Allocate a new empty SEI message in a message list.
+ *
+ * The new message is in place nb_messages - 1.
+ */
+int ff_cbs_sei_list_add(SEIRawMessageList *list);
+
+/**
+ * Free all SEI messages in a message list.
+ */
+void ff_cbs_sei_free_message_list(SEIRawMessageList *list);
+
+/**
+ * Add an SEI message to an access unit.
+ *
+ * Will add to an existing SEI NAL unit, or create a new one for the
+ * message if there is no suitable existing one.
+ *
+ * Takes a new reference to payload_buf, if set. If payload_buf is
+ * NULL then the new message will not be reference counted.
+ */
+int ff_cbs_sei_add_message(CodedBitstreamContext *ctx,
+ CodedBitstreamFragment *au,
+ int prefix,
+ uint32_t payload_type,
+ void *payload_data,
+ AVBufferRef *payload_buf);
+
+/**
+ * Iterate over messages with the given payload type in an access unit.
+ *
+ * Set message to NULL in the first call. Returns 0 while more messages
+ * are available, AVERROR(ENOENT) when all messages have been found.
+ */
+int ff_cbs_sei_find_message(CodedBitstreamContext *ctx,
+ CodedBitstreamFragment *au,
+ uint32_t payload_type,
+ SEIRawMessage **message);
+
+/**
+ * Delete all messages with the given payload type from an access unit.
+ */
+void ff_cbs_sei_delete_message_type(CodedBitstreamContext *ctx,
+ CodedBitstreamFragment *au,
+ uint32_t payload_type);
+
#endif /* AVCODEC_CBS_SEI_H */