diff options
author | Anton Khirnov <anton@khirnov.net> | 2023-05-21 20:29:59 +0200 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2023-05-31 16:15:47 +0200 |
commit | a1061d4bdcbfb866011c18e787ec334ae48f2820 (patch) | |
tree | fa84fbbac8f5ace84e267f39cc7b61327a1ad517 /fftools | |
parent | 00183880aa065e97a3ec37524c802b562f83876d (diff) | |
download | ffmpeg-a1061d4bdcbfb866011c18e787ec334ae48f2820.tar.gz |
fftools/ffmpeg_filter: move some functions higher up
Needed by the following commit.
Diffstat (limited to 'fftools')
-rw-r--r-- | fftools/ffmpeg_filter.c | 374 |
1 files changed, 187 insertions, 187 deletions
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index a8c4ef321f..5169a3ca82 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -246,6 +246,193 @@ static void choose_channel_layouts(OutputFilter *ofilter, AVBPrint *bprint) av_bprint_chars(bprint, ':', 1); } +static int read_binary(const char *path, uint8_t **data, int *len) +{ + AVIOContext *io = NULL; + int64_t fsize; + int ret; + + *data = NULL; + *len = 0; + + ret = avio_open2(&io, path, AVIO_FLAG_READ, &int_cb, NULL); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Cannot open file '%s': %s\n", + path, av_err2str(ret)); + return ret; + } + + fsize = avio_size(io); + if (fsize < 0 || fsize > INT_MAX) { + av_log(NULL, AV_LOG_ERROR, "Cannot obtain size of file %s\n", path); + ret = AVERROR(EIO); + goto fail; + } + + *data = av_malloc(fsize); + if (!*data) { + ret = AVERROR(ENOMEM); + goto fail; + } + + ret = avio_read(io, *data, fsize); + if (ret != fsize) { + av_log(NULL, AV_LOG_ERROR, "Error reading file %s\n", path); + ret = ret < 0 ? ret : AVERROR(EIO); + goto fail; + } + + *len = fsize; + + ret = 0; +fail: + avio_close(io); + if (ret < 0) { + av_freep(data); + *len = 0; + } + return ret; +} + +static int filter_opt_apply(AVFilterContext *f, const char *key, const char *val) +{ + const AVOption *o = NULL; + int ret; + + ret = av_opt_set(f, key, val, AV_OPT_SEARCH_CHILDREN); + if (ret >= 0) + return 0; + + if (ret == AVERROR_OPTION_NOT_FOUND && key[0] == '/') + o = av_opt_find(f, key + 1, NULL, 0, AV_OPT_SEARCH_CHILDREN); + if (!o) + goto err_apply; + + // key is a valid option name prefixed with '/' + // interpret value as a path from which to load the actual option value + key++; + + if (o->type == AV_OPT_TYPE_BINARY) { + uint8_t *data; + int len; + + ret = read_binary(val, &data, &len); + if (ret < 0) + goto err_load; + + ret = av_opt_set_bin(f, key, data, len, AV_OPT_SEARCH_CHILDREN); + av_freep(&data); + } else { + char *data = file_read(val); + if (!data) { + ret = AVERROR(EIO); + goto err_load; + } + + ret = av_opt_set(f, key, data, AV_OPT_SEARCH_CHILDREN); + av_freep(&data); + } + if (ret < 0) + goto err_apply; + + return 0; + +err_apply: + av_log(NULL, AV_LOG_ERROR, + "Error applying option '%s' to filter '%s': %s\n", + key, f->filter->name, av_err2str(ret)); + return ret; +err_load: + av_log(NULL, AV_LOG_ERROR, + "Error loading value for option '%s' from file '%s'\n", + key, val); + return ret; +} + +static int graph_opts_apply(AVFilterGraphSegment *seg) +{ + for (size_t i = 0; i < seg->nb_chains; i++) { + AVFilterChain *ch = seg->chains[i]; + + for (size_t j = 0; j < ch->nb_filters; j++) { + AVFilterParams *p = ch->filters[j]; + const AVDictionaryEntry *e = NULL; + + av_assert0(p->filter); + + while ((e = av_dict_iterate(p->opts, e))) { + int ret = filter_opt_apply(p->filter, e->key, e->value); + if (ret < 0) + return ret; + } + + av_dict_free(&p->opts); + } + } + + return 0; +} + +static int graph_parse(AVFilterGraph *graph, const char *desc, + AVFilterInOut **inputs, AVFilterInOut **outputs, + AVBufferRef *hw_device) +{ + AVFilterGraphSegment *seg; + int ret; + + *inputs = NULL; + *outputs = NULL; + + ret = avfilter_graph_segment_parse(graph, desc, 0, &seg); + if (ret < 0) + return ret; + + ret = avfilter_graph_segment_create_filters(seg, 0); + if (ret < 0) + goto fail; + + if (hw_device) { + for (int i = 0; i < graph->nb_filters; i++) { + AVFilterContext *f = graph->filters[i]; + + if (!(f->filter->flags & AVFILTER_FLAG_HWDEVICE)) + continue; + f->hw_device_ctx = av_buffer_ref(hw_device); + if (!f->hw_device_ctx) { + ret = AVERROR(ENOMEM); + goto fail; + } + } + } + + ret = graph_opts_apply(seg); + if (ret < 0) + goto fail; + + ret = avfilter_graph_segment_apply(seg, 0, inputs, outputs); + +fail: + avfilter_graph_segment_free(&seg); + return ret; +} + +static char *describe_filter_link(FilterGraph *fg, AVFilterInOut *inout, int in) +{ + AVFilterContext *ctx = inout->filter_ctx; + AVFilterPad *pads = in ? ctx->input_pads : ctx->output_pads; + int nb_pads = in ? ctx->nb_inputs : ctx->nb_outputs; + char *res; + + if (nb_pads > 1) + res = av_strdup(ctx->filter->name); + else + res = av_asprintf("%s:%s", ctx->filter->name, + avfilter_pad_get_name(pads, inout->pad_idx)); + if (!res) + report_and_exit(AVERROR(ENOMEM)); + return res; +} + static OutputFilter *ofilter_alloc(FilterGraph *fg) { OutputFilter *ofilter; @@ -395,23 +582,6 @@ int init_simple_filtergraph(InputStream *ist, OutputStream *ost, return 0; } -static char *describe_filter_link(FilterGraph *fg, AVFilterInOut *inout, int in) -{ - AVFilterContext *ctx = inout->filter_ctx; - AVFilterPad *pads = in ? ctx->input_pads : ctx->output_pads; - int nb_pads = in ? ctx->nb_inputs : ctx->nb_outputs; - char *res; - - if (nb_pads > 1) - res = av_strdup(ctx->filter->name); - else - res = av_asprintf("%s:%s", ctx->filter->name, - avfilter_pad_get_name(pads, inout->pad_idx)); - if (!res) - report_and_exit(AVERROR(ENOMEM)); - return res; -} - static void init_input_filter(FilterGraph *fg, AVFilterInOut *in) { FilterGraphPriv *fgp = fgp_from_fg(fg); @@ -480,176 +650,6 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in) } } -static int read_binary(const char *path, uint8_t **data, int *len) -{ - AVIOContext *io = NULL; - int64_t fsize; - int ret; - - *data = NULL; - *len = 0; - - ret = avio_open2(&io, path, AVIO_FLAG_READ, &int_cb, NULL); - if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Cannot open file '%s': %s\n", - path, av_err2str(ret)); - return ret; - } - - fsize = avio_size(io); - if (fsize < 0 || fsize > INT_MAX) { - av_log(NULL, AV_LOG_ERROR, "Cannot obtain size of file %s\n", path); - ret = AVERROR(EIO); - goto fail; - } - - *data = av_malloc(fsize); - if (!*data) { - ret = AVERROR(ENOMEM); - goto fail; - } - - ret = avio_read(io, *data, fsize); - if (ret != fsize) { - av_log(NULL, AV_LOG_ERROR, "Error reading file %s\n", path); - ret = ret < 0 ? ret : AVERROR(EIO); - goto fail; - } - - *len = fsize; - - ret = 0; -fail: - avio_close(io); - if (ret < 0) { - av_freep(data); - *len = 0; - } - return ret; -} - -static int filter_opt_apply(AVFilterContext *f, const char *key, const char *val) -{ - const AVOption *o = NULL; - int ret; - - ret = av_opt_set(f, key, val, AV_OPT_SEARCH_CHILDREN); - if (ret >= 0) - return 0; - - if (ret == AVERROR_OPTION_NOT_FOUND && key[0] == '/') - o = av_opt_find(f, key + 1, NULL, 0, AV_OPT_SEARCH_CHILDREN); - if (!o) - goto err_apply; - - // key is a valid option name prefixed with '/' - // interpret value as a path from which to load the actual option value - key++; - - if (o->type == AV_OPT_TYPE_BINARY) { - uint8_t *data; - int len; - - ret = read_binary(val, &data, &len); - if (ret < 0) - goto err_load; - - ret = av_opt_set_bin(f, key, data, len, AV_OPT_SEARCH_CHILDREN); - av_freep(&data); - } else { - char *data = file_read(val); - if (!data) { - ret = AVERROR(EIO); - goto err_load; - } - - ret = av_opt_set(f, key, data, AV_OPT_SEARCH_CHILDREN); - av_freep(&data); - } - if (ret < 0) - goto err_apply; - - return 0; - -err_apply: - av_log(NULL, AV_LOG_ERROR, - "Error applying option '%s' to filter '%s': %s\n", - key, f->filter->name, av_err2str(ret)); - return ret; -err_load: - av_log(NULL, AV_LOG_ERROR, - "Error loading value for option '%s' from file '%s'\n", - key, val); - return ret; -} - -static int graph_opts_apply(AVFilterGraphSegment *seg) -{ - for (size_t i = 0; i < seg->nb_chains; i++) { - AVFilterChain *ch = seg->chains[i]; - - for (size_t j = 0; j < ch->nb_filters; j++) { - AVFilterParams *p = ch->filters[j]; - const AVDictionaryEntry *e = NULL; - - av_assert0(p->filter); - - while ((e = av_dict_iterate(p->opts, e))) { - int ret = filter_opt_apply(p->filter, e->key, e->value); - if (ret < 0) - return ret; - } - - av_dict_free(&p->opts); - } - } - - return 0; -} - -static int graph_parse(AVFilterGraph *graph, const char *desc, - AVFilterInOut **inputs, AVFilterInOut **outputs, - AVBufferRef *hw_device) -{ - AVFilterGraphSegment *seg; - int ret; - - *inputs = NULL; - *outputs = NULL; - - ret = avfilter_graph_segment_parse(graph, desc, 0, &seg); - if (ret < 0) - return ret; - - ret = avfilter_graph_segment_create_filters(seg, 0); - if (ret < 0) - goto fail; - - if (hw_device) { - for (int i = 0; i < graph->nb_filters; i++) { - AVFilterContext *f = graph->filters[i]; - - if (!(f->filter->flags & AVFILTER_FLAG_HWDEVICE)) - continue; - f->hw_device_ctx = av_buffer_ref(hw_device); - if (!f->hw_device_ctx) { - ret = AVERROR(ENOMEM); - goto fail; - } - } - } - - ret = graph_opts_apply(seg); - if (ret < 0) - goto fail; - - ret = avfilter_graph_segment_apply(seg, 0, inputs, outputs); - -fail: - avfilter_graph_segment_free(&seg); - return ret; -} - int init_complex_filtergraph(FilterGraph *fg) { FilterGraphPriv *fgp = fgp_from_fg(fg); |