Browse code

lavfi/aresample: use libswresample.

Clément Bœsch authored on 2012/01/22 04:26:31
Showing 3 changed files
... ...
@@ -1649,6 +1649,7 @@ udp_protocol_deps="network"
1649 1649
 
1650 1650
 # filters
1651 1651
 amovie_filter_deps="avcodec avformat"
1652
+aresample_filter_deps="swresample"
1652 1653
 ass_filter_deps="libass"
1653 1654
 blackframe_filter_deps="gpl"
1654 1655
 boxblur_filter_deps="gpl"
... ...
@@ -5,7 +5,7 @@ FFLIBS = avutil
5 5
 
6 6
 FFLIBS-$(CONFIG_ACONVERT_FILTER)             += avcodec
7 7
 FFLIBS-$(CONFIG_AMOVIE_FILTER)               += avformat avcodec
8
-FFLIBS-$(CONFIG_ARESAMPLE_FILTER)            += avcodec
8
+FFLIBS-$(CONFIG_ARESAMPLE_FILTER)            += swresample
9 9
 FFLIBS-$(CONFIG_MOVIE_FILTER)                += avformat avcodec
10 10
 FFLIBS-$(CONFIG_PAN_FILTER)                  += swresample
11 11
 FFLIBS-$(CONFIG_SCALE_FILTER)                += swscale
... ...
@@ -24,20 +24,14 @@
24 24
  * resampling audio filter
25 25
  */
26 26
 
27
-#include "libavutil/eval.h"
28
-#include "libavcodec/avcodec.h"
27
+#include "libswresample/swresample.h"
29 28
 #include "avfilter.h"
30 29
 #include "internal.h"
31 30
 
32 31
 typedef struct {
33
-    struct AVResampleContext *resample;
34 32
     int out_rate;
35 33
     double ratio;
36
-    AVFilterBufferRef *outsamplesref;
37
-    int unconsumed_nb_samples,
38
-        max_cached_nb_samples;
39
-    int16_t *cached_data[8],
40
-            *resampled_data[8];
34
+    struct SwrContext *swr;
41 35
 } AResampleContext;
42 36
 
43 37
 static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
... ...
@@ -58,23 +52,12 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
58 58
 static av_cold void uninit(AVFilterContext *ctx)
59 59
 {
60 60
     AResampleContext *aresample = ctx->priv;
61
-    if (aresample->outsamplesref) {
62
-        int nb_channels =
63
-            av_get_channel_layout_nb_channels(
64
-                aresample->outsamplesref->audio->channel_layout);
65
-        avfilter_unref_buffer(aresample->outsamplesref);
66
-        while (nb_channels--) {
67
-            av_freep(&(aresample->cached_data[nb_channels]));
68
-            av_freep(&(aresample->resampled_data[nb_channels]));
69
-        }
70
-    }
71
-
72
-    if (aresample->resample)
73
-        av_resample_close(aresample->resample);
61
+    swr_free(&aresample->swr);
74 62
 }
75 63
 
76 64
 static int config_output(AVFilterLink *outlink)
77 65
 {
66
+    int ret;
78 67
     AVFilterContext *ctx = outlink->src;
79 68
     AVFilterLink *inlink = ctx->inputs[0];
80 69
     AResampleContext *aresample = ctx->priv;
... ...
@@ -85,9 +68,16 @@ static int config_output(AVFilterLink *outlink)
85 85
         outlink->sample_rate = aresample->out_rate;
86 86
     outlink->time_base = (AVRational) {1, aresample->out_rate};
87 87
 
88
-    //TODO: make the resampling parameters configurable
89
-    aresample->resample = av_resample_init(aresample->out_rate, inlink->sample_rate,
90
-                                           16, 10, 0, 0.8);
88
+    //TODO: make the resampling parameters (filter size, phrase shift, linear, cutoff) configurable
89
+    aresample->swr = swr_alloc_set_opts(aresample->swr,
90
+                                        inlink->channel_layout, inlink->format, aresample->out_rate,
91
+                                        inlink->channel_layout, inlink->format, inlink->sample_rate,
92
+                                        0, ctx);
93
+    if (!aresample->swr)
94
+        return AVERROR(ENOMEM);
95
+    ret = swr_init(aresample->swr);
96
+    if (ret < 0)
97
+        return ret;
91 98
 
92 99
     aresample->ratio = (double)outlink->sample_rate / inlink->sample_rate;
93 100
 
... ...
@@ -96,235 +86,24 @@ static int config_output(AVFilterLink *outlink)
96 96
     return 0;
97 97
 }
