diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-05-17 16:12:54 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-05-17 16:46:15 +0200 |
commit | b13d39bd812309aad7d912b3c55da8d16dd3efe8 (patch) | |
tree | b4d6e7643e13a0c657e6f3ea7abfc46bf8cb5b9e /libavfilter/af_aresample.c | |
parent | a0493be10e87443d493f680fcfc6a46f9e6c40eb (diff) | |
download | ffmpeg-b13d39bd812309aad7d912b3c55da8d16dd3efe8.tar.gz |
av_aresample: Allow changing sample format and channel layout as well
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavfilter/af_aresample.c')
-rw-r--r-- | libavfilter/af_aresample.c | 72 |
1 files changed, 45 insertions, 27 deletions
diff --git a/libavfilter/af_aresample.c b/libavfilter/af_aresample.c index aea5e5e75e..dde79e2a6a 100644 --- a/libavfilter/af_aresample.c +++ b/libavfilter/af_aresample.c @@ -26,13 +26,14 @@ #include "libavutil/avstring.h" #include "libavutil/opt.h" +#include "libavutil/samplefmt.h" +#include "libavutil/avassert.h" #include "libswresample/swresample.h" #include "avfilter.h" #include "audio.h" #include "internal.h" typedef struct { - int out_rate; double ratio; struct SwrContext *swr; } AResampleContext; @@ -57,12 +58,14 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) if(value) { if((ret=av_opt_set(aresample->swr, token, value, 0)) < 0) goto end; - } else if ((ret = ff_parse_sample_rate(&aresample->out_rate, token, ctx)) < 0) - goto end; + } else { + int out_rate; + if ((ret = ff_parse_sample_rate(&out_rate, token, ctx)) < 0) + goto end; + if((ret = av_opt_set_int(aresample->swr, "osr", out_rate, 0)) < 0) + goto end; + } } - - } else { - aresample->out_rate = -1; } end: av_free(argd); @@ -78,34 +81,42 @@ static av_cold void uninit(AVFilterContext *ctx) static int query_formats(AVFilterContext *ctx) { AResampleContext *aresample = ctx->priv; + int out_rate = av_get_int(aresample->swr, "osr", NULL); + uint64_t out_layout = av_get_int(aresample->swr, "ocl", NULL); + enum AVSampleFormat out_format = av_get_int(aresample->swr, "osf", NULL); AVFilterLink *inlink = ctx->inputs[0]; AVFilterLink *outlink = ctx->outputs[0]; AVFilterFormats *in_formats = avfilter_all_formats(AVMEDIA_TYPE_AUDIO); - AVFilterFormats *out_formats = avfilter_all_formats(AVMEDIA_TYPE_AUDIO); + AVFilterFormats *out_formats; AVFilterFormats *in_samplerates = ff_all_samplerates(); AVFilterFormats *out_samplerates; - - AVFilterChannelLayouts *in_layouts = ff_all_channel_layouts(); - AVFilterChannelLayouts *out_layouts = ff_all_channel_layouts(); - - avfilter_formats_ref(in_formats, &inlink->out_formats); - avfilter_formats_ref(out_formats, &outlink->in_formats); - - avfilter_formats_ref(in_samplerates, &inlink->out_samplerates); + AVFilterChannelLayouts *out_layouts; - ff_channel_layouts_ref(in_layouts, &inlink->out_channel_layouts); - ff_channel_layouts_ref(out_layouts, &outlink->in_channel_layouts); + avfilter_formats_ref (in_formats, &inlink->out_formats); + avfilter_formats_ref (in_samplerates, &inlink->out_samplerates); + ff_channel_layouts_ref(in_layouts, &inlink->out_channel_layouts); - if(aresample->out_rate > 0) { - int sample_rates[] = { aresample->out_rate, -1 }; - avfilter_formats_ref(avfilter_make_format_list(sample_rates), &outlink->in_samplerates); + if(out_rate > 0) { + out_samplerates = avfilter_make_format_list((int[]){ out_rate, -1 }); } else { out_samplerates = ff_all_samplerates(); - avfilter_formats_ref(out_samplerates, &outlink->in_samplerates); } + avfilter_formats_ref(out_samplerates, &outlink->in_samplerates); + + if(out_format != AV_SAMPLE_FMT_NONE) { + out_formats = avfilter_make_format_list((int[]){ out_format, -1 }); + } else + out_formats = avfilter_make_all_formats(AVMEDIA_TYPE_AUDIO); + avfilter_formats_ref(out_formats, &outlink->in_formats); + + if(out_layout) { + out_layouts = avfilter_make_format64_list((int64_t[]){ out_layout, -1 }); + } else + out_layouts = ff_all_channel_layouts(); + ff_channel_layouts_ref(out_layouts, &outlink->in_channel_layouts); return 0; } @@ -117,12 +128,9 @@ static int config_output(AVFilterLink *outlink) AVFilterContext *ctx = outlink->src; AVFilterLink *inlink = ctx->inputs[0]; AResampleContext *aresample = ctx->priv; - - if (aresample->out_rate == -1) - aresample->out_rate = outlink->sample_rate; - else - outlink->sample_rate = aresample->out_rate; - outlink->time_base = (AVRational) {1, aresample->out_rate}; + int out_rate; + uint64_t out_layout; + enum AVSampleFormat out_format; aresample->swr = swr_alloc_set_opts(aresample->swr, outlink->channel_layout, outlink->format, outlink->sample_rate, @@ -130,10 +138,20 @@ static int config_output(AVFilterLink *outlink) 0, ctx); if (!aresample->swr) return AVERROR(ENOMEM); + ret = swr_init(aresample->swr); if (ret < 0) return ret; + out_rate = av_get_int(aresample->swr, "osr", NULL); + out_layout = av_get_int(aresample->swr, "ocl", NULL); + out_format = av_get_int(aresample->swr, "osf", NULL); + outlink->time_base = (AVRational) {1, out_rate}; + + av_assert0(outlink->sample_rate == out_rate); + av_assert0(outlink->channel_layout == out_layout); + av_assert0(outlink->format == out_format); + aresample->ratio = (double)outlink->sample_rate / inlink->sample_rate; av_log(ctx, AV_LOG_INFO, "r:%"PRId64"Hz -> r:%"PRId64"Hz\n", |