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/audio_fifo.h"
27 #include "libavutil/avassert.h"
28 #include "libavutil/opt.h"
29 #include "libavutil/timestamp.h"
30 #include "audio.h"
31 #include "formats.h"
32 #include "avfilter.h"
33 #include "internal.h"
34 
38 };
39 
43 };
44 
51 };
52 
53 typedef struct SilenceRemoveContext {
54  const AVClass *class;
55 
57 
59  int64_t start_duration;
62  int64_t start_silence;
65 
67  int64_t stop_duration;
70  int64_t stop_silence;
72  int stop_mode;
73 
75 
83 
91 
94  int64_t window_duration;
95  double sum;
96 
98  int restart;
99  int64_t next_pts;
100 
102  void (*update)(struct SilenceRemoveContext *s, AVFrame *frame, int ch, int offset);
103  double (*compute)(struct SilenceRemoveContext *s, AVFrame *frame, int ch, int offset);
104  void (*copy)(struct SilenceRemoveContext *s, AVFrame *out, AVFrame *in,
105  int ch, int out_offset, int in_offset);
106 
109 
110 #define OFFSET(x) offsetof(SilenceRemoveContext, x)
111 #define AF AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM
112 
113 static const AVOption silenceremove_options[] = {
114  { "start_periods", "set periods of silence parts to skip from start", OFFSET(start_periods), AV_OPT_TYPE_INT, {.i64=0}, 0, 9000, AF },
115  { "start_duration", "set start duration of non-silence part", OFFSET(start_duration_opt), AV_OPT_TYPE_DURATION, {.i64=0}, 0, INT32_MAX, AF },
116  { "start_threshold", "set threshold for start silence detection", OFFSET(start_threshold), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, DBL_MAX, AF },
117  { "start_silence", "set start duration of silence part to keep", OFFSET(start_silence_opt), AV_OPT_TYPE_DURATION, {.i64=0}, 0, INT32_MAX, AF },
118  { "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" },
119  { "any", 0, 0, AV_OPT_TYPE_CONST, {.i64=T_ANY}, 0, 0, AF, "mode" },
120  { "all", 0, 0, AV_OPT_TYPE_CONST, {.i64=T_ALL}, 0, 0, AF, "mode" },
121  { "stop_periods", "set periods of silence parts to skip from end", OFFSET(stop_periods), AV_OPT_TYPE_INT, {.i64=0}, -9000, 9000, AF },
122  { "stop_duration", "set stop duration of non-silence part", OFFSET(stop_duration_opt), AV_OPT_TYPE_DURATION, {.i64=0}, 0, INT32_MAX, AF },
123  { "stop_threshold", "set threshold for stop silence detection", OFFSET(stop_threshold), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, DBL_MAX, AF },
124  { "stop_silence", "set stop duration of silence part to keep", OFFSET(stop_silence_opt), AV_OPT_TYPE_DURATION, {.i64=0}, 0, INT32_MAX, AF },
125  { "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" },
126  { "detection", "set how silence is detected", OFFSET(detection), AV_OPT_TYPE_INT, {.i64=D_RMS}, D_PEAK,D_RMS, AF, "detection" },
127  { "peak", "use absolute values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_PEAK},0, 0, AF, "detection" },
128  { "rms", "use squared values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_RMS}, 0, 0, AF, "detection" },
129  { "window", "set duration of window for silence detection", OFFSET(window_duration_opt), AV_OPT_TYPE_DURATION, {.i64=20000}, 0, 100000000, AF },
130  { NULL }
131 };
132 
133 AVFILTER_DEFINE_CLASS(silenceremove);
134 
136  int ch, int out_offset, int in_offset)
137 {
138  const double *srcp = (const double *)in->data[0];
139  const double src = srcp[in->channels * in_offset + ch];
140  double *dstp = (double *)out->data[0];
141 
142  dstp[out->channels * out_offset + ch] = src;
143 }
144 
146  int ch, int out_offset, int in_offset)
147 {
148  const double *srcp = (const double *)in->extended_data[ch];
149  const double src = srcp[in_offset];
150  double *dstp = (double *)out->extended_data[ch];
151 
152  dstp[out_offset] = src;
153 }
154 
156  int ch, int out_offset, int in_offset)
157 {
158  const float *srcp = (const float *)in->data[0];
159  const float src = srcp[in->channels * in_offset + ch];
160  float *dstp = (float *)out->data[0];
161 
162  dstp[out->channels * out_offset + ch] = src;
163 }
164 
166  int ch, int out_offset, int in_offset)
167 {
168  const float *srcp = (const float *)in->extended_data[ch];
169  const float src = srcp[in_offset];
170  float *dstp = (float *)out->extended_data[ch];
171 
172  dstp[out_offset] = src;
173 }
174 
176 {
177  const double *samples = (const double *)frame->data[0];
178  const double *wsamples = (const double *)s->window->data[0];
179  double sample = samples[frame->channels * offset + ch];
180  double wsample = wsamples[frame->channels * s->window_offset + ch];
181  double new_sum;
182 
183  new_sum = s->sum;
184  new_sum -= wsample;
185  new_sum = fmax(new_sum, 0.);
186  new_sum += fabs(sample);
187 
188  return new_sum / s->window_duration;
189 }
190 
192 {
193  const double *samples = (const double *)frame->data[0];
194  double *wsamples = (double *)s->window->data[0];
195  double sample = samples[frame->channels * offset + ch];
196  double *wsample = &wsamples[frame->channels * s->window_offset + ch];
197 
198  s->sum -= *wsample;
199  s->sum = fmax(s->sum, 0.);
200  *wsample = fabs(sample);
201  s->sum += *wsample;
202 }
203 
205 {
206  const float *samples = (const float *)frame->data[0];
207  const float *wsamples = (const float *)s->window->data[0];
208  float sample = samples[frame->channels * offset + ch];
209  float wsample = wsamples[frame->channels * s->window_offset + ch];
210  float new_sum;
211 
212  new_sum = s->sum;
213  new_sum -= wsample;
214  new_sum = fmaxf(new_sum, 0.f);
215  new_sum += fabsf(sample);
216 
217  return new_sum / s->window_duration;
218 }
219 
221 {
222  const float *samples = (const float *)frame->data[0];
223  float *wsamples = (float *)s->window->data[0];
224  float sample = samples[frame->channels * offset + ch];
225  float *wsample = &wsamples[frame->channels * s->window_offset + ch];
226 
227  s->sum -= *wsample;
228  s->sum = fmaxf(s->sum, 0.f);
229  *wsample = fabsf(sample);
230  s->sum += *wsample;
231 }
232 
234 {
235  const double *samples = (const double *)frame->data[0];
236  const double *wsamples = (const double *)s->window->data[0];
237  double sample = samples[frame->channels * offset + ch];
238  double wsample = wsamples[frame->channels * s->window_offset + ch];
239  double new_sum;
240 
241  new_sum = s->sum;
242  new_sum -= wsample;
243  new_sum = fmax(new_sum, 0.);
244  new_sum += sample * sample;
245 
246  av_assert2(new_sum >= 0.);
247  return sqrt(new_sum / s->window_duration);
248 }
249 
251 {
252  const double *samples = (const double *)frame->data[0];
253  double *wsamples = (double *)s->window->data[0];
254  double sample = samples[frame->channels * offset + ch];
255  double *wsample = &wsamples[frame->channels * s->window_offset + ch];
256 
257  s->sum -= *wsample;
258  s->sum = fmax(s->sum, 0.);
259  *wsample = sample * sample;
260  s->sum += *wsample;
261 }
262 
264 {
265  const float *samples = (const float *)frame->data[0];
266  const float *wsamples = (const float *)s->window->data[0];
267  float sample = samples[frame->channels * offset + ch];
268  float wsample = wsamples[frame->channels * s->window_offset + ch];
269  float new_sum;
270 
271  new_sum = s->sum;
272  new_sum -= wsample;
273  new_sum = fmaxf(new_sum, 0.f);
274  new_sum += sample * sample;
275 
276  av_assert2(new_sum >= 0.f);
277  return sqrtf(new_sum / s->window_duration);
278 }
279 
281 {
282  const float *samples = (const float *)frame->data[0];
283  float sample = samples[frame->channels * offset + ch];
284  float *wsamples = (float *)s->window->data[0];
285  float *wsample = &wsamples[frame->channels * s->window_offset + ch];
286 
287  s->sum -= *wsample;
288  s->sum = fmaxf(s->sum, 0.f);
289  *wsample = sample * sample;
290  s->sum += *wsample;
291 }
292 
294 {
295  const double *samples = (const double *)frame->extended_data[ch];
296  const double *wsamples = (const double *)s->window->extended_data[ch];
297  double sample = samples[offset];
298  double wsample = wsamples[s->window_offset];
299  double new_sum;
300 
301  new_sum = s->sum;
302  new_sum -= wsample;
303  new_sum = fmax(new_sum, 0.);
304  new_sum += fabs(sample);
305 
306  return new_sum / s->window_duration;
307 }
308 
310 {
311  const double *samples = (const double *)frame->extended_data[ch];
312  double *wsamples = (double *)s->window->extended_data[ch];
313  double sample = samples[offset];
314  double *wsample = &wsamples[s->window_offset];
315 
316  s->sum -= *wsample;
317  s->sum = fmax(s->sum, 0.);
318  *wsample = fabs(sample);
319  s->sum += *wsample;
320 }
321 
323 {
324  const float *samples = (const float *)frame->extended_data[ch];
325  const float *wsamples = (const float *)s->window->extended_data[ch];
326  float sample = samples[offset];
327  float wsample = wsamples[s->window_offset];
328  float new_sum;
329 
330  new_sum = s->sum;
331  new_sum -= wsample;
332  new_sum = fmaxf(new_sum, 0.f);
333  new_sum += fabsf(sample);
334 
335  return new_sum / s->window_duration;
336 }
337 
339 {
340  const float *samples = (const float *)frame->extended_data[ch];
341  float *wsamples = (float *)s->window->extended_data[ch];
342  float sample = samples[offset];
343  float *wsample = &wsamples[s->window_offset];
344 
345  s->sum -= *wsample;
346  s->sum = fmaxf(s->sum, 0.f);
347  *wsample = fabsf(sample);
348  s->sum += *wsample;
349 }
350 
352 {
353  const double *samples = (const double *)frame->extended_data[ch];
354  const double *wsamples = (const double *)s->window->extended_data[ch];
355  double sample = samples[offset];
356  double wsample = wsamples[s->window_offset];
357  double new_sum;
358 
359  new_sum = s->sum;
360  new_sum -= wsample;
361  new_sum = fmax(new_sum, 0.);
362  new_sum += sample * sample;
363 
364  av_assert2(new_sum >= 0.);
365  return sqrt(new_sum / s->window_duration);
366 }
367 
369 {
370  const double *samples = (const double *)frame->extended_data[ch];
371  double *wsamples = (double *)s->window->extended_data[ch];
372  double sample = samples[offset];
373  double *wsample = &wsamples[s->window_offset];
374 
375  s->sum -= *wsample;
376  s->sum = fmax(s->sum, 0.);
377  *wsample = sample * sample;
378  s->sum += *wsample;
379 }
380 
382 {
383  const float *samples = (const float *)frame->extended_data[ch];
384  const float *wsamples = (const float *)s->window->extended_data[ch];
385  float sample = samples[offset];
386  float wsample = wsamples[s->window_offset];
387  float new_sum;
388 
389  new_sum = s->sum;
390  new_sum -= wsample;
391  new_sum = fmaxf(new_sum, 0.f);
392  new_sum += sample * sample;
393 
394  av_assert2(new_sum >= 0.f);
395  return sqrtf(new_sum / s->window_duration);
396 }
397 
399 {
400  const float *samples = (const float *)frame->extended_data[ch];
401  float *wsamples = (float *)s->window->extended_data[ch];
402  float sample = samples[offset];
403  float *wsample = &wsamples[s->window_offset];
404 
405  s->sum -= *wsample;
406  s->sum = fmaxf(s->sum, 0.f);
407  *wsample = sample * sample;
408  s->sum += *wsample;
409 }
410 
412 {
413  SilenceRemoveContext *s = ctx->priv;
414 
415  if (s->stop_periods < 0) {
416  s->stop_periods = -s->stop_periods;
417  s->restart = 1;
418  }
419 
420  return 0;
421 }
422 
424 {
425  av_samples_set_silence(s->window->extended_data, 0, s->window_duration,
426  s->window->channels, s->window->format);
427 
428  s->window_offset = 0;
429  s->sum = 0;
430 }
431 
433 {
434  AVFilterContext *ctx = inlink->dst;
435  SilenceRemoveContext *s = ctx->priv;
436 
437  s->next_pts = AV_NOPTS_VALUE;
438  s->window_duration = av_rescale(s->window_duration_opt, inlink->sample_rate,
439  AV_TIME_BASE);
440  s->window_duration = FFMAX(1, s->window_duration);
441  s->window = ff_get_audio_buffer(ctx->outputs[0], s->window_duration);
442  if (!s->window)
443  return AVERROR(ENOMEM);
444 
445  clear_window(s);
446 
447  s->start_duration = av_rescale(s->start_duration_opt, inlink->sample_rate,
448  AV_TIME_BASE);
449  s->start_silence = av_rescale(s->start_silence_opt, inlink->sample_rate,
450  AV_TIME_BASE);
451  s->stop_duration = av_rescale(s->stop_duration_opt, inlink->sample_rate,
452  AV_TIME_BASE);
453  s->stop_silence = av_rescale(s->stop_silence_opt, inlink->sample_rate,
454  AV_TIME_BASE);
455 
456  s->start_holdoff = ff_get_audio_buffer(ctx->outputs[0],
457  FFMAX(s->start_duration, 1));
458  if (!s->start_holdoff)
459  return AVERROR(ENOMEM);
460 
461  s->start_silence_hold = ff_get_audio_buffer(ctx->outputs[0],
462  FFMAX(s->start_silence, 1));
463  if (!s->start_silence_hold)
464  return AVERROR(ENOMEM);
465 
466  s->start_holdoff_offset = 0;
467  s->start_holdoff_end = 0;
468  s->start_found_periods = 0;
469 
470  s->stop_holdoff = ff_get_audio_buffer(ctx->outputs[0],
471  FFMAX(s->stop_duration, 1));
472  if (!s->stop_holdoff)
473  return AVERROR(ENOMEM);
474 
475  s->stop_silence_hold = ff_get_audio_buffer(ctx->outputs[0],
476  FFMAX(s->stop_silence, 1));
477  if (!s->stop_silence_hold)
478  return AVERROR(ENOMEM);
479 
480  s->stop_holdoff_offset = 0;
481  s->stop_holdoff_end = 0;
482  s->stop_found_periods = 0;
483 
484  if (s->start_periods)
485  s->mode = SILENCE_TRIM;
486  else
487  s->mode = SILENCE_COPY;
488 
489  switch (inlink->format) {
490  case AV_SAMPLE_FMT_DBL:
491  s->copy = copy_double;
492  switch (s->detection) {
493  case D_PEAK:
494  s->update = update_peak_double;
495  s->compute = compute_peak_double;
496  break;
497  case D_RMS:
498  s->update = update_rms_double;
499  s->compute = compute_rms_double;
500  break;
501  }
502  break;
503  case AV_SAMPLE_FMT_FLT:
504  s->copy = copy_float;
505  switch (s->detection) {
506  case D_PEAK:
507  s->update = update_peak_float;
508  s->compute = compute_peak_float;
509  break;
510  case D_RMS:
511  s->update = update_rms_float;
512  s->compute = compute_rms_float;
513  break;
514  }
515  break;
516  case AV_SAMPLE_FMT_DBLP:
517  s->copy = copy_doublep;
518  switch (s->detection) {
519  case D_PEAK:
520  s->update = update_peak_doublep;
521  s->compute = compute_peak_doublep;
522  break;
523  case D_RMS:
524  s->update = update_rms_doublep;
525  s->compute = compute_rms_doublep;
526  break;
527  }
528  break;
529  case AV_SAMPLE_FMT_FLTP:
530  s->copy = copy_floatp;
531  switch (s->detection) {
532  case D_PEAK:
533  s->update = update_peak_floatp;
534  s->compute = compute_peak_floatp;
535  break;
536  case D_RMS:
537  s->update = update_rms_floatp;
538  s->compute = compute_rms_floatp;
539  break;
540  }
541  break;
542  default:
543  return AVERROR_BUG;
544  }
545 
546  s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, 1024);
547  if (!s->fifo)
548  return AVERROR(ENOMEM);
549 
550  return 0;
551 }
552 
554  AVFrame *out, AVFilterLink *outlink,
555  int *nb_samples_written, int flush_silence)
556 {
557  AVFrame *silence;
558 
559  if (*nb_samples_written) {
560  out->nb_samples = *nb_samples_written;
561 
562  av_audio_fifo_write(s->fifo, (void **)out->extended_data, out->nb_samples);
563  *nb_samples_written = 0;
564  }
565 
566  av_frame_free(&out);
567 
568  if (s->stop_silence_end <= 0 || !flush_silence)
569  return;
570 
571  silence = ff_get_audio_buffer(outlink, s->stop_silence_end);
572  if (!silence)
573  return;
574 
575  if (s->stop_silence_offset < s->stop_silence_end) {
576  av_samples_copy(silence->extended_data, s->stop_silence_hold->extended_data, 0,
577  s->stop_silence_offset,
578  s->stop_silence_end - s->stop_silence_offset,
579  outlink->channels, outlink->format);
580  }
581 
582  if (s->stop_silence_offset > 0) {
583  av_samples_copy(silence->extended_data, s->stop_silence_hold->extended_data,
584  s->stop_silence_end - s->stop_silence_offset,
585  0, s->stop_silence_offset,
586  outlink->channels, outlink->format);
587  }
588 
589  s->stop_silence_offset = 0;
590  s->stop_silence_end = 0;
591 
592  av_audio_fifo_write(s->fifo, (void **)silence->extended_data, silence->nb_samples);
593  av_frame_free(&silence);
594 }
595 
597 {
598  AVFilterContext *ctx = inlink->dst;
599  AVFilterLink *outlink = ctx->outputs[0];
600  SilenceRemoveContext *s = ctx->priv;
601  int nbs, nb_samples_read, nb_samples_written;
602  int i, j, threshold, ret = 0;
603  AVFrame *out;
604 
605  nb_samples_read = nb_samples_written = 0;
606 
607  if (s->next_pts == AV_NOPTS_VALUE)
608  s->next_pts = in->pts;
609 
610  switch (s->mode) {
611  case SILENCE_TRIM:
612 silence_trim:
613  nbs = in->nb_samples - nb_samples_read;
614  if (!nbs)
615  break;
616 
617  for (i = 0; i < nbs; i++) {
618  if (s->start_mode == T_ANY) {
619  threshold = 0;
620  for (j = 0; j < outlink->channels; j++) {
621  threshold |= s->compute(s, in, j, nb_samples_read) > s->start_threshold;
622  }
623  } else {
624  threshold = 1;
625  for (j = 0; j < outlink->channels; j++) {
626  threshold &= s->compute(s, in, j, nb_samples_read) > s->start_threshold;
627  }
628  }
629 
630  if (threshold) {
631  for (j = 0; j < outlink->channels; j++) {
632  s->update(s, in, j, nb_samples_read);
633  s->copy(s, s->start_holdoff, in, j, s->start_holdoff_end, nb_samples_read);
634  }
635 
636  s->window_offset++;
637  if (s->window_offset >= s->window_duration)
638  s->window_offset = 0;
639  s->start_holdoff_end++;
640  nb_samples_read++;
641 
642  if (s->start_holdoff_end >= s->start_duration) {
643  s->start_found_periods += s->one_period >= 1;
644  s->one_period = 0;
645  if (s->start_found_periods >= s->start_periods) {
646  s->mode = SILENCE_TRIM_FLUSH;
647  goto silence_trim_flush;
648  }
649 
650  s->start_holdoff_offset = 0;
651  s->start_holdoff_end = 0;
652  s->start_silence_offset = 0;
653  s->start_silence_end = 0;
654  }
655  } else {
656  s->start_holdoff_end = 0;
657  s->one_period++;
658 
659  for (j = 0; j < outlink->channels; j++) {
660  s->update(s, in, j, nb_samples_read);
661  if (s->start_silence)
662  s->copy(s, s->start_silence_hold, in, j, s->start_silence_offset, nb_samples_read);
663  }
664 
665  s->window_offset++;
666  if (s->window_offset >= s->window_duration)
667  s->window_offset = 0;
668  nb_samples_read++;
669  s->start_silence_offset++;
670 
671  if (s->start_silence) {
672  s->start_silence_end = FFMIN(s->start_silence_end + 1, s->start_silence);
673  if (s->start_silence_offset >= s->start_silence)
674  s->start_silence_offset = 0;
675  }
676  }
677  }
678  break;
679 
680  case SILENCE_TRIM_FLUSH:
681 silence_trim_flush:
682  nbs = s->start_holdoff_end - s->start_holdoff_offset;
683  if (!nbs)
684  break;
685 
686  out = ff_get_audio_buffer(outlink, nbs + s->start_silence_end);
687  if (!out) {
688  av_frame_free(&in);
689  return AVERROR(ENOMEM);
690  }
691 
692  if (s->start_silence_end > 0) {
693  if (s->start_silence_offset < s->start_silence_end) {
694  av_samples_copy(out->extended_data, s->start_silence_hold->extended_data, 0,
695  s->start_silence_offset,
696  s->start_silence_end - s->start_silence_offset,
697  outlink->channels, outlink->format);
698  }
699 
700  if (s->start_silence_offset > 0) {
701  av_samples_copy(out->extended_data, s->start_silence_hold->extended_data,
702  s->start_silence_end - s->start_silence_offset,
703  0, s->start_silence_offset,
704  outlink->channels, outlink->format);
705  }
706  }
707 
708  av_samples_copy(out->extended_data, s->start_holdoff->extended_data,
709  s->start_silence_end,
710  s->start_holdoff_offset, nbs,
711  outlink->channels, outlink->format);
712 
713  s->start_holdoff_offset += nbs;
714 
715  av_audio_fifo_write(s->fifo, (void **)out->extended_data, out->nb_samples);
716  av_frame_free(&out);
717 
718  if (s->start_holdoff_offset == s->start_holdoff_end) {
719  s->start_holdoff_offset = 0;
720  s->start_holdoff_end = 0;
721  s->start_silence_offset = 0;
722  s->start_silence_end = 0;
723  s->mode = SILENCE_COPY;
724  goto silence_copy;
725  }
726  break;
727 
728  case SILENCE_COPY:
729 silence_copy:
730  nbs = in->nb_samples - nb_samples_read;
731  if (!nbs)
732  break;
733 
734  out = ff_get_audio_buffer(outlink, nbs);
735  if (!out) {
736  av_frame_free(&in);
737  return AVERROR(ENOMEM);
738  }
739 
740  if (s->stop_periods) {
741  for (i = 0; i < nbs; i++) {
742  if (s->stop_mode == T_ANY) {
743  threshold = 0;
744  for (j = 0; j < outlink->channels; j++) {
745  threshold |= s->compute(s, in, j, nb_samples_read) > s->stop_threshold;
746  }
747  } else {
748  threshold = 1;
749  for (j = 0; j < outlink->channels; j++) {
750  threshold &= s->compute(s, in, j, nb_samples_read) > s->stop_threshold;
751  }
752  }
753 
754  if (threshold && s->stop_holdoff_end && !s->stop_silence) {
755  s->mode = SILENCE_COPY_FLUSH;
756  flush(s, out, outlink, &nb_samples_written, 0);
757  s->one_period++;
758  goto silence_copy_flush;
759  } else if (threshold) {
760  for (j = 0; j < outlink->channels; j++) {
761  s->update(s, in, j, nb_samples_read);
762  s->copy(s, out, in, j, nb_samples_written, nb_samples_read);
763  }
764 
765  s->window_offset++;
766  if (s->window_offset >= s->window_duration)
767  s->window_offset = 0;
768  nb_samples_read++;
769  nb_samples_written++;
770  s->one_period++;
771  } else if (!threshold) {
772  for (j = 0; j < outlink->channels; j++) {
773  s->update(s, in, j, nb_samples_read);
774  if (s->stop_silence)
775  s->copy(s, s->stop_silence_hold, in, j, s->stop_silence_offset, nb_samples_read);
776 
777  s->copy(s, s->stop_holdoff, in, j, s->stop_holdoff_end, nb_samples_read);
778  }
779 
780  if (s->stop_silence) {
781  s->stop_silence_offset++;
782  s->stop_silence_end = FFMIN(s->stop_silence_end + 1, s->stop_silence);
783  if (s->stop_silence_offset >= s->stop_silence) {
784  s->stop_silence_offset = 0;
785  }
786  }
787 
788  s->window_offset++;
789  if (s->window_offset >= s->window_duration)
790  s->window_offset = 0;
791  nb_samples_read++;
792  s->stop_holdoff_end++;
793 
794  if (s->stop_holdoff_end >= s->stop_duration) {
795  s->stop_found_periods += s->one_period >= 1;
796  s->one_period = 0;
797  if (s->stop_found_periods >= s->stop_periods) {
798  s->stop_holdoff_offset = 0;
799  s->stop_holdoff_end = 0;
800 
801  if (!s->restart) {
802  s->mode = SILENCE_STOP;
803  flush(s, out, outlink, &nb_samples_written, 1);
804  goto silence_stop;
805  } else {
806  s->stop_found_periods = 0;
807  s->start_found_periods = 0;
808  s->start_holdoff_offset = 0;
809  s->start_holdoff_end = 0;
810  s->start_silence_offset = 0;
811  s->start_silence_end = 0;
812  clear_window(s);
813  s->mode = SILENCE_TRIM;
814  flush(s, out, outlink, &nb_samples_written, 1);
815  goto silence_trim;
816  }
817  }
818  s->mode = SILENCE_COPY_FLUSH;
819  flush(s, out, outlink, &nb_samples_written, 0);
820  goto silence_copy_flush;
821  }
822  }
823  }
824  s->one_period++;
825  flush(s, out, outlink, &nb_samples_written, 0);
826  } else {
827  av_samples_copy(out->extended_data, in->extended_data,
828  nb_samples_written,
829  nb_samples_read, nbs,
830  outlink->channels, outlink->format);
831 
832  av_audio_fifo_write(s->fifo, (void **)out->extended_data, out->nb_samples);
833  av_frame_free(&out);
834  }
835  break;
836 
837  case SILENCE_COPY_FLUSH:
838 silence_copy_flush:
839  nbs = s->stop_holdoff_end - s->stop_holdoff_offset;
840  if (!nbs)
841  break;
842 
843  out = ff_get_audio_buffer(outlink, nbs);
844  if (!out) {
845  av_frame_free(&in);
846  return AVERROR(ENOMEM);
847  }
848 
849  av_samples_copy(out->extended_data, s->stop_holdoff->extended_data, 0,
850  s->stop_holdoff_offset, nbs,
851  outlink->channels, outlink->format);
852 
853  s->stop_holdoff_offset += nbs;
854 
855  av_audio_fifo_write(s->fifo, (void **)out->extended_data, out->nb_samples);
856  av_frame_free(&out);
857 
858  if (s->stop_holdoff_offset == s->stop_holdoff_end) {
859  s->stop_holdoff_offset = 0;
860  s->stop_holdoff_end = 0;
861  s->stop_silence_offset = 0;
862  s->stop_silence_end = 0;
863  s->mode = SILENCE_COPY;
864  goto silence_copy;
865  }
866  break;
867  case SILENCE_STOP:
868 silence_stop:
869  break;
870  default:
871  ret = AVERROR_BUG;
872  }
873 
874  av_frame_free(&in);
875 
876  if (av_audio_fifo_size(s->fifo) > 0) {
877  out = ff_get_audio_buffer(outlink, av_audio_fifo_size(s->fifo));
878  if (!out)
879  return AVERROR(ENOMEM);
880 
881  av_audio_fifo_read(s->fifo, (void **)out->extended_data, out->nb_samples);
882  out->pts = s->next_pts;
883  s->next_pts += av_rescale_q(out->nb_samples,
884  (AVRational){1, outlink->sample_rate},
885  outlink->time_base);
886 
887  ret = ff_filter_frame(outlink, out);
888  }
889 
890  return ret;
891 }
892 
893 static int request_frame(AVFilterLink *outlink)
894 {
895  AVFilterContext *ctx = outlink->src;
896  SilenceRemoveContext *s = ctx->priv;
897  int ret;
898 
899  ret = ff_request_frame(ctx->inputs[0]);
900  if (ret == AVERROR_EOF && (s->mode == SILENCE_COPY_FLUSH ||
901  s->mode == SILENCE_COPY)) {
902  int nbs = s->stop_holdoff_end - s->stop_holdoff_offset;
903  if (nbs) {
904  AVFrame *frame;
905 
906  frame = ff_get_audio_buffer(outlink, nbs);
907  if (!frame)
908  return AVERROR(ENOMEM);
909 
910  av_samples_copy(frame->extended_data, s->stop_holdoff->extended_data, 0,
911  s->stop_holdoff_offset, nbs,
912  outlink->channels, outlink->format);
913 
914  frame->pts = s->next_pts;
915  s->next_pts += av_rescale_q(frame->nb_samples,
916  (AVRational){1, outlink->sample_rate},
917  outlink->time_base);
918 
919  ret = ff_filter_frame(outlink, frame);
920  }
921  s->mode = SILENCE_STOP;
922  }
923  return ret;
924 }
925 
927 {
928  SilenceRemoveContext *s = ctx->priv;
929 
930  av_frame_free(&s->start_holdoff);
931  av_frame_free(&s->start_silence_hold);
932  av_frame_free(&s->stop_holdoff);
933  av_frame_free(&s->stop_silence_hold);
934  av_frame_free(&s->window);
935 
936  av_audio_fifo_free(s->fifo);
937  s->fifo = NULL;
938 }
939 
941  {
942  .name = "default",
943  .type = AVMEDIA_TYPE_AUDIO,
944  .config_props = config_input,
945  .filter_frame = filter_frame,
946  },
947 };
948 
950  {
951  .name = "default",
952  .type = AVMEDIA_TYPE_AUDIO,
953  .request_frame = request_frame,
954  },
955 };
956 
958  .name = "silenceremove",
959  .description = NULL_IF_CONFIG_SMALL("Remove silence."),
960  .priv_size = sizeof(SilenceRemoveContext),
961  .priv_class = &silenceremove_class,
962  .init = init,
963  .uninit = uninit,
968 };
av_audio_fifo_free
void av_audio_fifo_free(AVAudioFifo *af)
Free an AVAudioFifo.
Definition: audio_fifo.c:45
compute_rms_double
static double compute_rms_double(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:233
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:88
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:368
SilenceRemoveContext::fifo
AVAudioFifo * fifo
Definition: af_silenceremove.c:107
update_rms_float
static void update_rms_float(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:280
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
out
FILE * out
Definition: movenc.c:54
SilenceRemoveContext::stop_silence_offset
size_t stop_silence_offset
Definition: af_silenceremove.c:88
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1018
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
init
static av_cold int init(AVFilterContext *ctx)
Definition: af_silenceremove.c:411
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
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:109
SilenceRemoveContext::start_holdoff_offset
size_t start_holdoff_offset
Definition: af_silenceremove.c:78
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:317
request_frame
static int request_frame(AVFilterLink *outlink)
Definition: af_silenceremove.c:893
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:424
SilenceDetect
SilenceDetect
Definition: af_silenceremove.c:35
SilenceRemoveContext::stop_silence_hold
AVFrame * stop_silence_hold
Definition: af_silenceremove.c:85
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:420
silenceremove_inputs
static const AVFilterPad silenceremove_inputs[]
Definition: af_silenceremove.c:940
SilenceRemoveContext::start_duration_opt
int64_t start_duration_opt
Definition: af_silenceremove.c:60
float.h
update_peak_float
static void update_peak_float(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:220
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:169
SilenceRemoveContext::start_silence_opt
int64_t start_silence_opt
Definition: af_silenceremove.c:63
SilenceRemoveContext::stop_silence
int64_t stop_silence
Definition: af_silenceremove.c:70
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:338
formats.h
compute_rms_float
static double compute_rms_float(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:263
AVAudioFifo
Context for an Audio FIFO Buffer.
Definition: audio_fifo.c:34
SilenceRemoveContext::detection
int detection
Definition: af_silenceremove.c:101
SilenceRemoveContext::window_offset
int window_offset
Definition: af_silenceremove.c:93
copy_floatp
static void copy_floatp(SilenceRemoveContext *s, AVFrame *out, AVFrame *in, int ch, int out_offset, int in_offset)
Definition: af_silenceremove.c:165
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:322
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:50
compute_peak_doublep
static double compute_peak_doublep(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:293
avassert.h
av_cold
#define av_cold
Definition: attributes.h:90
s
#define s(width, name)
Definition: cbs_vp9.c:257
flush
static void flush(SilenceRemoveContext *s, AVFrame *out, AVFilterLink *outlink, int *nb_samples_written, int flush_silence)
Definition: af_silenceremove.c:553
SilenceRemoveContext::mode
enum SilenceMode mode
Definition: af_silenceremove.c:56
SILENCE_STOP
@ SILENCE_STOP
Definition: af_silenceremove.c:50
AVFrame::channels
int channels
number of audio channels, only used for audio.
Definition: frame.h:628
av_audio_fifo_write
int av_audio_fifo_write(AVAudioFifo *af, void **data, int nb_samples)
Write data to an AVAudioFifo.
Definition: audio_fifo.c:112
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:596
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:338
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:81
SilenceRemoveContext::start_silence_hold
AVFrame * start_silence_hold
Definition: af_silenceremove.c:77
compute_rms_doublep
static double compute_rms_doublep(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:351
f
#define f(width, name)
Definition: cbs_vp9.c:255
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:191
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:175
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
av_audio_fifo_alloc
AVAudioFifo * av_audio_fifo_alloc(enum AVSampleFormat sample_fmt, int channels, int nb_samples)
Allocate an AVAudioFifo.
Definition: audio_fifo.c:59
SilenceRemoveContext::stop_holdoff
AVFrame * stop_holdoff
Definition: af_silenceremove.c:84
src
#define src
Definition: vp8dsp.c:255
SilenceRemoveContext::start_silence_offset
size_t start_silence_offset
Definition: af_silenceremove.c:80
SilenceRemoveContext
Definition: af_silenceremove.c:53
SilenceRemoveContext::one_period
int one_period
Definition: af_silenceremove.c:97
SILENCE_TRIM
@ SILENCE_TRIM
Definition: af_silenceremove.c:46
SilenceRemoveContext::start_threshold
double start_threshold
Definition: af_silenceremove.c:61
silenceremove_options
static const AVOption silenceremove_options[]
Definition: af_silenceremove.c:113
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_silenceremove.c:926
copy_double
static void copy_double(SilenceRemoveContext *s, AVFrame *out, AVFrame *in, int ch, int out_offset, int in_offset)
Definition: af_silenceremove.c:135
SilenceRemoveContext::window_duration_opt
int64_t window_duration_opt
Definition: af_silenceremove.c:74
SILENCE_COPY_FLUSH
@ SILENCE_COPY_FLUSH
Definition: af_silenceremove.c:49
AF
#define AF
Definition: af_silenceremove.c:111
SilenceRemoveContext::start_found_periods
int start_found_periods
Definition: af_silenceremove.c:82
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:117
config_input
static int config_input(AVFilterLink *inlink)
Definition: af_silenceremove.c:432
fmaxf
float fmaxf(float, float)
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:86
update_peak_doublep
static void update_peak_doublep(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:309
SilenceRemoveContext::stop_periods
int stop_periods
Definition: af_silenceremove.c:66
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:48
av_audio_fifo_size
int av_audio_fifo_size(AVAudioFifo *af)
Get the current number of samples in the AVAudioFifo available for reading.
Definition: audio_fifo.c:228
clear_window
static void clear_window(SilenceRemoveContext *s)
Definition: af_silenceremove.c:423
SilenceRemoveContext::sum
double sum
Definition: af_silenceremove.c:95
SILENCE_TRIM_FLUSH
@ SILENCE_TRIM_FLUSH
Definition: af_silenceremove.c:47
SilenceRemoveContext::start_holdoff_end
size_t start_holdoff_end
Definition: af_silenceremove.c:79
internal.h
av_audio_fifo_read
int av_audio_fifo_read(AVAudioFifo *af, void **data, int nb_samples)
Read data from an AVAudioFifo.
Definition: audio_fifo.c:181
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
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:64
update_rms_double
static void update_rms_double(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:250
AVFrame::nb_samples
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:397
update_peak_double
static void update_peak_double(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:191
SilenceRemoveContext::stop_silence_opt
int64_t stop_silence_opt
Definition: af_silenceremove.c:71
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
ff_af_silenceremove
const AVFilter ff_af_silenceremove
Definition: af_silenceremove.c:957
SilenceRemoveContext::stop_mode
int stop_mode
Definition: af_silenceremove.c:72
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:378
SilenceMode
SilenceMode
Definition: af_silenceremove.c:45
SilenceRemoveContext::stop_duration
int64_t stop_duration
Definition: af_silenceremove.c:67
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
audio_fifo.h
SilenceRemoveContext::stop_silence_end
size_t stop_silence_end
Definition: af_silenceremove.c:89
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:56
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:90
update_rms_floatp
static void update_rms_floatp(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:398
SilenceRemoveContext::start_mode
int start_mode
Definition: af_silenceremove.c:64
SilenceRemoveContext::update
void(* update)(struct SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:102
SilenceRemoveContext::compute
double(* compute)(struct SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:103
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:165
SilenceRemoveContext::stop_threshold
double stop_threshold
Definition: af_silenceremove.c:69
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:98
SilenceRemoveContext::window_duration
int64_t window_duration
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:204
fmax
double fmax(double, double)
D_PEAK
@ D_PEAK
Definition: af_silenceremove.c:36
OFFSET
#define OFFSET(x)
Definition: af_silenceremove.c:110
SilenceRemoveContext::window
AVFrame * window
Definition: af_silenceremove.c:92
SilenceRemoveContext::start_periods
int start_periods
Definition: af_silenceremove.c:58
copy_doublep
static void copy_doublep(SilenceRemoveContext *s, AVFrame *out, AVFrame *in, int ch, int out_offset, int in_offset)
Definition: af_silenceremove.c:145
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:402
ThresholdMode
ThresholdMode
Definition: af_silenceremove.c:40
audio.h
SilenceRemoveContext::stop_duration_opt
int64_t stop_duration_opt
Definition: af_silenceremove.c:68
SilenceRemoveContext::start_silence
int64_t start_silence
Definition: af_silenceremove.c:62
compute_rms_floatp
static double compute_rms_floatp(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset)
Definition: af_silenceremove.c:381
SilenceRemoveContext::copy
void(* copy)(struct SilenceRemoveContext *s, AVFrame *out, AVFrame *in, int ch, int out_offset, int in_offset)
Definition: af_silenceremove.c:104
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:192
silenceremove_outputs
static const AVFilterPad silenceremove_outputs[]
Definition: af_silenceremove.c:949
SilenceRemoveContext::start_holdoff
AVFrame * start_holdoff
Definition: af_silenceremove.c:76
timestamp.h
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
copy_float
static void copy_float(SilenceRemoveContext *s, AVFrame *out, AVFrame *in, int ch, int out_offset, int in_offset)
Definition: af_silenceremove.c:155
T_ALL
@ T_ALL
Definition: af_silenceremove.c:42
AV_SAMPLE_FMT_DBL
@ AV_SAMPLE_FMT_DBL
double
Definition: samplefmt.h:64
D_RMS
@ D_RMS
Definition: af_silenceremove.c:37
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:87
AV_SAMPLE_FMT_FLT
@ AV_SAMPLE_FMT_FLT
float
Definition: samplefmt.h:63
SilenceRemoveContext::start_duration
int64_t start_duration
Definition: af_silenceremove.c:59
T_ANY
@ T_ANY
Definition: af_silenceremove.c:41
FILTER_SAMPLEFMTS
#define FILTER_SAMPLEFMTS(...)
Definition: internal.h:179
SilenceRemoveContext::next_pts
int64_t next_pts
Definition: af_silenceremove.c:99