Commit d9f80ea2 authored by Anton Khirnov's avatar Anton Khirnov
Browse files

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
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, \
......
/*
* 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 @@
#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)
......
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