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
29
37
50
52
54 const uint8_t *
src, uint8_t *dst);
57
58 #define OFFSET(x) offsetof(AudioDelayContext, x)
59 #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
60
65 };
66
68
69 #define DELAY(name, type, fill) \
70 static void delay_channel_## name ##p(ChanDelay *d, int nb_samples, \
71 const uint8_t *ssrc, uint8_t *ddst) \
72 { \
73 const type *src = (type *)ssrc; \
74 type *dst = (type *)ddst; \
75 type *samples = (type *)d->samples; \
76 \
77 while (nb_samples) { \
78 if (d->delay_index < d->delay) { \
79 const int len = FFMIN(nb_samples, d->delay - d->delay_index); \
80 \
81 memcpy(&samples[d->delay_index], src, len * sizeof(type)); \
82 memset(dst, fill, len * sizeof(type)); \
83 d->delay_index += len; \
84 src += len; \
85 dst += len; \
86 nb_samples -= len; \
87 } else { \
88 *dst = samples[d->index]; \
89 samples[d->index] = *src; \
90 nb_samples--; \
91 d->index++; \
92 src++, dst++; \
93 d->index = d->index >= d->delay ? 0 : d->index; \
94 } \
95 } \
96 }
97
98 DELAY(u8, uint8_t, 0x80)
99 DELAY(s16, int16_t, 0)
102 DELAY(dbl,
double, 0)
103
104 #define CHANGE_DELAY(name, type, fill) \
105 static int resize_samples_## name ##p(ChanDelay *d, int64_t new_delay) \
106 { \
107 type *samples; \
108 \
109 if (new_delay == d->delay) { \
110 return 0; \
111 } \
112 \
113 if (new_delay == 0) { \
114 av_freep(&d->samples); \
115 d->samples_size = 0; \
116 d->delay = 0; \
117 d->index = 0; \
118 d->delay_index = 0; \
119 return 0; \
120 } \
121 \
122 samples = (type *) av_fast_realloc(d->samples, &d->samples_size, new_delay * sizeof(type)); \
123 if (!samples) { \
124 return AVERROR(ENOMEM); \
125 } \
126 \
127 if (new_delay < d->delay) { \
128 if (d->index > new_delay) { \
129 d->index -= new_delay; \
130 memmove(samples, &samples[new_delay], d->index * sizeof(type)); \
131 d->delay_index = new_delay; \
132 } else if (d->delay_index > d->index) { \
133 memmove(&samples[d->index], &samples[d->index+(d->delay-new_delay)], \
134 (new_delay - d->index) * sizeof(type)); \
135 d->delay_index -= d->delay - new_delay; \
136 } \
137 } else { \
138 size_t block_size; \
139 if (d->delay_index >= d->delay) { \
140 block_size = (d->delay - d->index) * sizeof(type); \
141 memmove(&samples[d->index+(new_delay - d->delay)], &samples[d->index], block_size); \
142 d->delay_index = new_delay; \
143 } else { \
144 d->delay_index += new_delay - d->delay; \
145 } \
146 block_size = (new_delay - d->delay) * sizeof(type); \
147 memset(&samples[d->index], fill, block_size); \
148 } \
149 d->delay = new_delay; \
150 d->samples = (void *) samples; \
151 return 0; \
152 }
153
159
161 float delay, div;
165
167 return 1;
168
171 div =
type ==
's' ? 1.0 : 1000.0;
175 }
177 }
178
182 }
183 return 0;
184 }
185
187 {
190 char *p, *saveptr =
NULL;
192
197 s->nb_delays =
inlink->ch_layout.nb_channels;
199
201 for (
i = 0;
i <
s->nb_delays;
i++) {
204
207 break;
211 }
212
214 for (
int j =
i; j <
s->nb_delays; j++)
215 s->chandelay[j].delay =
s->chandelay[
i-1].delay;
216 }
217
218 s->padding =
s->chandelay[0].delay;
219 for (
i = 1;
i <
s->nb_delays;
i++) {
221
222 s->padding =
FFMIN(
s->padding,
d->delay);
223 }
224
226 for (
i = 0;
i <
s->nb_delays;
i++) {
228
229 d->delay -=
s->padding;
230 }
231
235 }
236
237 for (
i = 0;
i <
s->nb_delays;
i++) {
239
241 continue;
242
243 if (
d->delay > SIZE_MAX) {
246 }
247
251 d->samples_size =
d->delay *
s->block_align;
252
253 s->max_delay =
FFMAX(
s->max_delay,
d->delay);
254 }
255
258 s->resize_channel_samples = resize_samples_u8p;
break;
260 s->resize_channel_samples = resize_samples_s16p;
break;
262 s->resize_channel_samples = resize_samples_s32p;
break;
264 s->resize_channel_samples = resize_samples_fltp;
break;
266 s->resize_channel_samples = resize_samples_dblp;
break;
267 }
268
269 return 0;
270 }
271
273 char *res,
int res_len,
int flags)
274 {
278
279 if (!strcmp(cmd, "delays")) {
281 char *p, *saveptr =
NULL;
285 if (args_cpy ==
NULL) {
287 }
288
290 p = args_cpy;
291
292 if (!strncmp(args, "all:", 4)) {
293 p = &args_cpy[4];
298 delay = all_delay;
299 }
300
302 for (
int i = 0;
i <
s->nb_delays;
i++) {
304
305 if (all_delay < 0) {
309 break;
310 }
312 }
313
314 ret =
s->resize_channel_samples(
d, delay);
316 break;
317 max_delay =
FFMAX(max_delay,
d->delay);
318 }
319 s->max_delay =
FFMAX(
s->max_delay, max_delay);
320 }
322 }
324 }
325
327 {
333
334 if (
ctx->is_disabled || !
s->delays) {
337 }
338
340
342 if (!out_frame) {
346 }
348
349 for (
i = 0;
i <
s->nb_delays;
i++) {
353
356 else
358 }
359
360 out_frame->
pts =
s->next_pts +
s->offset;
366 }
367
369 {
376
378
383 }
384
388 }
389
392
394 int nb_samples =
FFMIN(
s->padding, 2048);
395
399 s->padding -= nb_samples;
400
405
411
413 }
414
417
418 if (
s->eof &&
s->max_delay) {
419 int nb_samples =
FFMIN(
s->max_delay, 2048);
420
424 s->max_delay -= nb_samples;
425
430
437 }
438
439 if (
s->eof &&
s->max_delay == 0) {
441 return 0;
442 }
443
446
448 }
449
451 {
453
455 for (
int i = 0;
i <
s->nb_delays;
i++)
457 }
459 }
460
462 {
466 },
467 };
468
473 .priv_class = &adelay_class,
482 };