Based on current version of the asplit filter in FFmpeg written by Stefano Sabatini and others.
Unified · Split
| @@ -19,6 +19,7 @@ version <next>: · 18 unmodified lines | |||
| 19 | - add libavresample audio conversion library | 19 | - add libavresample audio conversion library |
| 20 | - audio filters support in libavfilter and avconv | 20 | - audio filters support in libavfilter and avconv |
| 21 | - add fps filter | 21 | - add fps filter |
| 22 | - audio split filter | ||
| 22 | 23 | ||
| 23 | 24 | ||
| 24 | version 0.8: | 25 | version 0.8: |
| @@ -137,6 +137,19 @@ aformat=sample_fmts\=u8\,s16:channel_layouts\=stereo · 136 unmodified lines | |||
| 137 | 137 | ||
| 138 | Pass the audio source unchanged to the output. | 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 | @section asyncts | 153 | @section asyncts |
| 141 | Synchronize audio data with timestamps by squeezing/stretching it and/or | 154 | Synchronize audio data with timestamps by squeezing/stretching it and/or |
| 142 | dropping samples/adding silence when needed. | 155 | dropping samples/adding silence when needed. |
| @@ -27,6 +27,7 @@ OBJS = allfilters.o \ · 26 unmodified lines | |||
| 27 | 27 | ||
| 28 | OBJS-$(CONFIG_AFORMAT_FILTER) += af_aformat.o | 28 | OBJS-$(CONFIG_AFORMAT_FILTER) += af_aformat.o |
| 29 | OBJS-$(CONFIG_ANULL_FILTER) += af_anull.o | 29 | OBJS-$(CONFIG_ANULL_FILTER) += af_anull.o |
| 30 | OBJS-$(CONFIG_ASPLIT_FILTER) += split.o | ||
| 30 | OBJS-$(CONFIG_ASYNCTS_FILTER) += af_asyncts.o | 31 | OBJS-$(CONFIG_ASYNCTS_FILTER) += af_asyncts.o |
| 31 | OBJS-$(CONFIG_RESAMPLE_FILTER) += af_resample.o | 32 | OBJS-$(CONFIG_RESAMPLE_FILTER) += af_resample.o |
| 32 | 33 | ||
| @@ -36,6 +36,7 @@ void avfilter_register_all(void) · 35 unmodified lines | |||
| 36 | 36 | ||
| 37 | REGISTER_FILTER (AFORMAT, aformat, af); | 37 | REGISTER_FILTER (AFORMAT, aformat, af); |
| 38 | REGISTER_FILTER (ANULL, anull, af); | 38 | REGISTER_FILTER (ANULL, anull, af); |
| 39 | REGISTER_FILTER (ASPLIT, asplit, af); | ||
| 39 | REGISTER_FILTER (ASYNCTS, asyncts, af); | 40 | REGISTER_FILTER (ASYNCTS, asyncts, af); |
| 40 | REGISTER_FILTER (RESAMPLE, resample, af); | 41 | REGISTER_FILTER (RESAMPLE, resample, af); |
| 41 | 42 | ||
| @@ -20,10 +20,11 @@ · 19 unmodified lines | |||
| 20 | 20 | ||
| 21 | /** | 21 | /** |
| 22 | * @file | 22 | * @file |
| 23 | * Video splitter | 23 | * audio and video splitter |
| 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 = ctx->filter->inputs[0].type; |
| 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,28 @@ 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[]) {{ .name = "default", | ||
| 129 | .type = AVMEDIA_TYPE_AUDIO, | ||
| 130 | .get_audio_buffer = ff_null_get_audio_buffer, | ||
| 131 | .filter_samples = filter_samples }, | ||
| 132 | { .name = NULL }}, | ||
| 133 | .outputs = (const AVFilterPad[]) {{ .name = NULL }}, | ||
| 134 | }; | ||
| @@ -29,7 +29,7 @@ · 28 unmodified lines | |||
| 29 | #include "libavutil/avutil.h" | 29 | #include "libavutil/avutil.h" |
| 30 | 30 | ||
| 31 | #define LIBAVFILTER_VERSION_MAJOR 2 | 31 | #define LIBAVFILTER_VERSION_MAJOR 2 |
| 32 | #define LIBAVFILTER_VERSION_MINOR 18 | 32 | #define LIBAVFILTER_VERSION_MINOR 19 |
| 33 | #define LIBAVFILTER_VERSION_MICRO 0 | 33 | #define LIBAVFILTER_VERSION_MICRO 0 |
| 34 | 34 | ||
| 35 | #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ | 35 | #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |