The move allows to share the init code already used by split.
Unified · Split
| @@ -304,16 +304,23 @@ expressed in the form "[@var{c0} @var{c1} @var{c2} @var{c3} @var{c4} @var{c5} · 303 unmodified lines | ||
| 304 | 304 | |
| 305 | 305 | @section asplit |
| 306 | 306 | |
| 307 | −Pass on the input audio to two outputs. Both outputs are identical to | |
| 308 | −the input audio. | |
| 307 | +Split input audio into several identical outputs. | |
| 308 | + | |
| 309 | +The filter accepts a single parameter which specifies the number of outputs. If | |
| 310 | +unspecified, it defaults to 2. | |
| 309 | 311 | |
| 310 | 312 | For example: |
| 311 | 313 | @example |
| 312 | −[in] asplit[out0], showaudio[out1] | |
| 314 | +[in] asplit [out0][out1] | |
| 313 | 315 | @end example |
| 314 | 316 | |
| 315 | −will create two separate outputs from the same input, one cropped and | |
| 316 | −one padded. | |
| 317 | +will create two separate outputs from the same input. | |
| 318 | + | |
| 319 | +To create 3 or more outputs, you need to specify the number of | |
| 320 | +outputs, like in: | |
| 321 | +@example | |
| 322 | +[in] asplit=3 [out0][out1][out2] | |
| 323 | +@end example | |
| 317 | 324 | |
| 318 | 325 | @section astreamsync |
| 319 | 326 | |
| @@ -50,7 +50,7 @@ OBJS-$(CONFIG_AMERGE_FILTER) += af_amerge.o · 49 unmodified lines | ||
| 50 | 50 | OBJS-$(CONFIG_ANULL_FILTER) += af_anull.o |
| 51 | 51 | OBJS-$(CONFIG_ARESAMPLE_FILTER) += af_aresample.o |
| 52 | 52 | OBJS-$(CONFIG_ASHOWINFO_FILTER) += af_ashowinfo.o |
| 53 | −OBJS-$(CONFIG_ASPLIT_FILTER) += af_asplit.o | |
| 53 | +OBJS-$(CONFIG_ASPLIT_FILTER) += vf_split.o | |
| 54 | 54 | OBJS-$(CONFIG_ASTREAMSYNC_FILTER) += af_astreamsync.o |
| 55 | 55 | OBJS-$(CONFIG_ASYNCTS_FILTER) += af_asyncts.o |
| 56 | 56 | OBJS-$(CONFIG_EARWAX_FILTER) += af_earwax.o |
| @@ -1,56 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * Copyright (c) 2011 Stefano Sabatini | |
| 3 | − * | |
| 4 | − * This file is part of FFmpeg. | |
| 5 | − * | |
| 6 | − * FFmpeg is free software; you can redistribute it and/or | |
| 7 | − * modify it under the terms of the GNU Lesser General Public | |
| 8 | − * License as published by the Free Software Foundation; either | |
| 9 | − * version 2.1 of the License, or (at your option) any later version. | |
| 10 | − * | |
| 11 | − * FFmpeg is distributed in the hope that it will be useful, | |
| 12 | − * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | − * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 14 | − * Lesser General Public License for more details. | |
| 15 | − * | |
| 16 | − * You should have received a copy of the GNU Lesser General Public | |
| 17 | − * License along with FFmpeg; if not, write to the Free Software | |
| 18 | − * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 19 | − */ | |
| 20 | − | |
| 21 | −/** | |
| 22 | − * @file | |
| 23 | − * audio splitter | |
| 24 | − */ | |
| 25 | − | |
| 26 | −#include "avfilter.h" | |
| 27 | −#include "audio.h" | |
| 28 | − | |
| 29 | −static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples) | |
| 30 | −{ | |
| 31 | − ff_filter_samples(inlink->dst->outputs[0], | |
| 32 | − avfilter_ref_buffer(insamples, ~AV_PERM_WRITE)); | |
| 33 | − ff_filter_samples(inlink->dst->outputs[1], | |
| 34 | − avfilter_ref_buffer(insamples, ~AV_PERM_WRITE)); | |
| 35 | − avfilter_unref_buffer(insamples); | |
| 36 | −} | |
| 37 | − | |
| 38 | −AVFilter avfilter_af_asplit = { | |
| 39 | − .name = "asplit", | |
| 40 | − .description = NULL_IF_CONFIG_SMALL("Pass on the audio input to two outputs."), | |
| 41 | − | |
| 42 | − .inputs = (const AVFilterPad[]) { | |
| 43 | − { .name = "default", | |
| 44 | − .type = AVMEDIA_TYPE_AUDIO, | |
| 45 | − .get_audio_buffer = ff_null_get_audio_buffer, | |
| 46 | − .filter_samples = filter_samples, }, | |
| 47 | − { .name = NULL} | |
| 48 | − }, | |
| 49 | − .outputs = (const AVFilterPad[]) { | |
| 50 | − { .name = "output1", | |
| 51 | − .type = AVMEDIA_TYPE_AUDIO, }, | |
| 52 | − { .name = "output2", | |
| 53 | − .type = AVMEDIA_TYPE_AUDIO, }, | |
| 54 | − { .name = NULL} | |
| 55 | − }, | |
| 56 | −}; | |
| @@ -30,7 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | |
| 31 | 31 | #define LIBAVFILTER_VERSION_MAJOR 2 |
| 32 | 32 | #define LIBAVFILTER_VERSION_MINOR 74 |
| 33 | −#define LIBAVFILTER_VERSION_MICRO 101 | |
| 33 | +#define LIBAVFILTER_VERSION_MICRO 102 | |
| 34 | 34 | |
| 35 | 35 | #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |
| 36 | 36 | LIBAVFILTER_VERSION_MINOR, \ |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | */ |
| 25 | 25 | |
| 26 | 26 | #include "avfilter.h" |
| 27 | +#include "audio.h" | |
| 27 | 28 | |
| 28 | 29 | static int split_init(AVFilterContext *ctx, const char *args, void *opaque) |
| 29 | 30 | { |
| @@ -43,7 +44,7 @@ static int split_init(AVFilterContext *ctx, const char *args, void *opaque) · 13 unmodified lines | ||
| 43 | 44 | AVFilterPad pad = { 0 }; |
| 44 | 45 | |
| 45 | 46 | snprintf(name, sizeof(name), "output%d", i); |
| 46 | − pad.type = AVMEDIA_TYPE_VIDEO; | |
| 47 | + pad.type = !strcmp(ctx->name, "split") ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO; | |
| 47 | 48 | pad.name = av_strdup(name); |
| 48 | 49 | |
| 49 | 50 | avfilter_insert_outpad(ctx, i, &pad); |
| @@ -106,3 +107,32 @@ AVFilter avfilter_vf_split = { · 56 unmodified lines | ||
| 106 | 107 | { .name = NULL}}, |
| 107 | 108 | .outputs = (AVFilterPad[]) {{ .name = NULL}}, |
| 108 | 109 | }; |
| 110 | + | |
| 111 | +static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref) | |
| 112 | +{ | |
| 113 | + AVFilterContext *ctx = inlink->dst; | |
| 114 | + int i; | |
| 115 | + | |
| 116 | + for (i = 0; i < ctx->output_count; i++) | |
| 117 | + ff_filter_samples(inlink->dst->outputs[i], | |
| 118 | + avfilter_ref_buffer(samplesref, ~AV_PERM_WRITE)); | |
| 119 | +} | |
| 120 | + | |
| 121 | +AVFilter avfilter_af_asplit = { | |
| 122 | + .name = "asplit", | |
| 123 | + .description = NULL_IF_CONFIG_SMALL("Pass on the audio input to N audio outputs."), | |
| 124 | + | |
| 125 | + .init = split_init, | |
| 126 | + .uninit = split_uninit, | |
| 127 | + | |
| 128 | + .inputs = (const AVFilterPad[]) { | |
| 129 | + { | |
| 130 | + .name = "default", | |
| 131 | + .type = AVMEDIA_TYPE_AUDIO, | |
| 132 | + .get_audio_buffer = ff_null_get_audio_buffer, | |
| 133 | + .filter_samples = filter_samples, | |
| 134 | + }, | |
| 135 | + { .name = NULL } | |
| 136 | + }, | |
| 137 | + .outputs = (const AVFilterPad[]) {{ .name = NULL }}, | |
| 138 | +}; | |