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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user