FFmpeg
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 
55 
57  int64_t start_duration;
60  int64_t start_silence;
63 
65  int64_t stop_duration;
68  int64_t stop_silence;
70  int stop_mode;
71 
79 
87 
88  double window_ratio;
92  double sum;
93 
94  int restart;
95  int64_t next_pts;
96 
97  int detection;
98  void (*update)(struct SilenceRemoveContext *s, AVFrame *frame, int ch, int offset);
99  double (*compute)(struct SilenceRemoveContext *s, AVFrame *frame, int ch, int offset);
100  void (*copy)(struct SilenceRemoveContext *s, AVFrame *out, AVFrame *in,
101  int ch, int out_offset, int in_offset);
103 
104 #define OFFSET(x) offsetof(SilenceRemoveContext, x)
105 #define AF AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM
106 
107 static const AVOption silenceremove_options[] = {
108  { "start_periods", NULL, OFFSET(start_periods), AV_OPT_TYPE_INT, {.i64=0}, 0, 9000, AF },
109  { "start_duration", "set start duration of non-silence part", OFFSET(start_duration_opt), AV_OPT_TYPE_DURATION, {.i64=0}, 0, INT32_MAX, AF },
110  { "start_threshold", "set threshold for start silence detection", OFFSET(start_threshold), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, DBL_MAX, AF },
111  { "start_silence", "set start duration of silence part to keep", OFFSET(start_silence_opt), AV_OPT_TYPE_DURATION, {.i64=0}, 0, INT32_MAX, AF },
112  { "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" },
113  { "any", 0, 0, AV_OPT_TYPE_CONST, {.i64=T_ANY}, 0, 0, AF, "mode" },
114  { "all", 0, 0, AV_OPT_TYPE_CONST, {.i64=T_ALL}, 0, 0, AF, "mode" },
115  { "stop_periods", NULL, OFFSET(stop_periods), AV_OPT_TYPE_INT, {.i64=0}, -9000, 9000, AF },
116  { "stop_duration", "set stop duration of non-silence part", OFFSET(stop_duration_opt), AV_OPT_TYPE_DURATION, {.i64=0}, 0, INT32_MAX, AF },
117  { "stop_threshold", "set threshold for stop silence detection", OFFSET(stop_threshold), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, DBL_MAX, AF },
118  { "stop_silence", "set stop duration of silence part to keep", OFFSET(stop_silence_opt), AV_OPT_TYPE_DURATION, {.i64=0}, 0, INT32_MAX, AF },
119  { "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" },
120  { "detection", "set how silence is detected", OFFSET(detection), AV_OPT_TYPE_INT, {.i64=D_RMS}, D_PEAK,D_RMS, AF, "detection" },
121  { "peak", "use absolute values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_PEAK},0, 0, AF, "detection" },
122  { "rms", "use squared values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_RMS}, 0, 0, AF, "detection" },
123  { "window", "set duration of window in seconds", OFFSET(window_ratio), AV_OPT_TYPE_DOUBLE, {.dbl=0.02}, 0, 10, AF },
124  { NULL }
125 };
126 
127 AVFILTER_DEFINE_CLASS(silenceremove);
128 
130  int ch, int out_offset, int in_offset)
131 {
132  const double *srcp = (const double *)in->data[0];
133  const double src = srcp[in->channels * in_offset + ch];
134  double *dstp = (double *)out->data[0];
135 
136  dstp[out->channels * out_offset + ch] = src;
137 }
138 
140  int ch, int out_offset, int in_offset)
141 {
142  const double *srcp = (const double *)in->extended_data[ch];
143  const double src = srcp[in_offset];
144  double *dstp = (double *)out->extended_data[ch];
145 
146  dstp[out_offset] = src;
147 }
148 
150  int ch, int out_offset, int in_offset)
151 {
152  const float *srcp = (const float *)in->data[0];
153  const float src = srcp[in->channels * in_offset + ch];
154  float *dstp = (float *)out->data[0];
155 
156  dstp[out->channels * out_offset + ch] = src;
157 }
158 
160  int ch, int out_offset, int in_offset)
161 {
162  const float *srcp = (const float *)in->extended_data[ch];
163  const float src = srcp[in_offset];
164  float *dstp = (float *)out->extended_data[ch];
165 
166  dstp[out_offset] = src;
167 }
168 
170 {
171  const double *samples = (const double *)frame->data[0];
172  const double *wsamples = (const double *)s->window->data[0];
173  double sample = samples[frame->channels * offset + ch];
174  double wsample = wsamples[frame->channels * s->window_offset + ch];
175  double new_sum;
176 
177  new_sum = s->sum;
178  new_sum -= wsample;
179  new_sum += fabs(sample);
180 
181  return new_sum / s->window_size;
182 }
183 
185 {
186  const double *samples = (const double *)frame->data[0];
187  double *wsamples = (double *)s->window->data[0];
188  double sample = samples[frame->channels * offset + ch];
189  double *wsample = &wsamples[frame->channels * s->window_offset + ch];
190 
191  s->sum -= *wsample;
192  *wsample = fabs(sample);
193  s->sum += *wsample;
194 }
195 
197 {
198  const float *samples = (const float *)frame->data[0];
199  const float *wsamples = (const float *)s->window->data[0];
200  float sample = samples[frame->channels * offset + ch];
201  float wsample = wsamples[frame->channels * s->window_offset + ch];
202  float new_sum;
203 
204  new_sum = s->sum;
205  new_sum -= wsample;
206  new_sum += fabsf(sample);
207 
208  return new_sum / s->window_size;
209 }
210 
212 {
213  const float *samples = (const float *)frame->data[0];
214  float *wsamples = (float *)s->window->data[0];
215  float sample = samples[frame->channels * offset + ch];
216  float *wsample = &wsamples[frame->channels * s->window_offset + ch];
217 
218  s->sum -= *wsample;
219  *wsample = fabsf(sample);
220  s->sum += *wsample;
221 }
222 
224 {
225  const double *samples = (const double *)frame->data[0];
226  const double *wsamples = (const double *)s->window->data[0];
227  double sample = samples[frame->channels * offset + ch];
228  double wsample = wsamples[frame->channels * s->window_offset + ch];
229  double new_sum;
230 
231  new_sum = s->sum;
232  new_sum -= wsample;
233  new_sum += sample * sample;
234 
235  return sqrt(new_sum / s->window_size);
236 }
237 
239 {
240  const double *samples = (const double *)frame->data[0];
241  double *wsamples = (double *)s->window->data[0];
242  double sample = samples[frame->channels * offset + ch];
243  double *wsample = &wsamples[frame->channels * s->window_offset + ch];
244 
245  s->sum -= *wsample;
246  *wsample = sample * sample;
247  s->sum += *wsample;
248 }
249 
251 {
252  const float *samples = (const float *)frame->data[0];
253  const float *wsamples = (const float *)s->window->data[0];
254  float sample = samples[frame->channels * offset + ch];
255  float wsample = wsamples[frame->channels * s->window_offset + ch];
256  float new_sum;
257 
258  new_sum = s->sum;
259  new_sum -= wsample;
260  new_sum += sample * sample;
261 
262  return sqrtf(new_sum / s->window_size);
263 }
264 
266 {
267  const float *samples = (const float *)frame->data[0];
268  float sample = samples[frame->channels * offset + ch];
269  float *wsamples = (float *)s->window->data[0];
270  float *wsample = &wsamples[frame->channels * s->window_offset + ch];
271 
272  s->sum -= *wsample;
273  *wsample = sample * sample;
274  s->sum += *wsample;
275 }
276 
278 {
279  const double *samples = (const double *)frame->extended_data[ch];
280  const double *wsamples = (const double *)s->window->extended_data[ch];
281  double sample = samples[offset];
282  double wsample = wsamples[s->window_offset];
283  double new_sum;
284 
285  new_sum = s->sum;
286  new_sum -= wsample;
287  new_sum += fabs(sample);
288 
289  return new_sum / s->window_size;
290 }
291 
293 {
294  const double *samples = (const double *)frame->extended_data[ch];
295  double *wsamples = (double *)s->window->extended_data[ch];
296  double sample = samples[offset];
297  double *wsample = &wsamples[s->window_offset];
298 
299  s->sum -= *wsample;
300  *wsample = fabs(sample);
301  s->sum += *wsample;
302 }
303 
305 {
306  const float *samples = (const float *)frame->extended_data[ch];
307  const float *wsamples = (const float *)s->window->extended_data[ch];
308  float sample = samples[offset];
309  float wsample = wsamples[s->window_offset];
310  float new_sum;
311 
312  new_sum = s->sum;
313  new_sum -= wsample;
314  new_sum += fabsf(sample);
315 
316  return new_sum / s->window_size;
317 }
318 
320 {
321  const float *samples = (const float *)frame->extended_data[ch];
322  float *wsamples = (float *)s->window->extended_data[ch];
323  float sample = samples[offset];
324  float *wsample = &wsamples[s->window_offset];
325 
326  s->sum -= *wsample;
327  *wsample = fabsf(sample);
328  s->sum += *wsample;
329 }
330 
332 {
333  const double *samples = (const double *)frame->extended_data[ch];
334  const double *wsamples = (const double *)s->window->extended_data[ch];
335  double sample = samples[offset];
336  double wsample = wsamples[s->window_offset];
337  double new_sum;
338 
339  new_sum = s->sum;
340  new_sum -= wsample;
341  new_sum += sample * sample;
342 
343  return sqrt(new_sum / s->window_size);
344 }
345 
347 {
348  const double *samples = (const double *)frame->extended_data[ch];
349  double *wsamples = (double *)s->window->extended_data[ch];
350  double sample = samples[offset];
351  double *wsample = &wsamples[s->window_offset];
352 
353  s->sum -= *wsample;
354  *wsample = sample * sample;
355  s->sum += *wsample;
356 }
357 
359 {
360  const float *samples = (const float *)frame->extended_data[ch];
361  const float *wsamples = (const float *)s->window->extended_data[ch];
362  float sample = samples[offset];
363  float wsample = wsamples[s->window_offset];
364  float new_sum;
365 
366  new_sum = s->sum;
367  new_sum -= wsample;
368  new_sum += sample * sample;
369 
370  return sqrtf(new_sum / s->window_size);
371 }
372 
374 {
375  const float *samples = (const float *)frame->extended_data[ch];
376  float *wsamples = (float *)s->window->extended_data[ch];
377  float sample = samples[offset];
378  float *wsample = &wsamples[s->window_offset];
379 
380  s->sum -= *wsample;
381  *wsample = sample * sample;
382  s->sum += *wsample;
383 }
384 
386 {
387  SilenceRemoveContext *s = ctx->priv;
388 
389  if (s->stop_periods < 0) {
390  s->stop_periods = -s->stop_periods;
391  s->restart = 1;
392  }
393 
394  return 0;
395 }
396 
398 {
399  av_samples_set_silence(s->window->extended_data, 0, s->window_size,
400  s->window->channels, s->window->format);
401 
402  s->window_offset = 0;
403  s->sum = 0;
404 }
405 
407 {
408  AVFilterContext *ctx = inlink->dst;
409  SilenceRemoveContext *s = ctx->priv;
410 
411  s->next_pts = AV_NOPTS_VALUE;
412  s->window_size = FFMAX((inlink->sample_rate * s->window_ratio), 1);
413  s->window = ff_get_audio_buffer(ctx->outputs[0], s->window_size);
414  if (!s->window)
415  return AVERROR(ENOMEM);
416 
417  clear_window(s);
418 
419  s->start_duration = av_rescale(s->start_duration_opt, inlink->sample_rate,
420  AV_TIME_BASE);
421  s->start_silence = av_rescale(s->start_silence_opt, inlink->sample_rate,
422  AV_TIME_BASE);
423  s->stop_duration = av_rescale(s->stop_duration_opt, inlink->sample_rate,
424  AV_TIME_BASE);
425  s->stop_silence = av_rescale(s->stop_silence_opt, inlink->sample_rate,
426  AV_TIME_BASE);
427 
428  s->start_holdoff = ff_get_audio_buffer(ctx->outputs[0],
429  FFMAX(s->start_duration, 1));
430  if (!s->start_holdoff)
431  return AVERROR(ENOMEM);
432 
433  s->start_silence_hold = ff_get_audio_buffer(ctx->outputs[0],
434  FFMAX(s->start_silence, 1));
435  if (!s->start_silence_hold)
436  return AVERROR(ENOMEM);
437 
438  s->start_holdoff_offset = 0;
439  s->start_holdoff_end = 0;
440  s->start_found_periods = 0;
441 
442  s->stop_holdoff = ff_get_audio_buffer(ctx->outputs[0],
443  FFMAX(s->stop_duration, 1));
444  if (!s->stop_holdoff)
445  return AVERROR(ENOMEM);
446 
447  s->stop_silence_hold = ff_get_audio_buffer(ctx->outputs[0],
448  FFMAX(s->stop_silence, 1));
449  if (!s->stop_silence_hold)
450  return AVERROR(ENOMEM);
451 
452  s->stop_holdoff_offset = 0;
453  s->stop_holdoff_end = 0;
454  s->stop_found_periods = 0;
455 
456  if (s->start_periods)
457  s->mode = SILENCE_TRIM;
458  else
459  s->mode = SILENCE_COPY;
460 
461  switch (inlink->format) {
462  case AV_SAMPLE_FMT_DBL:
463  s->copy = copy_double;
464  switch (s->detection) {
465  case D_PEAK:
466  s->update = update_peak_double;
467  s->compute = compute_peak_double;
468  break;
469  case D_RMS:
470  s->update = update_rms_double;
471  s->compute = compute_rms_double;
472  break;
473  }
474  break;
475  case AV_SAMPLE_FMT_FLT:
476  s->copy = copy_float;
477  switch (s->detection) {
478  case D_PEAK:
479  s->update = update_peak_float;
480  s->compute = compute_peak_float;
481  break;
482  case D_RMS:
483  s->update = update_rms_float;
484  s->compute = compute_rms_float;
485  break;
486  }
487  break;
488  case AV_SAMPLE_FMT_DBLP:
489  s->copy = copy_doublep;
490  switch (s->detection) {
491  case D_PEAK:
492  s->update = update_peak_doublep;
493  s->compute = compute_peak_doublep;
494  break;
495  case D_RMS:
496  s->update = update_rms_doublep;
497  s->compute = compute_rms_doublep;
498  break;
499  }
500  break;
501  case AV_SAMPLE_FMT_FLTP:
502  s->copy = copy_floatp;
503  switch (s->detection) {
504  case D_PEAK:
505  s->update = update_peak_floatp;
506  s->compute = compute_peak_floatp;
507  break;
508  case D_RMS:
509  s->update = update_rms_floatp;
510  s->compute = compute_rms_floatp;
511  break;
512  }
513  break;
514  }
515 
516  return 0;
517 }
518 
520  AVFrame *out, AVFilterLink *outlink,
521  int *nb_samples_written, int *ret, int flush_silence)
522 {
523  AVFrame *silence;
524 
525  if (*nb_samples_written) {
526  out->nb_samples = *nb_samples_written;
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  if (*ret < 0)
535  return;
536  *nb_samples_written = 0;
537  } else {
538  av_frame_free(&out);
539  }
540 
541  if (s->stop_silence_end <= 0 || !flush_silence)
542  return;
543 
544  silence = ff_get_audio_buffer(outlink, s->stop_silence_end);
545  if (!silence) {
546  *ret = AVERROR(ENOMEM);
547  return;
548  }
549 
550  if (s->stop_silence_offset < s->stop_silence_end) {
551  av_samples_copy(silence->extended_data, s->stop_silence_hold->extended_data, 0,
552  s->stop_silence_offset,
553  s->stop_silence_end - s->stop_silence_offset,
554  outlink->channels, outlink->format);
555  }
556 
557  if (s->stop_silence_offset > 0) {
558  av_samples_copy(silence->extended_data, s->stop_silence_hold->extended_data,
559  s->stop_silence_end - s->stop_silence_offset,
560  0, s->stop_silence_offset,
561  outlink->channels, outlink->format);
562  }
563 
564  s->stop_silence_offset = 0;
565  s->stop_silence_end = 0;
566 
567  silence->pts = s->next_pts;
568  s->next_pts += av_rescale_q(silence->nb_samples,
569  (AVRational){1, outlink->sample_rate},
570  outlink->time_base);
571 
572  *ret = ff_filter_frame(outlink, silence);
573 }
574 
576 {
577  AVFilterContext *ctx = inlink->dst;
578  AVFilterLink *outlink = ctx->outputs[0];
579  SilenceRemoveContext *s = ctx->priv;
580  int i, j, threshold, ret = 0;
581  int nbs, nb_samples_read, nb_samples_written;
582  AVFrame *out;
583 
584  nb_samples_read = nb_samples_written = 0;
585 
586  if (s->next_pts == AV_NOPTS_VALUE)
587  s->next_pts = in->pts;
588 
589  switch (s->mode) {
590  case SILENCE_TRIM:
591 silence_trim:
592  nbs = in->nb_samples - nb_samples_read;
593  if (!nbs)
594  break;
595 
596  for (i = 0; i < nbs; i++) {
597  if (s->start_mode == T_ANY) {
598  threshold = 0;
599  for (j = 0; j < outlink->channels; j++) {
600  threshold |= s->compute(s, in, j, nb_samples_read) > s->start_threshold;
601  }
602  } else {
603  threshold = 1;
604  for (j = 0; j < outlink->channels; j++) {
605  threshold &= s->compute(s, in, j, nb_samples_read) > s->start_threshold;
606  }
607  }
608 
609  if (threshold) {
610  for (j = 0; j < outlink->channels; j++) {
611  s->update(s, in, j, nb_samples_read);
612  s->copy(s, s->start_holdoff, in, j, s->start_holdoff_end, nb_samples_read);
613  }
614 
615  s->window_offset++;
616  if (s->window_offset >= s->window_size)
617  s->window_offset = 0;
618  s->start_holdoff_end++;
619  nb_samples_read++;
620 
621  if (s->start_holdoff_end >= s->start_duration) {
622  if (++s->start_found_periods >= s->start_periods) {
623  s->mode = SILENCE_TRIM_FLUSH;
624  goto silence_trim_flush;
625  }
626 
627  s->start_holdoff_offset = 0;
628  s->start_holdoff_end = 0;
629  s->start_silence_offset = 0;
630  s->start_silence_end = 0;
631  }
632  } else {
633  s->start_holdoff_end = 0;
634 
635  for (j = 0; j < outlink->channels; j++) {
636  s->update(s, in, j, nb_samples_read);
637  if (s->start_silence)
638  s->copy(s, s->start_silence_hold, in, j, s->start_silence_offset, nb_samples_read);
639  }
640 
641  s->window_offset++;
642  if (s->window_offset >= s->window_size)
643  s->window_offset = 0;
644  nb_samples_read++;
645  s->start_silence_offset++;
646 
647  if (s->start_silence) {
648  s->start_silence_end = FFMIN(s->start_silence_end + 1, s->start_silence);
649  if (s->start_silence_offset >= s->start_silence)
650  s->start_silence_offset = 0;
651  }
652  }
653  }
654  break;
655 
656  case SILENCE_TRIM_FLUSH:
657 silence_trim_flush:
658  nbs = s->start_holdoff_end - s->start_holdoff_offset;
659  if (!nbs)
660  break;
661 
662  out = ff_get_audio_buffer(outlink, nbs + s->start_silence_end);
663  if (!out) {
664  av_frame_free(&in);
665  return AVERROR(ENOMEM);
666  }
667 
668  if (s->start_silence_end > 0) {
669  if (s->start_silence_offset < s->start_silence_end) {
670  av_samples_copy(out->extended_data, s->start_silence_hold->extended_data, 0,
671  s->start_silence_offset,
672  s->start_silence_end - s->start_silence_offset,
673  outlink->channels, outlink->format);
674  }
675 
676  if (s->start_silence_offset > 0) {
677  av_samples_copy(out->extended_data, s->start_silence_hold->extended_data,
678  s->start_silence_end - s->start_silence_offset,
679  0, s->start_silence_offset,
680  outlink->channels, outlink->format);
681  }
682  }
683 
684  av_samples_copy(out->extended_data, s->start_holdoff->extended_data,
685  s->start_silence_end,
686  s->start_holdoff_offset, nbs,
687  outlink->channels, outlink->format);
688 
689  out->pts = s->next_pts;
690  s->next_pts += av_rescale_q(out->nb_samples,
691  (AVRational){1, outlink->sample_rate},
692  outlink->time_base);
693 
694  s->start_holdoff_offset += nbs;
695 
696  ret = ff_filter_frame(outlink, out);
697 
698  if (s->start_holdoff_offset == s->start_holdoff_end) {
699  s->start_holdoff_offset = 0;
700  s->start_holdoff_end = 0;
701  s->start_silence_offset = 0;
702  s->start_silence_end = 0;
703  s->mode = SILENCE_COPY;
704  goto silence_copy;
705  }
706  break;
707 
708  case SILENCE_COPY:
709 silence_copy:
710  nbs = in->nb_samples - nb_samples_read;
711  if (!nbs)
712  break;
713 
714  out = ff_get_audio_buffer(outlink, nbs);
715  if (!out) {
716  av_frame_free(&in);
717  return AVERROR(ENOMEM);
718  }
719 
720  if (s->stop_periods) {
721  for (i = 0; i < nbs; i++) {
722  if (s->stop_mode == T_ANY) {
723  threshold = 0;
724  for (j = 0; j < outlink->channels; j++) {
725  threshold |= s->compute(s, in, j, nb_samples_read) > s->stop_threshold;
726  }
727  } else {
728  threshold = 1;
729  for (j = 0; j < outlink->channels; j++) {
730  threshold &= s->compute(s, in, j, nb_samples_read) > s->stop_threshold;
731  }
732  }
733 
734  if (threshold && s->stop_holdoff_end && !s->stop_silence) {
735  s->mode = SILENCE_COPY_FLUSH;
736  flush(s, out, outlink, &nb_samples_written, &ret, 0);
737  goto silence_copy_flush;
738  } else if (threshold) {
739  for (j = 0; j < outlink->channels; j++) {
740  s->update(s, in, j, nb_samples_read);
741  s->copy(s, out, in, j, nb_samples_written, nb_samples_read);
742  }
743 
744  s->window_offset++;
745  if (s->window_offset >= s->window_size)
746  s->window_offset = 0;
747  nb_samples_read++;
748  nb_samples_written++;
749  } else if (!threshold) {
750  for (j = 0; j < outlink->channels; j++) {
751  s->update(s, in, j, nb_samples_read);
752  if (s->stop_silence) {
753  s->copy(s, s->stop_silence_hold, in, j, s->stop_silence_offset, nb_samples_read);
754  s->stop_silence_end = FFMIN(s->stop_silence_end + 1, s->stop_silence);
755  if (s->stop_silence_offset >= s->stop_silence) {
756  s->stop_silence_offset = 0;
757  }
758  }
759 
760  s->copy(s, s->stop_holdoff, in, j, s->stop_holdoff_end, nb_samples_read);
761  }
762 
763  s->window_offset++;
764  if (s->window_offset >= s->window_size)
765  s->window_offset = 0;
766  nb_samples_read++;
767  s->stop_holdoff_end++;
768 
769  if (s->stop_holdoff_end >= s->stop_duration) {
770  if (++s->stop_found_periods >= s->stop_periods) {
771  s->stop_holdoff_offset = 0;
772  s->stop_holdoff_end = 0;
773 
774  if (!s->restart) {
775  s->mode = SILENCE_STOP;
776  flush(s, out, outlink, &nb_samples_written, &ret, 1);
777  goto silence_stop;
778  } else {
779  s->stop_found_periods = 0;
780  s->start_found_periods = 0;
781  s->start_holdoff_offset = 0;
782  s->start_holdoff_end = 0;
783  s->start_silence_offset = 0;
784  s->start_silence_end = 0;
785  clear_window(s);
786  s->mode = SILENCE_TRIM;
787  flush(s, out, outlink, &nb_samples_written, &ret, 1);
788  goto silence_trim;
789  }
790  }
791  s->mode = SILENCE_COPY_FLUSH;
792  flush(s, out, outlink, &nb_samples_written, &ret, 0);
793  goto silence_copy_flush;
794  }
795  }
796  }
797  flush(s, out, outlink, &nb_samples_written, &ret, 0);
798  } else {
799  av_samples_copy(out->extended_data, in->extended_data,
800  nb_samples_written,
801  nb_samples_read, nbs,
802  outlink->channels, outlink->format);
803 
804  out->pts = s->next_pts;
805  s->next_pts += av_rescale_q(out->nb_samples,
806  (AVRational){1, outlink->sample_rate},
807  outlink->time_base);
808 
809  ret = ff_filter_frame(outlink, out);
810  }
811  break;
812 
813  case SILENCE_COPY_FLUSH:
814 silence_copy_flush:
815  nbs = s->stop_holdoff_end - s->stop_holdoff_offset;
816  if (!nbs)
817  break;
818 
819  out = ff_get_audio_buffer(outlink, nbs);
820  if (!out) {
821  av_frame_free(&in);
822  return AVERROR(ENOMEM);
823  }
824 
825  av_samples_copy(out->extended_data, s->stop_holdoff->extended_data, 0,
826  s->stop_holdoff_offset, nbs,
827  outlink->channels, outlink->format);
828 
829  s->stop_holdoff_offset += nbs;
830 
831  out->pts = s->next_pts;
832  s->next_pts += av_rescale_q(out->nb_samples,
833  (AVRational){1, outlink->sample_rate},
834  outlink->time_base);
835 
836  ret = ff_filter_frame(outlink, out);
837 
838  if (s->stop_holdoff_offset == s->stop_holdoff_end) {
839  s->stop_holdoff_offset = 0;
840  s->stop_holdoff_end = 0;
841  s->stop_silence_offset = 0;
842  s->stop_silence_end = 0;
843  s->mode = SILENCE_COPY;
844  goto silence_copy;
845  }
846  break;
847  case SILENCE_STOP:
848 silence_stop:
849  break;
850  }
851 
852  av_frame_free(&in);
853 
854  return ret;
855 }
856 
857 static int request_frame(AVFilterLink *outlink)
858 {
859  AVFilterContext *ctx = outlink->src;
860  SilenceRemoveContext *s = ctx->priv;
861  int ret;
862 
863  ret = ff_request_frame(ctx->inputs[0]);
864  if (ret == AVERROR_EOF && (s->mode == SILENCE_COPY_FLUSH ||
865  s->mode == SILENCE_COPY)) {
866  int nbs = s->stop_holdoff_end - s->stop_holdoff_offset;
867  if (nbs) {
868  AVFrame *frame;
869 
870  frame = ff_get_audio_buffer(outlink, nbs);
871  if (!frame)
872  return AVERROR(ENOMEM);
873 
874  av_samples_copy(frame->extended_data, s->stop_holdoff->extended_data, 0,
875  s->stop_holdoff_offset, nbs,
876  outlink->channels, outlink->format);
877 
878  frame->pts = s->next_pts;
879  s->next_pts += av_rescale_q(frame->nb_samples,
880  (AVRational){1, outlink->sample_rate},
881  outlink->time_base);
882 
883  ret = ff_filter_frame(outlink, frame);
884  }
885  s->mode = SILENCE_STOP;
886  }
887  return ret;
888 }
889 
891 {
894  static const enum AVSampleFormat sample_fmts[] = {
898  };
899  int ret;
900 
902  if (!layouts)
903  return AVERROR(ENOMEM);
905  if (ret < 0)
906  return ret;
907 
909  if (!formats)
910  return AVERROR(ENOMEM);
912  if (ret < 0)
913  return ret;
914 
916  if (!formats)
917  return AVERROR(ENOMEM);
919 }
920 
922 {
923  SilenceRemoveContext *s = ctx->priv;
924 
925  av_frame_free(&s->start_holdoff);
926  av_frame_free(&s->start_silence_hold);
927  av_frame_free(&s->stop_holdoff);
928  av_frame_free(&s->stop_silence_hold);
929  av_frame_free(&s->window);
930 }
931 
933  {
934  .name = "default",
935  .type = AVMEDIA_TYPE_AUDIO,
936  .config_props = config_input,
937  .filter_frame = filter_frame,
938  },
939  { NULL }
940 };
941 
943  {
944  .name = "default",
945  .type = AVMEDIA_TYPE_AUDIO,
946  .request_frame = request_frame,
947  },
948  { NULL }
949 };
950 
952  .name = "silenceremove",
953  .description = NULL_IF_CONFIG_SMALL("Remove silence."),
954  .priv_size = sizeof(SilenceRemoveContext),
955  .priv_class = &silenceremove_class,
956  .init = init,
957  .uninit = uninit,
961 };
formats
formats
Definition: signature.h:48
compute_rms_double
static double compute_rms_double(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:223
ff_get_audio_buffer
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
AV_SAMPLE_FMT_FLTP
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition: samplefmt.h:69
update_rms_doublep
static void update_rms_doublep(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:346
AVFilterChannelLayouts
A list of supported channel layouts.
Definition: formats.h:85
update_rms_float
static void update_rms_float(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:265
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:286
out
FILE * out
Definition: movenc.c:54
SilenceRemoveContext::stop_silence_offset
size_t stop_silence_offset
Definition: af_silenceremove.c:84
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:978
sample_fmts
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:948
layouts
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:55
init
static av_cold int init(AVFilterContext *ctx)
Definition: af_silenceremove.c:385
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
SilenceRemoveContext::window_size
int window_size
Definition: af_silenceremove.c:91
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:112
ff_all_channel_counts
AVFilterChannelLayouts * ff_all_channel_counts(void)
Construct an AVFilterChannelLayouts coding for any channel layout, with known or unknown disposition.
Definition: formats.c:429
SilenceRemoveContext::start_holdoff_offset
size_t start_holdoff_offset
Definition: af_silenceremove.c:74
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:303
request_frame
static int request_frame(AVFilterLink *outlink)
Definition: af_silenceremove.c:857
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:396
SilenceDetect
SilenceDetect
Definition: af_silenceremove.c:33
SilenceRemoveContext::stop_silence_hold
AVFrame * stop_silence_hold
Definition: af_silenceremove.c:81
AVOption
AVOption.
Definition: opt.h:247
AV_OPT_TYPE_DURATION
@ AV_OPT_TYPE_DURATION
Definition: opt.h:238
ff_request_frame
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Definition: avfilter.c:395
silenceremove_inputs
static const AVFilterPad silenceremove_inputs[]
Definition: af_silenceremove.c:932
SilenceRemoveContext::start_duration_opt
int64_t start_duration_opt
Definition: af_silenceremove.c:58
float.h
update_peak_float
static void update_peak_float(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:211
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:149
SilenceRemoveContext::start_silence_opt
int64_t start_silence_opt
Definition: af_silenceremove.c:61
SilenceRemoveContext::stop_silence
int64_t stop_silence
Definition: af_silenceremove.c:68
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(silenceremove)
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:317
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:64
formats.h
compute_rms_float
static double compute_rms_float(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:250
SilenceRemoveContext::detection
int detection
Definition: af_silenceremove.c:97
SilenceRemoveContext::window_offset
int window_offset
Definition: af_silenceremove.c:90
copy_floatp
static void copy_floatp(SilenceRemoveContext *s, AVFrame *out, AVFrame *in, int ch, int out_offset, int in_offset)
Definition: af_silenceremove.c:159
fabsf
static __device__ float fabsf(float a)
Definition: cuda_runtime.h:181
compute_peak_floatp
static double compute_peak_floatp(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:304
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:54
compute_peak_doublep
static double compute_peak_doublep(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:277
av_cold
#define av_cold
Definition: attributes.h:90
inputs
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
Definition: filter_design.txt:243
ff_set_common_formats
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:580
s
#define s(width, name)
Definition: cbs_vp9.c:257
SilenceRemoveContext::mode
enum SilenceMode mode
Definition: af_silenceremove.c:54
SILENCE_STOP
@ SILENCE_STOP
Definition: af_silenceremove.c:48
AVFrame::channels
int channels
number of audio channels, only used for audio.
Definition: frame.h:592
AV_OPT_TYPE_DOUBLE
@ AV_OPT_TYPE_DOUBLE
Definition: opt.h:226
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: af_silenceremove.c:575
outputs
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
ctx
AVFormatContext * ctx
Definition: movenc.c:48
update_peak_floatp
static void update_peak_floatp(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:319
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:141
SilenceRemoveContext::start_silence_end
size_t start_silence_end
Definition: af_silenceremove.c:77
SilenceRemoveContext::start_silence_hold
AVFrame * start_silence_hold
Definition: af_silenceremove.c:73
compute_rms_doublep
static double compute_rms_doublep(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:331
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: af_silenceremove.c:890
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
NULL
#define NULL
Definition: coverity.c:32
compute_peak_double
static double compute_peak_double(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:169
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
SilenceRemoveContext::stop_holdoff
AVFrame * stop_holdoff
Definition: af_silenceremove.c:80
src
#define src
Definition: vp8dsp.c:255
SilenceRemoveContext::start_silence_offset
size_t start_silence_offset
Definition: af_silenceremove.c:76
SilenceRemoveContext
Definition: af_silenceremove.c:51
SILENCE_TRIM
@ SILENCE_TRIM
Definition: af_silenceremove.c:44
SilenceRemoveContext::start_threshold
double start_threshold
Definition: af_silenceremove.c:59
silenceremove_options
static const AVOption silenceremove_options[]
Definition: af_silenceremove.c:107
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_silenceremove.c:921
copy_double
static void copy_double(SilenceRemoveContext *s, AVFrame *out, AVFrame *in, int ch, int out_offset, int in_offset)
Definition: af_silenceremove.c:129
SILENCE_COPY_FLUSH
@ SILENCE_COPY_FLUSH
Definition: af_silenceremove.c:47
AF
#define AF
Definition: af_silenceremove.c:105
SilenceRemoveContext::start_found_periods
int start_found_periods
Definition: af_silenceremove.c:78
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:116
config_input
static int config_input(AVFilterLink *inlink)
Definition: af_silenceremove.c:406
FFMAX
#define FFMAX(a, b)
Definition: common.h:103
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:59
sample
#define sample
Definition: flacdsp_template.c:44
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
SilenceRemoveContext::stop_holdoff_offset
size_t stop_holdoff_offset
Definition: af_silenceremove.c:82
update_peak_doublep
static void update_peak_doublep(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:292
SilenceRemoveContext::stop_periods
int stop_periods
Definition: af_silenceremove.c:64
FFMIN
#define FFMIN(a, b)
Definition: common.h:105
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
SILENCE_COPY
@ SILENCE_COPY
Definition: af_silenceremove.c:46
clear_window
static void clear_window(SilenceRemoveContext *s)
Definition: af_silenceremove.c:397
SilenceRemoveContext::sum
double sum
Definition: af_silenceremove.c:92
flush
static void flush(SilenceRemoveContext *s, AVFrame *out, AVFilterLink *outlink, int *nb_samples_written, int *ret, int flush_silence)
Definition: af_silenceremove.c:519
SILENCE_TRIM_FLUSH
@ SILENCE_TRIM_FLUSH
Definition: af_silenceremove.c:45
SilenceRemoveContext::start_holdoff_end
size_t start_holdoff_end
Definition: af_silenceremove.c:75
internal.h
av_samples_copy
int av_samples_copy(uint8_t **dst, uint8_t *const *src, int dst_offset, int src_offset, int nb_samples, int nb_channels, enum AVSampleFormat sample_fmt)
Copy samples from src to dst.
Definition: samplefmt.c:220
update_rms_double
static void update_rms_double(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:238
AVFrame::nb_samples
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:369
update_peak_double
static void update_peak_double(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:184
SilenceRemoveContext::stop_silence_opt
int64_t stop_silence_opt
Definition: af_silenceremove.c:69
i
int i
Definition: input.c:406
ff_af_silenceremove
const AVFilter ff_af_silenceremove
Definition: af_silenceremove.c:951
SilenceRemoveContext::stop_mode
int stop_mode
Definition: af_silenceremove.c:70
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:254
AVFrame::extended_data
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:350
SilenceMode
SilenceMode
Definition: af_silenceremove.c:43
SilenceRemoveContext::stop_duration
int64_t stop_duration
Definition: af_silenceremove.c:65
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
SilenceRemoveContext::stop_silence_end
size_t stop_silence_end
Definition: af_silenceremove.c:85
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:60
av_rescale
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:128
SilenceRemoveContext::stop_found_periods
int stop_found_periods
Definition: af_silenceremove.c:86
update_rms_floatp
static void update_rms_floatp(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:373
SilenceRemoveContext::start_mode
int start_mode
Definition: af_silenceremove.c:62
SilenceRemoveContext::update
void(* update)(struct SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:98
SilenceRemoveContext::compute
double(* compute)(struct SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:99
av_samples_set_silence
int av_samples_set_silence(uint8_t **audio_data, int offset, int nb_samples, int nb_channels, enum AVSampleFormat sample_fmt)
Fill an audio buffer with silence.
Definition: samplefmt.c:244
AVFilter
Filter definition.
Definition: avfilter.h:145
SilenceRemoveContext::stop_threshold
double stop_threshold
Definition: af_silenceremove.c:67
ret
ret
Definition: filter_design.txt:187
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
SilenceRemoveContext::restart
int restart
Definition: af_silenceremove.c:94
compute_peak_float
static double compute_peak_float(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:196
D_PEAK
@ D_PEAK
Definition: af_silenceremove.c:34
OFFSET
#define OFFSET(x)
Definition: af_silenceremove.c:104
SilenceRemoveContext::window
AVFrame * window
Definition: af_silenceremove.c:89
SilenceRemoveContext::start_periods
int start_periods
Definition: af_silenceremove.c:56
ff_all_samplerates
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:414
copy_doublep
static void copy_doublep(SilenceRemoveContext *s, AVFrame *out, AVFrame *in, int ch, int out_offset, int in_offset)
Definition: af_silenceremove.c:139
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:224
avfilter.h
AV_SAMPLE_FMT_DBLP
@ AV_SAMPLE_FMT_DBLP
double, planar
Definition: samplefmt.h:70
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
AVFilterContext
An instance of a filter.
Definition: avfilter.h:333
ThresholdMode
ThresholdMode
Definition: af_silenceremove.c:38
audio.h
SilenceRemoveContext::stop_duration_opt
int64_t stop_duration_opt
Definition: af_silenceremove.c:66
SilenceRemoveContext::start_silence
int64_t start_silence
Definition: af_silenceremove.c:60
compute_rms_floatp
static double compute_rms_floatp(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:358
SilenceRemoveContext::copy
void(* copy)(struct SilenceRemoveContext *s, AVFrame *out, AVFrame *in, int ch, int out_offset, int in_offset)
Definition: af_silenceremove.c:100
silenceremove_outputs
static const AVFilterPad silenceremove_outputs[]
Definition: af_silenceremove.c:942
SilenceRemoveContext::start_holdoff
AVFrame * start_holdoff
Definition: af_silenceremove.c:72
timestamp.h
ff_set_common_samplerates
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:568
copy_float
static void copy_float(SilenceRemoveContext *s, AVFrame *out, AVFrame *in, int ch, int out_offset, int in_offset)
Definition: af_silenceremove.c:149
T_ALL
@ T_ALL
Definition: af_silenceremove.c:40
AV_SAMPLE_FMT_DBL
@ AV_SAMPLE_FMT_DBL
double
Definition: samplefmt.h:64
D_RMS
@ D_RMS
Definition: af_silenceremove.c:35
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:233
SilenceRemoveContext::stop_holdoff_end
size_t stop_holdoff_end
Definition: af_silenceremove.c:83
AV_SAMPLE_FMT_FLT
@ AV_SAMPLE_FMT_FLT
float
Definition: samplefmt.h:63
SilenceRemoveContext::start_duration
int64_t start_duration
Definition: af_silenceremove.c:57
T_ANY
@ T_ANY
Definition: af_silenceremove.c:39
SilenceRemoveContext::window_ratio
double window_ratio
Definition: af_silenceremove.c:88
ff_set_common_channel_layouts
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:561
SilenceRemoveContext::next_pts
int64_t next_pts
Definition: af_silenceremove.c:95