diff options
Diffstat (limited to 'libavutil')
-rw-r--r-- | libavutil/avutil.h | 5 | ||||
-rw-r--r-- | libavutil/dict.c | 13 | ||||
-rw-r--r-- | libavutil/dict.h | 2 | ||||
-rw-r--r-- | libavutil/intreadwrite.h | 20 | ||||
-rw-r--r-- | libavutil/log.h | 7 | ||||
-rw-r--r-- | libavutil/opt.c | 52 | ||||
-rw-r--r-- | libavutil/opt.h | 48 |
7 files changed, 130 insertions, 17 deletions
diff --git a/libavutil/avutil.h b/libavutil/avutil.h index 500c700851..36dcf8f718 100644 --- a/libavutil/avutil.h +++ b/libavutil/avutil.h @@ -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 8 +#define LIBAVUTIL_VERSION_MINOR 9 #define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ @@ -63,6 +63,9 @@ #ifndef FF_API_GET_BITS_PER_SAMPLE_FMT #define FF_API_GET_BITS_PER_SAMPLE_FMT (LIBAVUTIL_VERSION_MAJOR < 52) #endif +#ifndef FF_API_FIND_OPT +#define FF_API_FIND_OPT (LIBAVUTIL_VERSION_MAJOR < 52) +#endif /** * Return the LIBAVUTIL_VERSION_INT constant. diff --git a/libavutil/dict.c b/libavutil/dict.c index 332eccd679..74301fbf11 100644 --- a/libavutil/dict.c +++ b/libavutil/dict.c @@ -19,6 +19,7 @@ */ #include <strings.h> +#include "avstring.h" #include "dict.h" #include "internal.h" #include "mem.h" @@ -51,6 +52,7 @@ 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); + char *oldval = NULL; if(!m) m = *pm = av_mallocz(sizeof(*m)); @@ -58,7 +60,10 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags if(tag) { if (flags & AV_DICT_DONT_OVERWRITE) return 0; - av_free(tag->value); + if (flags & AV_DICT_APPEND) + oldval = tag->value; + else + av_free(tag->value); av_free(tag->key); *tag = m->elems[--m->count]; } else { @@ -75,6 +80,12 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags m->elems[m->count].key = av_strdup(key ); if (flags & AV_DICT_DONT_STRDUP_VAL) { m->elems[m->count].value = value; + } else if (oldval && flags & AV_DICT_APPEND) { + int len = strlen(oldval) + strlen(value) + 1; + if (!(oldval = av_realloc(oldval, len))) + return AVERROR(ENOMEM); + av_strlcat(oldval, value, len); + m->elems[m->count].value = oldval; } else m->elems[m->count].value = av_strdup(value); m->count++; diff --git a/libavutil/dict.h b/libavutil/dict.h index 19cc0915d8..421be32244 100644 --- a/libavutil/dict.h +++ b/libavutil/dict.h @@ -29,6 +29,8 @@ #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. +#define AV_DICT_APPEND 32 /**< If the entry already exists, append to it. Note that no + delimiter is added, the strings are simply concatenated. */ typedef struct { char *key; diff --git a/libavutil/intreadwrite.h b/libavutil/intreadwrite.h index 1849a64661..09d796c8b8 100644 --- a/libavutil/intreadwrite.h +++ b/libavutil/intreadwrite.h @@ -229,11 +229,11 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; #endif #ifndef AV_RB32 -# define AV_RB32(x) \ - ((((const uint8_t*)(x))[0] << 24) | \ - (((const uint8_t*)(x))[1] << 16) | \ - (((const uint8_t*)(x))[2] << 8) | \ - ((const uint8_t*)(x))[3]) +# define AV_RB32(x) \ + (((uint32_t)((const uint8_t*)(x))[0] << 24) | \ + (((const uint8_t*)(x))[1] << 16) | \ + (((const uint8_t*)(x))[2] << 8) | \ + ((const uint8_t*)(x))[3]) #endif #ifndef AV_WB32 # define AV_WB32(p, d) do { \ @@ -245,11 +245,11 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; #endif #ifndef AV_RL32 -# define AV_RL32(x) \ - ((((const uint8_t*)(x))[3] << 24) | \ - (((const uint8_t*)(x))[2] << 16) | \ - (((const uint8_t*)(x))[1] << 8) | \ - ((const uint8_t*)(x))[0]) +# define AV_RL32(x) \ + (((uint32_t)((const uint8_t*)(x))[3] << 24) | \ + (((const uint8_t*)(x))[2] << 16) | \ + (((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[0]) #endif #ifndef AV_WL32 # define AV_WL32(p, d) do { \ diff --git a/libavutil/log.h b/libavutil/log.h index c87125d2d5..149225dadf 100644 --- a/libavutil/log.h +++ b/libavutil/log.h @@ -70,6 +70,13 @@ typedef struct { * can be NULL of course */ int parent_log_context_offset; + + /** + * A function for extended searching, e.g. in possible + * children objects. + */ + const struct AVOption* (*opt_find)(void *obj, const char *name, const char *unit, + int opt_flags, int search_flags); } AVClass; /* av_log API */ diff --git a/libavutil/opt.c b/libavutil/opt.c index d57a547377..8c351488a8 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -29,7 +29,9 @@ #include "avstring.h" #include "opt.h" #include "eval.h" +#include "dict.h" +#if FF_API_FIND_OPT //FIXME order them and do a bin search const AVOption *av_find_opt(void *v, const char *name, const char *unit, int mask, int flags) { @@ -41,6 +43,7 @@ const AVOption *av_find_opt(void *v, const char *name, const char *unit, int mas } return NULL; } +#endif const AVOption *av_next_option(void *obj, const AVOption *last) { @@ -51,7 +54,7 @@ const AVOption *av_next_option(void *obj, const AVOption *last) static int av_set_number2(void *obj, const char *name, double num, int den, int64_t intnum, const AVOption **o_out) { - const AVOption *o= av_find_opt(obj, name, NULL, 0, 0); + const AVOption *o = av_opt_find(obj, name, NULL, 0, 0); void *dst; if (o_out) *o_out= o; @@ -114,7 +117,7 @@ static int hexchar2int(char c) { int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out) { int ret; - const AVOption *o= av_find_opt(obj, name, NULL, 0, 0); + const AVOption *o = av_opt_find(obj, name, NULL, 0, 0); if (o_out) *o_out = o; if (!o) @@ -161,7 +164,7 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons buf[i]=0; { - const AVOption *o_named= av_find_opt(obj, buf, o->unit, 0, 0); + const AVOption *o_named = av_opt_find(obj, buf, o->unit, 0, 0); if (o_named && o_named->type == FF_OPT_TYPE_CONST) d= o_named->default_val.dbl; else if (!strcmp(buf, "default")) d= o->default_val.dbl; @@ -226,7 +229,7 @@ const AVOption *av_set_int(void *obj, const char *name, int64_t n) */ const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len) { - const AVOption *o= av_find_opt(obj, name, NULL, 0, 0); + const AVOption *o = av_opt_find(obj, name, NULL, 0, 0); void *dst; uint8_t *bin; int len, i; @@ -259,7 +262,7 @@ const char *av_get_string(void *obj, const char *name, const AVOption **o_out, c static int av_get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum) { - const AVOption *o= av_find_opt(obj, name, NULL, 0, 0); + const AVOption *o = av_opt_find(obj, name, NULL, 0, 0); void *dst; if (!o || (o->offset<=0 && o->type != FF_OPT_TYPE_CONST)) goto error; @@ -538,6 +541,45 @@ void av_opt_free(void *obj) av_freep((uint8_t *)obj + o->offset); } +int av_opt_set_dict(void *obj, AVDictionary **options) +{ + AVDictionaryEntry *t = NULL; + AVDictionary *tmp = NULL; + int ret = 0; + + while ((t = av_dict_get(*options, "", t, AV_DICT_IGNORE_SUFFIX))) { + ret = av_set_string3(obj, t->key, t->value, 1, NULL); + if (ret == AVERROR_OPTION_NOT_FOUND) + av_dict_set(&tmp, t->key, t->value, 0); + else if (ret < 0) { + av_log(obj, AV_LOG_ERROR, "Error setting option %s to value %s.\n", t->key, t->value); + break; + } + ret = 0; + } + av_dict_free(options); + *options = tmp; + return ret; +} + +const AVOption *av_opt_find(void *obj, const char *name, const char *unit, + int opt_flags, int search_flags) +{ + AVClass *c = *(AVClass**)obj; + const AVOption *o = NULL; + + if (c->opt_find && search_flags & AV_OPT_SEARCH_CHILDREN && + (o = c->opt_find(obj, name, unit, opt_flags, search_flags))) + return o; + + while (o = av_next_option(obj, o)) { + if (!strcmp(o->name, name) && (!unit || (o->unit && !strcmp(o->unit, unit))) && + (o->flags & opt_flags) == opt_flags) + return o; + } + return NULL; +} + #ifdef TEST #undef printf diff --git a/libavutil/opt.h b/libavutil/opt.h index 872b5547c1..97a1cb5774 100644 --- a/libavutil/opt.h +++ b/libavutil/opt.h @@ -29,6 +29,7 @@ #include "rational.h" #include "avutil.h" +#include "dict.h" enum AVOptionType{ FF_OPT_TYPE_FLAGS, @@ -91,6 +92,7 @@ typedef struct AVOption { const char *unit; } AVOption; +#if FF_API_FIND_OPT /** * Look for an option in obj. Look only for the options which * have the flags set as specified in mask and flags (that is, @@ -102,8 +104,12 @@ typedef struct AVOption { * @param[in] unit the unit of the option to look for, or any if NULL * @return a pointer to the option found, or NULL if no option * has been found + * + * @deprecated use av_opt_find. */ +attribute_deprecated const AVOption *av_find_opt(void *obj, const char *name, const char *unit, int mask, int flags); +#endif /** * Set the field of obj with the given name to value. @@ -191,4 +197,46 @@ void av_opt_free(void *obj); */ int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name); +/* + * Set all the options from a given dictionary on an object. + * + * @param obj a struct whose first element is a pointer to AVClass + * @param options options to process. This dictionary will be freed and replaced + * by a new one containing all options not found in obj. + * Of course this new dictionary needs to be freed by caller + * with av_dict_free(). + * + * @return 0 on success, a negative AVERROR if some option was found in obj, + * but could not be set. + * + * @see av_dict_copy() + */ +int av_opt_set_dict(void *obj, struct AVDictionary **options); + +#define AV_OPT_SEARCH_CHILDREN 0x0001 /**< Search in possible children of the + given object first. */ + +/** + * Look for an option in an object. Consider only options which + * have all the specified flags set. + * + * @param[in] obj A pointer to a struct whose first element is a + * pointer to an AVClass. + * @param[in] name The name of the option to look for. + * @param[in] unit When searching for named constants, name of the unit + * it belongs to. + * @param opt_flags Find only options with all the specified flags set (AV_OPT_FLAG). + * @param search_flags A combination of AV_OPT_SEARCH_*. + * + * @return A pointer to the option found, or NULL if no option + * was found. + * + * @note Options found with AV_OPT_SEARCH_CHILDREN flag may not be settable + * directly with av_set_string3(). Use special calls which take an options + * AVDictionary (e.g. avformat_open_input()) to set options found with this + * flag. + */ +const AVOption *av_opt_find(void *obj, const char *name, const char *unit, + int opt_flags, int search_flags); + #endif /* AVUTIL_OPT_H */ |