X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fmetadata.c;h=080ebcde886ce4244ea58deed10cb90f889c0f0e;hb=889fce8e306f15a223d13f8c0dbb211ec4b52fd0;hp=d223d7c0d91a223fac6a297b09ec54c0ff15d335;hpb=a6d18a0e6addfcfc6f8790d4afc3b47673cbb607;p=ffmpeg diff --git a/libavformat/metadata.c b/libavformat/metadata.c index d223d7c0d91..080ebcde886 100644 --- a/libavformat/metadata.c +++ b/libavformat/metadata.c @@ -18,10 +18,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include +#include "avformat.h" #include "metadata.h" -AVMetaDataTag * -av_metadata_get(struct AVMetaData *m, const char *key, const AVMetaDataTag *prev, int flags) +AVMetadataTag * +av_metadata_get(AVMetadata *m, const char *key, const AVMetadataTag *prev, int flags) { unsigned int i, j; @@ -33,8 +35,8 @@ av_metadata_get(struct AVMetaData *m, const char *key, const AVMetaDataTag *prev for(; icount; i++){ const char *s= m->elems[i].key; - if(flags & AV_METADATA_IGNORE_CASE) for(j=0; toupper(s[j]) == toupper(key[j]) && key[j]; j++); - else for(j=0; s[j] == key[j] && key[j]; j++); + 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)) @@ -44,10 +46,10 @@ av_metadata_get(struct AVMetaData *m, const char *key, const AVMetaDataTag *prev return NULL; } -int av_metadata_set(struct AVMetaData **pm, AVMetaDataTag elem) +int av_metadata_set2(AVMetadata **pm, const char *key, const char *value, int flags) { - struct AVMetaData *m= *pm; - AVMetaDataTag *tag= av_metadata_get(m, elem.key, NULL, 0); + AVMetadata *m= *pm; + AVMetadataTag *tag= av_metadata_get(m, key, NULL, AV_METADATA_MATCH_CASE); if(!m) m=*pm= av_mallocz(sizeof(*m)); @@ -57,19 +59,93 @@ int av_metadata_set(struct AVMetaData **pm, AVMetaDataTag elem) av_free(tag->key); *tag= m->elems[--m->count]; }else{ - AVMetaDataTag *tmp= av_realloc(m->elems, (m->count+1) * sizeof(*m->elems)); + AVMetadataTag *tmp= av_realloc(m->elems, (m->count+1) * sizeof(*m->elems)); if(tmp){ m->elems= tmp; }else return AVERROR(ENOMEM); } - if(elem.value){ - elem.key = av_strdup(elem.key ); - elem.value= av_strdup(elem.value); - m->elems[m->count++]= elem; + 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) + if(!m->count) { + av_free(m->elems); av_freep(pm); + } return 0; } + +#if LIBAVFORMAT_VERSION_MAJOR == 52 +int av_metadata_set(AVMetadata **pm, const char *key, const char *value) +{ + return av_metadata_set2(pm, key, value, 0); +} +#endif + +void av_metadata_free(AVMetadata **pm) +{ + AVMetadata *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); +} + +static void metadata_conv(AVMetadata **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; + const char *key; + + while((mtag=av_metadata_get(*pm, "", mtag, AV_METADATA_IGNORE_SUFFIX))) { + key = mtag->key; + if (s_conv != d_conv) { + if (s_conv) + for (sc=s_conv; sc->native; sc++) + if (!strcasecmp(key, sc->native)) { + key = sc->generic; + break; + } + if (d_conv) + for (dc=d_conv; dc->native; dc++) + if (!strcasecmp(key, dc->generic)) { + key = dc->native; + break; + } + } + av_metadata_set(&dst, key, mtag->value); + } + av_metadata_free(pm); + *pm = dst; +} + +void av_metadata_conv(AVFormatContext *ctx, const AVMetadataConv *d_conv, + const AVMetadataConv *s_conv) +{ + int i; + metadata_conv(&ctx->metadata, d_conv, s_conv); + for (i=0; inb_streams ; i++) + metadata_conv(&ctx->streams [i]->metadata, d_conv, s_conv); + for (i=0; inb_chapters; i++) + metadata_conv(&ctx->chapters[i]->metadata, d_conv, s_conv); + for (i=0; inb_programs; i++) + metadata_conv(&ctx->programs[i]->metadata, d_conv, s_conv); +}