Commit d9f80ea2 authored by Anton Khirnov's avatar Anton Khirnov

Move metadata API from lavf to lavu.

Rename it to AVDictionary, since it will be used as such.  Tags
documentation and metadata conversion API is lavf-specific, so remains
there.
parent ac4a8548
...@@ -13,6 +13,11 @@ libavutil: 2011-04-18 ...@@ -13,6 +13,11 @@ libavutil: 2011-04-18
API changes, most recent first: 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() 2011-06-07 - a6703fa - lavu 51.4.0 - av_get_bytes_per_sample()
Add av_get_bytes_per_sample() in libavutil/samplefmt.h. Add av_get_bytes_per_sample() in libavutil/samplefmt.h.
Deprecate av_get_bits_per_sample_fmt(). Deprecate av_get_bits_per_sample_fmt().
......
...@@ -40,6 +40,7 @@ const char *avformat_license(void); ...@@ -40,6 +40,7 @@ const char *avformat_license(void);
#include <time.h> #include <time.h>
#include <stdio.h> /* FILE */ #include <stdio.h> /* FILE */
#include "libavcodec/avcodec.h" #include "libavcodec/avcodec.h"
#include "libavutil/dict.h"
#include "avio.h" #include "avio.h"
#include "libavformat/version.h" #include "libavformat/version.h"
...@@ -106,21 +107,24 @@ struct AVFormatContext; ...@@ -106,21 +107,24 @@ struct AVFormatContext;
* variant_bitrate -- the total bitrate of the bitrate variant that the current stream is part of * variant_bitrate -- the total bitrate of the bitrate variant that the current stream is part of
*/ */
#define AV_METADATA_MATCH_CASE 1 #if FF_API_OLD_METADATA2
#define AV_METADATA_IGNORE_SUFFIX 2 /**
#define AV_METADATA_DONT_STRDUP_KEY 4 * @defgroup old_metadata Old metadata API
#define AV_METADATA_DONT_STRDUP_VAL 8 * The following functions are deprecated, use
#define AV_METADATA_DONT_OVERWRITE 16 ///< Don't overwrite existing tags. * their equivalents from libavutil/dict.h instead.
* @{
*/
typedef struct { #define AV_METADATA_MATCH_CASE AV_DICT_MATCH_CASE
char *key; #define AV_METADATA_IGNORE_SUFFIX AV_DICT_IGNORE_SUFFIX
char *value; #define AV_METADATA_DONT_STRDUP_KEY AV_DICT_DONT_STRDUP_KEY
}AVMetadataTag; #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; typedef struct AVMetadataConv AVMetadataConv;
#endif
/** /**
* Get a metadata element with matching key. * Get a metadata element with matching key.
...@@ -130,8 +134,8 @@ typedef struct AVMetadataConv AVMetadataConv; ...@@ -130,8 +134,8 @@ typedef struct AVMetadataConv AVMetadataConv;
* @param flags Allows case as well as suffix-insensitive comparisons. * @param flags Allows case as well as suffix-insensitive comparisons.
* @return Found tag or NULL, changing key or value leads to undefined behavior. * @return Found tag or NULL, changing key or value leads to undefined behavior.
*/ */
AVMetadataTag * attribute_deprecated AVDictionaryEntry *
av_metadata_get(AVMetadata *m, const char *key, const AVMetadataTag *prev, int flags); av_metadata_get(AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags);
/** /**
* Set the given tag in *pm, overwriting an existing tag. * 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 ...@@ -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. * Passing a NULL value will cause an existing tag to be deleted.
* @return >= 0 on success otherwise an error code <0 * @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. * This function is provided for compatibility reason and currently does nothing.
*/ */
attribute_deprecated void av_metadata_conv(struct AVFormatContext *ctx, const AVMetadataConv *d_conv, attribute_deprecated void av_metadata_conv(struct AVFormatContext *ctx, const AVMetadataConv *d_conv,
const AVMetadataConv *s_conv); const AVMetadataConv *s_conv);
#endif
/** /**
* Copy metadata from one AVMetadata struct into another. * Copy metadata from one AVDictionary struct into another.
* @param dst pointer to a pointer to a AVMetadata struct. If *dst is NULL, * @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 * 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 * @param flags flags to use when setting metadata in *dst
* @note metadata is read using the AV_METADATA_IGNORE_SUFFIX flag * @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 */ /* packet functions */
......
...@@ -21,107 +21,51 @@ ...@@ -21,107 +21,51 @@
#include <strings.h> #include <strings.h>
#include "avformat.h" #include "avformat.h"
#include "metadata.h" #include "metadata.h"
#include "libavutil/dict.h"
AVMetadataTag * #if FF_API_OLD_METADATA2
av_metadata_get(AVMetadata *m, const char *key, const AVMetadataTag *prev, int flags) AVDictionaryEntry *
av_metadata_get(AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
{ {
unsigned int i, j; return av_dict_get(m, key, prev, flags);
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;
} }
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; return av_dict_set(pm, key, value, flags);
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;
} }
#if FF_API_OLD_METADATA2
void av_metadata_conv(AVFormatContext *ctx, const AVMetadataConv *d_conv, void av_metadata_conv(AVFormatContext *ctx, const AVMetadataConv *d_conv,
const AVMetadataConv *s_conv) const AVMetadataConv *s_conv)
{ {
return; return;
} }
#endif
void av_metadata_free(AVMetadata **pm) void av_metadata_free(AVDictionary **pm)
{ {
AVMetadata *m= *pm; av_dict_free(pm);
}
if(m){ void av_metadata_copy(AVDictionary **dst, AVDictionary *src, int flags)
while(m->count--){ {
av_free(m->elems[m->count].key); av_dict_copy(dst, src, flags);
av_free(m->elems[m->count].value);
}
av_free(m->elems);
}
av_freep(pm);
} }
#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) const AVMetadataConv *s_conv)
{ {
/* TODO: use binary search to look up the two conversion tables /* TODO: use binary search to look up the two conversion tables
if the tables are getting big enough that it would matter speed wise */ if the tables are getting big enough that it would matter speed wise */
const AVMetadataConv *sc, *dc; const AVMetadataConv *sc, *dc;
AVMetadataTag *mtag = NULL; AVDictionaryEntry *mtag = NULL;
AVMetadata *dst = NULL; AVDictionary *dst = NULL;
const char *key; const char *key;
if (d_conv == s_conv) if (d_conv == s_conv)
return; 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; key = mtag->key;
if (s_conv) if (s_conv)
for (sc=s_conv; sc->native; sc++) for (sc=s_conv; sc->native; sc++)
...@@ -135,9 +79,9 @@ void ff_metadata_conv(AVMetadata **pm, const AVMetadataConv *d_conv, ...@@ -135,9 +79,9 @@ void ff_metadata_conv(AVMetadata **pm, const AVMetadataConv *d_conv,
key = dc->native; key = dc->native;
break; 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; *pm = dst;
} }
...@@ -154,10 +98,3 @@ void ff_metadata_conv_ctx(AVFormatContext *ctx, const AVMetadataConv *d_conv, ...@@ -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); 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 @@ ...@@ -29,11 +29,7 @@
#include "avformat.h" #include "avformat.h"
#include "libavutil/dict.h"
struct AVMetadata{
int count;
AVMetadataTag *elems;
};
struct AVMetadataConv{ struct AVMetadataConv{
const char *native; const char *native;
......
...@@ -27,6 +27,7 @@ HEADERS = adler32.h \ ...@@ -27,6 +27,7 @@ HEADERS = adler32.h \
mathematics.h \ mathematics.h \
md5.h \ md5.h \
mem.h \ mem.h \
dict.h \
opt.h \ opt.h \
parseutils.h \ parseutils.h \
pixdesc.h \ pixdesc.h \
...@@ -60,6 +61,7 @@ OBJS = adler32.o \ ...@@ -60,6 +61,7 @@ OBJS = adler32.o \
mathematics.o \ mathematics.o \
md5.o \ md5.o \
mem.o \ mem.o \
dict.o \
opt.o \ opt.o \
parseutils.o \ parseutils.o \
pixdesc.o \ pixdesc.o \
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
#define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c) #define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c)
#define LIBAVUTIL_VERSION_MAJOR 51 #define LIBAVUTIL_VERSION_MAJOR 51
#define LIBAVUTIL_VERSION_MINOR 4 #define LIBAVUTIL_VERSION_MINOR 5
#define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_MICRO 0
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
......
/*
* 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);
}
/*
*
* 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 @@ ...@@ -37,6 +37,12 @@
#include "config.h" #include "config.h"
#include "attributes.h" #include "attributes.h"
#include "timer.h" #include "timer.h"
#include "dict.h"
struct AVDictionary {
int count;
AVDictionaryEntry *elems;
};
#ifndef attribute_align_arg #ifndef attribute_align_arg
#if ARCH_X86_32 && AV_GCC_VERSION_AT_LEAST(4,2) #if ARCH_X86_32 && AV_GCC_VERSION_AT_LEAST(4,2)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment