Showing the changes to libavfilter (2 of 3 files). Show all
Unified · Split
| @@ -36,6 +36,7 @@ enum SilenceDetect { · 35 unmodified lines | ||
| 36 | 36 | D_AVG, |
| 37 | 37 | D_RMS, |
| 38 | 38 | D_PEAK, |
| 39 | + D_MEDIAN, | |
| 39 | 40 | D_NB |
| 40 | 41 | }; |
| 41 | 42 | |
| @@ -132,6 +133,7 @@ static const AVOption silenceremove_options[] = { · 90 unmodified lines | ||
| 132 | 133 | { "avg", "use mean absolute values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_AVG}, 0, 0, AF, "detection" }, |
| 133 | 134 | { "rms", "use root mean squared values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_RMS}, 0, 0, AF, "detection" }, |
| 134 | 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 | 137 | { "window", "set duration of window for silence detection", OFFSET(window_duration_opt), AV_OPT_TYPE_DURATION, {.i64=20000}, 0, 100000000, AF }, |
| 136 | 138 | { NULL } |
| 137 | 139 | }; |
| @@ -234,6 +236,10 @@ static int config_output(AVFilterLink *outlink) · 96 unmodified lines | ||
| 234 | 236 | s->compute_flt = compute_avg_flt; |
| 235 | 237 | s->compute_dbl = compute_avg_dbl; |
| 236 | 238 | break; |
| 239 | + case D_MEDIAN: | |
| 240 | + s->compute_flt = compute_median_flt; | |
| 241 | + s->compute_dbl = compute_median_dbl; | |
| 242 | + break; | |
| 237 | 243 | case D_PEAK: |
| 238 | 244 | s->compute_flt = compute_peak_flt; |
| 239 | 245 | s->compute_dbl = compute_peak_dbl; |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | #undef SAMPLE_FORMAT |
| 23 | 23 | #undef SQRT |
| 24 | 24 | #undef ZERO |
| 25 | +#undef ONE | |
| 25 | 26 | #if DEPTH == 32 |
| 26 | 27 | #define SAMPLE_FORMAT flt |
| 27 | 28 | #define SQRT sqrtf |
| @@ -29,6 +30,7 @@ · 1 unmodified line | ||
| 29 | 30 | #define FABS fabsf |
| 30 | 31 | #define ftype float |
| 31 | 32 | #define ZERO 0.f |
| 33 | +#define ONE 1.f | |
| 32 | 34 | #else |
| 33 | 35 | #define SAMPLE_FORMAT dbl |
| 34 | 36 | #define SQRT sqrt |
| @@ -36,6 +38,7 @@ · 1 unmodified line | ||
| 36 | 38 | #define FABS fabs |
| 37 | 39 | #define ftype double |
| 38 | 40 | #define ZERO 0.0 |
| 41 | +#define ONE 1.0 | |
| 39 | 42 | #endif |
| 40 | 43 | |
| 41 | 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 | 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 | 179 | static ftype fn(compute_peak)(ftype *peak, ftype sample, ftype wsample, |
| 115 | 180 | int size, int *ffront, int *bback) |
| 116 | 181 | { |
| @@ -216,7 +281,7 @@ static void fn(filter_start)(AVFilterContext *ctx, · 99 unmodified lines | ||
| 216 | 281 | if (s->start_found_periods < 0) |
| 217 | 282 | goto skip; |
| 218 | 283 | |
| 219 | − if (s->detection != D_PEAK) | |
| 284 | + if (s->detection != D_PEAK && s->detection != D_MEDIAN) | |
| 220 | 285 | window_size = s->start_window_size; |
| 221 | 286 | |
| 222 | 287 | for (int ch = 0; ch < nb_channels; ch++) { |
| @@ -308,7 +373,7 @@ static void fn(filter_stop)(AVFilterContext *ctx, · 85 unmodified lines | ||
| 308 | 373 | stop_nb_samples, |
| 309 | 374 | stop_window_nb_samples); |
| 310 | 375 | |
| 311 | − if (s->detection != D_PEAK) | |
| 376 | + if (s->detection != D_PEAK && s->detection != D_MEDIAN) | |
| 312 | 377 | window_size = s->stop_window_size; |
| 313 | 378 | |
| 314 | 379 | for (int ch = 0; ch < nb_channels; ch++) { |