summaryrefslogtreecommitdiff
path: root/libavfilter/avfilter.c
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2012-11-27 07:49:45 +0100
committerAnton Khirnov <anton@khirnov.net>2012-11-28 08:50:19 +0100
commit565e4993c63f797e2d50ad2f1e8f62fdbe299666 (patch)
treebae5282b2ee875de4b01467f3cfaab54b0ab6ec0 /libavfilter/avfilter.c
parentbb6c67bb36b136de10256f0999128df4a42f9ffc (diff)
lavfi: merge start_frame/draw_slice/end_frame
Any alleged performance benefits gained from the split are purely mythological and do not justify added code complexity.
Diffstat (limited to 'libavfilter/avfilter.c')
-rw-r--r--libavfilter/avfilter.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index c7db857ef0..93302ccd23 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -23,12 +23,16 @@
#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
+#include "libavutil/imgutils.h"
#include "libavutil/pixdesc.h"
#include "libavutil/rational.h"
+#include "libavutil/samplefmt.h"
+#include "audio.h"
#include "avfilter.h"
#include "formats.h"
#include "internal.h"
+#include "video.h"
unsigned avfilter_version(void) {
return LIBAVFILTER_VERSION_INT;
@@ -446,3 +450,68 @@ enum AVMediaType avfilter_pad_get_type(AVFilterPad *pads, int pad_idx)
{
return pads[pad_idx].type;
}
+
+static int default_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
+{
+ return ff_filter_frame(link->dst->outputs[0], frame);
+}
+
+int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
+{
+ int (*filter_frame)(AVFilterLink *, AVFilterBufferRef *);
+ AVFilterPad *dst = link->dstpad;
+ AVFilterBufferRef *out;
+ int perms = frame->perms;
+
+ FF_DPRINTF_START(NULL, filter_frame);
+ ff_dlog_link(NULL, link, 1);
+
+ if (!(filter_frame = dst->filter_frame))
+ filter_frame = default_filter_frame;
+
+ if (frame->linesize[0] < 0)
+ perms |= AV_PERM_NEG_LINESIZES;
+ /* prepare to copy the frame if the buffer has insufficient permissions */
+ if ((dst->min_perms & perms) != dst->min_perms ||
+ dst->rej_perms & perms) {
+ av_log(link->dst, AV_LOG_DEBUG,
+ "Copying data in avfilter (have perms %x, need %x, reject %x)\n",
+ perms, link->dstpad->min_perms, link->dstpad->rej_perms);
+
+ switch (link->type) {
+ case AVMEDIA_TYPE_VIDEO:
+ out = ff_get_video_buffer(link, dst->min_perms,
+ link->w, link->h);
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ out = ff_get_audio_buffer(link, dst->min_perms,
+ frame->audio->nb_samples);
+ break;
+ default: return AVERROR(EINVAL);
+ }
+ if (!out) {
+ avfilter_unref_buffer(frame);
+ return AVERROR(ENOMEM);
+ }
+ avfilter_copy_buffer_ref_props(out, frame);
+
+ switch (link->type) {
+ case AVMEDIA_TYPE_VIDEO:
+ av_image_copy(out->data, out->linesize, frame->data, frame->linesize,
+ frame->format, frame->video->w, frame->video->h);
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ av_samples_copy(out->extended_data, frame->extended_data,
+ 0, 0, frame->audio->nb_samples,
+ av_get_channel_layout_nb_channels(frame->audio->channel_layout),
+ frame->format);
+ break;
+ default: return AVERROR(EINVAL);
+ }
+
+ avfilter_unref_buffer(frame);
+ } else
+ out = frame;
+
+ return filter_frame(link, out);
+}