diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-11-28 16:39:04 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-11-28 16:43:34 +0100 |
commit | 3ed483cdfa5bc9800702a4a505b7164e70b1bcd6 (patch) | |
tree | 199776884982bc63a621a18035e45ebcb60953fa | |
parent | a0b8eec719323bc242e47ab891af47cfd8f06aec (diff) | |
download | ffmpeg-3ed483cdfa5bc9800702a4a505b7164e70b1bcd6.tar.gz |
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>
-rw-r--r-- | libavfilter/audio.c | 8 | ||||
-rw-r--r-- | libavfilter/audio.h | 7 | ||||
-rw-r--r-- | libavfilter/avfilter.c | 22 | ||||
-rw-r--r-- | libavfilter/internal.h | 12 | ||||
-rw-r--r-- | libavfilter/video.c | 12 |
5 files changed, 50 insertions, 11 deletions
diff --git a/libavfilter/audio.c b/libavfilter/audio.c index 5389011f62..f157e877cd 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 35aa4e8a19..8fe4d8ee00 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 d1b6d05a38..6779777b7d 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 e0ca43ece1..329ac497ae 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 4d8804ba10..5eb37e6b5a 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; } |