FFmpeg  4.4.6
af_silenceremove.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2001 Heikki Leinonen
3  * Copyright (c) 2001 Chris Bagwell
4  * Copyright (c) 2003 Donnie Smith
5  * Copyright (c) 2014 Paul B Mahol
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include <float.h> /* DBL_MAX */
25 
26 #include "libavutil/opt.h"
27 #include "libavutil/timestamp.h"
28 #include "audio.h"
29 #include "formats.h"
30 #include "avfilter.h"
31 #include "internal.h"
32 
36 };
37 
41 };
42 
49 };
50 
51 typedef struct SilenceRemoveContext {
52  const AVClass *class;
53 
54  enum SilenceMode mode;
55 
63 
70  int stop_mode;
71 
72  double *start_holdoff;
79 
80  double *stop_holdoff;
87 
88  double window_ratio;
89  double *window;
90  double *window_current;
91  double *window_end;
93  double sum;
94 
95  int restart;
97 
98  int detection;
99  void (*update)(struct SilenceRemoveContext *s, double sample);
100  double(*compute)(struct SilenceRemoveContext *s, double sample);
102 
103 #define OFFSET(x) offsetof(SilenceRemoveContext, x)
104 #define AF AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM
105 
106 static const AVOption silenceremove_options[] = {
107  { "start_periods", NULL, OFFSET(start_periods), AV_OPT_TYPE_INT, {.i64=0}, 0, 9000, AF },
108  { "start_duration", "set start duration of non-silence part", OFFSET(start_duration_opt), AV_OPT_TYPE_DURATION, {.i64=0}, 0, INT32_MAX, AF },
109  { "start_threshold", "set threshold for start silence detection", OFFSET(start_threshold), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, DBL_MAX, AF },
110  { "start_silence", "set start duration of silence part to keep", OFFSET(start_silence_opt), AV_OPT_TYPE_DURATION, {.i64=0}, 0, INT32_MAX, AF },
111  { "start_mode", "set which channel will trigger trimming from start", OFFSET(start_mode), AV_OPT_TYPE_INT, {.i64=T_ANY}, T_ANY, T_ALL, AF, "mode" },
112  { "any", 0, 0, AV_OPT_TYPE_CONST, {.i64=T_ANY}, 0, 0, AF, "mode" },
113  { "all", 0, 0, AV_OPT_TYPE_CONST, {.i64=T_ALL}, 0, 0, AF, "mode" },
114  { "stop_periods", NULL, OFFSET(stop_periods), AV_OPT_TYPE_INT, {.i64=0}, -9000, 9000, AF },
115  { "stop_duration", "set stop duration of non-silence part", OFFSET(stop_duration_opt), AV_OPT_TYPE_DURATION, {.i64=0}, 0, INT32_MAX, AF },
116  { "stop_threshold", "set threshold for stop silence detection", OFFSET(stop_threshold), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, DBL_MAX, AF },
117  { "stop_silence", "set stop duration of silence part to keep", OFFSET(stop_silence_opt), AV_OPT_TYPE_DURATION, {.i64=0}, 0, INT32_MAX, AF },
118  { "stop_mode", "set which channel will trigger trimming from end", OFFSET(stop_mode), AV_OPT_TYPE_INT, {.i64=T_ANY}, T_ANY, T_ALL, AF, "mode" },
119  { "detection", "set how silence is detected", OFFSET(detection), AV_OPT_TYPE_INT, {.i64=D_RMS}, D_PEAK,D_RMS, AF, "detection" },
120  { "peak", "use absolute values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_PEAK},0, 0, AF, "detection" },
121  { "rms", "use squared values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_RMS}, 0, 0, AF, "detection" },
122  { "window", "set duration of window in seconds", OFFSET(window_ratio), AV_OPT_TYPE_DOUBLE, {.dbl=0.02}, 0, 10, AF },
123  { NULL }
124 };
125 
126 AVFILTER_DEFINE_CLASS(silenceremove);
127 
128 static double compute_peak(SilenceRemoveContext *s, double sample)
129 {
130  double new_sum;
131 
132  new_sum = s->sum;
133  new_sum -= *s->window_current;
134  new_sum += fabs(sample);
135 
136  return new_sum / s->window_size;
137 }
138 
140 {
141  s->sum -= *s->window_current;
142  *s->window_current = fabs(sample);
143  s->sum += *s->window_current;
144 
145  s->window_current++;
146  if (s->window_current >= s->window_end)
147  s->window_current = s->window;
148 }
149 
150 static double compute_rms(SilenceRemoveContext *s, double sample)
151 {
152  double new_sum;
153 
154  new_sum = s->sum;
155  new_sum -= *s->window_current;
156  new_sum += sample * sample;
157 
158  return sqrt(new_sum / s->window_size);
159 }
160 
162 {
163  s->sum -= *s->window_current;
164  *s->window_current = sample * sample;
165  s->sum += *s->window_current;
166 
167  s->window_current++;
168  if (s->window_current >= s->window_end)
169  s->window_current = s->window;
170 }
171 
173 {
174  SilenceRemoveContext *s = ctx->priv;
175 
176  if (s->stop_periods < 0) {
177  s->stop_periods = -s->stop_periods;
178  s->restart = 1;
179  }
180 
181  switch (s->detection) {
182  case D_PEAK:
183  s->update = update_peak;
184  s->compute = compute_peak;
185  break;
186  case D_RMS:
187  s->update = update_rms;
188  s->compute = compute_rms;
189  break;
190  }
191 
192  return 0;
193 }
194 
196 {
197  memset(s->window, 0, s->window_size * sizeof(*s->window));
198 
199  s->window_current = s->window;
200  s->window_end = s->window + s->window_size;
201  s->sum = 0;
202 }
203 
204 static int config_input(AVFilterLink *inlink)
205 {
206  AVFilterContext *ctx = inlink->dst;
207  SilenceRemoveContext *s = ctx->priv;
208 
209  s->next_pts = AV_NOPTS_VALUE;
210  s->window_size = FFMAX((inlink->sample_rate * s->window_ratio), 1) * inlink->channels;
211  s->window = av_malloc_array(s->window_size, sizeof(*s->window));
212  if (!s->window)
213  return AVERROR(ENOMEM);
214 
215  clear_window(s);
216 
217  s->start_duration = av_rescale(s->start_duration_opt, inlink->sample_rate,
218  AV_TIME_BASE);
219  s->start_silence = av_rescale(s->start_silence_opt, inlink->sample_rate,
220  AV_TIME_BASE);
221  s->stop_duration = av_rescale(s->stop_duration_opt, inlink->sample_rate,
222  AV_TIME_BASE);
223  s->stop_silence = av_rescale(s->stop_silence_opt, inlink->sample_rate,
224  AV_TIME_BASE);
225 
226  s->start_holdoff = av_malloc_array(FFMAX(s->start_duration, 1),
227  sizeof(*s->start_holdoff) *
228  inlink->channels);
229  if (!s->start_holdoff)
230  return AVERROR(ENOMEM);
231 
232  s->start_silence_hold = av_malloc_array(FFMAX(s->start_silence, 1),
233  sizeof(*s->start_silence_hold) *
234  inlink->channels);
235  if (!s->start_silence_hold)
236  return AVERROR(ENOMEM);
237 
238  s->start_holdoff_offset = 0;
239  s->start_holdoff_end = 0;
240  s->start_found_periods = 0;
241 
242  s->stop_holdoff = av_malloc_array(FFMAX(s->stop_duration, 1),
243  sizeof(*s->stop_holdoff) *
244  inlink->channels);
245  if (!s->stop_holdoff)
246  return AVERROR(ENOMEM);
247 
248  s->stop_silence_hold = av_malloc_array(FFMAX(s->stop_silence, 1),
249  sizeof(*s->stop_silence_hold) *
250  inlink->channels);
251  if (!s->stop_silence_hold)
252  return AVERROR(ENOMEM);
253 
254  s->stop_holdoff_offset = 0;
255  s->stop_holdoff_end = 0;
256  s->stop_found_periods = 0;
257 
258  if (s->start_periods)
259  s->mode = SILENCE_TRIM;
260  else
261  s->mode = SILENCE_COPY;
262 
263  return 0;
264 }
265 
267  AVFrame *out, AVFilterLink *outlink,
268  int *nb_samples_written, int *ret, int flush_silence)
269 {
270  AVFrame *silence;
271 
272  if (*nb_samples_written) {
273  out->nb_samples = *nb_samples_written / outlink->channels;
274 
275  out->pts = s->next_pts;
276  s->next_pts += av_rescale_q(out->nb_samples,
277  (AVRational){1, outlink->sample_rate},
278  outlink->time_base);
279 
280  *ret = ff_filter_frame(outlink, out);
281  if (*ret < 0)
282  return;
283  *nb_samples_written = 0;
284  } else {
285  av_frame_free(&out);
286  }
287 
288  if (s->stop_silence_end <= 0 || !flush_silence)
289  return;
290 
291  silence = ff_get_audio_buffer(outlink, s->stop_silence_end / outlink->channels);
292  if (!silence) {
293  *ret = AVERROR(ENOMEM);
294  return;
295  }
296 
297  if (s->stop_silence_offset < s->stop_silence_end) {
298  memcpy(silence->data[0],
299  &s->stop_silence_hold[s->stop_silence_offset],
300  (s->stop_silence_end - s->stop_silence_offset) * sizeof(double));
301  }
302 
303  if (s->stop_silence_offset > 0) {
304  memcpy(silence->data[0] + (s->stop_silence_end - s->stop_silence_offset) * sizeof(double),
305  &s->stop_silence_hold[0],
306  s->stop_silence_offset * sizeof(double));
307  }
308 
309  s->stop_silence_offset = 0;
310  s->stop_silence_end = 0;
311 
312  silence->pts = s->next_pts;
313  s->next_pts += av_rescale_q(silence->nb_samples,
314  (AVRational){1, outlink->sample_rate},
315  outlink->time_base);
316 
317  *ret = ff_filter_frame(outlink, silence);
318 }
319 
320 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
321 {
322  AVFilterContext *ctx = inlink->dst;
323  AVFilterLink *outlink = ctx->outputs[0];
324  SilenceRemoveContext *s = ctx->priv;
325  int i, j, threshold, ret = 0;
326  int nbs, nb_samples_read, nb_samples_written;
327  double *obuf, *ibuf = (double *)in->data[0];
328  AVFrame *out;
329 
330  nb_samples_read = nb_samples_written = 0;
331 
332  if (s->next_pts == AV_NOPTS_VALUE)
333  s->next_pts = in->pts;
334 
335  switch (s->mode) {
336  case SILENCE_TRIM:
337 silence_trim:
338  nbs = in->nb_samples - nb_samples_read / outlink->channels;
339  if (!nbs)
340  break;
341 
342  for (i = 0; i < nbs; i++) {
343  if (s->start_mode == T_ANY) {
344  threshold = 0;
345  for (j = 0; j < outlink->channels; j++) {
346  threshold |= s->compute(s, ibuf[j]) > s->start_threshold;
347  }
348  } else {
349  threshold = 1;
350  for (j = 0; j < outlink->channels; j++) {
351  threshold &= s->compute(s, ibuf[j]) > s->start_threshold;
352  }
353  }
354 
355  if (threshold) {
356  for (j = 0; j < outlink->channels; j++) {
357  s->update(s, *ibuf);
358  s->start_holdoff[s->start_holdoff_end++] = *ibuf++;
359  }
360  nb_samples_read += outlink->channels;
361 
362  if (s->start_holdoff_end >= s->start_duration * outlink->channels) {
363  if (++s->start_found_periods >= s->start_periods) {
364  s->mode = SILENCE_TRIM_FLUSH;
365  goto silence_trim_flush;
366  }
367 
368  s->start_holdoff_offset = 0;
369  s->start_holdoff_end = 0;
370  s->start_silence_offset = 0;
371  s->start_silence_end = 0;
372  }
373  } else {
374  s->start_holdoff_end = 0;
375 
376  for (j = 0; j < outlink->channels; j++) {
377  s->update(s, ibuf[j]);
378  if (s->start_silence) {
379  s->start_silence_hold[s->start_silence_offset++] = ibuf[j];
380  s->start_silence_end = FFMIN(s->start_silence_end + 1, outlink->channels * s->start_silence);
381  if (s->start_silence_offset >= outlink->channels * s->start_silence) {
382  s->start_silence_offset = 0;
383  }
384  }
385  }
386 
387  ibuf += outlink->channels;
388  nb_samples_read += outlink->channels;
389  }
390  }
391  break;
392 
393  case SILENCE_TRIM_FLUSH:
394 silence_trim_flush:
395  nbs = s->start_holdoff_end - s->start_holdoff_offset;
396  nbs -= nbs % outlink->channels;
397  if (!nbs)
398  break;
399 
400  out = ff_get_audio_buffer(outlink, nbs / outlink->channels + s->start_silence_end / outlink->channels);
401  if (!out) {
402  av_frame_free(&in);
403  return AVERROR(ENOMEM);
404  }
405 
406  if (s->start_silence_end > 0) {
407  if (s->start_silence_offset < s->start_silence_end) {
408  memcpy(out->data[0],
409  &s->start_silence_hold[s->start_silence_offset],
410  (s->start_silence_end - s->start_silence_offset) * sizeof(double));
411  }
412 
413  if (s->start_silence_offset > 0) {
414  memcpy(out->data[0] + (s->start_silence_end - s->start_silence_offset) * sizeof(double),
415  &s->start_silence_hold[0],
416  s->start_silence_offset * sizeof(double));
417  }
418  }
419 
420  memcpy(out->data[0] + s->start_silence_end * sizeof(double),
421  &s->start_holdoff[s->start_holdoff_offset],
422  nbs * sizeof(double));
423 
424  out->pts = s->next_pts;
425  s->next_pts += av_rescale_q(out->nb_samples,
426  (AVRational){1, outlink->sample_rate},
427  outlink->time_base);
428 
429  s->start_holdoff_offset += nbs;
430 
431  ret = ff_filter_frame(outlink, out);
432 
433  if (s->start_holdoff_offset == s->start_holdoff_end) {
434  s->start_holdoff_offset = 0;
435  s->start_holdoff_end = 0;
436  s->start_silence_offset = 0;
437  s->start_silence_end = 0;
438  s->mode = SILENCE_COPY;
439  goto silence_copy;
440  }
441  break;
442 
443  case SILENCE_COPY:
444 silence_copy:
445  nbs = in->nb_samples - nb_samples_read / outlink->channels;
446  if (!nbs)
447  break;
448 
449  out = ff_get_audio_buffer(outlink, nbs);
450  if (!out) {
451  av_frame_free(&in);
452  return AVERROR(ENOMEM);
453  }
454  obuf = (double *)out->data[0];
455 
456  if (s->stop_periods) {
457  for (i = 0; i < nbs; i++) {
458  if (s->stop_mode == T_ANY) {
459  threshold = 0;
460  for (j = 0; j < outlink->channels; j++) {
461  threshold |= s->compute(s, ibuf[j]) > s->stop_threshold;
462  }
463  } else {
464  threshold = 1;
465  for (j = 0; j < outlink->channels; j++) {
466  threshold &= s->compute(s, ibuf[j]) > s->stop_threshold;
467  }
468  }
469 
470  if (threshold && s->stop_holdoff_end && !s->stop_silence) {
471  s->mode = SILENCE_COPY_FLUSH;
472  flush(s, out, outlink, &nb_samples_written, &ret, 0);
473  goto silence_copy_flush;
474  } else if (threshold) {
475  for (j = 0; j < outlink->channels; j++) {
476  s->update(s, *ibuf);
477  *obuf++ = *ibuf++;
478  }
479  nb_samples_read += outlink->channels;
480  nb_samples_written += outlink->channels;
481  } else if (!threshold) {
482  for (j = 0; j < outlink->channels; j++) {
483  s->update(s, *ibuf);
484  if (s->stop_silence) {
485  s->stop_silence_hold[s->stop_silence_offset++] = *ibuf;
486  s->stop_silence_end = FFMIN(s->stop_silence_end + 1, outlink->channels * s->stop_silence);
487  if (s->stop_silence_offset >= outlink->channels * s->stop_silence) {
488  s->stop_silence_offset = 0;
489  }
490  }
491 
492  s->stop_holdoff[s->stop_holdoff_end++] = *ibuf++;
493  }
494  nb_samples_read += outlink->channels;
495 
496  if (s->stop_holdoff_end >= s->stop_duration * outlink->channels) {
497  if (++s->stop_found_periods >= s->stop_periods) {
498  s->stop_holdoff_offset = 0;
499  s->stop_holdoff_end = 0;
500 
501  if (!s->restart) {
502  s->mode = SILENCE_STOP;
503  flush(s, out, outlink, &nb_samples_written, &ret, 1);
504  goto silence_stop;
505  } else {
506  s->stop_found_periods = 0;
507  s->start_found_periods = 0;
508  s->start_holdoff_offset = 0;
509  s->start_holdoff_end = 0;
510  s->start_silence_offset = 0;
511  s->start_silence_end = 0;
512  clear_window(s);
513  s->mode = SILENCE_TRIM;
514  flush(s, out, outlink, &nb_samples_written, &ret, 1);
515  goto silence_trim;
516  }
517  }
518  s->mode = SILENCE_COPY_FLUSH;
519  flush(s, out, outlink, &nb_samples_written, &ret, 0);
520  goto silence_copy_flush;
521  }
522  }
523  }
524  flush(s, out, outlink, &nb_samples_written, &ret, 0);
525  } else {
526  memcpy(obuf, ibuf, sizeof(double) * nbs * outlink->channels);
527 
528  out->pts = s->next_pts;
529  s->next_pts += av_rescale_q(out->nb_samples,
530  (AVRational){1, outlink->sample_rate},
531  outlink->time_base);
532 
533  ret = ff_filter_frame(outlink, out);
534  }
535  break;
536 
537  case SILENCE_COPY_FLUSH:
538 silence_copy_flush:
539  nbs = s->stop_holdoff_end - s->stop_holdoff_offset;
540  nbs -= nbs % outlink->channels;
541  if (!nbs)
542  break;
543 
544  out = ff_get_audio_buffer(outlink, nbs / outlink->channels);
545  if (!out) {
546  av_frame_free(&in);
547  return AVERROR(ENOMEM);
548  }
549 
550  memcpy(out->data[0], &s->stop_holdoff[s->stop_holdoff_offset],
551  nbs * sizeof(double));
552  s->stop_holdoff_offset += nbs;
553 
554  out->pts = s->next_pts;
555  s->next_pts += av_rescale_q(out->nb_samples,
556  (AVRational){1, outlink->sample_rate},
557  outlink->time_base);
558 
559  ret = ff_filter_frame(outlink, out);
560 
561  if (s->stop_holdoff_offset == s->stop_holdoff_end) {
562  s->stop_holdoff_offset = 0;
563  s->stop_holdoff_end = 0;
564  s->stop_silence_offset = 0;
565  s->stop_silence_end = 0;
566  s->mode = SILENCE_COPY;
567  goto silence_copy;
568  }
569  break;
570  case SILENCE_STOP:
571 silence_stop:
572  break;
573  }
574 
575  av_frame_free(&in);
576 
577  return ret;
578 }
579 
580 static int request_frame(AVFilterLink *outlink)
581 {
582  AVFilterContext *ctx = outlink->src;
583  SilenceRemoveContext *s = ctx->priv;
584  int ret;
585 
586  ret = ff_request_frame(ctx->inputs[0]);
587  if (ret == AVERROR_EOF && (s->mode == SILENCE_COPY_FLUSH ||
588  s->mode == SILENCE_COPY)) {
589  int nbs = s->stop_holdoff_end - s->stop_holdoff_offset;
590  if (nbs) {
591  AVFrame *frame;
592 
593  frame = ff_get_audio_buffer(outlink, nbs / outlink->channels);
594  if (!frame)
595  return AVERROR(ENOMEM);
596 
597  memcpy(frame->data[0], &s->stop_holdoff[s->stop_holdoff_offset],
598  nbs * sizeof(double));
599 
600  frame->pts = s->next_pts;
601  s->next_pts += av_rescale_q(frame->nb_samples,
602  (AVRational){1, outlink->sample_rate},
603  outlink->time_base);
604 
605  ret = ff_filter_frame(outlink, frame);
606  }
607  s->mode = SILENCE_STOP;
608  }
609  return ret;
610 }
611 
613 {
616  static const enum AVSampleFormat sample_fmts[] = {
618  };
619  int ret;
620 
622  if (!layouts)
623  return AVERROR(ENOMEM);
625  if (ret < 0)
626  return ret;
627 
629  if (!formats)
630  return AVERROR(ENOMEM);
632  if (ret < 0)
633  return ret;
634 
636  if (!formats)
637  return AVERROR(ENOMEM);
639 }
640 
642 {
643  SilenceRemoveContext *s = ctx->priv;
644 
645  av_freep(&s->start_holdoff);
646  av_freep(&s->start_silence_hold);
647  av_freep(&s->stop_holdoff);
648  av_freep(&s->stop_silence_hold);
649  av_freep(&s->window);
650 }
651 
653  {
654  .name = "default",
655  .type = AVMEDIA_TYPE_AUDIO,
656  .config_props = config_input,
657  .filter_frame = filter_frame,
658  },
659  { NULL }
660 };
661 
663  {
664  .name = "default",
665  .type = AVMEDIA_TYPE_AUDIO,
666  .request_frame = request_frame,
667  },
668  { NULL }
669 };
670 
672  .name = "silenceremove",
673  .description = NULL_IF_CONFIG_SMALL("Remove silence."),
674  .priv_size = sizeof(SilenceRemoveContext),
675  .priv_class = &silenceremove_class,
676  .init = init,
677  .uninit = uninit,
681 };
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:925
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
AVFILTER_DEFINE_CLASS(silenceremove)
SilenceMode
@ SILENCE_TRIM_FLUSH
@ SILENCE_STOP
@ SILENCE_COPY
@ SILENCE_TRIM
@ SILENCE_COPY_FLUSH
static const AVFilterPad silenceremove_outputs[]
SilenceDetect
@ D_PEAK
@ D_RMS
static void update_rms(SilenceRemoveContext *s, double sample)
AVFilter ff_af_silenceremove
static int query_formats(AVFilterContext *ctx)
static int config_input(AVFilterLink *inlink)
static int request_frame(AVFilterLink *outlink)
#define AF
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
ThresholdMode
@ T_ANY
@ T_ALL
static double compute_peak(SilenceRemoveContext *s, double sample)
static double compute_rms(SilenceRemoveContext *s, double sample)
static void update_peak(SilenceRemoveContext *s, double sample)
static av_cold int init(AVFilterContext *ctx)
static av_cold void uninit(AVFilterContext *ctx)
static void clear_window(SilenceRemoveContext *s)
#define OFFSET(x)
static void flush(SilenceRemoveContext *s, AVFrame *out, AVFilterLink *outlink, int *nb_samples_written, int *ret, int flush_silence)
static const AVFilterPad silenceremove_inputs[]
static const AVOption silenceremove_options[]
#define av_cold
Definition: attributes.h:88
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition: audio.c:86
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1096
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Definition: avfilter.c:408
Main libavfilter public API header.
#define s(width, name)
Definition: cbs_vp9.c:257
#define FFMIN(a, b)
Definition: common.h:105
#define FFMAX(a, b)
Definition: common.h:103
#define NULL
Definition: coverity.c:32
long long int64_t
Definition: coverity.c:34
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
static AVFrame * frame
#define sample
AVFilterChannelLayouts * ff_all_channel_counts(void)
Construct an AVFilterChannelLayouts coding for any channel layout, with known or unknown disposition.
Definition: formats.c:436
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:587
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:286
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:575
int ff_set_common_channel_layouts(AVFilterContext *ctx, AVFilterChannelLayouts *channel_layouts)
A helper for query_formats() which sets all links to the same list of channel layouts/sample rates.
Definition: formats.c:568
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:421
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
@ AV_OPT_TYPE_DURATION
Definition: opt.h:239
@ AV_OPT_TYPE_INT
Definition: opt.h:225
@ AV_OPT_TYPE_DOUBLE
Definition: opt.h:227
#define AVERROR_EOF
End of file.
Definition: error.h:55
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:129
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:59
@ AV_SAMPLE_FMT_DBL
double
Definition: samplefmt.h:64
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:254
int i
Definition: input.c:407
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
AVOptions.
typedef void(RENAME(mix_any_func_type))
formats
Definition: signature.h:48
Describe the class of an AVClass context structure.
Definition: log.h:67
A list of supported channel layouts.
Definition: formats.h:86
An instance of a filter.
Definition: avfilter.h:341
A list of supported formats for one end of a filter link.
Definition: formats.h:65
A filter pad used for either input or output.
Definition: internal.h:54
const char * name
Pad name.
Definition: internal.h:60
Filter definition.
Definition: avfilter.h:145
const char * name
Filter name.
Definition: avfilter.h:149
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:384
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:411
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:332
AVOption.
Definition: opt.h:248
Rational number (pair of numerator and denominator).
Definition: rational.h:58
void(* update)(struct SilenceRemoveContext *s, double sample)
double(* compute)(struct SilenceRemoveContext *s, double sample)
enum SilenceMode mode
#define av_malloc_array(a, b)
#define av_freep(p)
FILE * out
Definition: movenc.c:54
AVFormatContext * ctx
Definition: movenc.c:48
timestamp utils, mostly useful for debugging/logging purposes
if(ret< 0)
Definition: vf_mcdeint.c:282