Showing the changes to libavfilter (2 of 3 files). Show all
Unified · Split
| @@ -36,6 +36,7 @@ enum SilenceDetect { · 35 unmodified lines | |||
| 36 | D_AVG, | 36 | D_AVG, |
| 37 | D_RMS, | 37 | D_RMS, |
| 38 | D_PEAK, | 38 | D_PEAK, |
| 39 | D_MEDIAN, | ||
| 39 | D_NB | 40 | D_NB |
| 40 | }; | 41 | }; |
| 41 | 42 | ||
| @@ -132,6 +133,7 @@ static const AVOption silenceremove_options[] = { · 90 unmodified lines | |||
| 132 | { "avg", "use mean absolute values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_AVG}, 0, 0, AF, "detection" }, | 133 | { "avg", "use mean absolute values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_AVG}, 0, 0, AF, "detection" }, |
| 133 | { "rms", "use root mean squared values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_RMS}, 0, 0, AF, "detection" }, | 134 | { "rms", "use root mean squared values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_RMS}, 0, 0, AF, "detection" }, |
| 134 | { "peak", "use max absolute values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_PEAK},0, 0, AF, "detection" }, | 135 | { "peak", "use max absolute values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_PEAK},0, 0, AF, "detection" }, |
| 136 | { "median", "use median of absolute values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_MEDIAN},0, 0, AF, "detection" }, | ||
| 135 | { "window", "set duration of window for silence detection", OFFSET(window_duration_opt), AV_OPT_TYPE_DURATION, {.i64=20000}, 0, 100000000, AF }, | 137 | { "window", "set duration of window for silence detection", OFFSET(window_duration_opt), AV_OPT_TYPE_DURATION, {.i64=20000}, 0, 100000000, AF }, |
| 136 | { NULL } | 138 | { NULL } |
| 137 | }; | 139 | }; |
| @@ -234,6 +236,10 @@ static int config_output(AVFilterLink *outlink) · 96 unmodified lines | |||
| 234 | s->compute_flt = compute_avg_flt; | 236 | s->compute_flt = compute_avg_flt; |
| 235 | s->compute_dbl = compute_avg_dbl; | 237 | s->compute_dbl = compute_avg_dbl; |
| 236 | break; | 238 | break; |
| 239 | case D_MEDIAN: | ||
| 240 | s->compute_flt = compute_median_flt; | ||
| 241 | s->compute_dbl = compute_median_dbl; | ||
| 242 | break; | ||
| 237 | case D_PEAK: | 243 | case D_PEAK: |
| 238 | s->compute_flt = compute_peak_flt; | 244 | s->compute_flt = compute_peak_flt; |
| 239 | s->compute_dbl = compute_peak_dbl; | 245 | s->compute_dbl = compute_peak_dbl; |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | |||
| 22 | #undef SAMPLE_FORMAT | 22 | #undef SAMPLE_FORMAT |
| 23 | #undef SQRT | 23 | #undef SQRT |
| 24 | #undef ZERO | 24 | #undef ZERO |
| 25 | #undef ONE | ||
| 25 | #if DEPTH == 32 | 26 | #if DEPTH == 32 |
| 26 | #define SAMPLE_FORMAT flt | 27 | #define SAMPLE_FORMAT flt |
| 27 | #define SQRT sqrtf | 28 | #define SQRT sqrtf |
| @@ -29,6 +30,7 @@ · 1 unmodified line | |||
| 29 | #define FABS fabsf | 30 | #define FABS fabsf |
| 30 | #define ftype float | 31 | #define ftype float |
| 31 | #define ZERO 0.f | 32 | #define ZERO 0.f |
| 33 | #define ONE 1.f | ||
| 32 | #else | 34 | #else |
| 33 | #define SAMPLE_FORMAT dbl | 35 | #define SAMPLE_FORMAT dbl |
| 34 | #define SQRT sqrt | 36 | #define SQRT sqrt |
| @@ -36,6 +38,7 @@ · 1 unmodified line | |||
| 36 | #define FABS fabs | 38 | #define FABS fabs |
| 37 | #define ftype double | 39 | #define ftype double |
| 38 | #define ZERO 0.0 | 40 | #define ZERO 0.0 |
| 41 | #define ONE 1.0 | ||
| 39 | #endif | 42 | #endif |
| 40 | 43 | ||
| 41 | #define fn3(a,b) a##_##b | 44 | #define fn3(a,b) a##_##b |
| @@ -111,6 +114,68 @@ static ftype fn(compute_avg)(ftype *cache, ftype sample, ftype wsample, · 69 unmodified lines | |||
| 111 | return r / window_size; | 114 | return r / window_size; |
| 112 | } | 115 | } |
| 113 | 116 | ||
| 117 | static ftype fn(compute_median)(ftype *peak, ftype sample, ftype wsample, | ||
| 118 | int size, int *ffront, int *bback) | ||
| 119 | { | ||
| 120 | ftype r, abs_sample = FABS(sample); | ||
| 121 | int front = *ffront; | ||
| 122 | int back = *bback; | ||
| 123 | int empty = front == back && peak[front] == -ONE; | ||
| 124 | int idx; | ||
| 125 | |||
| 126 | if (!empty && FABS(wsample) == peak[front]) { | ||
| 127 | peak[front] = -ONE; | ||
| 128 | if (back != front) { | ||
| 129 | front--; | ||
| 130 | if (front < 0) | ||
| 131 | front = size - 1; | ||
| 132 | } | ||
| 133 | empty = front == back; | ||
| 134 | } | ||
| 135 | |||
| 136 | if (!empty && abs_sample > peak[front]) { | ||
| 137 | while (1) { | ||
| 138 | peak[front] = -ONE; | ||
| 139 | if (back == front) { | ||
| 140 | empty = 1; | ||
| 141 | break; | ||
| 142 | } | ||
| 143 | front--; | ||
| 144 | if (front < 0) | ||
| 145 | front = size - 1; | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 149 | while (!empty && abs_sample > peak[back]) { | ||
| 150 | peak[back] = -ONE; | ||
| 151 | if (back == front) { | ||
| 152 | empty = 1; | ||
| 153 | break; | ||
| 154 | } | ||
| 155 | back++; | ||
| 156 | if (back >= size) | ||
| 157 | back = 0; | ||
| 158 | } | ||
| 159 | |||
| 160 | if (!empty) { | ||
| 161 | back--; | ||
| 162 | if (back < 0) | ||
| 163 | back = size - 1; | ||
| 164 | } | ||
| 165 | |||
| 166 | peak[back] = abs_sample; | ||
| 167 | idx = (back <= front) ? back + (front - back + 1) / 2 : back + (size + front - back + 1) / 2; | ||
| 168 | if (idx >= size) | ||
| 169 | idx -= size; | ||
| 170 | av_assert2(idx >= 0 && idx < size); | ||
| 171 | r = peak[idx]; | ||
| 172 | |||
| 173 | *ffront = front; | ||
| 174 | *bback = back; | ||
| 175 | |||
| 176 | return r; | ||
| 177 | } | ||
| 178 | |||
| 114 | static ftype fn(compute_peak)(ftype *peak, ftype sample, ftype wsample, | 179 | static ftype fn(compute_peak)(ftype *peak, ftype sample, ftype wsample, |
| 115 | int size, int *ffront, int *bback) | 180 | int size, int *ffront, int *bback) |
| 116 | { | 181 | { |
| @@ -216,7 +281,7 @@ static void fn(filter_start)(AVFilterContext *ctx, · 99 unmodified lines | |||
| 216 | if (s->start_found_periods < 0) | 281 | if (s->start_found_periods < 0) |
| 217 | goto skip; | 282 | goto skip; |
| 218 | 283 | ||
| 219 | if (s->detection != D_PEAK) | 284 | if (s->detection != D_PEAK && s->detection != D_MEDIAN) |
| 220 | window_size = s->start_window_size; | 285 | window_size = s->start_window_size; |
| 221 | 286 | ||
| 222 | for (int ch = 0; ch < nb_channels; ch++) { | 287 | for (int ch = 0; ch < nb_channels; ch++) { |
| @@ -308,7 +373,7 @@ static void fn(filter_stop)(AVFilterContext *ctx, · 85 unmodified lines | |||
| 308 | stop_nb_samples, | 373 | stop_nb_samples, |
| 309 | stop_window_nb_samples); | 374 | stop_window_nb_samples); |
| 310 | 375 | ||
| 311 | if (s->detection != D_PEAK) | 376 | if (s->detection != D_PEAK && s->detection != D_MEDIAN) |
| 312 | window_size = s->stop_window_size; | 377 | window_size = s->stop_window_size; |
| 313 | 378 | ||
| 314 | for (int ch = 0; ch < nb_channels; ch++) { | 379 | for (int ch = 0; ch < nb_channels; ch++) { |