* commit 'b439c992c23f3e0f3832fffd2a34a664b236c525': lavfi: switch to an AVOptions-based system. dfa: implement missing TDLT coding method Conflicts: libavcodec/dfa.c libavfilter/avfilter.c Merged-by: Michael Niedermayer <michaelni@gmx.at>tags/n2.0
| @@ -130,8 +130,25 @@ The name of the filter class is optionally followed by a string | |||||
| "=@var{arguments}". | "=@var{arguments}". | ||||
| @var{arguments} is a string which contains the parameters used to | @var{arguments} is a string which contains the parameters used to | ||||
| initialize the filter instance, and are described in the filter | |||||
| descriptions below. | |||||
| initialize the filter instance. It may have one of the two allowed forms: | |||||
| @itemize | |||||
| @item | |||||
| A ':'-separated list of @var{key=value} pairs. | |||||
| @item | |||||
| A ':'-separated list of @var{value}. In this case, the keys are assumed to be | |||||
| the option names in the order they are declared. E.g. the @code{fade} filter | |||||
| declares three options in this order -- @option{type}, @option{start_frame} and | |||||
| @option{nb_frames}. Then the parameter list @var{in:0:30} means that the value | |||||
| @var{in} is assigned to the option @option{type}, @var{0} to | |||||
| @option{start_frame} and @var{30} to @option{nb_frames}. | |||||
| @end itemize | |||||
| If the option value itself is a list of items (e.g. the @code{format} filter | |||||
| takes a list of pixel formats), the items in the list are usually separated by | |||||
| '|'. | |||||
| The list of arguments can be quoted using the character "'" as initial | The list of arguments can be quoted using the character "'" as initial | ||||
| and ending mark, and the character '\' for escaping the characters | and ending mark, and the character '\' for escaping the characters | ||||
| @@ -292,17 +292,19 @@ static int decode_tdlt(GetByteContext *gb, uint8_t *frame, int width, int height | |||||
| { | { | ||||
| const uint8_t *frame_end = frame + width * height; | const uint8_t *frame_end = frame + width * height; | ||||
| uint32_t segments = bytestream2_get_le32(gb); | uint32_t segments = bytestream2_get_le32(gb); | ||||
| int skip, copy; | |||||
| while (segments--) { | while (segments--) { | ||||
| int count = bytestream2_get_byte(gb) << 1; | |||||
| int skip = bytestream2_get_byte(gb) << 1; | |||||
| if (frame_end - frame < skip + count) | |||||
| if (bytestream2_get_bytes_left(gb) < 2) | |||||
| return AVERROR_INVALIDDATA; | return AVERROR_INVALIDDATA; | ||||
| frame += skip; | |||||
| if (bytestream2_get_buffer(gb, frame, count) != count) | |||||
| copy = bytestream2_get_byteu(gb) * 2; | |||||
| skip = bytestream2_get_byteu(gb) * 2; | |||||
| if (frame_end - frame < copy + skip || | |||||
| bytestream2_get_bytes_left(gb) < copy) | |||||
| return AVERROR_INVALIDDATA; | return AVERROR_INVALIDDATA; | ||||
| frame += count; | |||||
| frame += skip; | |||||
| bytestream2_get_buffer(gb, frame, copy); | |||||
| frame += copy; | |||||
| } | } | ||||
| return 0; | return 0; | ||||
| @@ -516,6 +516,11 @@ int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *in | |||||
| goto err; | goto err; | ||||
| } | } | ||||
| if (filter->priv_class) { | |||||
| *(const AVClass**)ret->priv = filter->priv_class; | |||||
| av_opt_set_defaults(ret->priv); | |||||
| } | |||||
| ret->nb_inputs = pad_count(filter->inputs); | ret->nb_inputs = pad_count(filter->inputs); | ||||
| if (ret->nb_inputs ) { | if (ret->nb_inputs ) { | ||||
| ret->input_pads = av_malloc(sizeof(AVFilterPad) * ret->nb_inputs); | ret->input_pads = av_malloc(sizeof(AVFilterPad) * ret->nb_inputs); | ||||
| @@ -567,8 +572,6 @@ void avfilter_free(AVFilterContext *filter) | |||||
| if (filter->filter->uninit) | if (filter->filter->uninit) | ||||
| filter->filter->uninit(filter); | filter->filter->uninit(filter); | ||||
| if (filter->filter->shorthand) | |||||
| av_opt_free(filter->priv); | |||||
| for (i = 0; i < filter->nb_inputs; i++) { | for (i = 0; i < filter->nb_inputs; i++) { | ||||
| if ((link = filter->inputs[i])) { | if ((link = filter->inputs[i])) { | ||||
| @@ -597,6 +600,9 @@ void avfilter_free(AVFilterContext *filter) | |||||
| avfilter_link_free(&link); | avfilter_link_free(&link); | ||||
| } | } | ||||
| if (filter->filter->priv_class || filter->filter->shorthand) | |||||
| av_opt_free(filter->priv); | |||||
| av_freep(&filter->name); | av_freep(&filter->name); | ||||
| av_freep(&filter->input_pads); | av_freep(&filter->input_pads); | ||||
| av_freep(&filter->output_pads); | av_freep(&filter->output_pads); | ||||
| @@ -609,9 +615,45 @@ void avfilter_free(AVFilterContext *filter) | |||||
| av_free(filter); | av_free(filter); | ||||
| } | } | ||||
| /* process a list of value1:value2:..., each value corresponding | |||||
| * to subsequent AVOption, in the order they are declared */ | |||||
| static int process_unnamed_options(AVFilterContext *ctx, AVDictionary **options, | |||||
| const char *args) | |||||
| { | |||||
| const AVOption *o = NULL; | |||||
| const char *p = args; | |||||
| char *val; | |||||
| while (*p) { | |||||
| o = av_opt_next(ctx->priv, o); | |||||
| if (!o) { | |||||
| av_log(ctx, AV_LOG_ERROR, "More options provided than " | |||||
| "this filter supports.\n"); | |||||
| return AVERROR(EINVAL); | |||||
| } | |||||
| if (o->type == AV_OPT_TYPE_CONST) | |||||
| continue; | |||||
| val = av_get_token(&p, ":"); | |||||
| if (!val) | |||||
| return AVERROR(ENOMEM); | |||||
| av_dict_set(options, o->name, val, 0); | |||||
| av_freep(&val); | |||||
| if (*p) | |||||
| p++; | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque) | int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque) | ||||
| { | { | ||||
| AVDictionary *options = NULL; | |||||
| AVDictionaryEntry *e; | |||||
| int ret=0; | int ret=0; | ||||
| int anton_options = 0; | |||||
| if (filter->filter->shorthand) { | if (filter->filter->shorthand) { | ||||
| av_assert0(filter->priv); | av_assert0(filter->priv); | ||||
| @@ -624,10 +666,46 @@ int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque | |||||
| return ret; | return ret; | ||||
| args = NULL; | args = NULL; | ||||
| } | } | ||||
| if (filter->filter->init_opaque) | |||||
| ret = filter->filter->init_opaque(filter, args, opaque); | |||||
| else if (filter->filter->init) | |||||
| ret = filter->filter->init(filter, args); | |||||
| if (anton_options && args && *args && filter->filter->priv_class) { | |||||
| if (strchr(args, '=')) { | |||||
| /* assume a list of key1=value1:key2=value2:... */ | |||||
| ret = av_dict_parse_string(&options, args, "=", ":", 0); | |||||
| if (ret < 0) | |||||
| goto fail; | |||||
| } else { | |||||
| ret = process_unnamed_options(filter, &options, args); | |||||
| if (ret < 0) | |||||
| goto fail; | |||||
| } | |||||
| } | |||||
| if (anton_options && filter->filter->priv_class) { | |||||
| ret = av_opt_set_dict(filter->priv, &options); | |||||
| if (ret < 0) { | |||||
| av_log(filter, AV_LOG_ERROR, "Error applying options to the filter.\n"); | |||||
| goto fail; | |||||
| } | |||||
| } | |||||
| if (filter->filter->init || filter->filter->init_opaque) { | |||||
| if (filter->filter->init_opaque) | |||||
| ret = filter->filter->init_opaque(filter, args, opaque); | |||||
| else | |||||
| ret = filter->filter->init(filter, args); | |||||
| if (ret < 0) | |||||
| goto fail; | |||||
| } | |||||
| if ((e = av_dict_get(options, "", NULL, AV_DICT_IGNORE_SUFFIX))) { | |||||
| av_log(filter, AV_LOG_ERROR, "No such option: %s.\n", e->key); | |||||
| ret = AVERROR_OPTION_NOT_FOUND; | |||||
| goto fail; | |||||
| } | |||||
| fail: | |||||
| av_dict_free(&options); | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| @@ -431,6 +431,12 @@ typedef struct AVFilter { | |||||
| const AVFilterPad *inputs; ///< NULL terminated list of inputs. NULL if none | const AVFilterPad *inputs; ///< NULL terminated list of inputs. NULL if none | ||||
| const AVFilterPad *outputs; ///< NULL terminated list of outputs. NULL if none | const AVFilterPad *outputs; ///< NULL terminated list of outputs. NULL if none | ||||
| /** | |||||
| * A class for the private data, used to access filter private | |||||
| * AVOptions. | |||||
| */ | |||||
| const AVClass *priv_class; | |||||
| /***************************************************************** | /***************************************************************** | ||||
| * All fields below this line are not part of the public API. They | * All fields below this line are not part of the public API. They | ||||
| * may not be used outside of libavfilter and can be changed and | * may not be used outside of libavfilter and can be changed and | ||||
| @@ -485,8 +491,6 @@ typedef struct AVFilter { | |||||
| */ | */ | ||||
| int (*init_opaque)(AVFilterContext *ctx, const char *args, void *opaque); | int (*init_opaque)(AVFilterContext *ctx, const char *args, void *opaque); | ||||
| const AVClass *priv_class; ///< private class, containing filter specific options | |||||
| /** | /** | ||||
| * Shorthand syntax for init arguments. | * Shorthand syntax for init arguments. | ||||
| * If this field is set (even to an empty list), just before init the | * If this field is set (even to an empty list), just before init the | ||||
| @@ -63,5 +63,8 @@ | |||||
| #ifndef FF_API_AVFILTERBUFFER | #ifndef FF_API_AVFILTERBUFFER | ||||
| #define FF_API_AVFILTERBUFFER (LIBAVFILTER_VERSION_MAJOR < 4) | #define FF_API_AVFILTERBUFFER (LIBAVFILTER_VERSION_MAJOR < 4) | ||||
| #endif | #endif | ||||
| #ifndef FF_API_OLD_FILTER_OPTS | |||||
| #define FF_API_OLD_FILTER_OPTS (LIBAVFILTER_VERSION_MAJOR < 4) | |||||
| #endif | |||||
| #endif /* AVFILTER_VERSION_H */ | #endif /* AVFILTER_VERSION_H */ | ||||