Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH v5 1/5] avutil/hwcontext: add a function to get the AVHWDeviceType
@ 2023-04-25  7:26 Tong Wu
  2023-04-25  7:26 ` [FFmpeg-devel] [PATCH v5 2/5] avfilter/vf_hwmap: get the AVHWDeviceType from outlink format Tong Wu
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Tong Wu @ 2023-04-25  7:26 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Tong Wu

Add a function to get the corresponding AVHWDeviceType from a given
hardware pixel format.

Signed-off-by: Tong Wu <tong1.wu@intel.com>
---
 libavutil/hwcontext.c | 11 +++++++++++
 libavutil/hwcontext.h | 12 ++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/libavutil/hwcontext.c b/libavutil/hwcontext.c
index 3396598269..3042bf9af0 100644
--- a/libavutil/hwcontext.c
+++ b/libavutil/hwcontext.c
@@ -80,6 +80,17 @@ static const char *const hw_type_names[] = {
     [AV_HWDEVICE_TYPE_VULKAN] = "vulkan",
 };
 
+enum AVHWDeviceType av_hwdevice_get_type_by_pix_fmt(enum AVPixelFormat fmt)
+{
+    for (int i = 0; hw_table[i]; i++) {
+        for (int j = 0; hw_table[i]->pix_fmts[j] != AV_PIX_FMT_NONE; j++) {
+            if (hw_table[i]->pix_fmts[j] == fmt)
+                return hw_table[i]->type;
+        }
+    }
+    return AV_HWDEVICE_TYPE_NONE;
+}
+
 enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name)
 {
     int type;
diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
index 7ff08c8608..940c7a6a46 100644
--- a/libavutil/hwcontext.h
+++ b/libavutil/hwcontext.h
@@ -229,6 +229,18 @@ typedef struct AVHWFramesContext {
     int width, height;
 } AVHWFramesContext;
 
+/**
+ * Get the device type by a given pixel format.
+ *
+ * This function only returns a preferred device type which supports the given
+ * pixel format. There is no guarantee that the device type is unique.
+ *
+ * @param fmt Pixel format from enum AVPixelFormat.
+ * @return The type from enum AVHWDeviceType, or AV_HWDEVICE_TYPE_NONE if
+ *         not found.
+ */
+enum AVHWDeviceType av_hwdevice_get_type_by_pix_fmt(enum AVPixelFormat fmt);
+
 /**
  * Look up an AVHWDeviceType by name.
  *
-- 
2.39.1.windows.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".

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [FFmpeg-devel] [PATCH v5 2/5] avfilter/vf_hwmap: get the AVHWDeviceType from outlink format
  2023-04-25  7:26 [FFmpeg-devel] [PATCH v5 1/5] avutil/hwcontext: add a function to get the AVHWDeviceType Tong Wu
@ 2023-04-25  7:26 ` Tong Wu
  2023-04-25  7:26 ` [FFmpeg-devel] [PATCH v5 3/5] lavfi/avfiltergraph: move convert codes into functions Tong Wu
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 10+ messages in thread
From: Tong Wu @ 2023-04-25  7:26 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Tong Wu

When both derive_device_type and device context are not
presented during hw->hw map, the hwmap filter should be
able to retrieve AVHWDeviceType from outlink->format and create
corresponding hwdevice context.

Signed-off-by: Tong Wu <tong1.wu@intel.com>
---
 libavfilter/vf_hwmap.c | 35 ++++++++++++++++++++++-------------
 1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/libavfilter/vf_hwmap.c b/libavfilter/vf_hwmap.c
index e246b22603..e5b40233b2 100644
--- a/libavfilter/vf_hwmap.c
+++ b/libavfilter/vf_hwmap.c
@@ -70,16 +70,31 @@ static int hwmap_config_output(AVFilterLink *outlink)
     device_is_derived = 0;
 
     if (inlink->hw_frames_ctx) {
+        enum AVHWDeviceType type;
         hwfc = (AVHWFramesContext*)inlink->hw_frames_ctx->data;
 
-        if (ctx->derive_device_type) {
-            enum AVHWDeviceType type;
+        desc = av_pix_fmt_desc_get(outlink->format);
+        if (!desc) {
+            err = AVERROR(EINVAL);
+            goto fail;
+        }
 
-            type = av_hwdevice_find_type_by_name(ctx->derive_device_type);
-            if (type == AV_HWDEVICE_TYPE_NONE) {
-                av_log(avctx, AV_LOG_ERROR, "Invalid device type.\n");
-                err = AVERROR(EINVAL);
-                goto fail;
+        if (ctx->derive_device_type || (!device && (desc->flags & AV_PIX_FMT_FLAG_HWACCEL))) {
+            if (ctx->derive_device_type) {
+                type = av_hwdevice_find_type_by_name(ctx->derive_device_type);
+                if (type == AV_HWDEVICE_TYPE_NONE) {
+                    av_log(avctx, AV_LOG_ERROR, "Invalid device type.\n");
+                    err = AVERROR(EINVAL);
+                    goto fail;
+                }
+            } else {
+                type = av_hwdevice_get_type_by_pix_fmt(outlink->format);
+                if (type == AV_HWDEVICE_TYPE_NONE) {
+                    av_log(avctx, AV_LOG_ERROR, "Could not get device type from "
+                        "format %s.\n", av_get_pix_fmt_name(outlink->format));
+                    err = AVERROR(EINVAL);
+                    goto fail;
+                }
             }
 
             err = av_hwdevice_ctx_create_derived(&device, type,
@@ -92,12 +107,6 @@ static int hwmap_config_output(AVFilterLink *outlink)
             device_is_derived = 1;
         }
 
-        desc = av_pix_fmt_desc_get(outlink->format);
-        if (!desc) {
-            err = AVERROR(EINVAL);
-            goto fail;
-        }
-
         if (inlink->format == hwfc->format &&
             (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) &&
             !ctx->reverse) {
-- 
2.39.1.windows.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".

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [FFmpeg-devel] [PATCH v5 3/5] lavfi/avfiltergraph: move convert codes into functions
  2023-04-25  7:26 [FFmpeg-devel] [PATCH v5 1/5] avutil/hwcontext: add a function to get the AVHWDeviceType Tong Wu
  2023-04-25  7:26 ` [FFmpeg-devel] [PATCH v5 2/5] avfilter/vf_hwmap: get the AVHWDeviceType from outlink format Tong Wu
