[FFmpeg-cvslog] libavfilter: Support using filter_frame for video

Michael Niedermayer git at videolan.org
Wed Nov 28 16:49:07 CET 2012


ffmpeg | branch: master | Michael Niedermayer <michaelni at gmx.at> | Wed Nov 28 16:39:04 2012 +0100| [3ed483cdfa5bc9800702a4a505b7164e70b1bcd6] | committer: Michael Niedermayer

libavfilter: Support using filter_frame for video

With this we can mix filters using filter_frame OR start/draw_slice/end

Signed-off-by: Michael Niedermayer <michaelni at gmx.at>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=3ed483cdfa5bc9800702a4a505b7164e70b1bcd6
---

 libavfilter/audio.c    |    8 ++++----
 libavfilter/audio.h    |    7 ++++---
 libavfilter/avfilter.c |   22 +++++++++++++++++++++-
 libavfilter/internal.h |   12 ++++++++++++
 libavfilter/video.c    |   12 +++++++++---
 5 files changed, 50 insertions(+), 11 deletions(-)

diff --git a/libavfilter/audio.c b/libavfilter/audio.c
index 5389011..f157e87 100644
--- a/libavfilter/audio.c
+++ b/libavfilter/audio.c
@@ -162,7 +162,7 @@ static int default_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
     return ff_filter_frame(link->dst->outputs[0], frame);
 }
 
-int ff_filter_frame_framed(AVFilterLink *link, AVFilterBufferRef *samplesref)
+int ff_filter_samples_framed(AVFilterLink *link, AVFilterBufferRef *samplesref)
 {
     int (*filter_frame)(AVFilterLink *, AVFilterBufferRef *);
     AVFilterPad *src = link->srcpad;
@@ -217,7 +217,7 @@ int ff_filter_frame_framed(AVFilterLink *link, AVFilterBufferRef *samplesref)
     return ret;
 }
 
-int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *samplesref)
+int ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
 {
     int insamples = samplesref->audio->nb_samples, inpos = 0, nb_samples;
     AVFilterBufferRef *pbuf = link->partial_buf;
@@ -231,7 +231,7 @@ int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *samplesref)
     if (!link->min_samples ||
         (!pbuf &&
          insamples >= link->min_samples && insamples <= link->max_samples)) {
-        return ff_filter_frame_framed(link, samplesref);
+        return ff_filter_samples_framed(link, samplesref);
     }
     /* Handle framing (min_samples, max_samples) */
     while (insamples) {
@@ -258,7 +258,7 @@ int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *samplesref)
         insamples               -= nb_samples;
         pbuf->audio->nb_samples += nb_samples;
         if (pbuf->audio->nb_samples >= link->min_samples) {
-            ret = ff_filter_frame_framed(link, pbuf);
+            ret = ff_filter_samples_framed(link, pbuf);
             pbuf = NULL;
         }
     }
diff --git a/libavfilter/audio.h b/libavfilter/audio.h
index 35aa4e8..8fe4d8e 100644
--- a/libavfilter/audio.h
+++ b/libavfilter/audio.h
@@ -23,6 +23,7 @@
 #define AVFILTER_AUDIO_H
 
 #include "avfilter.h"
+#include "internal.h"
 
 static const enum AVSampleFormat ff_packed_sample_fmts_array[] = {
     AV_SAMPLE_FMT_U8,
@@ -74,13 +75,13 @@ AVFilterBufferRef *ff_get_audio_buffer(AVFilterLink *link, int perms,
  * @return >= 0 on success, a negative AVERROR on error. The receiving filter
  * is responsible for unreferencing samplesref in case of error.
  */
-int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *samplesref);
+int ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref);
 
 /**
  * Send a buffer of audio samples to the next link, without checking
  * min_samples.
  */