98 98
 
99
-static int query_formats(AVFilterContext *ctx)
100
-{
101
-    AVFilterFormats *formats = NULL;
102
-
103
-    avfilter_add_format(&formats, AV_SAMPLE_FMT_S16);
104
-    if (!formats)
105
-        return AVERROR(ENOMEM);
106
-    avfilter_set_common_sample_formats(ctx, formats);
107
-
108
-    formats = avfilter_make_all_channel_layouts();
109
-    if (!formats)
110
-        return AVERROR(ENOMEM);
111
-    avfilter_set_common_channel_layouts(ctx, formats);
112
-
113
-    formats = avfilter_make_all_packing_formats();
114
-    if (!formats)
115
-        return AVERROR(ENOMEM);
116
-    avfilter_set_common_packing_formats(ctx, formats);
117
-
118
-    return 0;
119
-}
120
-
121
-static void deinterleave(int16_t **outp, int16_t *in,
122
-                         int nb_channels, int nb_samples)
123
-{
124
-    int16_t *out[8];
125
-    memcpy(out, outp, nb_channels * sizeof(int16_t*));
126
-
127
-    switch (nb_channels) {
128
-    case 2:
129
-        while (nb_samples--) {
130
-            *out[0]++ = *in++;
131
-            *out[1]++ = *in++;
132
-        }
133
-        break;
134
-    case 3:
135
-        while (nb_samples--) {
136
-            *out[0]++ = *in++;
137
-            *out[1]++ = *in++;
138
-            *out[2]++ = *in++;
139
-        }
140
-        break;
141
-    case 4:
142
-        while (nb_samples--) {
143
-            *out[0]++ = *in++;
144
-            *out[1]++ = *in++;
145
-            *out[2]++ = *in++;
146
-            *out[3]++ = *in++;
147
-        }
148
-        break;
149
-    case 5:
150
-        while (nb_samples--) {
151
-            *out[0]++ = *in++;
152
-            *out[1]++ = *in++;
153
-            *out[2]++ = *in++;
154
-            *out[3]++ = *in++;
155
-            *out[4]++ = *in++;
156
-        }
157
-        break;
158
-    case 6:
159
-        while (nb_samples--) {
160
-            *out[0]++ = *in++;
161
-            *out[1]++ = *in++;
162
-            *out[2]++ = *in++;
163
-            *out[3]++ = *in++;
164
-            *out[4]++ = *in++;
165
-            *out[5]++ = *in++;
166
-        }
167
-        break;
168
-    case 8:
169
-        while (nb_samples--) {
170
-            *out[0]++ = *in++;
171
-            *out[1]++ = *in++;
172
-            *out[2]++ = *in++;
173
-            *out[3]++ = *in++;
174
-            *out[4]++ = *in++;
175
-            *out[5]++ = *in++;
176
-            *out[6]++ = *in++;
177
-            *out[7]++ = *in++;
178
-        }
179
-        break;
180
-    }
181
-}
182
-
183
-static void interleave(int16_t *out, int16_t **inp,
184
-        int nb_channels, int nb_samples)
185
-{
186
-    int16_t *in[8];
187
-    memcpy(in, inp, nb_channels * sizeof(int16_t*));
188
-
189
-    switch (nb_channels) {
190
-    case 2:
191
-        while (nb_samples--) {
192
-            *out++ = *in[0]++;
193
-            *out++ = *in[1]++;
194
-        }
195
-        break;
196
-    case 3:
197
-        while (nb_samples--) {
198
-            *out++ = *in[0]++;
199
-            *out++ = *in[1]++;
200
-            *out++ = *in[2]++;
201
-        }
202
-        break;
203
-    case 4:
204
-        while (nb_samples--) {
205
-            *out++ = *in[0]++;
206
-            *out++ = *in[1]++;
207
-            *out++ = *in[2]++;
208
-            *out++ = *in[3]++;
209
-        }
210
-        break;
211
-    case 5:
212
-        while (nb_samples--) {
213
-            *out++ = *in[0]++;
214
-            *out++ = *in[1]++;
215
-            *out++ = *in[2]++;
216
-            *out++ = *in[3]++;
217
-            *out++ = *in[4]++;
218
-        }
219
-        break;
220
-    case 6:
221
-        while (nb_samples--) {
222
-            *out++ = *in[0]++;
223
-            *out++ = *in[1]++;
224
-            *out++ = *in[2]++;
225
-            *out++ = *in[3]++;
226
-            *out++ = *in[4]++;
227
-            *out++ = *in[5]++;
228
-        }
229
-        break;
230
-    case 8:
231
-        while (nb_samples--) {
232
-            *out++ = *in[0]++;
233
-            *out++ = *in[1]++;
234
-            *out++ = *in[2]++;
235
-            *out++ = *in[3]++;
236
-            *out++ = *in[4]++;
237
-            *out++ = *in[5]++;
238
-            *out++ = *in[6]++;
239
-            *out++ = *in[7]++;
240
-        }
241
-        break;
242
-    }
243
-}
244
-
245 99
 static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref)