@ 2023-04-25  7:26 ` Tong Wu
  2023-04-25  7:26 ` [FFmpeg-devel] [PATCH v5 4/5] lavfi/format: wrap auto filters into structures Tong Wu
  2023-04-25  7:26 ` [FFmpeg-devel] [PATCH v5 5/5] lavfi/format: add a hwmap auto conversion filter Tong Wu
  3 siblings, 0 replies; 10+ messages in thread
From: Tong Wu @ 2023-04-25  7:26 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Tong Wu

This patch moves the auto-insert filter codes into two functions.

Signed-off-by: Tong Wu <tong1.wu@intel.com>
---
 libavfilter/avfiltergraph.c | 128 ++++++++++++++++++++++--------------
 1 file changed, 79 insertions(+), 49 deletions(-)

diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index 53f468494d..9e5bb32886 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -393,6 +393,74 @@ static int formats_declared(AVFilterContext *f)
     return 1;
 }
 
+static int insert_auto_filter(AVFilterContext **convert, AVFilterGraph *graph,
+                              AVFilterLink *link, const AVFilterNegotiation *neg,
+                              int *converter_count, void *log_ctx)
+{
+    int ret;
+    const AVFilter *filter;
+    AVFilterContext *ctx;
+    AVFilterLink *inlink, *outlink;
+    char inst_name[30];
+    const char *opts;
+
+    if (!(filter = avfilter_get_by_name(neg->conversion_filter))) {
+        av_log(log_ctx, AV_LOG_ERROR,
+               "'%s' filter not present, cannot convert formats.\n",
+               neg->conversion_filter);
+        return AVERROR(EINVAL);
+    }
+    snprintf(inst_name, sizeof(inst_name), "auto_%s_%d",
+             neg->conversion_filter, (*converter_count)++);
+    opts = FF_FIELD_AT(char *, neg->conversion_opts_offset, *graph);
+    ret = avfilter_graph_create_filter(&ctx, filter, inst_name, opts, NULL, graph);
+    if (ret < 0)
+        return ret;
+
+    if ((ret = avfilter_insert_filter(link, ctx, 0, 0)) < 0)
+        return ret;
+
+    if ((ret = filter_query_formats(ctx)) < 0)
+        return ret;
+
+    inlink  = ctx->inputs[0];
+    outlink = ctx->outputs[0];
+    av_assert0( inlink->incfg.formats->refcount > 0);
+    av_assert0( inlink->outcfg.formats->refcount > 0);
+    av_assert0(outlink->incfg.formats->refcount > 0);
+    av_assert0(outlink->outcfg.formats->refcount > 0);
+    if (outlink->type == AVMEDIA_TYPE_AUDIO) {
+        av_assert0( inlink-> incfg.samplerates->refcount > 0);
+        av_assert0( inlink->outcfg.samplerates->refcount > 0);
+        av_assert0(outlink-> incfg.samplerates->refcount > 0);
+        av_assert0(outlink->outcfg.samplerates->refcount > 0);
+        av_assert0( inlink-> incfg.channel_layouts->refcount > 0);
+        av_assert0( inlink->outcfg.channel_layouts->refcount > 0);
+        av_assert0(outlink-> incfg.channel_layouts->refcount > 0);
+        av_assert0(outlink->outcfg.channel_layouts->refcount > 0);
+    }
+
+    *convert = ctx;
+    return 0;
+}
+
+static int merge_auto_filter(AVFilterContext *convert, const AVFilterNegotiation *neg)
+{
+    int ret;
+    AVFilterLink *inlink  = convert->inputs[0];
+    AVFilterLink *outlink = convert->outputs[0];
+#define MERGE(merger, link)                                                  \
+    ((merger)->merge(FF_FIELD_AT(void *, (merger)->offset, (link)->incfg),   \
+                     FF_FIELD_AT(void *, (merger)->offset, (link)->outcfg)))
+    for (unsigned neg_step = 0; neg_step < neg->nb_mergers; neg_step++) {
+        const AVFilterFormatsMerger *m = &neg->mergers[neg_step];
+        if ((ret = MERGE(m,  inlink)) <= 0 ||
+            (ret = MERGE(m, outlink)) <= 0)
+                break;
+    }
+    return ret;
+}
+
 /**
  * Perform one round of query_formats() and merging formats lists on the
  * filter graph.
@@ -470,10 +538,6 @@ static int query_formats(AVFilterGraph *graph, void *log_ctx)
 
             if (convert_needed) {
                 AVFilterContext *convert;
-                const AVFilter *filter;
-                AVFilterLink *inlink, *outlink;
-                char inst_name[30];
-                const char *opts;
 
                 if (graph->disable_auto_convert) {
                     av_log(log_ctx, AV_LOG_ERROR,
@@ -484,54 +548,20 @@ static int query_formats(AVFilterGraph *graph, void *log_ctx)
                 }
 
                 /* couldn't merge format lists. auto-insert conversion filter */
-                if (!(filter = avfilter_get_by_name(neg->conversion_filter))) {
-                    av_log(log_ctx, AV_LOG_ERROR,
-                           "'%s' filter not present, cannot convert formats.\n",
-                           neg->conversion_filter);
-                    return AVERROR(EINVAL);
-                }
-                snprintf(inst_name, sizeof(inst_name), "auto_%s_%d",
-                         neg->conversion_filter, converter_count++);
-                opts = FF_FIELD_AT(char *, neg->conversion_opts_offset, *graph);
-                ret = avfilter_graph_create_filter(&convert, filter, inst_name, opts, NULL, graph);
-                if (ret < 0)
-                    return ret;
-                if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0)
+                ret = insert_auto_filter(&convert, graph, link, neg, &converter_count, log_ctx);
+                if (ret < 0) {
+                    av_log(log_ctx, AV_LOG_ERROR, "Failed to insert an auto filter.\n");
                     return ret;
+                }
 
-                if ((ret = filter_query_formats(convert)) < 0)
+                ret = merge_auto_filter(convert, neg);
+                if (ret < 0)
                     return ret;
-
-                inlink  = convert->inputs[0];
-                outlink = convert->outputs[0];
-                av_assert0( inlink->incfg.formats->refcount > 0);
-                av_assert0( inlink->outcfg.formats->refcount > 0);
-                av_assert0(outlink->incfg.formats->refcount > 0);
-                av_assert0(outlink->outcfg.formats->refcount > 0);
-                if (outlink->type == AVMEDIA_TYPE_AUDIO) {
-                    av_assert0( inlink-> incfg.samplerates->refcount > 0);
-                    av_assert0( inlink->outcfg.samplerates->refcount > 0);
-                    av_assert0(outlink-> incfg.samplerates->refcount > 0);
-                    av_assert0(outlink->outcfg.samplerates->refcount > 0);
-                    av_assert0( inlink-> incfg.channel_layouts->refcount > 0);
-                    av_assert0( inlink->outcfg.channel_layouts->refcount > 0);
-                    av_assert0(outlink-> incfg.channel_layouts->refcount > 0);
-                    av_assert0(outlink->outcfg.channel_layouts->refcount > 0);
-                }
-#define MERGE(merger, link)                                                  \
-    ((merger)->merge(FF_FIELD_AT(void *, (merger)->offset, (link)->incfg),   \
-                     FF_FIELD_AT(void *, (merger)->offset, (link)->outcfg)))
-                for (neg_step = 0; neg_step < neg->nb_mergers; neg_step++) {
-                    const AVFilterFormatsMerger *m = &neg->mergers[neg_step];
-                    if ((ret = MERGE(m,  inlink)) <= 0 ||
-                        (ret = MERGE(m, outlink)) <= 0) {
-                        if (ret < 0)
-                            return ret;
-                        av_log(log_ctx, AV_LOG_ERROR,
-                               "Impossible to convert between the formats supported by the filter "
-                               "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
-                        return AVERROR(ENOSYS);
-                    }
+                else if (ret == 0) {
+                    av_log(log_ctx, AV_LOG_ERROR,
+                           "Impossible to convert between the formats supported by the filter "
+                           "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
+                    return AVERROR(ENOSYS);
                 }
             }
         }
-- 
2.39.1.windows.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".

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [FFmpeg-devel] [PATCH v5 4/5] lavfi/format: wrap auto filters into structures
  2023-04-25  7:26 [FFmpeg-devel] [PATCH v5 1/5] avutil/hwcontext: add a function to get the AVHWDeviceType Tong Wu
  2023-04-25  7:26 ` [FFmpeg-devel] [PATCH v5 2/5] avfilter/vf_hwmap: get the AVHWDeviceType from outlink format Tong Wu
  2023-04-25  7:26 ` [FFmpeg-devel] [PATCH v5 3/5] lavfi/avfiltergraph: move convert codes into functions Tong Wu
@ 2023-04-25  7:26 ` Tong Wu
  2023-05-13  6:33   ` Paul B Mahol
  2023-04-25  7:26 ` [FFmpeg-devel] [PATCH v5 5/5] lavfi/format: add a hwmap auto conversion filter Tong Wu
  3 siblings, 1 reply; 10+ messages in thread
