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