Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Michael Niedermayer authored on 2012/05/17 23:12:54... | ... |
@@ -26,13 +26,14 @@ |
26 | 26 |
|
27 | 27 |
#include "libavutil/avstring.h" |
28 | 28 |
#include "libavutil/opt.h" |
29 |
+#include "libavutil/samplefmt.h" |
|
30 |
+#include "libavutil/avassert.h" |
|
29 | 31 |
#include "libswresample/swresample.h" |
30 | 32 |
#include "avfilter.h" |
31 | 33 |
#include "audio.h" |
32 | 34 |
#include "internal.h" |
33 | 35 |
|
34 | 36 |
typedef struct { |
35 |
- int out_rate; |
|
36 | 37 |
double ratio; |
37 | 38 |
struct SwrContext *swr; |
38 | 39 |
} AResampleContext; |
... | ... |
@@ -57,12 +58,14 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) |
57 | 57 |
if(value) { |
58 | 58 |
if((ret=av_opt_set(aresample->swr, token, value, 0)) < 0) |
59 | 59 |
goto end; |
60 |
- } else if ((ret = ff_parse_sample_rate(&aresample->out_rate, token, ctx)) < 0) |
|
61 |
- goto end; |
|
60 |
+ } else { |
|
61 |
+ int out_rate; |
|
62 |
+ if ((ret = ff_parse_sample_rate(&out_rate, token, ctx)) < 0) |
|
63 |
+ goto end; |
|
64 |
+ if((ret = av_opt_set_int(aresample->swr, "osr", out_rate, 0)) < 0) |
|
65 |
+ goto end; |
|
66 |
+ } |
|
62 | 67 |
} |
63 |
- |
|
64 |
- } else { |
|
65 |
- aresample->out_rate = -1; |
|
66 | 68 |
} |
67 | 69 |
end: |
68 | 70 |
av_free(argd); |
... | ... |
@@ -78,34 +81,42 @@ static av_cold void uninit(AVFilterContext *ctx) |
78 | 78 |
static int query_formats(AVFilterContext *ctx) |
79 | 79 |
{ |
80 | 80 |
AResampleContext *aresample = ctx->priv; |
81 |
+ int out_rate = av_get_int(aresample->swr, "osr", NULL); |
|
82 |
+ uint64_t out_layout = av_get_int(aresample->swr, "ocl", NULL); |
|
83 |
+ enum AVSampleFormat out_format = av_get_int(aresample->swr, "osf", NULL); |
|
81 | 84 |
|
82 | 85 |
AVFilterLink *inlink = ctx->inputs[0]; |
83 | 86 |
AVFilterLink *outlink = ctx->outputs[0]; |
84 | 87 |
|
85 | 88 |
AVFilterFormats *in_formats = avfilter_all_formats(AVMEDIA_TYPE_AUDIO); |
86 |
- AVFilterFormats *out_formats = avfilter_all_formats(AVMEDIA_TYPE_AUDIO); |
|
89 |
+ AVFilterFormats *out_formats; |
|
87 | 90 |
AVFilterFormats *in_samplerates = ff_all_samplerates(); |
88 | 91 |
AVFilterFormats *out_samplerates; |
89 |
- |
|
90 |
- |
|
91 | 92 |
AVFilterChannelLayouts *in_layouts = ff_all_channel_layouts(); |
92 |
- AVFilterChannelLayouts *out_layouts = ff_all_channel_layouts(); |
|
93 |
- |
|
94 |
- avfilter_formats_ref(in_formats, &inlink->out_formats); |
|
95 |
- avfilter_formats_ref(out_formats, &outlink->in_formats); |
|
96 |
- |
|
97 |
- avfilter_formats_ref(in_samplerates, &inlink->out_samplerates); |
|
93 |
+ AVFilterChannelLayouts *out_layouts; |
|
98 | 94 |
|
99 |
- ff_channel_layouts_ref(in_layouts, &inlink->out_channel_layouts); |
|
100 |
- ff_channel_layouts_ref(out_layouts, &outlink->in_channel_layouts); |
|
95 |
+ avfilter_formats_ref (in_formats, &inlink->out_formats); |
|
96 |
+ avfilter_formats_ref (in_samplerates, &inlink->out_samplerates); |
|
97 |
+ ff_channel_layouts_ref(in_layouts, &inlink->out_channel_layouts); |
|
101 | 98 |
|
102 |
- if(aresample->out_rate > 0) { |
|
103 |
- int sample_rates[] = { aresample->out_rate, -1 }; |
|
104 |
- avfilter_formats_ref(avfilter_make_format_list(sample_rates), &outlink->in_samplerates); |
|
99 |
+ if(out_rate > 0) { |
|
100 |
+ out_samplerates = avfilter_make_format_list((int[]){ out_rate, -1 }); |
|
105 | 101 |
} else { |
106 | 102 |
out_samplerates = ff_all_samplerates(); |
107 |
- avfilter_formats_ref(out_samplerates, &outlink->in_samplerates); |
|
108 | 103 |
} |
104 |
+ avfilter_formats_ref(out_samplerates, &outlink->in_samplerates); |
|
105 |
+ |
|
106 |
+ if(out_format != AV_SAMPLE_FMT_NONE) { |
|
107 |
+ out_formats = avfilter_make_format_list((int[]){ out_format, -1 }); |
|
108 |
+ } else |
|
109 |
+ out_formats = avfilter_make_all_formats(AVMEDIA_TYPE_AUDIO); |
|
110 |
+ avfilter_formats_ref(out_formats, &outlink->in_formats); |
|
111 |
+ |
|
112 |
+ if(out_layout) { |
|
113 |
+ out_layouts = avfilter_make_format64_list((int64_t[]){ out_layout, -1 }); |
|
114 |
+ } else |
|
115 |
+ out_layouts = ff_all_channel_layouts(); |
|
116 |
+ ff_channel_layouts_ref(out_layouts, &outlink->in_channel_layouts); |
|
109 | 117 |
|
110 | 118 |
return 0; |
111 | 119 |
} |
... | ... |
@@ -117,12 +128,9 @@ static int config_output(AVFilterLink *outlink) |
117 | 117 |
AVFilterContext *ctx = outlink->src; |
118 | 118 |
AVFilterLink *inlink = ctx->inputs[0]; |
119 | 119 |
AResampleContext *aresample = ctx->priv; |
120 |
- |
|
121 |
- if (aresample->out_rate == -1) |
|
122 |
- aresample->out_rate = outlink->sample_rate; |
|
123 |
- else |
|
124 |
- outlink->sample_rate = aresample->out_rate; |
|
125 |
- outlink->time_base = (AVRational) {1, aresample->out_rate}; |
|
120 |
+ int out_rate; |
|
121 |
+ uint64_t out_layout; |
|
122 |
+ enum AVSampleFormat out_format; |
|
126 | 123 |
|
127 | 124 |
aresample->swr = swr_alloc_set_opts(aresample->swr, |
128 | 125 |
outlink->channel_layout, outlink->format, outlink->sample_rate, |
... | ... |
@@ -130,10 +138,20 @@ static int config_output(AVFilterLink *outlink) |
130 | 130 |
0, ctx); |
131 | 131 |
if (!aresample->swr) |
132 | 132 |
return AVERROR(ENOMEM); |
133 |
+ |
|
133 | 134 |
ret = swr_init(aresample->swr); |
134 | 135 |
if (ret < 0) |
135 | 136 |
return ret; |
136 | 137 |
|
138 |
+ out_rate = av_get_int(aresample->swr, "osr", NULL); |
|
139 |
+ out_layout = av_get_int(aresample->swr, "ocl", NULL); |
|
140 |
+ out_format = av_get_int(aresample->swr, "osf", NULL); |
|
141 |
+ outlink->time_base = (AVRational) {1, out_rate}; |
|
142 |
+ |
|
143 |
+ av_assert0(outlink->sample_rate == out_rate); |
|
144 |
+ av_assert0(outlink->channel_layout == out_layout); |
|
145 |
+ av_assert0(outlink->format == out_format); |
|
146 |
+ |
|
137 | 147 |
aresample->ratio = (double)outlink->sample_rate / inlink->sample_rate; |
138 | 148 |
|
139 | 149 |
av_log(ctx, AV_LOG_INFO, "r:%"PRId64"Hz -> r:%"PRId64"Hz\n", |