Unified · Split
| @@ -23,6 +23,7 @@ · 22 unmodified lines | |||
| 23 | 23 | ||
| 24 | #include <float.h> /* DBL_MAX */ | 24 | #include <float.h> /* DBL_MAX */ |
| 25 | 25 | ||
| 26 | #include "libavutil/audio_fifo.h" | ||
| 26 | #include "libavutil/avassert.h" | 27 | #include "libavutil/avassert.h" |
| 27 | #include "libavutil/opt.h" | 28 | #include "libavutil/opt.h" |
| 28 | #include "libavutil/timestamp.h" | 29 | #include "libavutil/timestamp.h" |
| @@ -103,6 +104,8 @@ typedef struct SilenceRemoveContext { · 74 unmodified lines | |||
| 103 | double (*compute)(struct SilenceRemoveContext *s, AVFrame *frame, int ch, int offset); | 104 | double (*compute)(struct SilenceRemoveContext *s, AVFrame *frame, int ch, int offset); |
| 104 | void (*copy)(struct SilenceRemoveContext *s, AVFrame *out, AVFrame *in, | 105 | void (*copy)(struct SilenceRemoveContext *s, AVFrame *out, AVFrame *in, |
| 105 | int ch, int out_offset, int in_offset); | 106 | int ch, int out_offset, int in_offset); |
| 107 | |||
| 108 | AVAudioFifo *fifo; | ||
| 106 | } SilenceRemoveContext; | 109 | } SilenceRemoveContext; |
| 107 | 110 | ||
| 108 | #define OFFSET(x) offsetof(SilenceRemoveContext, x) | 111 | #define OFFSET(x) offsetof(SilenceRemoveContext, x) |
| @@ -542,12 +545,16 @@ static int config_input(AVFilterLink *inlink) · 433 unmodified lines | |||
| 542 | return AVERROR_BUG; | 545 | return AVERROR_BUG; |
| 543 | } | 546 | } |
| 544 | 547 | ||
| 548 | s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, 1024); | ||
| 549 | if (!s->fifo) | ||
| 550 | return AVERROR(ENOMEM); | ||
| 551 | |||
| 545 | return 0; | 552 | return 0; |
| 546 | } | 553 | } |
| 547 | 554 | ||
| 548 | static void flush(SilenceRemoveContext *s, | 555 | static void flush(SilenceRemoveContext *s, |
| 549 | AVFrame *out, AVFilterLink *outlink, | 556 | AVFrame *out, AVFilterLink *outlink, |
| 550 | int *nb_samples_written, int *ret, int flush_silence) | 557 | int *nb_samples_written, int flush_silence) |
| 551 | { | 558 | { |
| 552 | AVFrame *silence; | 559 | AVFrame *silence; |
| 553 | 560 | ||
| @@ -559,22 +566,18 @@ static void flush(SilenceRemoveContext *s, · 5 unmodified lines | |||
| 559 | (AVRational){1, outlink->sample_rate}, | 566 | (AVRational){1, outlink->sample_rate}, |
| 560 | outlink->time_base); | 567 | outlink->time_base); |
| 561 | 568 | ||
| 562 | *ret = ff_filter_frame(outlink, out); | 569 | av_audio_fifo_write(s->fifo, (void **)out->extended_data, out->nb_samples); |
| 563 | if (*ret < 0) | ||
| 564 | return; | ||
| 565 | *nb_samples_written = 0; | 570 | *nb_samples_written = 0; |
| 566 | } else { | ||
| 567 | av_frame_free(&out); | ||
| 568 | } | 571 | } |
| 569 | 572 | ||
| 573 | av_frame_free(&out); | ||
| 574 | |||
| 570 | if (s->stop_silence_end <= 0 || !flush_silence) | 575 | if (s->stop_silence_end <= 0 || !flush_silence) |
| 571 | return; | 576 | return; |
| 572 | 577 | ||
| 573 | silence = ff_get_audio_buffer(outlink, s->stop_silence_end); | 578 | silence = ff_get_audio_buffer(outlink, s->stop_silence_end); |
| 574 | if (!silence) { | 579 | if (!silence) |
| 575 | *ret = AVERROR(ENOMEM); | ||
| 576 | return; | 580 | return; |
| 577 | } | ||
| 578 | 581 | ||
| 579 | if (s->stop_silence_offset < s->stop_silence_end) { | 582 | if (s->stop_silence_offset < s->stop_silence_end) { |
| 580 | av_samples_copy(silence->extended_data, s->stop_silence_hold->extended_data, 0, | 583 | av_samples_copy(silence->extended_data, s->stop_silence_hold->extended_data, 0, |
| @@ -598,7 +601,8 @@ static void flush(SilenceRemoveContext *s, · 17 unmodified lines | |||
| 598 | (AVRational){1, outlink->sample_rate}, | 601 | (AVRational){1, outlink->sample_rate}, |
| 599 | outlink->time_base); | 602 | outlink->time_base); |
| 600 | 603 | ||
| 601 | *ret = ff_filter_frame(outlink, silence); | 604 | av_audio_fifo_write(s->fifo, (void **)silence->extended_data, silence->nb_samples); |
| 605 | av_frame_free(&silence); | ||
| 602 | } | 606 | } |
| 603 | 607 | ||
| 604 | static int filter_frame(AVFilterLink *inlink, AVFrame *in) | 608 | static int filter_frame(AVFilterLink *inlink, AVFrame *in) |
| @@ -727,7 +731,8 @@ silence_trim_flush: · 122 unmodified lines | |||
| 727 | 731 | ||
| 728 | s->start_holdoff_offset += nbs; | 732 | s->start_holdoff_offset += nbs; |
| 729 | 733 | ||
| 730 | ret = ff_filter_frame(outlink, out); | 734 | av_audio_fifo_write(s->fifo, (void **)out->extended_data, out->nb_samples); |
| 735 | av_frame_free(&out); | ||
| 731 | 736 | ||
| 732 | if (s->start_holdoff_offset == s->start_holdoff_end) { | 737 | if (s->start_holdoff_offset == s->start_holdoff_end) { |
| 733 | s->start_holdoff_offset = 0; | 738 | s->start_holdoff_offset = 0; |
| @@ -771,7 +776,7 @@ silence_copy: · 37 unmodified lines | |||
| 771 | 776 | ||
| 772 | if (threshold && s->stop_holdoff_end && !s->stop_silence) { | 777 | if (threshold && s->stop_holdoff_end && !s->stop_silence) { |
| 773 | s->mode = SILENCE_COPY_FLUSH; | 778 | s->mode = SILENCE_COPY_FLUSH; |
| 774 | flush(s, out, outlink, &nb_samples_written, &ret, 0); | 779 | flush(s, out, outlink, &nb_samples_written, 0); |
| 775 | goto silence_copy_flush; | 780 | goto silence_copy_flush; |
| 776 | } else if (threshold) { | 781 | } else if (threshold) { |
| 777 | for (j = 0; j < outlink->channels; j++) { | 782 | for (j = 0; j < outlink->channels; j++) { |
| @@ -812,7 +817,7 @@ silence_copy: · 34 unmodified lines | |||
| 812 | 817 | ||
| 813 | if (!s->restart) { | 818 | if (!s->restart) { |
| 814 | s->mode = SILENCE_STOP; | 819 | s->mode = SILENCE_STOP; |
| 815 | flush(s, out, outlink, &nb_samples_written, &ret, 1); | 820 | flush(s, out, outlink, &nb_samples_written, 1); |
| 816 | goto silence_stop; | 821 | goto silence_stop; |
| 817 | } else { | 822 | } else { |
| 818 | s->stop_found_periods = 0; | 823 | s->stop_found_periods = 0; |
| @@ -823,17 +828,17 @@ silence_copy: · 4 unmodified lines | |||
| 823 | s->start_silence_end = 0; | 828 | s->start_silence_end = 0; |
| 824 | clear_window(s); | 829 | clear_window(s); |
| 825 | s->mode = SILENCE_TRIM; | 830 | s->mode = SILENCE_TRIM; |
| 826 | flush(s, out, outlink, &nb_samples_written, &ret, 1); | 831 | flush(s, out, outlink, &nb_samples_written, 1); |
| 827 | goto silence_trim; | 832 | goto silence_trim; |
| 828 | } | 833 | } |
| 829 | } | 834 | } |
| 830 | s->mode = SILENCE_COPY_FLUSH; | 835 | s->mode = SILENCE_COPY_FLUSH; |
| 831 | flush(s, out, outlink, &nb_samples_written, &ret, 0); | 836 | flush(s, out, outlink, &nb_samples_written, 0); |
| 832 | goto silence_copy_flush; | 837 | goto silence_copy_flush; |
| 833 | } | 838 | } |
| 834 | } | 839 | } |
| 835 | } | 840 | } |
| 836 | flush(s, out, outlink, &nb_samples_written, &ret, 0); | 841 | flush(s, out, outlink, &nb_samples_written, 0); |
| 837 | } else { | 842 | } else { |
| 838 | av_samples_copy(out->extended_data, in->extended_data, | 843 | av_samples_copy(out->extended_data, in->extended_data, |
| 839 | nb_samples_written, | 844 | nb_samples_written, |
| @@ -845,7 +850,8 @@ silence_copy: · 5 unmodified lines | |||
| 845 | (AVRational){1, outlink->sample_rate}, | 850 | (AVRational){1, outlink->sample_rate}, |
| 846 | outlink->time_base); | 851 | outlink->time_base); |
| 847 | 852 | ||
| 848 | ret = ff_filter_frame(outlink, out); | 853 | av_audio_fifo_write(s->fifo, (void **)out->extended_data, out->nb_samples); |
| 854 | av_frame_free(&out); | ||
| 849 | } | 855 | } |
| 850 | break; | 856 | break; |
| 851 | 857 | ||
| @@ -872,7 +878,8 @@ silence_copy_flush: · 20 unmodified lines | |||
| 872 | (AVRational){1, outlink->sample_rate}, | 878 | (AVRational){1, outlink->sample_rate}, |
| 873 | outlink->time_base); | 879 | outlink->time_base); |
| 874 | 880 | ||
| 875 | ret = ff_filter_frame(outlink, out); | 881 | av_audio_fifo_write(s->fifo, (void **)out->extended_data, out->nb_samples); |
| 882 | av_frame_free(&out); | ||
| 876 | 883 | ||
| 877 | if (s->stop_holdoff_offset == s->stop_holdoff_end) { | 884 | if (s->stop_holdoff_offset == s->stop_holdoff_end) { |
| 878 | s->stop_holdoff_offset = 0; | 885 | s->stop_holdoff_offset = 0; |
| @@ -892,6 +899,16 @@ silence_stop: · 13 unmodified lines | |||
| 892 | 899 | ||
| 893 | av_frame_free(&in); | 900 | av_frame_free(&in); |
| 894 | 901 | ||
| 902 | if (av_audio_fifo_size(s->fifo) > 0) { | ||
| 903 | out = ff_get_audio_buffer(outlink, av_audio_fifo_size(s->fifo)); | ||
| 904 | if (!out) | ||
| 905 | return AVERROR(ENOMEM); | ||
| 906 | |||
| 907 | av_audio_fifo_read(s->fifo, (void **)out->extended_data, out->nb_samples); | ||
| 908 | out->pts = s->next_pts; | ||
| 909 | ret = ff_filter_frame(outlink, out); | ||
| 910 | } | ||
| 911 | |||
| 895 | return ret; | 912 | return ret; |
| 896 | } | 913 | } |
| 897 | 914 | ||
| @@ -955,6 +972,9 @@ static av_cold void uninit(AVFilterContext *ctx) · 57 unmodified lines | |||
| 955 | av_frame_free(&s->stop_holdoff); | 972 | av_frame_free(&s->stop_holdoff); |
| 956 | av_frame_free(&s->stop_silence_hold); | 973 | av_frame_free(&s->stop_silence_hold); |
| 957 | av_frame_free(&s->window); | 974 | av_frame_free(&s->window); |
| 975 | |||
| 976 | av_audio_fifo_free(s->fifo); | ||
| 977 | s->fifo = NULL; | ||
| 958 | } | 978 | } |
| 959 | 979 | ||
| 960 | static const AVFilterPad silenceremove_inputs[] = { | 980 | static const AVFilterPad silenceremove_inputs[] = { |