avfilter/af_silenceremove: avoid returning 1 sample duration frames
This commit is contained in:
parent
3b331468da
commit
8a42ee6697
@ -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[] = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user