From 591741b51d4f0fee4680f1ae67247205a1ce56d8 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Tue, 21 Jul 2015 10:43:04 +0000 Subject: avfilter: add areverse filter Signed-off-by: Paul B Mahol --- libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/version.h | 2 +- libavfilter/vf_reverse.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+), 1 deletion(-) (limited to 'libavfilter') diff --git a/libavfilter/Makefile b/libavfilter/Makefile index db86d57c42..114227e177 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -43,6 +43,7 @@ OBJS-$(CONFIG_APAD_FILTER) += af_apad.o OBJS-$(CONFIG_APERMS_FILTER) += f_perms.o OBJS-$(CONFIG_APHASER_FILTER) += af_aphaser.o generate_wave_table.o OBJS-$(CONFIG_ARESAMPLE_FILTER) += af_aresample.o +OBJS-$(CONFIG_AREVERSE_FILTER) += vf_reverse.o OBJS-$(CONFIG_ASELECT_FILTER) += f_select.o OBJS-$(CONFIG_ASENDCMD_FILTER) += f_sendcmd.o OBJS-$(CONFIG_ASETNSAMPLES_FILTER) += af_asetnsamples.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 939eaff2e2..ad7242d592 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -59,6 +59,7 @@ void avfilter_register_all(void) REGISTER_FILTER(APERMS, aperms, af); REGISTER_FILTER(APHASER, aphaser, af); REGISTER_FILTER(ARESAMPLE, aresample, af); + REGISTER_FILTER(AREVERSE, areverse, af); REGISTER_FILTER(ASELECT, aselect, af); REGISTER_FILTER(ASENDCMD, asendcmd, af); REGISTER_FILTER(ASETNSAMPLES, asetnsamples, af); diff --git a/libavfilter/version.h b/libavfilter/version.h index 694f5d1676..06edb368b1 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 5 -#define LIBAVFILTER_VERSION_MINOR 27 +#define LIBAVFILTER_VERSION_MINOR 28 #define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vf_reverse.c b/libavfilter/vf_reverse.c index 4930238422..10529dfc5b 100644 --- a/libavfilter/vf_reverse.c +++ b/libavfilter/vf_reverse.c @@ -95,6 +95,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) return 0; } +#if CONFIG_REVERSE_FILTER + static int request_frame(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; @@ -141,3 +143,117 @@ AVFilter ff_vf_reverse = { .inputs = reverse_inputs, .outputs = reverse_outputs, }; + +#endif /* CONFIG_REVERSE_FILTER */ + +#if CONFIG_AREVERSE_FILTER + +static int query_formats(AVFilterContext *ctx) +{ + AVFilterFormats *formats; + AVFilterChannelLayouts *layouts; + int ret; + + layouts = ff_all_channel_layouts(); + if (!layouts) + return AVERROR(ENOMEM); + ret = ff_set_common_channel_layouts(ctx, layouts); + if (ret < 0) + return ret; + + ret = ff_set_common_formats(ctx, ff_planar_sample_fmts()); + if (ret < 0) + return ret; + + formats = ff_all_samplerates(); + if (!formats) + return AVERROR(ENOMEM); + return ff_set_common_samplerates(ctx, formats); +} + +static int areverse_request_frame(AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + ReverseContext *s = ctx->priv; + int ret, p, i, j; + + ret = ff_request_frame(ctx->inputs[0]); + + if (ret == AVERROR_EOF && s->nb_frames > 0) { + AVFrame *out = s->frames[s->nb_frames - 1]; + out->pts = s->pts[s->flush_idx++]; + + for (p = 0; p < outlink->channels; p++) { + switch (outlink->format) { + case AV_SAMPLE_FMT_U8P: { + uint8_t *dst = (uint8_t *)out->extended_data[p]; + for (i = 0, j = out->nb_samples - 1; i < j; i++, j--) + FFSWAP(uint8_t, dst[i], dst[j]); + } + break; + case AV_SAMPLE_FMT_S16P: { + int16_t *dst = (int16_t *)out->extended_data[p]; + for (i = 0, j = out->nb_samples - 1; i < j; i++, j--) + FFSWAP(int16_t, dst[i], dst[j]); + } + break; + case AV_SAMPLE_FMT_S32P: { + int32_t *dst = (int32_t *)out->extended_data[p]; + for (i = 0, j = out->nb_samples - 1; i < j; i++, j--) + FFSWAP(int32_t, dst[i], dst[j]); + } + break; + case AV_SAMPLE_FMT_FLTP: { + float *dst = (float *)out->extended_data[p]; + for (i = 0, j = out->nb_samples - 1; i < j; i++, j--) + FFSWAP(float, dst[i], dst[j]); + } + break; + case AV_SAMPLE_FMT_DBLP: { + double *dst = (double *)out->extended_data[p]; + for (i = 0, j = out->nb_samples - 1; i < j; i++, j--) + FFSWAP(double, dst[i], dst[j]); + } + break; + } + } + + ret = ff_filter_frame(outlink, out); + s->nb_frames--; + } + + return ret; +} + +static const AVFilterPad areverse_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + .filter_frame = filter_frame, + .needs_writable = 1, + }, + { NULL } +}; + +static const AVFilterPad areverse_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + .request_frame = areverse_request_frame, + .config_props = config_output, + }, + { NULL } +}; + +AVFilter ff_af_areverse = { + .name = "areverse", + .description = NULL_IF_CONFIG_SMALL("Reverse an audio clip."), + .query_formats = query_formats, + .priv_size = sizeof(ReverseContext), + .init = init, + .uninit = uninit, + .inputs = areverse_inputs, + .outputs = areverse_outputs, +}; + +#endif /* CONFIG_AREVERSE_FILTER */ -- cgit v1.2.3