summaryrefslogtreecommitdiff
path: root/libavfilter/af_aresample.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-05-17 16:12:54 +0200
committerMichael Niedermayer <michaelni@gmx.at>2012-05-17 16:46:15 +0200
commitb13d39bd812309aad7d912b3c55da8d16dd3efe8 (patch)
treeb4d6e7643e13a0c657e6f3ea7abfc46bf8cb5b9e /libavfilter/af_aresample.c
parenta0493be10e87443d493f680fcfc6a46f9e6c40eb (diff)
downloadffmpeg-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.c72
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",