From: Anton Khirnov <anton@khirnov.net> To: ffmpeg-devel@ffmpeg.org Subject: [FFmpeg-devel] [PATCH 07/24] fftools/ffmpeg_filter: move some functions higher up Date: Sun, 28 May 2023 11:13:59 +0200 Message-ID: <20230528091416.17927-7-anton@khirnov.net> (raw) In-Reply-To: <20230528091416.17927-1-anton@khirnov.net> Needed by the following commit. --- fftools/ffmpeg_filter.c | 374 ++++++++++++++++++++-------------------- 1 file 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); -- 2.40.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2023-05-28 9:16 UTC|newest] Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-05-28 9:13 [FFmpeg-devel] [PATCH 01/24] fftools/ffmpeg_mux_init: merge ost_add_from_filter() to ost_add() Anton Khirnov 2023-05-28 9:13 ` [FFmpeg-devel] [PATCH 02/24] fftools/ffmpeg: add logging for creating output streams Anton Khirnov 2023-05-28 9:13 ` [FFmpeg-devel] [PATCH 03/24] fftools/ffmpeg_filter: use a dedicated variable for marking simple filtergraphs Anton Khirnov 2023-05-28 9:13 ` [FFmpeg-devel] [PATCH 04/24] fftools/ffmpeg_filter: always pass graph description to fg_create() Anton Khirnov 2023-05-28 9:13 ` [FFmpeg-devel] [PATCH 05/24] fftools/ffmpeg_filter: store just the link label in OutputFilter Anton Khirnov 2023-05-28 9:13 ` [FFmpeg-devel] [PATCH 06/24] fftools/ffmpeg_filter: decouple allocating InputFilter and binding it to InputStream Anton Khirnov 2023-05-28 9:13 ` Anton Khirnov [this message] 2023-05-28 9:14 ` [FFmpeg-devel] [PATCH 08/24] fftools/ffmpeg_filter: create Input/OutputFilters together with FilterGraph Anton Khirnov 2023-05-28 9:14 ` [FFmpeg-devel] [PATCH 09/24] fftools/ffmpeg_filter: factor out binding an output stream to OutputFilter Anton Khirnov 2023-05-28 9:14 ` [FFmpeg-devel] [PATCH 10/24] fftools/ffmpeg_mux_init: move OutputFilter setup code to ffmpeg_filter Anton Khirnov 2023-05-28 9:14 ` [FFmpeg-devel] [PATCH 11/24] fftools/ffmpeg_filter: try to configure filtergraphs earlier Anton Khirnov 2023-05-28 9:14 ` [FFmpeg-devel] [PATCH 12/24] fftools/ffmpeg: constify AVSubtitle parameters as appropriate Anton Khirnov 2023-05-28 9:14 ` [FFmpeg-devel] [PATCH 13/24] fftools/ffmpeg_dec: move sub2video submission to ffmpeg_filter Anton Khirnov 2023-05-28 9:14 ` [FFmpeg-devel] [PATCH 14/24] fftools/ffmpeg_filter: move sub2video subtitle queue to InputFilterPriv Anton Khirnov 2023-05-28 9:14 ` [FFmpeg-devel] [PATCH 15/24] fftools/ffmpeg: tweak sub2video_heartbeat() arguments Anton Khirnov 2023-05-28 9:14 ` [FFmpeg-devel] [PATCH 16/24] fftools/ffmpeg: rework setting sub2video parameters Anton Khirnov 2023-05-28 19:43 ` Michael Niedermayer 2023-05-29 12:49 ` [FFmpeg-devel] [PATCH] " Anton Khirnov 2023-05-31 17:02 ` Michael Niedermayer 2023-05-28 9:14 ` [FFmpeg-devel] [PATCH 17/24] fftools/ffmpeg: move sub2video handling to ffmpeg_filter Anton Khirnov 2023-05-28 9:14 ` [FFmpeg-devel] [PATCH 18/24] fftools/ffmpeg_enc: stop configuring filters from encoder flush Anton Khirnov 2023-05-28 9:14 ` [FFmpeg-devel] [PATCH 19/24] fftools/ffmpeg_filter: drop unreachable code Anton Khirnov 2023-05-28 9:14 ` [FFmpeg-devel] [PATCH 20/24] fftools/ffmpeg_filter: make ifilter_has_all_input_formats() static Anton Khirnov 2023-05-28 9:14 ` [FFmpeg-devel] [PATCH 21/24] fftools/ffmpeg_filter: make InputStream.filter private Anton Khirnov 2023-05-28 9:14 ` [FFmpeg-devel] [PATCH 22/24] fftools/ffmpeg_filter: constify the argument of filtergraph_is_simple() Anton Khirnov 2023-05-28 9:14 ` [FFmpeg-devel] [PATCH 23/24] fftools/ffmpeg_mux: flush bsfs immediately on exceeding recoding time Anton Khirnov 2023-05-28 9:14 ` [FFmpeg-devel] [PATCH 24/24] fftools/ffmpeg_filter: do not flush encoders on parameter change Anton Khirnov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20230528091416.17927-7-anton@khirnov.net \ --to=anton@khirnov.net \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git