lavfi: Always propagate hw_frames_ctx through links
authorMark Thompson <sw@jkqxz.net>
Tue, 25 Oct 2016 19:42:27 +0000 (20:42 +0100)
committerMark Thompson <sw@jkqxz.net>
Wed, 2 Nov 2016 20:29:05 +0000 (20:29 +0000)
Also adds a new flag to mark filters which are aware of hwframes and
will perform this task themselves, and marks all appropriate filters
with this flag.

This is required to allow software-mapped hardware frames to work,
because we need to have the frames context available for any later
mapping operation in the filter graph.

The output from the filter graph should only propagate further to an
encoder if the hardware format actually matches the visible format
(mapped frames are valid here and have an hw_frames_ctx, but this
should not be given to the encoder as its hardware context).

avconv.c
libavfilter/avfilter.c
libavfilter/avfilter.h
libavfilter/internal.h
libavfilter/vf_deinterlace_qsv.c
libavfilter/vf_hwdownload.c
libavfilter/vf_hwupload.c
libavfilter/vf_hwupload_cuda.c
libavfilter/vf_scale_npp.c
libavfilter/vf_scale_qsv.c
libavfilter/vf_scale_vaapi.c

index 4bd28e6e3b4191cc93cd11f1b99ef1611a461413..769b9e095bb94332a7b0e48ea1a417d4dc6cd3c7 100644 (file)
--- a/avconv.c
+++ b/avconv.c
@@ -38,6 +38,7 @@
 #include "libavutil/parseutils.h"
 #include "libavutil/samplefmt.h"
 #include "libavutil/fifo.h"
+#include "libavutil/hwcontext.h"
 #include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/dict.h"
@@ -2035,7 +2036,9 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len)
         if (!av_dict_get(ost->encoder_opts, "threads", NULL, 0))
             av_dict_set(&ost->encoder_opts, "threads", "auto", 0);
 
-        if (ost->filter && ost->filter->filter->inputs[0]->hw_frames_ctx) {
+        if (ost->filter && ost->filter->filter->inputs[0]->hw_frames_ctx &&
+            ((AVHWFramesContext*)ost->filter->filter->inputs[0]->hw_frames_ctx->data)->format ==
+            ost->filter->filter->inputs[0]->format) {
             ost->enc_ctx->hw_frames_ctx = av_buffer_ref(ost->filter->filter->inputs[0]->hw_frames_ctx);
             if (!ost->enc_ctx->hw_frames_ctx)
                 return AVERROR(ENOMEM);
index 1cedb15db457e0dd5e8c00cb934b882b23130655..99531e5690a7203aef65abd7ebc8b043c2e02bd1 100644 (file)
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/buffer.h"
 #include "libavutil/channel_layout.h"
@@ -212,14 +213,12 @@ int avfilter_config_links(AVFilterContext *filter)
             }
 
             if (link->src->nb_inputs && link->src->inputs[0]->hw_frames_ctx &&
-                !link->hw_frames_ctx) {
-                AVHWFramesContext *input_ctx = (AVHWFramesContext*)link->src->inputs[0]->hw_frames_ctx->data;
-
-                if (input_ctx->format == link->format) {
-                    link->hw_frames_ctx = av_buffer_ref(link->src->inputs[0]->hw_frames_ctx);
-                    if (!link->hw_frames_ctx)
-                        return AVERROR(ENOMEM);
-                }
+                !(link->src->filter->flags_internal & FF_FILTER_FLAG_HWFRAME_AWARE)) {
+                av_assert0(!link->hw_frames_ctx &&
+                           "should not be set by non-hwframe-aware filter");
+                link->hw_frames_ctx = av_buffer_ref(link->src->inputs[0]->hw_frames_ctx);
+                if (!link->hw_frames_ctx)
+                    return AVERROR(ENOMEM);
             }
 
             if ((config_link = link->dstpad->config_props))
index a17b2a2f5c359b4fc40cd0921efc8ce7d831e17f..568480dd3e4d4c9a201cd2283c93cd1cc41183e0 100644 (file)
@@ -244,6 +244,8 @@ typedef struct AVFilter {
 
     int priv_size;      ///< size of private data to allocate for the filter
 
+    int flags_internal; ///< Additional flags for avfilter internal use only.
+
     /**
      * Used by the filter registration system. Must not be touched by any other
      * code.
index 202c2c018df4c313f8c220e2a80396320d2cbee6..a377f9b2bab7e2213f54a0ba6ed662c0e83793ad 100644 (file)
@@ -220,4 +220,10 @@ AVFilterContext *ff_filter_alloc(const AVFilter *filter, const char *inst_name);
  */
 void ff_filter_graph_remove_filter(AVFilterGraph *graph, AVFilterContext *filter);
 
+/**
+ * The filter is aware of hardware frames, and any hardware frame context
+ * should not be automatically propagated through it.
+ */
+#define FF_FILTER_FLAG_HWFRAME_AWARE (1 << 0)
+
 #endif /* AVFILTER_INTERNAL_H */
index 36eea15fcc10be5ba4da34581a57dce8408ffb6a..5cda2868395f22d7e2680c2010b3f48f9a55e0a2 100644 (file)
@@ -575,4 +575,6 @@ AVFilter ff_vf_deinterlace_qsv = {
 
     .inputs    = qsvdeint_inputs,
     .outputs   = qsvdeint_outputs,
+
+    .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
index 42925b83d3b974abc1ccfd4e8bc525852f6633c6..aee8d23cb78f9f221370145c55dd1dbb6e30e5cc 100644 (file)
@@ -212,4 +212,5 @@ AVFilter ff_vf_hwdownload = {
     .priv_class    = &hwdownload_class,
     .inputs        = hwdownload_inputs,
     .outputs       = hwdownload_outputs,
+    .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
index 8c43e0080d9251ad878b437a2ec134ee69b89ff3..8cca9f42e2f7b2bb6ba9995f55f6d6eaf16c562f 100644 (file)
@@ -233,4 +233,5 @@ AVFilter ff_vf_hwupload = {
     .priv_class    = &hwupload_class,
     .inputs        = hwupload_inputs,
     .outputs       = hwupload_outputs,
+    .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
index 0ab5276933047db63bb4d88579298fd356749594..94d5013cc6ac0ef94c9a60e193292874c603755d 100644 (file)
@@ -230,4 +230,6 @@ AVFilter ff_vf_hwupload_cuda = {
 
     .inputs    = cudaupload_inputs,
     .outputs   = cudaupload_outputs,
+
+    .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
index 2fb4990953cb1dce6b6467d02213686509f2acd1..0e636a997d01f063388c75176a181f586f38c9c9 100644 (file)
@@ -657,4 +657,6 @@ AVFilter ff_vf_scale_npp = {
 
     .inputs    = nppscale_inputs,
     .outputs   = nppscale_outputs,
+
+    .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
index f7c1c550928cfaa612ad4eb6346072d24208304d..8ef77835dca00df942ced2987d08127d06eb1384 100644 (file)
@@ -626,4 +626,6 @@ AVFilter ff_vf_scale_qsv = {
 
     .inputs    = qsvscale_inputs,
     .outputs   = qsvscale_outputs,
+
+    .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
index 67648a9aa014eaa954d9305dbd549ab92fae48cf..50be68eee07374a78bba1eed8850c3ab9e019fe6 100644 (file)
@@ -463,4 +463,5 @@ AVFilter ff_vf_scale_vaapi = {
     .inputs        = scale_vaapi_inputs,
     .outputs       = scale_vaapi_outputs,
     .priv_class    = &scale_vaapi_class,
+    .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };