Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
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".

  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