Based on current version of the asplit filter in FFmpeg written by
Stefano Sabatini and others.
| ... | ... |
@@ -137,6 +137,19 @@ aformat=sample_fmts\=u8\,s16:channel_layouts\=stereo |
| 137 | 137 |
|
| 138 | 138 |
Pass the audio source unchanged to the output. |
| 139 | 139 |
|
| 140 |
+@section asplit |
|
| 141 |
+ |
|
| 142 |
+Split input audio into several identical outputs. |
|
| 143 |
+ |
|
| 144 |
+The filter accepts a single parameter which specifies the number of outputs. If |
|
| 145 |
+unspecified, it defaults to 2. |
|
| 146 |
+ |
|
| 147 |
+For example |
|
| 148 |
+@example |
|
| 149 |
+avconv -i INPUT -filter_complex asplit=5 OUTPUT |
|
| 150 |
+@end example |
|
| 151 |
+will create 5 copies of the input audio. |
|
| 152 |
+ |
|
| 140 | 153 |
@section asyncts |
| 141 | 154 |
Synchronize audio data with timestamps by squeezing/stretching it and/or |
| 142 | 155 |
dropping samples/adding silence when needed. |
| ... | ... |
@@ -27,6 +27,7 @@ OBJS = allfilters.o \ |
| 27 | 27 |
|
| 28 | 28 |
OBJS-$(CONFIG_AFORMAT_FILTER) += af_aformat.o |
| 29 | 29 |
OBJS-$(CONFIG_ANULL_FILTER) += af_anull.o |
| 30 |
+OBJS-$(CONFIG_ASPLIT_FILTER) += split.o |
|
| 30 | 31 |
OBJS-$(CONFIG_ASYNCTS_FILTER) += af_asyncts.o |
| 31 | 32 |
OBJS-$(CONFIG_RESAMPLE_FILTER) += af_resample.o |
| 32 | 33 |
|
| ... | ... |
@@ -20,10 +20,11 @@ |
| 20 | 20 |
|
| 21 | 21 |
/** |
| 22 | 22 |
* @file |
| 23 |
- * Video splitter |
|
| 23 |
+ * audio and video splitter |
|
| 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) |
| 43 | 43 |
AVFilterPad pad = { 0 };
|
| 44 | 44 |
|
| 45 | 45 |
snprintf(name, sizeof(name), "output%d", i); |
| 46 |
- pad.type = AVMEDIA_TYPE_VIDEO; |
|
| 46 |
+ pad.type = ctx->filter->inputs[0].type; |
|
| 47 | 47 |
pad.name = av_strdup(name); |
| 48 | 48 |
|
| 49 | 49 |
avfilter_insert_outpad(ctx, i, &pad); |
| ... | ... |
@@ -106,3 +107,28 @@ AVFilter avfilter_vf_split = {
|
| 106 | 106 |
{ .name = NULL}},
|
| 107 | 107 |
.outputs = (AVFilterPad[]) {{ .name = NULL}},
|
| 108 | 108 |
}; |
| 109 |
+ |
|
| 110 |
+static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref) |
|
| 111 |
+{
|
|
| 112 |
+ AVFilterContext *ctx = inlink->dst; |
|
| 113 |
+ int i; |
|
| 114 |
+ |
|
| 115 |
+ for (i = 0; i < ctx->output_count; i++) |
|
| 116 |
+ ff_filter_samples(inlink->dst->outputs[i], |
|
| 117 |
+ avfilter_ref_buffer(samplesref, ~AV_PERM_WRITE)); |
|
| 118 |
+} |
|
| 119 |
+ |
|
| 120 |
+AVFilter avfilter_af_asplit = {
|
|
| 121 |
+ .name = "asplit", |
|
| 122 |
+ .description = NULL_IF_CONFIG_SMALL("Pass on the audio input to N audio outputs."),
|
|
| 123 |
+ |
|
| 124 |
+ .init = split_init, |
|
| 125 |
+ .uninit = split_uninit, |
|
| 126 |
+ |
|
| 127 |
+ .inputs = (const AVFilterPad[]) {{ .name = "default",
|
|
| 128 |
+ .type = AVMEDIA_TYPE_AUDIO, |
|
| 129 |
+ .get_audio_buffer = ff_null_get_audio_buffer, |
|
| 130 |
+ .filter_samples = filter_samples }, |
|
| 131 |
+ { .name = NULL }},
|
|
| 132 |
+ .outputs = (const AVFilterPad[]) {{ .name = NULL }},
|
|
| 133 |
+}; |
| ... | ... |
@@ -29,7 +29,7 @@ |
| 29 | 29 |
#include "libavutil/avutil.h" |
| 30 | 30 |
|
| 31 | 31 |
#define LIBAVFILTER_VERSION_MAJOR 2 |
| 32 |
-#define LIBAVFILTER_VERSION_MINOR 18 |
|
| 32 |
+#define LIBAVFILTER_VERSION_MINOR 19 |
|
| 33 | 33 |
#define LIBAVFILTER_VERSION_MICRO 0 |
| 34 | 34 |
|
| 35 | 35 |
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |