Browse Source

vf_split: support user-specifiable number of outputs.

tags/n0.11
Anton Khirnov 13 years ago
parent
commit
fd18ee0ff6
2 changed files with 68 additions and 13 deletions
  1. +13
    -0
      doc/filters.texi
  2. +55
    -13
      libavfilter/vf_split.c

+ 13
- 0
doc/filters.texi View File

@@ -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 Adding this in the beginning of filter chains should make filtering
faster due to better use of the memory cache. faster due to better use of the memory cache.


@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
@example
avconv -i INPUT -filter_complex split=5 OUTPUT
@end example
will create 5 copies of the input video.

@section transpose @section transpose


Transpose rows with columns in the input video and optionally flip it. Transpose rows with columns in the input video and optionally flip it.


+ 55
- 13
libavfilter/vf_split.c View File

@@ -25,24 +25,67 @@


#include "avfilter.h" #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) 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) 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) 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); avfilter_unref_buffer(inlink->cur_buf);
} }
@@ -51,6 +94,9 @@ AVFilter avfilter_vf_split = {
.name = "split", .name = "split",
.description = NULL_IF_CONFIG_SMALL("Pass on the input to two outputs."), .description = NULL_IF_CONFIG_SMALL("Pass on the input to two outputs."),


.init = split_init,
.uninit = split_uninit,

.inputs = (AVFilterPad[]) {{ .name = "default", .inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO, .type = AVMEDIA_TYPE_VIDEO,
.get_video_buffer= avfilter_null_get_video_buffer, .get_video_buffer= avfilter_null_get_video_buffer,
@@ -58,9 +104,5 @@ AVFilter avfilter_vf_split = {
.draw_slice = draw_slice, .draw_slice = draw_slice,
.end_frame = end_frame, }, .end_frame = end_frame, },
{ .name = NULL}}, { .name = NULL}},
.outputs = (AVFilterPad[]) {{ .name = "output1",
.type = AVMEDIA_TYPE_VIDEO, },
{ .name = "output2",
.type = AVMEDIA_TYPE_VIDEO, },
{ .name = NULL}},
.outputs = (AVFilterPad[]) {{ .name = NULL}},
}; };

Loading…
Cancel
Save