X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fmetadata.c;h=8fc1771956a74c0a510c76841622bc7566b9c582;hb=5ba24e4982f988343ac1444b7ddd16cecc3e9bbf;hp=8a25782f29ee4636b12ca7a12783f1feb4d814bf;hpb=176aee8282c7d53b658de07ddf5bc4b0b3e5a7fc;p=ffmpeg diff --git a/libavformat/metadata.c b/libavformat/metadata.c index 8a25782f29e..8fc1771956a 100644 --- a/libavformat/metadata.c +++ b/libavformat/metadata.c @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include +#include "avformat.h" #include "metadata.h" AVMetadataTag * @@ -33,8 +35,8 @@ av_metadata_get(AVMetadata *m, const char *key, const AVMetadataTag *prev, int f 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,15 +46,17 @@ av_metadata_get(AVMetadata *m, const char *key, const AVMetadataTag *prev, int f return NULL; } -int av_metadata_set(AVMetadata **pm, AVMetadataTag elem) +int av_metadata_set2(AVMetadata **pm, const char *key, const char *value, int flags) { AVMetadata *m= *pm; - AVMetadataTag *tag= av_metadata_get(m, elem.key, NULL, 0); + AVMetadataTag *tag= av_metadata_get(m, key, NULL, AV_METADATA_MATCH_CASE); 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]; @@ -63,50 +67,88 @@ int av_metadata_set(AVMetadata **pm, AVMetadataTag elem) }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 < 53 -#define FILL_METADATA(s, key, value) { \ - if (value && *value && \ - !av_metadata_get(s->metadata, #key, NULL, AV_METADATA_IGNORE_CASE)) \ - av_metadata_set(&s->metadata, (const AVMetadataTag){#key, value}); \ - } -#define FILL_METADATA_STR(s, key) FILL_METADATA(s, key, s->key) -#define FILL_METADATA_INT(s, key) { \ - char number[10]; \ - snprintf(number, sizeof(number), "%d", s->key); \ - FILL_METADATA(s, key, number) } +#if FF_API_OLD_METADATA +int av_metadata_set(AVMetadata **pm, const char *key, const char *value) +{ + return av_metadata_set2(pm, key, value, 0); +} +#endif -void ff_metadata_sync_compat(AVFormatContext *ctx) +void av_metadata_free(AVMetadata **pm) { - int i; + AVMetadata *m= *pm; - FILL_METADATA_STR(ctx, title); - FILL_METADATA_STR(ctx, author); - FILL_METADATA_STR(ctx, copyright); - FILL_METADATA_STR(ctx, comment); - FILL_METADATA_STR(ctx, album); - FILL_METADATA_INT(ctx, year); - FILL_METADATA_INT(ctx, track); - FILL_METADATA_STR(ctx, genre); - for (i=0; inb_chapters; i++) - FILL_METADATA_STR(ctx->chapters[i], title); - for (i=0; inb_programs; i++) { - FILL_METADATA_STR(ctx->programs[i], name); - FILL_METADATA_STR(ctx->programs[i], provider_name); + if(m){ + while(m->count--){ + av_free(m->elems[m->count].key); + av_free(m->elems[m->count].value); + } + av_free(m->elems); } - for (i=0; inb_streams; i++) { - FILL_METADATA_STR(ctx->streams[i], language); - FILL_METADATA_STR(ctx->streams[i], filename); + av_freep(pm); +} + +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; + + if (d_conv == s_conv) + return; + + while((mtag=av_metadata_get(*pm, "", mtag, AV_METADATA_IGNORE_SUFFIX))) { + key = mtag->key; + 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_set2(&dst, key, mtag->value, 0); } + 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); } -#endif