aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec
diff options
context:
space:
mode:
authorJames Almer <jamrial@gmail.com>2023-07-16 15:03:49 -0300
committerJames Almer <jamrial@gmail.com>2023-10-06 09:53:22 -0300
commit74279227dd28d01b447edb8e617a545982171c2c (patch)
tree81b53f9feb0fe69777b3ab6a0959441d27d7db7b /libavcodec
parentf62c441e7a36629d7272524237d9358e76854091 (diff)
downloadffmpeg-74279227dd28d01b447edb8e617a545982171c2c.tar.gz
avcodec/packet: add generic side data helpers
Handling AVPacketSideData directly, which can used on structs other than AVPacket. This will be useful in the following commits. Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/avpacket.c100
-rw-r--r--libavcodec/packet.h96
-rw-r--r--libavcodec/version.h2
3 files changed, 193 insertions, 5 deletions
diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
index 9ec1feb068..e29725c2d2 100644
--- a/libavcodec/avpacket.c
+++ b/libavcodec/avpacket.c
@@ -646,3 +646,103 @@ 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 == 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;
+ uint8_t *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;
+ memset(data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+
+ 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 {
@@ -319,6 +319,96 @@ typedef struct AVPacketSideData {
} 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
* then passed to muxers.
@@ -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.
*
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 87b7284a95..5183deb68b 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,7 +29,7 @@
#include "version_major.h"
-#define LIBAVCODEC_VERSION_MINOR 28
+#define LIBAVCODEC_VERSION_MINOR 29
#define LIBAVCODEC_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \