• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013 Paul B Mahol
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "libavutil/avstring.h"
22 #include "libavutil/eval.h"
23 #include "libavutil/opt.h"
24 #include "libavutil/samplefmt.h"
25 #include "avfilter.h"
26 #include "audio.h"
27 #include "filters.h"
28 #include "internal.h"
29 
30 typedef struct ChanDelay {
31     int64_t delay;
32     size_t delay_index;
33     size_t index;
34     unsigned int samples_size;
35     uint8_t *samples;
36 } ChanDelay;
37 
38 typedef struct AudioDelayContext {
39     const AVClass *class;
40     int all;
41     char *delays;
42     ChanDelay *chandelay;
43     int nb_delays;
44     int block_align;
45     int64_t padding;
46     int64_t max_delay;
47     int64_t next_pts;
48     int eof;
49 
50     void (*delay_channel)(ChanDelay *d, int nb_samples,
51                           const uint8_t *src, uint8_t *dst);
52     int (*resize_channel_samples)(ChanDelay *d, int64_t new_delay);
53 } AudioDelayContext;
54 
55 #define OFFSET(x) offsetof(AudioDelayContext, x)
56 #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
57 
58 static const AVOption adelay_options[] = {
59     { "delays", "set list of delays for each channel", OFFSET(delays), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, A | AV_OPT_FLAG_RUNTIME_PARAM },
60     { "all",    "use last available delay for remained channels", OFFSET(all), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, A },
61     { NULL }
62 };
63 
64 AVFILTER_DEFINE_CLASS(adelay);
65 
66 #define DELAY(name, type, fill)                                           \
67 static void delay_channel_## name ##p(ChanDelay *d, int nb_samples,       \
68                                       const uint8_t *ssrc, uint8_t *ddst) \
69 {                                                                         \
70     const type *src = (type *)ssrc;                                       \
71     type *dst = (type *)ddst;                                             \
72     type *samples = (type *)d->samples;                                   \
73                                                                           \
74     while (nb_samples) {                                                  \
75         if (d->delay_index < d->delay) {                                  \
76             const int len = FFMIN(nb_samples, d->delay - d->delay_index); \
77                                                                           \
78             memcpy(&samples[d->delay_index], src, len * sizeof(type));    \
79             memset(dst, fill, len * sizeof(type));                        \
80             d->delay_index += len;                                        \
81             src += len;                                                   \
82             dst += len;                                                   \
83             nb_samples -= len;                                            \
84         } else {                                                          \
85             *dst = samples[d->index];                                     \
86             samples[d->index] = *src;                                     \
87             nb_samples--;                                                 \
88             d->index++;                                                   \
89             src++, dst++;                                                 \
90             d->index = d->index >= d->delay ? 0 : d->index;               \
91         }                                                                 \
92     }                                                                     \
93 }
94 
95 DELAY(u8,  uint8_t, 0x80)
96 DELAY(s16, int16_t, 0)
97 DELAY(s32, int32_t, 0)
98 DELAY(flt, float,   0)
99 DELAY(dbl, double,  0)
100 
101 #define CHANGE_DELAY(name, type, fill)                                                                  \
102 static int resize_samples_## name ##p(ChanDelay *d, int64_t new_delay)                                  \
103 {                                                                                                       \
104     type *samples;                                                                                      \
105                                                                                                         \
106     if (new_delay == d->delay) {                                                                        \
107         return 0;                                                                                       \
108     }                                                                                                   \
109                                                                                                         \
110     if (new_delay == 0) {                                                                               \
111         av_freep(&d->samples);                                                                          \
112         d->samples_size = 0;                                                                            \
113         d->delay = 0;                                                                                   \
114         d->index = 0;                                                                                   \
115         d->delay_index = 0;                                                                             \
116         return 0;                                                                                       \
117     }                                                                                                   \
118                                                                                                         \
119     samples = (type *) av_fast_realloc(d->samples, &d->samples_size, new_delay * sizeof(type));         \
120     if (!samples) {                                                                                     \
121         return AVERROR(ENOMEM);                                                                         \
122     }                                                                                                   \
123                                                                                                         \
124     if (new_delay < d->delay) {                                                                         \
125         if (d->index > new_delay) {                                                                     \
126             d->index -= new_delay;                                                                      \
127             memmove(samples, &samples[new_delay], d->index * sizeof(type));                             \
128             d->delay_index = new_delay;                                                                 \
129         } else if (d->delay_index > d->index) {                                                         \
130             memmove(&samples[d->index], &samples[d->index+(d->delay-new_delay)],                        \
131                     (new_delay - d->index) * sizeof(type));                                             \
132             d->delay_index -= d->delay - new_delay;                                                     \
133         }                                                                                               \
134     } else {                                                                                            \
135         size_t block_size;                                                                              \
136         if (d->delay_index >= d->delay) {                                                               \
137             block_size = (d->delay - d->index) * sizeof(type);                                          \
138             memmove(&samples[d->index+(new_delay - d->delay)], &samples[d->index], block_size);         \
139             d->delay_index = new_delay;                                                                 \
140         } else {                                                                                        \
141             d->delay_index += new_delay - d->delay;                                                     \
142         }                                                                                               \
143         block_size = (new_delay - d->delay) * sizeof(type);                                             \
144         memset(&samples[d->index], fill, block_size);                                                   \
145     }                                                                                                   \
146     d->delay = new_delay;                                                                               \
147     d->samples = (void *) samples;                                                                      \
148     return 0;                                                                                           \
149 }
150 
151 CHANGE_DELAY(u8,  uint8_t, 0x80)
152 CHANGE_DELAY(s16, int16_t, 0)
153 CHANGE_DELAY(s32, int32_t, 0)
154 CHANGE_DELAY(flt, float,   0)
155 CHANGE_DELAY(dbl, double,  0)
156 
parse_delays(char * p,char ** saveptr,int64_t * result,AVFilterContext * ctx,int sample_rate)157 static int parse_delays(char *p, char **saveptr, int64_t *result, AVFilterContext *ctx, int sample_rate) {
158     float delay, div;
159     int ret;
160     char *arg;
161     char type = 0;
162 
163     if (!(arg = av_strtok(p, "|", saveptr)))
164         return 1;
165 
166     ret = av_sscanf(arg, "%"SCNd64"%c", result, &type);
167     if (ret != 2 || type != 'S') {
168         div = type == 's' ? 1.0 : 1000.0;
169         if (av_sscanf(arg, "%f", &delay) != 1) {
170             av_log(ctx, AV_LOG_ERROR, "Invalid syntax for delay.\n");
171             return AVERROR(EINVAL);
172         }
173         *result = delay * sample_rate / div;
174     }
175 
176     if (*result < 0) {
177         av_log(ctx, AV_LOG_ERROR, "Delay must be non negative number.\n");
178         return AVERROR(EINVAL);
179     }
180     return 0;
181 }
182 
config_input(AVFilterLink * inlink)183 static int config_input(AVFilterLink *inlink)
184 {
185     AVFilterContext *ctx = inlink->dst;
186     AudioDelayContext *s = ctx->priv;
187     char *p, *saveptr = NULL;
188     int i;
189 
190     s->chandelay = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->chandelay));
191     if (!s->chandelay)
192         return AVERROR(ENOMEM);
193     s->nb_delays = inlink->ch_layout.nb_channels;
194     s->block_align = av_get_bytes_per_sample(inlink->format);
195 
196     p = s->delays;
197     for (i = 0; i < s->nb_delays; i++) {
198         ChanDelay *d = &s->chandelay[i];
199         int ret;
200 
201         ret = parse_delays(p, &saveptr, &d->delay, ctx, inlink->sample_rate);
202         if (ret == 1)
203             break;
204         else if (ret < 0)
205             return ret;
206         p = NULL;
207     }
208 
209     if (s->all && i) {
210         for (int j = i; j < s->nb_delays; j++)
211             s->chandelay[j].delay = s->chandelay[i-1].delay;
212     }
213 
214     s->padding = s->chandelay[0].delay;
215     for (i = 1; i < s->nb_delays; i++) {
216         ChanDelay *d = &s->chandelay[i];
217 
218         s->padding = FFMIN(s->padding, d->delay);
219     }
220 
221     if (s->padding) {
222         for (i = 0; i < s->nb_delays; i++) {
223             ChanDelay *d = &s->chandelay[i];
224 
225             d->delay -= s->padding;
226         }
227     }
228 
229     for (i = 0; i < s->nb_delays; i++) {
230         ChanDelay *d = &s->chandelay[i];
231 
232         if (!d->delay)
233             continue;
234 
235         if (d->delay > SIZE_MAX) {
236             av_log(ctx, AV_LOG_ERROR, "Requested delay is too big.\n");
237             return AVERROR(EINVAL);
238         }
239 
240         d->samples = av_malloc_array(d->delay, s->block_align);
241         if (!d->samples)
242             return AVERROR(ENOMEM);
243         d->samples_size = d->delay * s->block_align;
244 
245         s->max_delay = FFMAX(s->max_delay, d->delay);
246     }
247 
248     switch (inlink->format) {
249     case AV_SAMPLE_FMT_U8P : s->delay_channel = delay_channel_u8p ;
250                              s->resize_channel_samples = resize_samples_u8p; break;
251     case AV_SAMPLE_FMT_S16P: s->delay_channel = delay_channel_s16p;
252                              s->resize_channel_samples = resize_samples_s16p; break;
253     case AV_SAMPLE_FMT_S32P: s->delay_channel = delay_channel_s32p;
254                              s->resize_channel_samples = resize_samples_s32p; break;
255     case AV_SAMPLE_FMT_FLTP: s->delay_channel = delay_channel_fltp;
256                              s->resize_channel_samples = resize_samples_fltp; break;
257     case AV_SAMPLE_FMT_DBLP: s->delay_channel = delay_channel_dblp;
258                              s->resize_channel_samples = resize_samples_dblp; break;
259     }
260 
261     return 0;
262 }
263 
process_command(AVFilterContext * ctx,const char * cmd,const char * args,char * res,int res_len,int flags)264 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
265                            char *res, int res_len, int flags)
266 {
267     int ret = AVERROR(ENOSYS);
268     AVFilterLink *inlink = ctx->inputs[0];
269     AudioDelayContext *s = ctx->priv;
270 
271     if (!strcmp(cmd, "delays")) {
272         int64_t delay;
273         char *p, *saveptr = NULL;
274         int64_t all_delay = -1;
275         int64_t max_delay = 0;
276         char *args_cpy = av_strdup(args);
277         if (args_cpy == NULL) {
278             return AVERROR(ENOMEM);
279         }
280 
281         ret = 0;
282         p = args_cpy;
283 
284         if (!strncmp(args, "all:", 4)) {
285             p = &args_cpy[4];
286             ret = parse_delays(p, &saveptr, &all_delay, ctx, inlink->sample_rate);
287             if (ret == 1)
288                 ret = AVERROR(EINVAL);
289             else if (ret == 0)
290                 delay = all_delay;
291         }
292 
293         if (!ret) {
294             for (int i = 0; i < s->nb_delays; i++) {
295                 ChanDelay *d = &s->chandelay[i];
296 
297                 if (all_delay < 0) {
298                     ret = parse_delays(p, &saveptr, &delay, ctx, inlink->sample_rate);
299                     if (ret != 0) {
300                         ret = 0;
301                         break;
302                     }
303                     p = NULL;
304                 }
305 
306                 ret = s->resize_channel_samples(d, delay);
307                 if (ret)
308                     break;
309                 max_delay = FFMAX(max_delay, d->delay);
310             }
311             s->max_delay = FFMAX(s->max_delay, max_delay);
312         }
313         av_freep(&args_cpy);
314     }
315     return ret;
316 }
317 
filter_frame(AVFilterLink * inlink,AVFrame * frame)318 static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
319 {
320     AVFilterContext *ctx = inlink->dst;
321     AVFilterLink *outlink = ctx->outputs[0];
322     AudioDelayContext *s = ctx->priv;
323     AVFrame *out_frame;
324     int i;
325 
326     if (ctx->is_disabled || !s->delays)
327         return ff_filter_frame(outlink, frame);
328 
329     out_frame = ff_get_audio_buffer(outlink, frame->nb_samples);
330     if (!out_frame) {
331         av_frame_free(&frame);
332         return AVERROR(ENOMEM);
333     }
334     av_frame_copy_props(out_frame, frame);
335 
336     for (i = 0; i < s->nb_delays; i++) {
337         ChanDelay *d = &s->chandelay[i];
338         const uint8_t *src = frame->extended_data[i];
339         uint8_t *dst = out_frame->extended_data[i];
340 
341         if (!d->delay)
342             memcpy(dst, src, frame->nb_samples * s->block_align);
343         else
344             s->delay_channel(d, frame->nb_samples, src, dst);
345     }
346 
347     out_frame->pts = s->next_pts;
348     s->next_pts += av_rescale_q(frame->nb_samples, (AVRational){1, outlink->sample_rate}, outlink->time_base);
349     av_frame_free(&frame);
350     return ff_filter_frame(outlink, out_frame);
351 }
352 
activate(AVFilterContext * ctx)353 static int activate(AVFilterContext *ctx)
354 {
355     AVFilterLink *inlink = ctx->inputs[0];
356     AVFilterLink *outlink = ctx->outputs[0];
357     AudioDelayContext *s = ctx->priv;
358     AVFrame *frame = NULL;
359     int ret, status;
360     int64_t pts;
361 
362     FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
363 
364     if (s->padding) {
365         int nb_samples = FFMIN(s->padding, 2048);
366 
367         frame = ff_get_audio_buffer(outlink, nb_samples);
368         if (!frame)
369             return AVERROR(ENOMEM);
370         s->padding -= nb_samples;
371 
372         av_samples_set_silence(frame->extended_data, 0,
373                                frame->nb_samples,
374                                outlink->ch_layout.nb_channels,
375                                frame->format);
376 
377         frame->pts = s->next_pts;
378         if (s->next_pts != AV_NOPTS_VALUE)
379             s->next_pts += av_rescale_q(nb_samples, (AVRational){1, outlink->sample_rate}, outlink->time_base);
380 
381         return ff_filter_frame(outlink, frame);
382     }
383 
384     ret = ff_inlink_consume_frame(inlink, &frame);
385     if (ret < 0)
386         return ret;
387 
388     if (ret > 0)
389         return filter_frame(inlink, frame);
390 
391     if (ff_inlink_acknowledge_status(inlink, &status, &pts)) {
392         if (status == AVERROR_EOF)
393             s->eof = 1;
394     }
395 
396     if (s->eof && s->max_delay) {
397         int nb_samples = FFMIN(s->max_delay, 2048);
398 
399         frame = ff_get_audio_buffer(outlink, nb_samples);
400         if (!frame)
401             return AVERROR(ENOMEM);
402         s->max_delay -= nb_samples;
403 
404         av_samples_set_silence(frame->extended_data, 0,
405                                frame->nb_samples,
406                                outlink->ch_layout.nb_channels,
407                                frame->format);
408 
409         frame->pts = s->next_pts;
410         return filter_frame(inlink, frame);
411     }
412 
413     if (s->eof && s->max_delay == 0) {
414         ff_outlink_set_status(outlink, AVERROR_EOF, s->next_pts);
415         return 0;
416     }
417 
418     if (!s->eof)
419         FF_FILTER_FORWARD_WANTED(outlink, inlink);
420 
421     return FFERROR_NOT_READY;
422 }
423 
uninit(AVFilterContext * ctx)424 static av_cold void uninit(AVFilterContext *ctx)
425 {
426     AudioDelayContext *s = ctx->priv;
427 
428     if (s->chandelay) {
429         for (int i = 0; i < s->nb_delays; i++)
430             av_freep(&s->chandelay[i].samples);
431     }
432     av_freep(&s->chandelay);
433 }
434 
435 static const AVFilterPad adelay_inputs[] = {
436     {
437         .name         = "default",
438         .type         = AVMEDIA_TYPE_AUDIO,
439         .config_props = config_input,
440     },
441 };
442 
443 static const AVFilterPad adelay_outputs[] = {
444     {
445         .name = "default",
446         .type = AVMEDIA_TYPE_AUDIO,
447     },
448 };
449 
450 const AVFilter ff_af_adelay = {
451     .name          = "adelay",
452     .description   = NULL_IF_CONFIG_SMALL("Delay one or more audio channels."),
453     .priv_size     = sizeof(AudioDelayContext),
454     .priv_class    = &adelay_class,
455     .activate      = activate,
456     .uninit        = uninit,
457     FILTER_INPUTS(adelay_inputs),
458     FILTER_OUTPUTS(adelay_outputs),
459     FILTER_SAMPLEFMTS(AV_SAMPLE_FMT_U8P, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S32P,
460                       AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_DBLP),
461     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
462     .process_command = process_command,
463 };
464