00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00026 #include <stdio.h>
00027
00028 #include "libavutil/internal.h"
00029 #include "libavutil/mem.h"
00030 #include "avfilter.h"
00031 #include "audio.h"
00032 #include "internal.h"
00033 #include "video.h"
00034
00035 static int split_init(AVFilterContext *ctx, const char *args)
00036 {
00037 int i, nb_outputs = 2;
00038
00039 if (args) {
00040 nb_outputs = strtol(args, NULL, 0);
00041 if (nb_outputs <= 0) {
00042 av_log(ctx, AV_LOG_ERROR, "Invalid number of outputs specified: %d.\n",
00043 nb_outputs);
00044 return AVERROR(EINVAL);
00045 }
00046 }
00047
00048 for (i = 0; i < nb_outputs; i++) {
00049 char name[32];
00050 AVFilterPad pad = { 0 };
00051
00052 snprintf(name, sizeof(name), "output%d", i);
00053 pad.type = ctx->filter->inputs[0].type;
00054 pad.name = av_strdup(name);
00055 pad.rej_perms = AV_PERM_WRITE;
00056
00057 ff_insert_outpad(ctx, i, &pad);
00058 }
00059
00060 return 0;
00061 }
00062
00063 static void split_uninit(AVFilterContext *ctx)
00064 {
00065 int i;
00066
00067 for (i = 0; i < ctx->nb_outputs; i++)
00068 av_freep(&ctx->output_pads[i].name);
00069 }
00070
00071 static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
00072 {
00073 AVFilterContext *ctx = inlink->dst;
00074 int i, ret = AVERROR_EOF;
00075
00076 for (i = 0; i < ctx->nb_outputs; i++) {
00077 AVFilterBufferRef *buf_out;
00078
00079 if (ctx->outputs[i]->closed)
00080 continue;
00081 buf_out = avfilter_ref_buffer(frame, ~AV_PERM_WRITE);
00082 if (!buf_out) {
00083 ret = AVERROR(ENOMEM);
00084 break;
00085 }
00086
00087 ret = ff_filter_frame(ctx->outputs[i], buf_out);
00088 if (ret < 0)
00089 break;
00090 }
00091 avfilter_unref_bufferp(&frame);
00092 return ret;
00093 }
00094
00095 static const AVFilterPad avfilter_vf_split_inputs[] = {
00096 {
00097 .name = "default",
00098 .type = AVMEDIA_TYPE_VIDEO,
00099 .get_video_buffer = ff_null_get_video_buffer,
00100 .filter_frame = filter_frame,
00101 },
00102 { NULL }
00103 };
00104
00105 AVFilter avfilter_vf_split = {
00106 .name = "split",
00107 .description = NULL_IF_CONFIG_SMALL("Pass on the input video to N outputs."),
00108
00109 .init = split_init,
00110 .uninit = split_uninit,
00111
00112 .inputs = avfilter_vf_split_inputs,
00113 .outputs = NULL,
00114 };
00115
00116 static const AVFilterPad avfilter_af_asplit_inputs[] = {
00117 {
00118 .name = "default",
00119 .type = AVMEDIA_TYPE_AUDIO,
00120 .get_audio_buffer = ff_null_get_audio_buffer,
00121 .filter_frame = filter_frame,
00122 },
00123 { NULL }
00124 };
00125
00126 AVFilter avfilter_af_asplit = {
00127 .name = "asplit",
00128 .description = NULL_IF_CONFIG_SMALL("Pass on the audio input to N audio outputs."),
00129
00130 .init = split_init,
00131 .uninit = split_uninit,
00132
00133 .inputs = avfilter_af_asplit_inputs,
00134 .outputs = NULL,
00135 };