With this we can mix filters using filter_frame OR start/draw_slice/end
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
... | ... |
@@ -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 |
} |