avfilter/af_silenceremove: avoid returning 1 sample duration frames

This commit is contained in:
Paul B Mahol 2021-09-08 15:15:19 +02:00
parent 3b331468da
commit 8a42ee6697
1 changed files with 38 additions and 18 deletions

View File

@ -23,6 +23,7 @@
#include <float.h> /* DBL_MAX */
#include "libavutil/audio_fifo.h"
#include "libavutil/avassert.h"
#include "libavutil/opt.h"
#include "libavutil/timestamp.h"
@ -103,6 +104,8 @@ typedef struct SilenceRemoveContext {
double (*compute)(struct SilenceRemoveContext *s, AVFrame *frame, int ch, int offset);
void (*copy)(struct SilenceRemoveContext *s, AVFrame *out, AVFrame *in,
int ch, int out_offset, int in_offset);
AVAudioFifo *fifo;
} SilenceRemoveContext;
#define OFFSET(x) offsetof(SilenceRemoveContext, x)
@ -542,12 +545,16 @@ static int config_input(AVFilterLink *inlink)
return AVERROR_BUG;
}
s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, 1024);
if (!s->fifo)
return AVERROR(ENOMEM);
return 0;
}
static void flush(SilenceRemoveContext *s,
AVFrame *out, AVFilterLink *outlink,
int *nb_samples_written, int *ret, int flush_silence)
int *nb_samples_written, int flush_silence)
{
AVFrame *silence;
@ -559,22 +566,18 @@ static void flush(SilenceRemoveContext *s,
(AVRational){1, outlink->sample_rate},
outlink->time_base);
*ret = ff_filter_frame(outlink, out);
if (*ret < 0)
return;
av_audio_fifo_write(s->fifo, (void **)out->extended_data, out->nb_samples);
*nb_samples_written = 0;
} else {
av_frame_free(&out);
}
av_frame_free(&out);
if (s->stop_silence_end <= 0 || !flush_silence)
return;
silence = ff_get_audio_buffer(outlink, s->stop_silence_end);
if (!silence) {
*ret = AVERROR(ENOMEM);
if (!silence)
return;
}
if (s->stop_silence_offset < s->stop_silence_end) {
av_samples_copy(silence->extended_data, s->stop_silence_hold->extended_data, 0,
@ -598,7 +601,8 @@ static void flush(SilenceRemoveContext *s,
(AVRational){1, outlink->sample_rate},
outlink->time_base);
*ret = ff_filter_frame(outlink, silence);
av_audio_fifo_write(s->fifo, (void **)silence->extended_data, silence->nb_samples);
av_frame_free(&silence);
}
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
@ -727,7 +731,8 @@ silence_trim_flush:
s->start_holdoff_offset += nbs;
ret = ff_filter_frame(outlink, out);
av_audio_fifo_write(s->fifo, (void **)out->extended_data, out->nb_samples);
av_frame_free(&out);
if (s->start_holdoff_offset == s->start_holdoff_end) {
s->start_holdoff_offset = 0;
@ -771,7 +776,7 @@ silence_copy:
if (threshold && s->stop_holdoff_end && !s->stop_silence) {
s->mode = SILENCE_COPY_FLUSH;
flush(s, out, outlink, &nb_samples_written, &ret, 0);
flush(s, out, outlink, &nb_samples_written, 0);
goto silence_copy_flush;
} else if (threshold) {
for (j = 0; j < outlink->channels; j++) {
@ -812,7 +817,7 @@ silence_copy:
if (!s->restart) {
s->mode = SILENCE_STOP;
flush(s, out, outlink, &nb_samples_written, &ret, 1);
flush(s, out, outlink, &nb_samples_written, 1);
goto silence_stop;
} else {
s->stop_found_periods = 0;
@ -823,17 +828,17 @@ silence_copy:
s->start_silence_end = 0;
clear_window(s);
s->mode = SILENCE_TRIM;
flush(s, out, outlink, &nb_samples_written, &ret, 1);
flush(s, out, outlink, &nb_samples_written, 1);
goto silence_trim;
}
}
s->mode = SILENCE_COPY_FLUSH;
flush(s, out, outlink, &nb_samples_written, &ret, 0);
flush(s, out, outlink, &nb_samples_written, 0);
goto silence_copy_flush;
}
}
}
flush(s, out, outlink, &nb_samples_written, &ret, 0);
flush(s, out, outlink, &nb_samples_written, 0);
} else {
av_samples_copy(out->extended_data, in->extended_data,
nb_samples_written,
@ -845,7 +850,8 @@ silence_copy:
(AVRational){1, outlink->sample_rate},
outlink->time_base);
ret = ff_filter_frame(outlink, out);
av_audio_fifo_write(s->fifo, (void **)out->extended_data, out->nb_samples);
av_frame_free(&out);
}
break;
@ -872,7 +878,8 @@ silence_copy_flush:
(AVRational){1, outlink->sample_rate},
outlink->time_base);
ret = ff_filter_frame(outlink, out);
av_audio_fifo_write(s->fifo, (void **)out->extended_data, out->nb_samples);
av_frame_free(&out);
if (s->stop_holdoff_offset == s->stop_holdoff_end) {
s->stop_holdoff_offset = 0;
@ -892,6 +899,16 @@ silence_stop:
av_frame_free(&in);
if (av_audio_fifo_size(s->fifo) > 0) {
out = ff_get_audio_buffer(outlink, av_audio_fifo_size(s->fifo));
if (!out)
return AVERROR(ENOMEM);
av_audio_fifo_read(s->fifo, (void **)out->extended_data, out->nb_samples);
out->pts = s->next_pts;
ret = ff_filter_frame(outlink, out);
}
return ret;
}
@ -955,6 +972,9 @@ static av_cold void uninit(AVFilterContext *ctx)
av_frame_free(&s->stop_holdoff);
av_frame_free(&s->stop_silence_hold);
av_frame_free(&s->window);
av_audio_fifo_free(s->fifo);
s->fifo = NULL;
}
static const AVFilterPad silenceremove_inputs[] = {