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 | @section asplit | 305 | @section asplit |
| 306 | 306 | ||
| 307 | Pass on the input audio to two outputs. Both outputs are identical to | 307 | Split input audio into several identical outputs. |
| 308 | the input audio. | 308 | |
| 309 | The filter accepts a single parameter which specifies the number of outputs. If | ||
| 310 | unspecified, it defaults to 2. | ||
| 309 | 311 | ||
| 310 | For example: | 312 | For example: |
| 311 | @example | 313 | @example |
| 312 | [in] asplit[out0], showaudio[out1] | 314 | [in] asplit [out0][out1] |
| 313 | @end example | 315 | @end example |
| 314 | 316 | ||
| 315 | will create two separate outputs from the same input, one cropped and | 317 | will create two separate outputs from the same input. |
| 316 | one padded. | 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 | @section astreamsync | 325 | @section astreamsync |
| 319 | 326 | ||
| @@ -50,7 +50,7 @@ OBJS-$(CONFIG_AMERGE_FILTER) += af_amerge.o · 49 unmodified lines | |||
| 50 | OBJS-$(CONFIG_ANULL_FILTER) += af_anull.o | 50 | OBJS-$(CONFIG_ANULL_FILTER) += af_anull.o |
| 51 | OBJS-$(CONFIG_ARESAMPLE_FILTER) += af_aresample.o | 51 | OBJS-$(CONFIG_ARESAMPLE_FILTER) += af_aresample.o |
| 52 | OBJS-$(CONFIG_ASHOWINFO_FILTER) += af_ashowinfo.o | 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 | OBJS-$(CONFIG_ASTREAMSYNC_FILTER) += af_astreamsync.o | 54 | OBJS-$(CONFIG_ASTREAMSYNC_FILTER) += af_astreamsync.o |
| 55 | OBJS-$(CONFIG_ASYNCTS_FILTER) += af_asyncts.o | 55 | OBJS-$(CONFIG_ASYNCTS_FILTER) += af_asyncts.o |
| 56 | OBJS-$(CONFIG_EARWAX_FILTER) += af_earwax.o | 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 | #define LIBAVFILTER_VERSION_MAJOR 2 | 31 | #define LIBAVFILTER_VERSION_MAJOR 2 |
| 32 | #define LIBAVFILTER_VERSION_MINOR 74 | 32 | #define LIBAVFILTER_VERSION_MINOR 74 |
| 33 | #define LIBAVFILTER_VERSION_MICRO 101 | 33 | #define LIBAVFILTER_VERSION_MICRO 102 |
| 34 | 34 | ||
| 35 | #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ | 35 | #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |
| 36 | LIBAVFILTER_VERSION_MINOR, \ | 36 | LIBAVFILTER_VERSION_MINOR, \ |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | |||
| 24 | */ | 24 | */ |
| 25 | 25 | ||
| 26 | #include "avfilter.h" | 26 | #include "avfilter.h" |
| 27 | #include "audio.h" | ||
| 27 | 28 | ||
| 28 | static int split_init(AVFilterContext *ctx, const char *args, void *opaque) | 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 | AVFilterPad pad = { 0 }; | 44 | AVFilterPad pad = { 0 }; |
| 44 | 45 | ||
| 45 | snprintf(name, sizeof(name), "output%d", i); | 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 | pad.name = av_strdup(name); | 48 | pad.name = av_strdup(name); |
| 48 | 49 | ||
| 49 | avfilter_insert_outpad(ctx, i, &pad); | 50 | avfilter_insert_outpad(ctx, i, &pad); |
| @@ -106,3 +107,32 @@ AVFilter avfilter_vf_split = { · 56 unmodified lines | |||
| 106 | { .name = NULL}}, | 107 | { .name = NULL}}, |
| 107 | .outputs = (AVFilterPad[]) {{ .name = NULL}}, | 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 | }; | ||