aboutsummaryrefslogtreecommitdiffstats
path: root/fftools/ffmpeg_filter.c
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2023-05-21 20:29:59 +0200
committerAnton Khirnov <anton@khirnov.net>2023-05-31 16:15:47 +0200
commita1061d4bdcbfb866011c18e787ec334ae48f2820 (patch)
treefa84fbbac8f5ace84e267f39cc7b61327a1ad517 /fftools/ffmpeg_filter.c
parent00183880aa065e97a3ec37524c802b562f83876d (diff)
downloadffmpeg-a1061d4bdcbfb866011c18e787ec334ae48f2820.tar.gz
fftools/ffmpeg_filter: move some functions higher up
Needed by the following commit.
Diffstat (limited to 'fftools/ffmpeg_filter.c')
-rw-r--r--fftools/ffmpeg_filter.c374
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);