This only supports one device globally, but more can be used by
passing them with input streams in hw_frames_ctx or by deriving new
devices inside a filter graph with hwmap.
---
 avtools/avconv.h        |  1 +
 avtools/avconv_filter.c | 10 ++++++++--
 avtools/avconv_opt.c    | 21 +++++++++++++++++++++
 3 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/avtools/avconv.h b/avtools/avconv.h
index 9415b208b..3354c5044 100644
--- a/avtools/avconv.h
+++ b/avtools/avconv.h
@@ -489,6 +489,7 @@ extern const OptionDef options[];
 extern const HWAccel hwaccels[];
 extern int hwaccel_lax_profile_check;
 extern AVBufferRef *hw_device_ctx;
+extern HWDevice *filter_hw_device;
 
 void reset_options(OptionsContext *o);
 void show_usage(void);
diff --git a/avtools/avconv_filter.c b/avtools/avconv_filter.c
index e53dcd271..884478da2 100644
--- a/avtools/avconv_filter.c
+++ b/avtools/avconv_filter.c
@@ -711,9 +711,15 @@ int configure_filtergraph(FilterGraph *fg)
     if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, 
&outputs)) < 0)
         goto fail;
 
-    if (hw_device_ctx) {
+    if (filter_hw_device || hw_device_ctx) {
+        AVBufferRef *device = filter_hw_device ? filter_hw_device->device_ref
+                                               : hw_device_ctx;
         for (i = 0; i < fg->graph->nb_filters; i++) {
-            fg->graph->filters[i]->hw_device_ctx = 
av_buffer_ref(hw_device_ctx);
+            fg->graph->filters[i]->hw_device_ctx = av_buffer_ref(device);
+            if (!fg->graph->filters[i]->hw_device_ctx) {
+                ret = AVERROR(ENOMEM);
+                goto fail;
+            }
         }
     }
 
diff --git a/avtools/avconv_opt.c b/avtools/avconv_opt.c
index e970c8e46..cdc980870 100644
--- a/avtools/avconv_opt.c
+++ b/avtools/avconv_opt.c
@@ -80,6 +80,7 @@ const HWAccel hwaccels[] = {
 };
 int hwaccel_lax_profile_check = 0;
 AVBufferRef *hw_device_ctx;
+HWDevice *filter_hw_device;
 
 char *vstats_filename;
 
@@ -369,6 +370,24 @@ static int opt_init_hw_device(void *optctx, const char 
*opt, const char *arg)
     }
 }
 
+static int opt_filter_hw_device(void *optctx, const char *opt, const char *arg)
+{
+    int err;
+    if (filter_hw_device) {
+        av_log(NULL, AV_LOG_ERROR, "Only one filter device can be used.\n");
+        return AVERROR(EINVAL);
+    }
+    filter_hw_device = hw_device_get_by_name(arg);
+    if (!filter_hw_device) {
+        err = hw_device_init_from_string(arg, &filter_hw_device);
+        if (err < 0) {
+            av_log(NULL, AV_LOG_ERROR, "Invalid filter device %s.\n", arg);
+            return AVERROR_UNKNOWN;
+        }
+    }
+    return 0;
+}
+
 /**
  * Parse a metadata specifier passed as 'arg' parameter.
  * @param arg  metadata string to parse
@@ -2775,6 +2794,8 @@ const OptionDef options[] = {
 
     { "init_hw_device", HAS_ARG | OPT_EXPERT, { .func_arg = opt_init_hw_device 
},
         "initialise hardware device", "args" },
+    { "filter_hw_device", HAS_ARG | OPT_EXPERT, { .func_arg = 
opt_filter_hw_device },
+        "set hardware device used when filtering", "device" },
 
     { NULL, },
 };
-- 
2.11.0

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to