[FFmpeg-cvslog] avcodec/packet: add generic side data helpers

James Almer git at videolan.org
Fri Oct 6 16:11:17 EEST 2023


ffmpeg | branch: master | James Almer <jamrial at gmail.com> | Sun Jul 16 15:03:49 2023 -0300| [74279227dd28d01b447edb8e617a545982171c2c] | committer: James Almer

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 at gmail.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=74279227dd28d01b447edb8e617a545982171c2c
---

 doc/APIchanges        |   5 +++
 libavcodec/avpacket.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++
 libavcodec/packet.h   |  96 ++++++++++++++++++++++++++++++++++++++++++++++--
 libavcodec/version.h  |   2 +-
 4 files changed, 198 insertions(+), 5 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index e15c715ce1..68a31726de 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -2,6 +2,11 @@ The last version increases of all libraries were on 2023-02-09
 
 API changes, most recent first:
 
+2023-10-06 - xxxxxxxxxx - lavc 60.29.100 - packet.h
+  Added av_packet_side_data_new(), av_packet_side_data_add(),
+  av_packet_side_data_get(), av_packet_side_data_remove, and
+  av_packet_side_data_free().
+
 2023-10-03 - xxxxxxxxxx - lavc 60.28.100 - codec_par.h defs.h
   Move the definition of enum AVFieldOrder from codec_par.h to defs.h.
 
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 {
@@ -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.
  *
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, \



More information about the ffmpeg-cvslog mailing list