---
 libavfilter/avfilter.c  | 15 +++++++++++++++
 libavfilter/avfilter.h  |  7 +++++++
 libavfilter/buffersrc.c |  9 +++++++++
 3 files changed, 31 insertions(+)

diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index cd98d16..8eefc51 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -20,8 +20,10 @@
  */
 
 #include "libavutil/avstring.h"
+#include "libavutil/buffer.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
+#include "libavutil/hwcontext.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/internal.h"
 #include "libavutil/opt.h"
@@ -217,6 +219,17 @@ int avfilter_config_links(AVFilterContext *filter)
                     return ret;
                 }
 
+            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->init_state = AVLINK_INIT;
         }
     }
@@ -481,6 +494,8 @@ static void free_link(AVFilterLink *link)
     if (link->dst)
         link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
 
+    av_buffer_unref(&link->hw_frames_ctx);
+
     ff_formats_unref(&link->in_formats);
     ff_formats_unref(&link->out_formats);
     ff_formats_unref(&link->in_samplerates);
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index 1890858..0a0c415 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -35,6 +35,7 @@
 
 #include "libavutil/attributes.h"
 #include "libavutil/avutil.h"
+#include "libavutil/buffer.h"
 #include "libavutil/frame.h"
 #include "libavutil/log.h"
 #include "libavutil/samplefmt.h"
@@ -387,6 +388,12 @@ struct AVFilterLink {
      * Sinks can use it to set a default output frame rate.
      */
     AVRational frame_rate;
+
+    /**
+     * For hwaccel pixel formats, this should be a reference to the
+     * AVHWFramesContext describing the frames.
+     */
+    AVBufferRef *hw_frames_ctx;
 };
 
 /**
diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c
index f5b852f..41ac9fd 100644
--- a/libavfilter/buffersrc.c
+++ b/libavfilter/buffersrc.c
@@ -52,6 +52,8 @@ typedef struct BufferSourceContext {
     char               *pix_fmt_str;
     AVRational        pixel_aspect;
 
+    AVBufferRef **hw_frames_ctx;
+
     /* audio only */
     int sample_rate;
     enum AVSampleFormat sample_fmt;
@@ -193,6 +195,7 @@ static const AVOption video_options[] = {
     { "sar",           "sample aspect ratio",    OFFSET(pixel_aspect),     
AV_OPT_TYPE_RATIONAL, { .dbl = 1 }, 0, DBL_MAX, V },
     { "time_base",     NULL,                     OFFSET(time_base),        
AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V },
     { "frame_rate",    NULL,                     OFFSET(frame_rate),       
AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V },
+    { "hw_frames_ctx", NULL,                     OFFSET(hw_frames_ctx),    
AV_OPT_TYPE_BINARY, .flags = V },
     { NULL },
 };
 
@@ -300,6 +303,12 @@ static int config_props(AVFilterLink *link)
         link->w = c->w;
         link->h = c->h;
         link->sample_aspect_ratio = c->pixel_aspect;
+
+        if (c->hw_frames_ctx && *c->hw_frames_ctx) {
+            link->hw_frames_ctx = av_buffer_ref(*c->hw_frames_ctx);
+            if (!link->hw_frames_ctx)
+                return AVERROR(ENOMEM);
+        }
         break;
     case AVMEDIA_TYPE_AUDIO:
         link->channel_layout = c->channel_layout;
-- 
2.0.0

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

Reply via email to