[FFmpeg-cvslog] vf_split: support user-specifiable number of outputs.
Anton Khirnov
git at videolan.org
Sun May 6 22:19:00 CEST 2012
ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Fri Apr 27 07:41:32 2012 +0200| [fd18ee0ff659fc73e56bd43f5b93ed82934c6c7f] | committer: Anton Khirnov
vf_split: support user-specifiable number of outputs.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=fd18ee0ff659fc73e56bd43f5b93ed82934c6c7f
---
doc/filters.texi | 13 +++++++++
libavfilter/vf_split.c | 68 ++++++++++++++++++++++++++++++++++++++---------
2 files changed, 68 insertions(+), 13 deletions(-)
diff --git a/doc/filters.texi b/doc/filters.texi
index b012dc7..c5a56f4 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -1666,6 +1666,19 @@ not specified it will use the default value of 16.
Adding this in the beginning of filter chains should make filtering
faster due to better use of the memory cache.
+ at section split
+
+Split input video into several identical outputs.
+
+The filter accepts a single parameter which specifies the number of outputs. If
+unspecified, it defaults to 2.
+
+For example
+ at example
+avconv -i INPUT -filter_complex split=5 OUTPUT
+ at end example
+will create 5 copies of the input video.
+
@section transpose
Transpose rows with columns in the input video and optionally flip it.
diff --git a/libavfilter/vf_split.c b/libavfilter/vf_split.c
index 54fdd21..da6b3ff 100644
--- a/libavfilter/vf_split.c
+++ b/libavfilter/vf_split.c
@@ -25,24 +25,67 @@
#include "avfilter.h"
+static int split_init(AVFilterContext *ctx, const char *args, void *opaque)
+{
+ int i, nb_outputs = 2;
+
+ if (args) {
+ nb_outputs = strtol(args, NULL, 0);
+ if (nb_outputs <= 0) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid number of outputs specified: %d.\n",
+ nb_outputs);
+ return AVERROR(EINVAL);
+ }
+ }
+
+ for (i = 0; i < nb_outputs; i++) {
+ char name[32];
+ AVFilterPad pad = { 0 };
+
+ snprintf(name, sizeof(name), "output%d", i);
+ pad.type = AVMEDIA_TYPE_VIDEO;
+ pad.name = av_strdup(name);
+
+ avfilter_insert_outpad(ctx, i, &pad);
+ }
+
+ return 0;
+}
+
+static void split_uninit(AVFilterContext *ctx)
+{
+ int i;
+
+ for (i = 0; i < ctx->output_count; i++)
+ av_freep(&ctx->output_pads[i].name);
+}
+
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
{
- avfilter_start_frame(inlink->dst->outputs[0],
- avfilter_ref_buffer(picref, ~AV_PERM_WRITE));
- avfilter_start_frame(inlink->dst->outputs[1],
- avfilter_ref_buffer(picref, ~AV_PERM_WRITE));
+ AVFilterContext *ctx = inlink->dst;
+ int i;
+
+ for (i = 0; i < ctx->output_count; i++)
+ avfilter_start_frame(ctx->outputs[i],
+ avfilter_ref_buffer(picref, ~AV_PERM_WRITE));
}
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
{
- avfilter_draw_slice(inlink->dst->outputs[0], y, h, slice_dir);
- avfilter_draw_slice(inlink->dst->outputs[1], y, h, slice_dir);
+ AVFilterContext *ctx = inlink->dst;
+ int i;
+
+ for (i = 0; i < ctx->output_count; i++)
+ avfilter_draw_slice(ctx->outputs[i], y, h, slice_dir);
}
static void end_frame(AVFilterLink *inlink)
{
- avfilter_end_frame(inlink->dst->outputs[0]);
- avfilter_end_frame(inlink->dst->outputs[1]);
+ AVFilterContext *ctx = inlink->dst;
+ int i;
+
+ for (i = 0; i < ctx->output_count; i++)
+ avfilter_end_frame(ctx->outputs[i]);
avfilter_unref_buffer(inlink->cur_buf);
}
@@ -51,6 +94,9 @@ AVFilter avfilter_vf_split = {
.name = "split",
.description = NULL_IF_CONFIG_SMALL("Pass on the input to two outputs."),
+ .init = split_init,
+ .uninit = split_uninit,
+
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.get_video_buffer= avfilter_null_get_video_buffer,
@@ -58,9 +104,5 @@ AVFilter avfilter_vf_split = {
.draw_slice = draw_slice,
.end_frame = end_frame, },
{ .name = NULL}},
- .outputs = (AVFilterPad[]) {{ .name = "output1",
- .type = AVMEDIA_TYPE_VIDEO, },
- { .name = "output2",
- .type = AVMEDIA_TYPE_VIDEO, },
- { .name = NULL}},
+ .outputs = (AVFilterPad[]) {{ .name = NULL}},
};
More information about the ffmpeg-cvslog
mailing list