Browse code

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@gmx.at>

Michael Niedermayer authored on 2012/11/29 00:39:04
Showing 5 changed files
... ...
@@ -162,7 +162,7 @@ static int default_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
162 162
     return ff_filter_frame(link->dst->outputs[0], frame);
163 163
 }
164 164
 
165
-int ff_filter_frame_framed(AVFilterLink *link, AVFilterBufferRef *samplesref)
165
+int ff_filter_samples_framed(AVFilterLink *link, AVFilterBufferRef *samplesref)
166 166
 {
167 167
     int (*filter_frame)(AVFilterLink *, AVFilterBufferRef *);
168 168
     AVFilterPad *src = link->srcpad;
... ...
@@ -217,7 +217,7 @@ int ff_filter_frame_framed(AVFilterLink *link, AVFilterBufferRef *samplesref)
217 217
     return ret;
218 218
 }
219 219
 
220
-int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *samplesref)
220
+int ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
221 221
 {
222 222
     int insamples = samplesref->audio->nb_samples, inpos = 0, nb_samples;
223 223
     AVFilterBufferRef *pbuf = link->partial_buf;
... ...
@@ -231,7 +231,7 @@ int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *samplesref)
231 231
     if (!link->min_samples ||
232 232
         (!pbuf &&
233 233
          insamples >= link->min_samples && insamples <= link->max_samples)) {
234
-        return ff_filter_frame_framed(link, samplesref);
234
+        return ff_filter_samples_framed(link, samplesref);
235 235
     }
236 236
     /* Handle framing (min_samples, max_samples) */
237 237
     while (insamples) {
... ...
@@ -258,7 +258,7 @@ int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *samplesref)
258 258
         insamples               -= nb_samples;
259 259
         pbuf->audio->nb_samples += nb_samples;
260 260
         if (pbuf->audio->nb_samples >= link->min_samples) {
261
-            ret = ff_filter_frame_framed(link, pbuf);
261
+            ret = ff_filter_samples_framed(link, pbuf);
262 262
             pbuf = NULL;
263 263
         }
264 264
     }
... ...
@@ -23,6 +23,7 @@
23 23
 #define AVFILTER_AUDIO_H
24 24
 
25 25
 #include "avfilter.h"
26
+#include "internal.h"
26 27
 
27 28
 static const enum AVSampleFormat ff_packed_sample_fmts_array[] = {
28 29
     AV_SAMPLE_FMT_U8,
... ...
@@ -74,13 +75,13 @@ AVFilterBufferRef *ff_get_audio_buffer(AVFilterLink *link, int perms,
74 74
  * @return >= 0 on success, a negative AVERROR on error. The receiving filter
75 75
  * is responsible for unreferencing samplesref in case of error.
76 76
  */
77
-int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *samplesref);
77
+int ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref);
78 78
 
79 79
 /**
80 80
  * Send a buffer of audio samples to the next link, without checking
81 81
  * min_samples.
82 82
  */
83
-int ff_filter_frame_framed(AVFilterLink *link,
84
-                              AVFilterBufferRef *samplesref);
83
+int ff_filter_samples_framed(AVFilterLink *link,
84
+                             AVFilterBufferRef *samplesref);
85 85
 
86 86
 #endif /* AVFILTER_AUDIO_H */
... ...
@@ -343,7 +343,7 @@ int ff_request_frame(AVFilterLink *link)
343 343
     if (ret == AVERROR_EOF && link->partial_buf) {
344 344
         AVFilterBufferRef *pbuf = link->partial_buf;
345 345
         link->partial_buf = NULL;
346
-        ff_filter_frame_framed(link, pbuf);
346
+        ff_filter_samples_framed(link, pbuf);
347 347
         return 0;
348 348
     }
349 349
     if (ret == AVERROR_EOF)
... ...
@@ -631,3 +631,23 @@ enum AVMediaType avfilter_pad_get_type(AVFilterPad *pads, int pad_idx)
631 631
 {
632 632
     return pads[pad_idx].type;
633 633
 }
634
+
635
+int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
636
+{
637
+    int ret;
638
+    FF_TPRINTF_START(NULL, filter_frame); ff_tlog_link(NULL, link, 1); ff_tlog(NULL, " "); ff_tlog_ref(NULL, frame, 1);
639
+
640
+    switch (link->type) {
641
+    case AVMEDIA_TYPE_VIDEO:
642
+        if((ret = ff_start_frame(link, frame)) < 0)
643
+            return ret;
644
+        if((ret = ff_draw_slice(link, 0, frame->video->h, 1)) < 0)
645
+            return ret;
646
+        if((ret = ff_end_frame(link)) < 0)
647
+            return ret;
648
+        return ret;
649
+    case AVMEDIA_TYPE_AUDIO:
650
+        return ff_filter_samples(link, frame);
651
+    default: return AVERROR(EINVAL);
652
+    }
653
+}
... ...
@@ -368,5 +368,17 @@ AVFilterBufferRef *ff_copy_buffer_ref(AVFilterLink *outlink,
368 368
 int ff_buffersink_read_compat(AVFilterContext *ctx, AVFilterBufferRef **buf);
369 369
 int ff_buffersink_read_samples_compat(AVFilterContext *ctx, AVFilterBufferRef **pbuf,
370 370
                                       int nb_samples);
371
+/**
372
+ * Send a frame of data to the next filter.
373
+ *
374
+ * @param link   the output link over which the data is being sent
375
+ * @param frame a reference to the buffer of data being sent. The
376
+ *              receiving filter will free this reference when it no longer
377
+ *              needs it or pass it on to the next filter.
378
+ *
379
+ * @return >= 0 on success, a negative AVERROR on error. The receiving filter
380
+ * is responsible for unreferencing frame in case of error.
381
+ */
382
+int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame);
371 383
 
372 384
 #endif /* AVFILTER_INTERNAL_H */
... ...
@@ -210,7 +210,7 @@ static int default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
210 210
     if (inlink->dst->nb_outputs)
211 211
         outlink = inlink->dst->outputs[0];
212 212
 
213
-    if (outlink) {
213
+    if (outlink && !inlink->dstpad->filter_frame) {
214 214
         AVFilterBufferRef *buf_out;
215 215
         outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
216 216
         if (!outlink->out_buf)
... ...
@@ -328,7 +328,13 @@ static int default_end_frame(AVFilterLink *inlink)
328 328
         outlink = inlink->dst->outputs[0];
329 329
 
330 330
     if (outlink) {
331
-        return ff_end_frame(outlink);
331
+        if (inlink->dstpad->filter_frame) {
332
+            int ret = inlink->dstpad->filter_frame(inlink, inlink->cur_buf);
333
+            inlink->cur_buf = NULL;
334
+            return ret;
335
+        } else {
336
+            return ff_end_frame(outlink);
337
+        }
332 338
     }
333 339
     return 0;
334 340
 }
... ...
@@ -360,7 +366,7 @@ static int default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
360 360
     if (inlink->dst->nb_outputs)
361 361
         outlink = inlink->dst->outputs[0];
362 362
 
363
-    if (outlink)
363
+    if (outlink && !inlink->dstpad->filter_frame)
364 364
         return ff_draw_slice(outlink, y, h, slice_dir);
365 365
     return 0;
366 366
 }