From: Tong Wu @ 2023-04-25  7:26 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Tong Wu

This patch wraps auto conversion filters into new structures, making it
easier to add more auto filters. And it adds a loop to automatically insert
every possible conversion filter until merge succeeds.

Signed-off-by: Tong Wu <tong1.wu@intel.com>
---
 libavfilter/avfiltergraph.c | 76 +++++++++++++++++++++++++------------
 libavfilter/formats.c       | 22 +++++++++--
 libavfilter/formats.h       | 10 ++++-
 3 files changed, 78 insertions(+), 30 deletions(-)

diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index 9e5bb32886..8af0467bc5 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -395,24 +395,22 @@ static int formats_declared(AVFilterContext *f)
 
 static int insert_auto_filter(AVFilterContext **convert, AVFilterGraph *graph,
                               AVFilterLink *link, const AVFilterNegotiation *neg,
-                              int *converter_count, void *log_ctx)
+                              unsigned conv_step, int *converter_count, void *log_ctx)
 {
     int ret;
     const AVFilter *filter;
     AVFilterContext *ctx;
     AVFilterLink *inlink, *outlink;
     char inst_name[30];
-    const char *opts;
+    const char *opts = FF_FIELD_AT(char *, neg->conversion_filters[conv_step].conversion_opts_offset, *graph);
+    const char *name = neg->conversion_filters[conv_step].conversion_filter;
 
-    if (!(filter = avfilter_get_by_name(neg->conversion_filter))) {
+    if (!(filter = avfilter_get_by_name(name))) {
         av_log(log_ctx, AV_LOG_ERROR,
-               "'%s' filter not present, cannot convert formats.\n",
-               neg->conversion_filter);
+               "'%s' filter not present, cannot convert formats.\n", name);
         return AVERROR(EINVAL);
     }
-    snprintf(inst_name, sizeof(inst_name), "auto_%s_%d",
-             neg->conversion_filter, (*converter_count)++);
-    opts = FF_FIELD_AT(char *, neg->conversion_opts_offset, *graph);
+    snprintf(inst_name, sizeof(inst_name), "auto_%s_%d", name, (*converter_count)++);
     ret = avfilter_graph_create_filter(&ctx, filter, inst_name, opts, NULL, graph);
     if (ret < 0)
         return ret;
@@ -501,7 +499,7 @@ static int query_formats(AVFilterGraph *graph, void *log_ctx)
         for (j = 0; j < filter->nb_inputs; j++) {
             AVFilterLink *link = filter->inputs[j];
             const AVFilterNegotiation *neg;
-            unsigned neg_step;
+            unsigned neg_step, conv_step;
             int convert_needed = 0;
 
             if (!link)
@@ -537,8 +535,6 @@ static int query_formats(AVFilterGraph *graph, void *log_ctx)
             }
 
             if (convert_needed) {
-                AVFilterContext *convert;
-
                 if (graph->disable_auto_convert) {
                     av_log(log_ctx, AV_LOG_ERROR,
                            "The filters '%s' and '%s' do not have a common format "
@@ -548,20 +544,52 @@ static int query_formats(AVFilterGraph *graph, void *log_ctx)
                 }
 
                 /* couldn't merge format lists. auto-insert conversion filter */
-                ret = insert_auto_filter(&convert, graph, link, neg, &converter_count, log_ctx);
-                if (ret < 0) {
-                    av_log(log_ctx, AV_LOG_ERROR, "Failed to insert an auto filter.\n");
-                    return ret;
-                }
+                for (conv_step = 0; conv_step < neg->nb_conversion_filters; conv_step++) {
+                    AVFilterContext *convert;
+                    ret = insert_auto_filter(&convert, graph, link, neg,
+                                             conv_step, &converter_count, log_ctx);
+                    if (ret < 0) {
+                        av_log(log_ctx, AV_LOG_ERROR, "Failed to insert an auto filter.\n");
+                        return ret;
+                    }
 
-                ret = merge_auto_filter(convert, neg);
-                if (ret < 0)
-                    return ret;
-                else if (ret == 0) {
-                    av_log(log_ctx, AV_LOG_ERROR,
-                           "Impossible to convert between the formats supported by the filter "
-                           "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
-                    return AVERROR(ENOSYS);
+                    ret = merge_auto_filter(convert, neg);
+                    if (ret < 0)
+                        return ret;
+                    else if (ret > 0)
+                        break;
+                    else if (conv_step < neg->nb_conversion_filters - 1) {
+                        AVFilterLink *inlink  = convert->inputs[0];
+                        AVFilterLink *outlink = convert->outputs[0];
+                        av_log(log_ctx, AV_LOG_VERBOSE,
+                               "Impossible to convert between the formats supported by the filter "
+                               "'%s' and the filter '%s', try another conversion filter.\n",
+                               link->src->name, link->dst->name);
+                        unsigned dstpad_idx = outlink->dstpad - outlink->dst->input_pads;
+                        converter_count--;
+                        /* re-hookup the link */
+                        inlink->dst                      = outlink->dst;
+                        inlink->dstpad                   = &outlink->dst->input_pads[dstpad_idx];
+                        outlink->dst->inputs[dstpad_idx] = inlink;
+                        if (outlink->outcfg.formats)
+                            ff_formats_changeref(&outlink->outcfg.formats,
+                                                 &inlink->outcfg.formats);
+                        if (outlink->outcfg.samplerates)
+                            ff_formats_changeref(&outlink->outcfg.samplerates,
+                                                 &inlink->outcfg.samplerates);
+                        if (outlink->outcfg.channel_layouts)
+                            ff_channel_layouts_changeref(&outlink->outcfg.channel_layouts,
+                                                         &inlink->outcfg.channel_layouts);
+                        /* remove the previous auto filter */
+                        convert->inputs[0]       = NULL;
+                        convert->outputs[0]->dst = NULL;
+                        avfilter_free(convert);
+                    } else {
+                        av_log(log_ctx, AV_LOG_ERROR,
+                               "Impossible to convert between the formats supported by the filter "
+                               "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
+                        return AVERROR(ENOSYS);
+                    }
                 }
             }
         }
diff --git a/libavfilter/formats.c b/libavfilter/formats.c
index e8c2888c0c..c8e20e5b20 100644
--- a/libavfilter/formats.c
+++ b/libavfilter/formats.c
@@ -326,18 +326,32 @@ static const AVFilterFormatsMerger mergers_audio[] = {
     },
 };
 
+static const AVFilterFormatsFilter filters_video[] = {
+    {
+        .conversion_filter = "scale",
+        .conversion_opts_offset = offsetof(AVFilterGraph, scale_sws_opts),
+    },
+};
+
+static const AVFilterFormatsFilter filters_audio[] = {
+    {
+        .conversion_filter = "aresample",
+        .conversion_opts_offset = offsetof(AVFilterGraph, aresample_swr_opts),
+    }
+};
+
 static const AVFilterNegotiation negotiate_video = {
     .nb_mergers = FF_ARRAY_ELEMS(mergers_video),
     .mergers = mergers_video,
-    .conversion_filter = "scale",
-    .conversion_opts_offset = offsetof(AVFilterGraph, scale_sws_opts),
+    .nb_conversion_filters = FF_ARRAY_ELEMS(filters_video),
+    .conversion_filters = filters_video,
 };
 
 static const AVFilterNegotiation negotiate_audio = {
     .nb_mergers = FF_ARRAY_ELEMS(mergers_audio),
     .mergers = mergers_audio,
-    .conversion_filter = "aresample",
-    .conversion_opts_offset = offsetof(AVFilterGraph, aresample_swr_opts),
+    .nb_conversion_filters = FF_ARRAY_ELEMS(filters_audio),
+    .conversion_filters = filters_audio,
 };
 
 const AVFilterNegotiation *ff_filter_get_negotiation(AVFilterLink *link)
diff --git a/libavfilter/formats.h b/libavfilter/formats.h
index 22224dce2d..868cbe98dd 100644
--- a/libavfilter/formats.h
+++ b/libavfilter/formats.h
@@ -330,6 +330,12 @@ typedef struct AVFilterFormatMerger {
     int (*can_merge)(const void *a, const void *b);
 } AVFilterFormatsMerger;
 
+typedef struct AVFilterFormatFilter {
+    const char *conversion_filter;
+    unsigned conversion_opts_offset;
+} AVFilterFormatsFilter;
+
+
 /**
  * Callbacks and properties to describe the steps of a format negotiation.
  *
@@ -418,8 +424,8 @@ typedef struct AVFilterFormatMerger {
 typedef struct AVFilterNegotiation {
     unsigned nb_mergers;
     const AVFilterFormatsMerger *mergers;
-    const char *conversion_filter;
-    unsigned conversion_opts_offset;
+    unsigned nb_conversion_filters;
+    const AVFilterFormatsFilter *conversion_filters;
 } AVFilterNegotiation;
 
 const AVFilterNegotiation *ff_filter_get_negotiation(AVFilterLink *link);
-- 
2.39.1.windows.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".

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [FFmpeg-devel] [PATCH v5 5/5] lavfi/format: add a hwmap auto conversion filter
  2023-04-25  7:26 [FFmpeg-devel] [PATCH v5 1/5] avutil/hwcontext: add a function to get the AVHWDeviceType Tong Wu
                   ` (2 preceding siblings ...)
  2023-04-25  7:26 ` [FFmpeg-devel] [PATCH v5 4/5] lavfi/format: wrap auto filters into structures Tong Wu
@ 2023-04-25  7:26 ` Tong Wu
  2023-06-07  8:51   ` Marvin Scholz
  3 siblings, 1 reply; 10+ messages in thread
From: Tong Wu @ 2023-04-25  7:26 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Tong Wu

When two formats lists cannot be merged, a scale filter is
auto-inserted. However, when it comes to hardware map, we have to
manually add a hwmap filter to do the conversion. This patch introduces
an auto hwmap filter to do the hwmap conversion automatically.

Signed-off-by: Tong Wu <tong1.wu@intel.com>
---
 libavfilter/avfiltergraph.c | 3 ++-
 libavfilter/formats.c       | 4 ++++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index 8af0467bc5..b2b627ad6a 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -402,7 +402,8 @@ static int insert_auto_filter(AVFilterContext **convert, AVFilterGraph *graph,
     AVFilterContext *ctx;
     AVFilterLink *inlink, *outlink;
     char inst_name[30];
-    const char *opts = FF_FIELD_AT(char *, neg->conversion_filters[conv_step].conversion_opts_offset, *graph);
+    const char *opts = neg->conversion_filters[conv_step].conversion_opts_offset == 0 ? NULL :
+                       FF_FIELD_AT(char *, neg->conversion_filters[conv_step].conversion_opts_offset, *graph);
     const char *name = neg->conversion_filters[conv_step].conversion_filter;
 
     if (!(filter = avfilter_get_by_name(name))) {
diff --git a/libavfilter/formats.c b/libavfilter/formats.c
index c8e20e5b20..fee10fa0ee 100644
--- a/libavfilter/formats.c
+++ b/libavfilter/formats.c
@@ -331,6 +331,10 @@ static const AVFilterFormatsFilter filters_video[] = {
         .conversion_filter = "scale",
         .conversion_opts_offset = offsetof(AVFilterGraph, scale_sws_opts),
     },
+    {
+        .conversion_filter = "hwmap",
+        .conversion_opts_offset = 0,
+    }
 };
 
 static const AVFilterFormatsFilter filters_audio[] = {
-- 
2.39.1.windows.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".

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [FFmpeg-devel] [PATCH v5 4/5] lavfi/format: wrap auto filters into structures
  2023-04-25  7:26 ` [FFmpeg-devel] [PATCH v5 4/5] lavfi/format: wrap auto filters into structures Tong Wu
@ 2023-05-13  6:33   ` Paul B Mahol
  2023-05-25  7:06     ` Wu, Tong1
  0 siblings, 1 reply; 10+ messages in thread
From: Paul B Mahol @ 2023-05-13  6:33 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: Tong Wu

Possibility for infinite loops?

In what cases this helps, have graphs examples to test?
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [FFmpeg-devel] [PATCH v5 4/5] lavfi/format: wrap auto filters into structures
  2023-05-13  6:33   ` Paul B Mahol
@ 2023-05-25  7:06     ` Wu, Tong1
  2023-06-07  8:42       ` Wu, Tong1
  0 siblings, 1 reply; 10+ messages in thread
From: Wu, Tong1 @ 2023-05-25  7:06 UTC (permalink / raw)
  To: Paul B Mahol, FFmpeg development discussions and patches




>Possibility for infinite loops?

>In what cases this helps, have graphs examples to test?

Now we only have scale filter that can be auto inserted. This patch set basically gives the potential capability to add more auto filters. An auto hwmap filter is introduced for now. It can be beneficial to hwmap use cases.

For example,
ffmpeg -init_hw_device d3d11va=d3d11 -init_hw_device qsv=qsv@d3d11 -hwaccel d3d11va -hwaccel_output_format d3d11 -i input.mp4 -vf “hwmap=derive_device=qsv:extra_hw_frames=16,format=qsv” -c:v h264_qsv output.mp4

Now we don’t have to explicitly specify hwmap. The auto filter mechanism will try to insert a hwmap filter automatically. The command line will be much simpler.

ffmpeg -init_hw_device d3d11va=d3d11 -init_hw_device qsv=qsv@d3d11 -hwaccel d3d11va -hwaccel_output_format d3d11 -i input.mp4 -c:v h264_qsv output.mp4

Could you explain a little bit why the loop could be infinite?
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [FFmpeg-devel] [PATCH v5 4/5] lavfi/format: wrap auto filters into structures
  2023-05-25  7:06     ` Wu, Tong1
@ 2023-06-07  8:42       ` Wu, Tong1
  0 siblings, 0 replies; 10+ messages in thread
From: Wu, Tong1 @ 2023-06-07  8:42 UTC (permalink / raw)
  To: FFmpeg development discussions and patches, Paul B Mahol

Kindly ping


>>Possibility for infinite loops?
>
>>In what cases this helps, have graphs examples to test?
>
>Now we only have scale filter that can be auto inserted. This patch set
>basically gives the potential capability to add more auto filters. An auto
>hwmap filter is introduced for now. It can be beneficial to hwmap use cases.
>
>For example,
>ffmpeg -init_hw_device d3d11va=d3d11 -init_hw_device qsv=qsv@d3d11 -
>hwaccel d3d11va -hwaccel_output_format d3d11 -i input.mp4 -vf
>“hwmap=derive_device=qsv:extra_hw_frames=16,format=qsv” -c:v h264_qsv
>output.mp4
>
>Now we don’t have to explicitly specify hwmap. The auto filter mechanism will
>try to insert a hwmap filter automatically. The command line will be much
>simpler.
>
>ffmpeg -init_hw_device d3d11va=d3d11 -init_hw_device qsv=qsv@d3d11 -
>hwaccel d3d11va -hwaccel_output_format d3d11 -i input.mp4 -c:v h264_qsv
>output.mp4
>
>Could you explain a little bit why the loop could be infinite?
>_______________________________________________
>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".
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [FFmpeg-devel] [PATCH v5 5/5] lavfi/format: add a hwmap auto conversion filter
  2023-04-25  7:26 ` [FFmpeg-devel] [PATCH v5 5/5] lavfi/format: add a hwmap auto conversion filter Tong Wu
@ 2023-06-07  8:51   ` Marvin Scholz
  2023-06-08  8:47     ` Wu, Tong1
  0 siblings, 1 reply; 10+ messages in thread
From: Marvin Scholz @ 2023-06-07  8:51 UTC (permalink / raw)
  To: FFmpeg development discussions and patches



On 25 Apr 2023, at 9:26, Tong Wu wrote:

> When two formats lists cannot be merged, a scale filter is
> auto-inserted. However, when it comes to hardware map, we have to
> manually add a hwmap filter to do the conversion. This patch introduces
> an auto hwmap filter to do the hwmap conversion automatically.
>

Thanks for trying to improve this!

I've recently done quite a bit of experimentation with hardware
filters and at least for the Cuda - Vulkan - Cuda case, hwmap
was useless, and I was told I need to use hwupload instead, so I wonder
what cases this would help with?

I just fear that, especially given the bad error messages hwmap gives,
this will just implicitly insert it because it seemingly works but then
just fail to actually do the job and give an absolutely indescriptive
error to the user for a filter they did not even insert themselves.

> Signed-off-by: Tong Wu <tong1.wu@intel.com>
> ---
>  libavfilter/avfiltergraph.c | 3 ++-
>  libavfilter/formats.c       | 4 ++++
>  2 files changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
> index 8af0467bc5..b2b627ad6a 100644
> --- a/libavfilter/avfiltergraph.c
> +++ b/libavfilter/avfiltergraph.c
> @@ -402,7 +402,8 @@ static int insert_auto_filter(AVFilterContext **convert, AVFilterGraph *graph,
>      AVFilterContext *ctx;
>      AVFilterLink *inlink, *outlink;
>      char inst_name[30];
> -    const char *opts = FF_FIELD_AT(char *, neg->conversion_filters[conv_step].conversion_opts_offset, *graph);
> +    const char *opts = neg->conversion_filters[conv_step].conversion_opts_offset == 0 ? NULL :
> +                       FF_FIELD_AT(char *, neg->conversion_filters[conv_step].conversion_opts_offset, *graph);
>      const char *name = neg->conversion_filters[conv_step].conversion_filter;
>
>      if (!(filter = avfilter_get_by_name(name))) {
> diff --git a/libavfilter/formats.c b/libavfilter/formats.c
> index c8e20e5b20..fee10fa0ee 100644
> --- a/libavfilter/formats.c
> +++ b/libavfilter/formats.c
> @@ -331,6 +331,10 @@ static const AVFilterFormatsFilter filters_video[] = {
>          .conversion_filter = "scale",
>          .conversion_opts_offset = offsetof(AVFilterGraph, scale_sws_opts),
>      },
> +    {
> +        .conversion_filter = "hwmap",
> +        .conversion_opts_offset = 0,
> +    }
>  };
>
>  static const AVFilterFormatsFilter filters_audio[] = {
> -- 
> 2.39.1.windows.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".
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [FFmpeg-devel] [PATCH v5 5/5] lavfi/format: add a hwmap auto conversion filter
  2023-06-07  8:51   ` Marvin Scholz
@ 2023-06-08  8:47     ` Wu, Tong1
  0 siblings, 0 replies; 10+ messages in thread
From: Wu, Tong1 @ 2023-06-08  8:47 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

>On 25 Apr 2023, at 9:26, Tong Wu wrote:
>
>> When two formats lists cannot be merged, a scale filter is
>> auto-inserted. However, when it comes to hardware map, we have to
>> manually add a hwmap filter to do the conversion. This patch introduces
>> an auto hwmap filter to do the hwmap conversion automatically.
>>
>
>Thanks for trying to improve this!
>
>I've recently done quite a bit of experimentation with hardware
>filters and at least for the Cuda - Vulkan - Cuda case, hwmap
>was useless, and I was told I need to use hwupload instead, so I wonder
>what cases this would help with?

Thanks for the reply!

Actually we are using hwmap filter to do vaapi<->qsv, d3d11<->qsv conversions.

For the use case I have replied in another mail. I'll just copy here again.
For example,
ffmpeg -init_hw_device d3d11va=d3d11 -init_hw_device qsv=qsv@d3d11 -
hwaccel d3d11va -hwaccel_output_format d3d11 -i input.mp4 -vf
"hwmap=derive_device=qsv:extra_hw_frames=16,format=qsv" -c:v h264_qsv
output.mp4

Now we don't have to explicitly specify hwmap. The auto filter mechanism will
try to insert a hwmap filter automatically. The command line will be much
simpler.

ffmpeg -init_hw_device d3d11va=d3d11 -init_hw_device qsv=qsv@d3d11 -
hwaccel d3d11va -hwaccel_output_format d3d11 -i input.mp4 -c:v h264_qsv
output.mp4



>
>I just fear that, especially given the bad error messages hwmap gives,
>this will just implicitly insert it because it seemingly works but then
>just fail to actually do the job and give an absolutely indescriptive
>error to the user for a filter they did not even insert themselves.

Yes I agree with that. However, we already have an auto scale filter in the framework.
It will always be inserted when two filters cannot be linked.

In my opinion, I'm just kinda appending another filter. It should be no harmful to the original framework. The only way you can get to this auto hwmap filter is that you already fail to insert scale filter and the program will return error. That's the current situation. With this patch set, those failed cmdlines could still fail but some cmdlines like above could pass. It just give it another chance to run and simplify the cmdlines.

Regards,
Tong


>
>> Signed-off-by: Tong Wu <tong1.wu@intel.com>
>> ---
>>  libavfilter/avfiltergraph.c | 3 ++-
>>  libavfilter/formats.c       | 4 ++++
>>  2 files changed, 6 insertions(+), 1 deletion(-)
>>
>> diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
>> index 8af0467bc5..b2b627ad6a 100644
>> --- a/libavfilter/avfiltergraph.c
>> +++ b/libavfilter/avfiltergraph.c
>> @@ -402,7 +402,8 @@ static int insert_auto_filter(AVFilterContext
>**convert, AVFilterGraph *graph,
>>      AVFilterContext *ctx;
>>      AVFilterLink *inlink, *outlink;
>>      char inst_name[30];
>> -    const char *opts = FF_FIELD_AT(char *, neg-
>>conversion_filters[conv_step].conversion_opts_offset, *graph);
>> +    const char *opts = neg-
>>conversion_filters[conv_step].conversion_opts_offset == 0 ? NULL :
>> +                       FF_FIELD_AT(char *, neg-
>>conversion_filters[conv_step].conversion_opts_offset, *graph);
>>      const char *name = neg->conversion_filters[conv_step].conversion_filter;
>>
>>      if (!(filter = avfilter_get_by_name(name))) {
>> diff --git a/libavfilter/formats.c b/libavfilter/formats.c
>> index c8e20e5b20..fee10fa0ee 100644
>> --- a/libavfilter/formats.c
>> +++ b/libavfilter/formats.c
>> @@ -331,6 +331,10 @@ static const AVFilterFormatsFilter filters_video[] = {
>>          .conversion_filter = "scale",
>>          .conversion_opts_offset = offsetof(AVFilterGraph, scale_sws_opts),
>>      },
>> +    {
>> +        .conversion_filter = "hwmap",
>> +        .conversion_opts_offset = 0,
>> +    }
>>  };
>>
>>  static const AVFilterFormatsFilter filters_audio[] = {
>> --
>> 2.39.1.windows.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".
>_______________________________________________
>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".
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2023-06-08  8:47 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-25  7:26 [FFmpeg-devel] [PATCH v5 1/5] avutil/hwcontext: add a function to get the AVHWDeviceType Tong Wu
2023-04-25  7:26 ` [FFmpeg-devel] [PATCH v5 2/5] avfilter/vf_hwmap: get the AVHWDeviceType from outlink format Tong Wu
2023-04-25  7:26 ` [FFmpeg-devel] [PATCH v5 3/5] lavfi/avfiltergraph: move convert codes into functions Tong Wu
2023-04-25  7:26 ` [FFmpeg-devel] [PATCH v5 4/5] lavfi/format: wrap auto filters into structures Tong Wu
2023-05-13  6:33   ` Paul B Mahol
2023-05-25  7:06     ` Wu, Tong1
2023-06-07  8:42       ` Wu, Tong1
2023-04-25  7:26 ` [FFmpeg-devel] [PATCH v5 5/5] lavfi/format: add a hwmap auto conversion filter Tong Wu
2023-06-07  8:51   ` Marvin Scholz
2023-06-08  8:47     ` Wu, Tong1

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