aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/avpacket.c
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/avpacket.c
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/avpacket.c')
-rw-r--r--libavcodec/avpacket.c100
1 files changed, 100 insertions, 0 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;
+}