246 100
 {
247
-    AResampleContext *aresample  = inlink->dst->priv;
248
-    AVFilterLink * const outlink = inlink->dst->outputs[0];
249
-    int i,
250
-        in_nb_samples            = insamplesref->audio->nb_samples,
251
-        cached_nb_samples        = in_nb_samples + aresample->unconsumed_nb_samples,
252
-        requested_out_nb_samples = aresample->ratio * cached_nb_samples,
253
-        nb_channels              =
254
-            av_get_channel_layout_nb_channels(inlink->channel_layout);
255
-
256
-    if (cached_nb_samples > aresample->max_cached_nb_samples) {
257
-        for (i = 0; i < nb_channels; i++) {
258
-            aresample->cached_data[i]    =
259
-                av_realloc(aresample->cached_data[i], cached_nb_samples * sizeof(int16_t));
260
-            aresample->resampled_data[i] =
261
-                av_realloc(aresample->resampled_data[i],
262
-                           FFALIGN(sizeof(int16_t) * requested_out_nb_samples, 16));
263
-
264
-            if (aresample->cached_data[i] == NULL || aresample->resampled_data[i] == NULL)
265
-                return;
266
-        }
267
-        aresample->max_cached_nb_samples = cached_nb_samples;
268
-
269
-        if (aresample->outsamplesref)
270
-            avfilter_unref_buffer(aresample->outsamplesref);
271
-
272
-        aresample->outsamplesref =
273
-            avfilter_get_audio_buffer(outlink, AV_PERM_WRITE, requested_out_nb_samples);
274
-        outlink->out_buf = aresample->outsamplesref;
275
-    }
276
-
277
-    avfilter_copy_buffer_ref_props(aresample->outsamplesref, insamplesref);
278
-    aresample->outsamplesref->audio->sample_rate = outlink->sample_rate;
279
-    aresample->outsamplesref->pts =
280
-        av_rescale(outlink->sample_rate, insamplesref->pts, inlink->sample_rate);
281
-
282
-    /* av_resample() works with planar audio buffers */
283
-    if (!inlink->planar && nb_channels > 1) {
284
-        int16_t *out[8];
285
-        for (i = 0; i < nb_channels; i++)
286
-            out[i] = aresample->cached_data[i] + aresample->unconsumed_nb_samples;
287
-
288
-        deinterleave(out, (int16_t *)insamplesref->data[0],
289
-                     nb_channels, in_nb_samples);
290
-    } else {
291
-        for (i = 0; i < nb_channels; i++)
292
-            memcpy(aresample->cached_data[i] + aresample->unconsumed_nb_samples,
293
-                   insamplesref->data[i],
294
-                   in_nb_samples * sizeof(int16_t));
295
-    }
296
-
297
-    for (i = 0; i < nb_channels; i++) {
298
-        int consumed_nb_samples;
299
-        const int is_last = i+1 == nb_channels;
300
-
301
-        aresample->outsamplesref->audio->nb_samples =
302
-            av_resample(aresample->resample,
303
-                        aresample->resampled_data[i], aresample->cached_data[i],
304
-                        &consumed_nb_samples,
305
-                        cached_nb_samples,
306
-                        requested_out_nb_samples, is_last);
307
-
308
-        /* move unconsumed data back to the beginning of the cache */
309
-        aresample->unconsumed_nb_samples = cached_nb_samples - consumed_nb_samples;
310
-        memmove(aresample->cached_data[i],
311
-                aresample->cached_data[i] + consumed_nb_samples,
312
-                aresample->unconsumed_nb_samples * sizeof(int16_t));
313
-    }
314
-
315
-
316
-    /* copy resampled data to the output samplesref */
317
-    if (!inlink->planar && nb_channels > 1) {
318
-        interleave((int16_t *)aresample->outsamplesref->data[0],
319
-                   aresample->resampled_data,
320
-                   nb_channels, aresample->outsamplesref->audio->nb_samples);
321
-    } else {
322
-        for (i = 0; i < nb_channels; i++)
323
-            memcpy(aresample->outsamplesref->data[i], aresample->resampled_data[i],
324
-                   aresample->outsamplesref->audio->nb_samples * sizeof(int16_t));
325
-    }
326
-
327
-    avfilter_filter_samples(outlink, avfilter_ref_buffer(aresample->outsamplesref, ~0));
101
+    AResampleContext *aresample = inlink->dst->priv;
102
+    const int n_in  = insamplesref->audio->nb_samples;
103
+    int n_out       = n_in * aresample->ratio;
104
+    AVFilterLink *const outlink = inlink->dst->outputs[0];
105
+    AVFilterBufferRef *outsamplesref = avfilter_get_audio_buffer(outlink, AV_PERM_WRITE, n_out);
106
+
107
+    n_out = swr_convert(aresample->swr, outsamplesref->data, n_out,
108
+                                 (void *)insamplesref->data, n_in);
109
+
110
+    avfilter_copy_buffer_ref_props(outsamplesref, insamplesref);
111
+    outsamplesref->audio->sample_rate = outlink->sample_rate;
112
+    outsamplesref->audio->nb_samples  = n_out;
113
+    outsamplesref->pts = av_rescale(outlink->sample_rate, insamplesref->pts,
114
+                                    inlink ->sample_rate);
115
+
116
+    avfilter_filter_samples(outlink, outsamplesref);
328 117
     avfilter_unref_buffer(insamplesref);
329 118
 }
330 119
 
... ...
@@ -333,7 +112,6 @@ AVFilter avfilter_af_aresample = {
333 333
     .description   = NULL_IF_CONFIG_SMALL("Resample audio data."),
334 334
     .init          = init,
335 335
     .uninit        = uninit,
336
-    .query_formats = query_formats,
337 336
     .priv_size     = sizeof(AResampleContext),
338 337
 
339 338
     .inputs    = (const AVFilterPad[]) {{ .name      = "default",