diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c index cce3f31d4f..615a7cf5ec 100644 --- a/libavcodec/cbs_h2645.c +++ b/libavcodec/cbs_h2645.c @@ -331,6 +331,23 @@ static int cbs_h2645_read_more_rbsp_data(GetBitContext *gbc) #define bit_position(rw) (get_bits_count(rw)) #define byte_alignment(rw) (get_bits_count(rw) % 8) +/* The CBS SEI code uses the refstruct API for the allocation + * of its child buffers. */ +#define allocate(name, size) do { \ + name = ff_refstruct_allocz(size + \ + AV_INPUT_BUFFER_PADDING_SIZE); \ + if (!name) \ + return AVERROR(ENOMEM); \ + } while (0) + +#define FUNC(name) FUNC_SEI(name) +#include "cbs_sei_syntax_template.c" +#undef FUNC + +#undef allocate + +/* The other code uses the refstruct API for the allocation + * of its child buffers. */ #define allocate(name, size) do { \ name ## _ref = av_buffer_allocz(size + \ AV_INPUT_BUFFER_PADDING_SIZE); \ @@ -339,10 +356,6 @@ static int cbs_h2645_read_more_rbsp_data(GetBitContext *gbc) name = name ## _ref->data; \ } while (0) -#define FUNC(name) FUNC_SEI(name) -#include "cbs_sei_syntax_template.c" -#undef FUNC - #define FUNC(name) FUNC_H264(name) #include "cbs_h264_syntax_template.c" #undef FUNC diff --git a/libavcodec/cbs_sei.c b/libavcodec/cbs_sei.c index bd7f6f4938..e28c2f9093 100644 --- a/libavcodec/cbs_sei.c +++ b/libavcodec/cbs_sei.c @@ -22,25 +22,25 @@ #include "cbs_h265.h" #include "cbs_h266.h" #include "cbs_sei.h" +#include "refstruct.h" -static void cbs_free_user_data_registered(void *opaque, uint8_t *data) +static void cbs_free_user_data_registered(FFRefStructOpaque unused, void *obj) { - SEIRawUserDataRegistered *udr = (SEIRawUserDataRegistered*)data; - av_buffer_unref(&udr->data_ref); - av_free(udr); + SEIRawUserDataRegistered *udr = obj; + ff_refstruct_unref(&udr->data); } -static void cbs_free_user_data_unregistered(void *opaque, uint8_t *data) +static void cbs_free_user_data_unregistered(FFRefStructOpaque unused, void *obj) { - SEIRawUserDataUnregistered *udu = (SEIRawUserDataUnregistered*)data; - av_buffer_unref(&udu->data_ref); - av_free(udu); + SEIRawUserDataUnregistered *udu = obj; + ff_refstruct_unref(&udu->data); } int ff_cbs_sei_alloc_message_payload(SEIRawMessage *message, const SEIMessageTypeDescriptor *desc) { - void (*free_func)(void*, uint8_t*); + void (*free_func)(FFRefStructOpaque, void*); + unsigned flags = 0; av_assert0(message->payload == NULL && message->payload_ref == NULL); @@ -50,24 +50,16 @@ int ff_cbs_sei_alloc_message_payload(SEIRawMessage *message, free_func = &cbs_free_user_data_registered; else if (desc->type == SEI_TYPE_USER_DATA_UNREGISTERED) free_func = &cbs_free_user_data_unregistered; - else + else { free_func = NULL; + flags = FF_REFSTRUCT_FLAG_NO_ZEROING; + } - if (free_func) { - message->payload = av_mallocz(desc->size); - if (!message->payload) - return AVERROR(ENOMEM); - message->payload_ref = - av_buffer_create(message->payload, desc->size, - free_func, NULL, 0); - } else { - message->payload_ref = av_buffer_alloc(desc->size); - } - if (!message->payload_ref) { - av_freep(&message->payload); + message->payload_ref = ff_refstruct_alloc_ext(desc->size, flags, + NULL, free_func); + if (!message->payload_ref) return AVERROR(ENOMEM); - } - message->payload = message->payload_ref->data; + message->payload = message->payload_ref; return 0; } @@ -101,8 +93,8 @@ void ff_cbs_sei_free_message_list(SEIRawMessageList *list) { for (int i = 0; i < list->nb_messages; i++) { SEIRawMessage *message = &list->messages[i]; - av_buffer_unref(&message->payload_ref); - av_buffer_unref(&message->extension_data_ref); + ff_refstruct_unref(&message->payload_ref); + ff_refstruct_unref(&message->extension_data); } av_free(list->messages); } @@ -278,13 +270,12 @@ int ff_cbs_sei_add_message(CodedBitstreamContext *ctx, int prefix, uint32_t payload_type, void *payload_data, - AVBufferRef *payload_buf) + void *payload_ref) { const SEIMessageTypeDescriptor *desc; CodedBitstreamUnit *unit; SEIRawMessageList *list; SEIRawMessage *message; - AVBufferRef *payload_ref; int err; desc = ff_cbs_sei_find_type(ctx, payload_type); @@ -306,12 +297,10 @@ int ff_cbs_sei_add_message(CodedBitstreamContext *ctx, if (err < 0) return err; - if (payload_buf) { - payload_ref = av_buffer_ref(payload_buf); - if (!payload_ref) - return AVERROR(ENOMEM); - } else { - payload_ref = NULL; + if (payload_ref) { + /* The following just increments payload_ref's refcount, + * so that payload_ref is now owned by us. */ + payload_ref = ff_refstruct_ref(payload_ref); } message = &list->messages[list->nb_messages - 1]; @@ -364,8 +353,8 @@ static void cbs_sei_delete_message(SEIRawMessageList *list, av_assert0(0 <= position && position < list->nb_messages); message = &list->messages[position]; - av_buffer_unref(&message->payload_ref); - av_buffer_unref(&message->extension_data_ref); + ff_refstruct_unref(&message->payload_ref); + ff_refstruct_unref(&message->extension_data); --list->nb_messages; diff --git a/libavcodec/cbs_sei.h b/libavcodec/cbs_sei.h index 1c327a4689..4511c506cc 100644 --- a/libavcodec/cbs_sei.h +++ b/libavcodec/cbs_sei.h @@ -22,8 +22,6 @@ #include #include -#include "libavutil/buffer.h" - #include "cbs.h" #include "sei.h" @@ -35,15 +33,13 @@ typedef struct SEIRawFillerPayload { typedef struct SEIRawUserDataRegistered { uint8_t itu_t_t35_country_code; uint8_t itu_t_t35_country_code_extension_byte; - uint8_t *data; - AVBufferRef *data_ref; + uint8_t *data; ///< RefStruct reference size_t data_length; } SEIRawUserDataRegistered; typedef struct SEIRawUserDataUnregistered { uint8_t uuid_iso_iec_11578[16]; - uint8_t *data; - AVBufferRef *data_ref; + uint8_t *data; ///< RefStruct reference size_t data_length; } SEIRawUserDataUnregistered; @@ -75,9 +71,8 @@ typedef struct SEIRawMessage { uint32_t payload_type; uint32_t payload_size; void *payload; - AVBufferRef *payload_ref; - uint8_t *extension_data; - AVBufferRef *extension_data_ref; + void *payload_ref; ///< RefStruct reference + uint8_t *extension_data; ///< RefStruct reference size_t extension_bit_length; } SEIRawMessage; @@ -174,15 +169,16 @@ void ff_cbs_sei_free_message_list(SEIRawMessageList *list); * 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. + * If set, payload_ref must be a RefStruct reference backing payload_data. + * This function creates a new reference to payload_ref in this case. + * If payload_ref is NULL, 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); + void *payload_ref); /** * Iterate over messages with the given payload type in an access unit. diff --git a/libavcodec/cbs_sei_syntax_template.c b/libavcodec/cbs_sei_syntax_template.c index 6a7cc36dda..62dd1dabaa 100644 --- a/libavcodec/cbs_sei_syntax_template.c +++ b/libavcodec/cbs_sei_syntax_template.c @@ -234,7 +234,12 @@ static int FUNC(message)(CodedBitstreamContext *ctx, RWContext *rw, } else { uint8_t *data; +#ifdef READ + allocate(current->payload_ref, current->payload_size); + current->payload = current->payload_ref; +#else allocate(current->payload, current->payload_size); +#endif data = current->payload; for (i = 0; i < current->payload_size; i++)