mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
avpacket: add pack/unpack functions for AVDictionary
These functions are intended for use with side_data which comes in an AVPacket. Signed-off-by: Ben Boeckel <mathstuf@gmail.com> Reviewed-by: wm4 Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
1e506a2cc5
commit
51a84a6bca
@ -3587,6 +3587,24 @@ int av_packet_merge_side_data(AVPacket *pkt);
|
||||
|
||||
int av_packet_split_side_data(AVPacket *pkt);
|
||||
|
||||
/**
|
||||
* Pack a dictionary for use in side_data.
|
||||
*
|
||||
* @param dict The dictionary to pack.
|
||||
* @param size pointer to store the size of the returned data
|
||||
* @return pointer to data if successful, NULL otherwise
|
||||
*/
|
||||
uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size);
|
||||
/**
|
||||
* Unpack a dictionary from side_data.
|
||||
*
|
||||
* @param data data from side_data
|
||||
* @param size size of the data
|
||||
* @param dict the metadata storage dictionary
|
||||
* @return 0 on success, < 0 on failure
|
||||
*/
|
||||
int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict);
|
||||
|
||||
|
||||
/**
|
||||
* Convenience function to free all the side data stored.
|
||||
|
@ -427,6 +427,64 @@ int av_packet_split_side_data(AVPacket *pkt){
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size)
|
||||
{
|
||||
AVDictionaryEntry *t = NULL;
|
||||
uint8_t *data = NULL;
|
||||
*size = 0;
|
||||
|
||||
if (!dict)
|
||||
return NULL;
|
||||
|
||||
while ((t = av_dict_get(dict, "", t, AV_DICT_IGNORE_SUFFIX))) {
|
||||
const int keylen = strlen(t->key);
|
||||
const int valuelen = strlen(t->value);
|
||||
const size_t new_size = *size + keylen + 1 + valuelen + 1;
|
||||
uint8_t *const new_data = av_realloc(data, new_size);
|
||||
|
||||
if (!new_data)
|
||||
goto fail;
|
||||
data = new_data;
|
||||
|
||||
memcpy(data + *size, t->key, keylen + 1);
|
||||
memcpy(data + *size + keylen + 1, t->value, valuelen + 1);
|
||||
|
||||
*size = new_size;
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
fail:
|
||||
av_freep(&data);
|
||||
*size = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict)
|
||||
{
|
||||
const uint8_t *end = data + size;
|
||||
int ret = 0;
|
||||
|
||||
if (!dict || !data || !size)
|
||||
return ret;
|
||||
if (size && end[-1])
|
||||
return AVERROR_INVALIDDATA;
|
||||
while (data < end) {
|
||||
const uint8_t *key = data;
|
||||
const uint8_t *val = data + strlen(key) + 1;
|
||||
|
||||
if (val >= end)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
ret = av_dict_set(dict, key, val, 0);
|
||||
if (ret < 0)
|
||||
break;
|
||||
data = val + strlen(val) + 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
|
||||
int size)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user