-int ff_filter_frame_framed(AVFilterLink *link,
-                              AVFilterBufferRef *samplesref);
+int ff_filter_samples_framed(AVFilterLink *link,
+                             AVFilterBufferRef *samplesref);
 
 #endif /* AVFILTER_AUDIO_H */
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index d1b6d05..6779777 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -343,7 +343,7 @@ int ff_request_frame(AVFilterLink *link)
     if (ret == AVERROR_EOF && link->partial_buf) {
         AVFilterBufferRef *pbuf = link->partial_buf;
         link->partial_buf = NULL;
-        ff_filter_frame_framed(link, pbuf);
+        ff_filter_samples_framed(link, pbuf);
         return 0;
     }
     if (ret == AVERROR_EOF)
@@ -631,3 +631,23 @@ enum AVMediaType avfilter_pad_get_type(AVFilterPad *pads, int pad_idx)
 {
     return pads[pad_idx].type;
 }
+
+int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
+{
+    int ret;
+    FF_TPRINTF_START(NULL, filter_frame); ff_tlog_link(NULL, link, 1); ff_tlog(NULL, " "); ff_tlog_ref(NULL, frame, 1);
+
+    switch (link->type) {
+    case AVMEDIA_TYPE_VIDEO:
+        if((ret = ff_start_frame(link, frame)) < 0)
+            return ret;
+        if((ret = ff_draw_slice(link, 0, frame->video->h, 1)) < 0)
+            return ret;
+        if((ret = ff_end_frame(link)) < 0)
+            return ret;
+        return ret;
+    case AVMEDIA_TYPE_AUDIO:
+        return ff_filter_samples(link, frame);
+    default: return AVERROR(EINVAL);
+    }
+}
diff --git a/libavfilter/internal.h b/libavfilter/internal.h
index e0ca43e..329ac49 100644
--- a/libavfilter/internal.h
+++ b/libavfilter/internal.h
@@ -368,5 +368,17 @@ AVFilterBufferRef *ff_copy_buffer_ref(AVFilterLink *outlink,
 int ff_buffersink_read_compat(AVFilterContext *ctx, AVFilterBufferRef **buf);
 int ff_buffersink_read_samples_compat(AVFilterContext *ctx, AVFilterBufferRef **pbuf,
                                       int nb_samples);
+/**
+ * Send a frame of data to the next filter.
+ *
+ * @param link   the output link over which the data is being sent
+ * @param frame a reference to the buffer of data being sent. The
+ *              receiving filter will free this reference when it no longer
+ *              needs it or pass it on to the next filter.
+ *
+ * @return >= 0 on success, a negative AVERROR on error. The receiving filter
+ * is responsible for unreferencing frame in case of error.
+ */
+int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame);
 
 #endif /* AVFILTER_INTERNAL_H */
diff --git a/libavfilter/video.c b/libavfilter/video.c
index 4d8804b..5eb37e6 100644
--- a/libavfilter/video.c
+++ b/libavfilter/video.c
@@ -210,7 +210,7 @@ static int default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
     if (inlink->dst->nb_outputs)
         outlink = inlink->dst->outputs[0];
 
-    if (outlink) {
+    if (outlink && !inlink->dstpad->filter_frame) {
         AVFilterBufferRef *buf_out;
         outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
         if (!outlink->out_buf)
@@ -328,7 +328,13 @@ static int default_end_frame(AVFilterLink *inlink)
         outlink = inlink->dst->outputs[0];
 
     if (outlink) {
-        return ff_end_frame(outlink);
+        if (inlink->dstpad->filter_frame) {
+            int ret = inlink->dstpad->filter_frame(inlink, inlink->cur_buf);
+            inlink->cur_buf = NULL;
+            return ret;
+        } else {
+            return ff_end_frame(outlink);
+        }
     }
     return 0;
 }
@@ -360,7 +366,7 @@ static int default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
     if (inlink->dst->nb_outputs)
         outlink = inlink->dst->outputs[0];
 
-    if (outlink)
+    if (outlink && !inlink->dstpad->filter_frame)
         return ff_draw_slice(outlink, y, h, slice_dir);
     return 0;
 }



More information about the ffmpeg-cvslog mailing list