aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2024-10-07 12:38:43 +0200
committerAnton Khirnov <anton@khirnov.net>2024-10-10 09:09:29 +0200
commit0f5592cfc73773b895e81ae1ab8404b0ff2dc6b1 (patch)
tree07108599f24e44f1eafac2714b8c4b2a12285085
parent84c2ca6fa07e5507092ffaffb47f4a0d88a7b88c (diff)
downloadffmpeg-0f5592cfc73773b895e81ae1ab8404b0ff2dc6b1.tar.gz
fftools/ffmpeg: supply hw device context to probe-filtergraphs
I.e. those that are only used to figure out input/output counts, since some filters might expect a valid hw device in init and refuse to initalize otherwise. This requires complex filtergraphs to be created in a separate step after parsing global options, after all hw devices are guaranteed to exist.
-rw-r--r--fftools/ffmpeg_filter.c3
-rw-r--r--fftools/ffmpeg_opt.c43
2 files changed, 41 insertions, 5 deletions
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 4d444c161f..4524a3e535 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -1097,7 +1097,8 @@ int fg_create(FilterGraph **pfg, char *graph_desc, Scheduler *sch)
return AVERROR(ENOMEM);;
graph->nb_threads = 1;
- ret = graph_parse(graph, fgp->graph_desc, &inputs, &outputs, NULL);
+ ret = graph_parse(graph, fgp->graph_desc, &inputs, &outputs,
+ hw_device_for_filter());
if (ret < 0)
goto fail;
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index 052e68e943..9bf0c4f0c4 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -90,6 +90,9 @@ int recast_media = 0;
// to func_arg() for global options
typedef struct GlobalOptionsContext {
Scheduler *sch;
+
+ char **filtergraphs;
+ int nb_filtergraphs;
} GlobalOptionsContext;
static void uninit_options(OptionsContext *o)
@@ -1157,25 +1160,45 @@ static int opt_audio_qscale(void *optctx, const char *opt, const char *arg)
static int opt_filter_complex(void *optctx, const char *opt, const char *arg)
{
GlobalOptionsContext *go = optctx;
- char *graph_desc = av_strdup(arg);
+ char *graph_desc;
+ int ret;
+
+ graph_desc = av_strdup(arg);
if (!graph_desc)
return AVERROR(ENOMEM);
- return fg_create(NULL, graph_desc, go->sch);
+ ret = GROW_ARRAY(go->filtergraphs, go->nb_filtergraphs);
+ if (ret < 0) {
+ av_freep(&graph_desc);
+ return ret;
+ }
+ go->filtergraphs[go->nb_filtergraphs - 1] = graph_desc;
+
+ return 0;
}
#if FFMPEG_OPT_FILTER_SCRIPT
static int opt_filter_complex_script(void *optctx, const char *opt, const char *arg)
{
GlobalOptionsContext *go = optctx;
- char *graph_desc = file_read(arg);
+ char *graph_desc;
+ int ret;
+
+ graph_desc = file_read(arg);
if (!graph_desc)
return AVERROR(EINVAL);
av_log(NULL, AV_LOG_WARNING, "-%s is deprecated, use -/filter_complex %s instead\n",
opt, arg);
- return fg_create(NULL, graph_desc, go->sch);
+ ret = GROW_ARRAY(go->filtergraphs, go->nb_filtergraphs);
+ if (ret < 0) {
+ av_freep(&graph_desc);
+ return ret;
+ }
+ go->filtergraphs[go->nb_filtergraphs - 1] = graph_desc;
+
+ return 0;
}
#endif
@@ -1377,6 +1400,14 @@ int ffmpeg_parse_options(int argc, char **argv, Scheduler *sch)
/* configure terminal and setup signal handlers */
term_init();
+ /* create complex filtergraphs */
+ for (int i = 0; i < go.nb_filtergraphs; i++) {
+ ret = fg_create(NULL, go.filtergraphs[i], sch);
+ go.filtergraphs[i] = NULL;
+ if (ret < 0)
+ goto fail;
+ }
+
/* open input files */
ret = open_files(&octx.groups[GROUP_INFILE], "input", sch, ifile_open);
if (ret < 0) {
@@ -1412,6 +1443,10 @@ int ffmpeg_parse_options(int argc, char **argv, Scheduler *sch)
goto fail;
fail:
+ for (int i = 0; i < go.nb_filtergraphs; i++)
+ av_freep(&go.filtergraphs[i]);
+ av_freep(&go.filtergraphs);
+
uninit_parse_context(&octx);
if (ret < 0 && ret != AVERROR_EXIT) {
av_log(NULL, AV_LOG_FATAL, "Error %s: %s\n",