Rename it to AVDictionary, since it will be used as such. Tags documentation and metadata conversion API is lavf-specific, so remains there.tags/n0.8
@@ -13,6 +13,11 @@ libavutil: 2011-04-18 | |||
API changes, most recent first: | |||
2011-06-xx - xxxxxxx - lavu 51.5.0 - AVMetadata | |||
Move AVMetadata from lavf to lavu and rename it to | |||
AVDictionary -- new installed header dict.h. | |||
All av_metadata_* functions renamed to av_dict_*. | |||
2011-06-07 - a6703fa - lavu 51.4.0 - av_get_bytes_per_sample() | |||
Add av_get_bytes_per_sample() in libavutil/samplefmt.h. | |||
Deprecate av_get_bits_per_sample_fmt(). | |||
@@ -40,6 +40,7 @@ const char *avformat_license(void); | |||
#include <time.h> | |||
#include <stdio.h> /* FILE */ | |||
#include "libavcodec/avcodec.h" | |||
#include "libavutil/dict.h" | |||
#include "avio.h" | |||
#include "libavformat/version.h" | |||
@@ -106,21 +107,24 @@ struct AVFormatContext; | |||
* variant_bitrate -- the total bitrate of the bitrate variant that the current stream is part of | |||
*/ | |||
#define AV_METADATA_MATCH_CASE 1 | |||
#define AV_METADATA_IGNORE_SUFFIX 2 | |||
#define AV_METADATA_DONT_STRDUP_KEY 4 | |||
#define AV_METADATA_DONT_STRDUP_VAL 8 | |||
#define AV_METADATA_DONT_OVERWRITE 16 ///< Don't overwrite existing tags. | |||
#if FF_API_OLD_METADATA2 | |||
/** | |||
* @defgroup old_metadata Old metadata API | |||
* The following functions are deprecated, use | |||
* their equivalents from libavutil/dict.h instead. | |||
* @{ | |||
*/ | |||
typedef struct { | |||
char *key; | |||
char *value; | |||
}AVMetadataTag; | |||
#define AV_METADATA_MATCH_CASE AV_DICT_MATCH_CASE | |||
#define AV_METADATA_IGNORE_SUFFIX AV_DICT_IGNORE_SUFFIX | |||
#define AV_METADATA_DONT_STRDUP_KEY AV_DICT_DONT_STRDUP_KEY | |||
#define AV_METADATA_DONT_STRDUP_VAL AV_DICT_DONT_STRDUP_VAL | |||
#define AV_METADATA_DONT_OVERWRITE AV_DICT_DONT_OVERWRITE | |||
typedef attribute_deprecated AVDictionary AVMetadata; | |||
typedef attribute_deprecated AVDictionaryEntry AVMetadataTag; | |||
typedef struct AVMetadata AVMetadata; | |||
#if FF_API_OLD_METADATA2 | |||
typedef struct AVMetadataConv AVMetadataConv; | |||
#endif | |||
/** | |||
* Get a metadata element with matching key. | |||
@@ -130,8 +134,8 @@ typedef struct AVMetadataConv AVMetadataConv; | |||
* @param flags Allows case as well as suffix-insensitive comparisons. | |||
* @return Found tag or NULL, changing key or value leads to undefined behavior. | |||
*/ | |||
AVMetadataTag * | |||
av_metadata_get(AVMetadata *m, const char *key, const AVMetadataTag *prev, int flags); | |||
attribute_deprecated AVDictionaryEntry * | |||
av_metadata_get(AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags); | |||
/** | |||
* Set the given tag in *pm, overwriting an existing tag. | |||
@@ -143,30 +147,32 @@ av_metadata_get(AVMetadata *m, const char *key, const AVMetadataTag *prev, int f | |||
* Passing a NULL value will cause an existing tag to be deleted. | |||
* @return >= 0 on success otherwise an error code <0 | |||
*/ | |||
int av_metadata_set2(AVMetadata **pm, const char *key, const char *value, int flags); | |||
attribute_deprecated int av_metadata_set2(AVDictionary **pm, const char *key, const char *value, int flags); | |||
#if FF_API_OLD_METADATA2 | |||
/** | |||
* This function is provided for compatibility reason and currently does nothing. | |||
*/ | |||
attribute_deprecated void av_metadata_conv(struct AVFormatContext *ctx, const AVMetadataConv *d_conv, | |||
const AVMetadataConv *s_conv); | |||
#endif | |||
/** | |||
* Copy metadata from one AVMetadata struct into another. | |||
* @param dst pointer to a pointer to a AVMetadata struct. If *dst is NULL, | |||
* Copy metadata from one AVDictionary struct into another. | |||
* @param dst pointer to a pointer to a AVDictionary struct. If *dst is NULL, | |||
* this function will allocate a struct for you and put it in *dst | |||
* @param src pointer to source AVMetadata struct | |||
* @param src pointer to source AVDictionary struct | |||
* @param flags flags to use when setting metadata in *dst | |||
* @note metadata is read using the AV_METADATA_IGNORE_SUFFIX flag | |||
*/ | |||
void av_metadata_copy(AVMetadata **dst, AVMetadata *src, int flags); | |||
attribute_deprecated void av_metadata_copy(AVDictionary **dst, AVDictionary *src, int flags); | |||
/** | |||
* Free all the memory allocated for an AVMetadata struct. | |||
* Free all the memory allocated for an AVDictionary struct. | |||
*/ | |||
void av_metadata_free(AVMetadata **m); | |||
attribute_deprecated void av_metadata_free(AVDictionary **m); | |||
/** | |||
* @} | |||
*/ | |||
#endif | |||
/* packet functions */ | |||
@@ -21,107 +21,51 @@ | |||
#include <strings.h> | |||
#include "avformat.h" | |||
#include "metadata.h" | |||
#include "libavutil/dict.h" | |||
AVMetadataTag * | |||
av_metadata_get(AVMetadata *m, const char *key, const AVMetadataTag *prev, int flags) | |||
#if FF_API_OLD_METADATA2 | |||
AVDictionaryEntry * | |||
av_metadata_get(AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags) | |||
{ | |||
unsigned int i, j; | |||
if(!m) | |||
return NULL; | |||
if(prev) i= prev - m->elems + 1; | |||
else i= 0; | |||
for(; i<m->count; i++){ | |||
const char *s= m->elems[i].key; | |||
if(flags & AV_METADATA_MATCH_CASE) for(j=0; s[j] == key[j] && key[j]; j++); | |||
else for(j=0; toupper(s[j]) == toupper(key[j]) && key[j]; j++); | |||
if(key[j]) | |||
continue; | |||
if(s[j] && !(flags & AV_METADATA_IGNORE_SUFFIX)) | |||
continue; | |||
return &m->elems[i]; | |||
} | |||
return NULL; | |||
return av_dict_get(m, key, prev, flags); | |||
} | |||
int av_metadata_set2(AVMetadata **pm, const char *key, const char *value, int flags) | |||
int av_metadata_set2(AVDictionary **pm, const char *key, const char *value, int flags) | |||
{ | |||
AVMetadata *m= *pm; | |||
AVMetadataTag *tag= av_metadata_get(m, key, NULL, flags); | |||
if(!m) | |||
m=*pm= av_mallocz(sizeof(*m)); | |||
if(tag){ | |||
if (flags & AV_METADATA_DONT_OVERWRITE) | |||
return 0; | |||
av_free(tag->value); | |||
av_free(tag->key); | |||
*tag= m->elems[--m->count]; | |||
}else{ | |||
AVMetadataTag *tmp= av_realloc(m->elems, (m->count+1) * sizeof(*m->elems)); | |||
if(tmp){ | |||
m->elems= tmp; | |||
}else | |||
return AVERROR(ENOMEM); | |||
} | |||
if(value){ | |||
if(flags & AV_METADATA_DONT_STRDUP_KEY){ | |||
m->elems[m->count].key = key; | |||
}else | |||
m->elems[m->count].key = av_strdup(key ); | |||
if(flags & AV_METADATA_DONT_STRDUP_VAL){ | |||
m->elems[m->count].value= value; | |||
}else | |||
m->elems[m->count].value= av_strdup(value); | |||
m->count++; | |||
} | |||
if(!m->count) { | |||
av_free(m->elems); | |||
av_freep(pm); | |||
} | |||
return 0; | |||
return av_dict_set(pm, key, value, flags); | |||
} | |||
#if FF_API_OLD_METADATA2 | |||
void av_metadata_conv(AVFormatContext *ctx, const AVMetadataConv *d_conv, | |||
const AVMetadataConv *s_conv) | |||
{ | |||
return; | |||
} | |||
#endif | |||
void av_metadata_free(AVMetadata **pm) | |||
void av_metadata_free(AVDictionary **pm) | |||
{ | |||
AVMetadata *m= *pm; | |||
av_dict_free(pm); | |||
} | |||
if(m){ | |||
while(m->count--){ | |||
av_free(m->elems[m->count].key); | |||
av_free(m->elems[m->count].value); | |||
} | |||
av_free(m->elems); | |||
} | |||
av_freep(pm); | |||
void av_metadata_copy(AVDictionary **dst, AVDictionary *src, int flags) | |||
{ | |||
av_dict_copy(dst, src, flags); | |||
} | |||
#endif | |||
void ff_metadata_conv(AVMetadata **pm, const AVMetadataConv *d_conv, | |||
void ff_metadata_conv(AVDictionary **pm, const AVMetadataConv *d_conv, | |||
const AVMetadataConv *s_conv) | |||
{ | |||
/* TODO: use binary search to look up the two conversion tables | |||
if the tables are getting big enough that it would matter speed wise */ | |||
const AVMetadataConv *sc, *dc; | |||
AVMetadataTag *mtag = NULL; | |||
AVMetadata *dst = NULL; | |||
AVDictionaryEntry *mtag = NULL; | |||
AVDictionary *dst = NULL; | |||
const char *key; | |||
if (d_conv == s_conv) | |||
return; | |||
while((mtag=av_metadata_get(*pm, "", mtag, AV_METADATA_IGNORE_SUFFIX))) { | |||
while ((mtag = av_dict_get(*pm, "", mtag, AV_DICT_IGNORE_SUFFIX))) { | |||
key = mtag->key; | |||
if (s_conv) | |||
for (sc=s_conv; sc->native; sc++) | |||
@@ -135,9 +79,9 @@ void ff_metadata_conv(AVMetadata **pm, const AVMetadataConv *d_conv, | |||
key = dc->native; | |||
break; | |||
} | |||
av_metadata_set2(&dst, key, mtag->value, 0); | |||
av_dict_set(&dst, key, mtag->value, 0); | |||
} | |||
av_metadata_free(pm); | |||
av_dict_free(pm); | |||
*pm = dst; | |||
} | |||
@@ -154,10 +98,3 @@ void ff_metadata_conv_ctx(AVFormatContext *ctx, const AVMetadataConv *d_conv, | |||
ff_metadata_conv(&ctx->programs[i]->metadata, d_conv, s_conv); | |||
} | |||
void av_metadata_copy(AVMetadata **dst, AVMetadata *src, int flags) | |||
{ | |||
AVMetadataTag *t = NULL; | |||
while ((t = av_metadata_get(src, "", t, AV_METADATA_IGNORE_SUFFIX))) | |||
av_metadata_set2(dst, t->key, t->value, flags); | |||
} |
@@ -29,11 +29,7 @@ | |||
#include "avformat.h" | |||
struct AVMetadata{ | |||
int count; | |||
AVMetadataTag *elems; | |||
}; | |||
#include "libavutil/dict.h" | |||
struct AVMetadataConv{ | |||
const char *native; | |||
@@ -27,6 +27,7 @@ HEADERS = adler32.h \ | |||
mathematics.h \ | |||
md5.h \ | |||
mem.h \ | |||
dict.h \ | |||
opt.h \ | |||
parseutils.h \ | |||
pixdesc.h \ | |||
@@ -60,6 +61,7 @@ OBJS = adler32.o \ | |||
mathematics.o \ | |||
md5.o \ | |||
mem.o \ | |||
dict.o \ | |||
opt.o \ | |||
parseutils.o \ | |||
pixdesc.o \ | |||
@@ -40,7 +40,7 @@ | |||
#define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c) | |||
#define LIBAVUTIL_VERSION_MAJOR 51 | |||
#define LIBAVUTIL_VERSION_MINOR 4 | |||
#define LIBAVUTIL_VERSION_MINOR 5 | |||
#define LIBAVUTIL_VERSION_MICRO 0 | |||
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ | |||
@@ -0,0 +1,110 @@ | |||
/* | |||
* copyright (c) 2009 Michael Niedermayer | |||
* | |||
* This file is part of Libav. | |||
* | |||
* Libav is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 2.1 of the License, or (at your option) any later version. | |||
* | |||
* Libav is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public | |||
* License along with Libav; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
*/ | |||
#include <strings.h> | |||
#include "dict.h" | |||
#include "internal.h" | |||
#include "mem.h" | |||
AVDictionaryEntry * | |||
av_dict_get(AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags) | |||
{ | |||
unsigned int i, j; | |||
if(!m) | |||
return NULL; | |||
if(prev) i= prev - m->elems + 1; | |||
else i= 0; | |||
for(; i<m->count; i++){ | |||
const char *s= m->elems[i].key; | |||
if(flags & AV_DICT_MATCH_CASE) for(j=0; s[j] == key[j] && key[j]; j++); | |||
else for(j=0; toupper(s[j]) == toupper(key[j]) && key[j]; j++); | |||
if(key[j]) | |||
continue; | |||
if(s[j] && !(flags & AV_DICT_IGNORE_SUFFIX)) | |||
continue; | |||
return &m->elems[i]; | |||
} | |||
return NULL; | |||
} | |||
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags) | |||
{ | |||
AVDictionary *m = *pm; | |||
AVDictionaryEntry *tag = av_dict_get(m, key, NULL, flags); | |||
if(!m) | |||
m = *pm = av_mallocz(sizeof(*m)); | |||
if(tag) { | |||
if (flags & AV_DICT_DONT_OVERWRITE) | |||
return 0; | |||
av_free(tag->value); | |||
av_free(tag->key); | |||
*tag = m->elems[--m->count]; | |||
} else { | |||
AVDictionaryEntry *tmp = av_realloc(m->elems, (m->count+1) * sizeof(*m->elems)); | |||
if(tmp) { | |||
m->elems = tmp; | |||
} else | |||
return AVERROR(ENOMEM); | |||
} | |||
if (value) { | |||
if (flags & AV_DICT_DONT_STRDUP_KEY) { | |||
m->elems[m->count].key = key; | |||
} else | |||
m->elems[m->count].key = av_strdup(key ); | |||
if (flags & AV_DICT_DONT_STRDUP_VAL) { | |||
m->elems[m->count].value = value; | |||
} else | |||
m->elems[m->count].value = av_strdup(value); | |||
m->count++; | |||
} | |||
if (!m->count) { | |||
av_free(m->elems); | |||
av_freep(pm); | |||
} | |||
return 0; | |||
} | |||
void av_dict_free(AVDictionary **pm) | |||
{ | |||
AVDictionary *m = *pm; | |||
if (m) { | |||
while(m->count--) { | |||
av_free(m->elems[m->count].key); | |||
av_free(m->elems[m->count].value); | |||
} | |||
av_free(m->elems); | |||
} | |||
av_freep(pm); | |||
} | |||
void av_dict_copy(AVDictionary **dst, AVDictionary *src, int flags) | |||
{ | |||
AVDictionaryEntry *t = NULL; | |||
while ((t = av_dict_get(src, "", t, AV_DICT_IGNORE_SUFFIX))) | |||
av_dict_set(dst, t->key, t->value, flags); | |||
} |
@@ -0,0 +1,78 @@ | |||
/* | |||
* | |||
* This file is part of Libav. | |||
* | |||
* Libav is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 2.1 of the License, or (at your option) any later version. | |||
* | |||
* Libav is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public | |||
* License along with Libav; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
*/ | |||
/** | |||
* @file Public dictionary API. | |||
*/ | |||
#ifndef AVUTIL_DICT_H | |||
#define AVUTIL_DICT_H | |||
#define AV_DICT_MATCH_CASE 1 | |||
#define AV_DICT_IGNORE_SUFFIX 2 | |||
#define AV_DICT_DONT_STRDUP_KEY 4 | |||
#define AV_DICT_DONT_STRDUP_VAL 8 | |||
#define AV_DICT_DONT_OVERWRITE 16 ///< Don't overwrite existing entries. | |||
typedef struct { | |||
char *key; | |||
char *value; | |||
} AVDictionaryEntry; | |||
typedef struct AVDictionary AVDictionary; | |||
/** | |||
* Get a dictionary entry with matching key. | |||
* | |||
* @param prev Set to the previous matching element to find the next. | |||
* If set to NULL the first matching element is returned. | |||
* @param flags Allows case as well as suffix-insensitive comparisons. | |||
* @return Found entry or NULL, changing key or value leads to undefined behavior. | |||
*/ | |||
AVDictionaryEntry * | |||
av_dict_get(AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags); | |||
/** | |||
* Set the given entry in *pm, overwriting an existing entry. | |||
* | |||
* @param pm pointer to a pointer to a dictionary struct. If *pm is NULL | |||
* a dictionary struct is allocated and put in *pm. | |||
* @param key entry key to add to *pm (will be av_strduped depending on flags) | |||
* @param value entry value to add to *pm (will be av_strduped depending on flags). | |||
* Passing a NULL value will cause an existing tag to be deleted. | |||
* @return >= 0 on success otherwise an error code <0 | |||
*/ | |||
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags); | |||
/** | |||
* Copy entries from one AVDictionary struct into another. | |||
* @param dst pointer to a pointer to a AVDictionary struct. If *dst is NULL, | |||
* this function will allocate a struct for you and put it in *dst | |||
* @param src pointer to source AVDictionary struct | |||
* @param flags flags to use when setting entries in *dst | |||
* @note metadata is read using the AV_DICT_IGNORE_SUFFIX flag | |||
*/ | |||
void av_dict_copy(AVDictionary **dst, AVDictionary *src, int flags); | |||
/** | |||
* Free all the memory allocated for an AVDictionary struct. | |||
*/ | |||
void av_dict_free(AVDictionary **m); | |||
#endif // AVUTIL_DICT_H |
@@ -37,6 +37,12 @@ | |||
#include "config.h" | |||
#include "attributes.h" | |||
#include "timer.h" | |||
#include "dict.h" | |||
struct AVDictionary { | |||
int count; | |||
AVDictionaryEntry *elems; | |||
}; | |||
#ifndef attribute_align_arg | |||
#if ARCH_X86_32 && AV_GCC_VERSION_AT_LEAST(4,2) | |||