Handling AVPacketSideData directly, which can used on structs other than AVPacket. This will be useful in the following commits.
Signed-off-by: James Almer <jamr...@gmail.com> --- libavcodec/avpacket.c | 99 +++++++++++++++++++++++++++++++++++++++++++ libavcodec/packet.h | 96 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 191 insertions(+), 4 deletions(-) diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index 9ec1feb068..750a17de48 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -646,3 +646,102 @@ int ff_side_data_set_prft(AVPacket *pkt, int64_t timestamp) return 0; } + +const AVPacketSideData *av_packet_side_data_get(const AVPacketSideData *sd, int nb_sd, + enum AVPacketSideDataType type) +{ + for (int i = 0; i < nb_sd; i++) + if (sd[i].type == type) + return &sd[i]; + + return NULL; +} + +static AVPacketSideData *packet_side_data_add(AVPacketSideData **psd, int *pnb_sd, + enum AVPacketSideDataType type, + void *data, size_t size) +{ + AVPacketSideData *sd = *psd, *tmp; + int nb_sd = *pnb_sd; + + for (int i = 0; i < nb_sd; i++) { + if (sd[i].type != type) + continue; + + av_free(sd[i].data); + sd[i].data = data; + sd[i].size = size; + return &sd[i]; + } + + if (nb_sd + 1U > INT_MAX) + return NULL; + + tmp = av_realloc_array(sd, nb_sd + 1, sizeof(*tmp)); + if (!tmp) + return NULL; + + *psd = sd = tmp; + sd[nb_sd].type = type; + sd[nb_sd].data = data; + sd[nb_sd].size = size; + *pnb_sd = nb_sd + 1; + + return &sd[nb_sd]; +} + +AVPacketSideData *av_packet_side_data_add(AVPacketSideData **psd, int *pnb_sd, + enum AVPacketSideDataType type, + void *data, size_t size, int flags) +{ + return packet_side_data_add(psd, pnb_sd, type, data, size); +} + +AVPacketSideData *av_packet_side_data_new(AVPacketSideData **psd, int *pnb_sd, + enum AVPacketSideDataType type, + size_t size, int flags) +{ + AVPacketSideData *sd = NULL; + void *data; + + if (size > SIZE_MAX - AV_INPUT_BUFFER_PADDING_SIZE) + return NULL; + + data = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!data) + return NULL; + + sd = packet_side_data_add(psd, pnb_sd, type, data, size); + if (!sd) + av_freep(&data); + + return sd; +} + +void av_packet_side_data_remove(AVPacketSideData *sd, int *pnb_sd, + enum AVPacketSideDataType type) +{ + int nb_sd = *pnb_sd; + + for (int i = nb_sd - 1; i >= 0; i--) { + if (sd[i].type != type) + continue; + av_free(sd[i].data); + sd[i] = sd[--nb_sd]; + break; + } + + *pnb_sd = nb_sd; +} + +void av_packet_side_data_free(AVPacketSideData **psd, int *pnb_sd) +{ + AVPacketSideData *sd = *psd; + int nb_sd = *pnb_sd; + + for (int i = 0; i < nb_sd; i++) + av_free(sd[i].data); + + av_freep(psd); + *pnb_sd = 0; +} diff --git a/libavcodec/packet.h b/libavcodec/packet.h index f28e7e7011..96fc0084d6 100644 --- a/libavcodec/packet.h +++ b/libavcodec/packet.h @@ -33,9 +33,9 @@ #include "libavcodec/version_major.h" /** - * @defgroup lavc_packet AVPacket + * @defgroup lavc_packet_side_data AVPacketSideData * - * Types and functions for working with AVPacket. + * Types and functions for working with AVPacketSideData. * @{ */ enum AVPacketSideDataType { @@ -318,6 +318,96 @@ typedef struct AVPacketSideData { enum AVPacketSideDataType type; } AVPacketSideData; +/** + * Allocate a new packet side data. + * + * @param sd pointer to an array of side data to which the side data should + * be added. *sd may be NULL, in which case the array will be + * initialized. + * @param nb_sd pointer to an integer containing the number of entries in + * the array. The integer value will be increased by 1 on success. + * @param type side data type + * @param size desired side data size + * @param flags currently unused. Must be zero + * + * @return pointer to freshly allocated side data on success, or NULL otherwise. + */ +AVPacketSideData *av_packet_side_data_new(AVPacketSideData **psd, int *pnb_sd, + enum AVPacketSideDataType type, + size_t size, int flags); + +/** + * Wrap existing data as packet side data. + * + * @param sd pointer to an array of side data to which the side data should + * be added. *sd may be NULL, in which case the array will be + * initialized + * @param nb_sd pointer to an integer containing the number of entries in + * the array. The integer value will be increased by 1 on success. + * @param type side data type + * @param data a data array. It must be allocated with the av_malloc() family + * of functions. The ownership of the data is transferred to the + * side data array on success + * @param size size of the data array + * @param flags currently unused. Must be zero + * + * @return pointer to freshly allocated side data on success, or NULL otherwise + * On failure, the side data array is unchanged and the data remains + * owned by the caller. + */ +AVPacketSideData *av_packet_side_data_add(AVPacketSideData **sd, int *nb_sd, + enum AVPacketSideDataType type, + void *data, size_t size, int flags); + +/** + * Get side information from a side data array. + * + * @param sd the array from which the side data should be fetched + * @param nb_sd value containing the number of entries in the array. + * @param type desired side information type + * + * @return pointer to side data if present or NULL otherwise + */ +const AVPacketSideData *av_packet_side_data_get(const AVPacketSideData *sd, + int nb_sd, + enum AVPacketSideDataType type); + +/** + * Remove side data of the given type from a side data array. + * + * @param sd the array from which the side data should be removed + * @param nb_sd pointer to an integer containing the number of entries in + * the array. Will be reduced by the amount of entries removed + * upon return + * @param type side information type + */ +void av_packet_side_data_remove(AVPacketSideData *sd, int *nb_sd, + enum AVPacketSideDataType type); + +/** + * Convenience function to free all the side data stored in an array, and + * the array itself. + * + * @param sd pointer to array of side data to free. Will be set to NULL + * upon return. + * @param nb_sd pointer to an integer containing the number of entries in + * the array. Will be set to 0 upon return. + */ +void av_packet_side_data_free(AVPacketSideData **sd, int *nb_sd); + +const char *av_packet_side_data_name(enum AVPacketSideDataType type); + +/** + * @} + */ + +/** + * @defgroup lavc_packet AVPacket + * + * Types and functions for working with AVPacket. + * @{ + */ + /** * This structure stores compressed data. It is typically exported by demuxers * and then passed as input to decoders, or received as output from encoders and @@ -603,8 +693,6 @@ int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t* av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, size_t *size); -const char *av_packet_side_data_name(enum AVPacketSideDataType type); - /** * Pack a dictionary for use in side_data. * -- 2.42.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".