Unified · Split
| @@ -27,13 +27,18 @@ · 26 unmodified lines | ||
| 27 | 27 | #include "filters.h" |
| 28 | 28 | #include "internal.h" |
| 29 | 29 | |
| 30 | +typedef struct ChanStats { | |
| 31 | + double u; | |
| 32 | + double v; | |
| 33 | + double uv; | |
| 34 | +} ChanStats; | |
| 35 | + | |
| 30 | 36 | typedef struct AudioSDRContext { |
| 31 | 37 | int channels; |
| 32 | 38 | uint64_t nb_samples; |
| 33 | 39 | double max; |
| 34 | − double *sum_u; | |
| 35 | − double *sum_v; | |
| 36 | − double *sum_uv; | |
| 40 | + | |
| 41 | + ChanStats *chs; | |
| 37 | 42 | |
| 38 | 43 | AVFrame *cache[2]; |
| 39 | 44 | |
| @@ -52,6 +57,7 @@ static int sdr_##name(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)\ · 12 unmodified lines | ||
| 52 | 57 | const int nb_samples = u->nb_samples; \ |
| 53 | 58 | \ |
| 54 | 59 | for (int ch = start; ch < end; ch++) { \ |
| 60 | + ChanStats *chs = &s->chs[ch]; \ | |
| 55 | 61 | const type *const us = (type *)u->extended_data[ch]; \ |
| 56 | 62 | const type *const vs = (type *)v->extended_data[ch]; \ |
| 57 | 63 | double sum_uv = 0.; \ |
| @@ -62,8 +68,8 @@ static int sdr_##name(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)\ · 4 unmodified lines | ||
| 62 | 68 | sum_uv += (us[n] - vs[n]) * (us[n] - vs[n]); \ |
| 63 | 69 | } \ |
| 64 | 70 | \ |
| 65 | − s->sum_uv[ch] += sum_uv; \ | |
| 66 | − s->sum_u[ch] += sum_u; \ | |
| 71 | + chs->uv += sum_uv; \ | |
| 72 | + chs->u += sum_u; \ | |
| 67 | 73 | } \ |
| 68 | 74 | \ |
| 69 | 75 | return 0; \ |
| @@ -84,6 +90,7 @@ static int sisdr_##name(AVFilterContext *ctx, void *arg,int jobnr,int nb_jobs)\ · 14 unmodified lines | ||
| 84 | 90 | const int nb_samples = u->nb_samples; \ |
| 85 | 91 | \ |
| 86 | 92 | for (int ch = start; ch < end; ch++) { \ |
| 93 | + ChanStats *chs = &s->chs[ch]; \ | |
| 87 | 94 | const type *const us = (type *)u->extended_data[ch]; \ |
| 88 | 95 | const type *const vs = (type *)v->extended_data[ch]; \ |
| 89 | 96 | double sum_uv = 0.; \ |
| @@ -96,9 +103,9 @@ static int sisdr_##name(AVFilterContext *ctx, void *arg,int jobnr,int nb_jobs)\ · 6 unmodified lines | ||
| 96 | 103 | sum_uv += us[n] * vs[n]; \ |
| 97 | 104 | } \ |
| 98 | 105 | \ |
| 99 | − s->sum_uv[ch] += sum_uv; \ | |
| 100 | − s->sum_u[ch] += sum_u; \ | |
| 101 | − s->sum_v[ch] += sum_v; \ | |
| 106 | + chs->uv += sum_uv; \ | |
| 107 | + chs->u += sum_u; \ | |
| 108 | + chs->v += sum_v; \ | |
| 102 | 109 | } \ |
| 103 | 110 | \ |
| 104 | 111 | return 0; \ |
| @@ -119,6 +126,7 @@ static int psnr_##name(AVFilterContext *ctx, void *arg, int jobnr,int nb_jobs)\ · 14 unmodified lines | ||
| 119 | 126 | const int nb_samples = u->nb_samples; \ |
| 120 | 127 | \ |
| 121 | 128 | for (int ch = start; ch < end; ch++) { \ |
| 129 | + ChanStats *chs = &s->chs[ch]; \ | |
| 122 | 130 | const type *const us = (type *)u->extended_data[ch]; \ |
| 123 | 131 | const type *const vs = (type *)v->extended_data[ch]; \ |
| 124 | 132 | double sum_uv = 0.; \ |
| @@ -126,7 +134,7 @@ static int psnr_##name(AVFilterContext *ctx, void *arg, int jobnr,int nb_jobs)\ · 1 unmodified line | ||
| 126 | 134 | for (int n = 0; n < nb_samples; n++) \ |
| 127 | 135 | sum_uv += (us[n] - vs[n]) * (us[n] - vs[n]); \ |
| 128 | 136 | \ |
| 129 | − s->sum_uv[ch] += sum_uv; \ | |
| 137 | + chs->uv += sum_uv; \ | |
| 130 | 138 | } \ |
| 131 | 139 | \ |
| 132 | 140 | return 0; \ |
| @@ -204,10 +212,8 @@ static int config_output(AVFilterLink *outlink) · 71 unmodified lines | ||
| 204 | 212 | s->filter = inlink->format == AV_SAMPLE_FMT_FLTP ? psnr_fltp : psnr_dblp; |
| 205 | 213 | s->max = inlink->format == AV_SAMPLE_FMT_FLTP ? FLT_MAX : DBL_MAX; |
| 206 | 214 | |
| 207 | − s->sum_u = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_u)); | |
| 208 | − s->sum_v = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_v)); | |
| 209 | − s->sum_uv = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_uv)); | |
| 210 | − if (!s->sum_u || !s->sum_uv || !s->sum_v) | |
| 215 | + s->chs = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->chs)); | |
| 216 | + if (!s->chs) | |
| 211 | 217 | return AVERROR(ENOMEM); |
| 212 | 218 | |
| 213 | 219 | return 0; |
| @@ -219,17 +225,17 @@ static av_cold void uninit(AVFilterContext *ctx) · 5 unmodified lines | ||
| 219 | 225 | |
| 220 | 226 | if (!strcmp(ctx->filter->name, "asdr")) { |
| 221 | 227 | for (int ch = 0; ch < s->channels; ch++) |
| 222 | − av_log(ctx, AV_LOG_INFO, "SDR ch%d: %g dB\n", ch, 20. * log10(s->sum_u[ch] / s->sum_uv[ch])); | |
| 228 | + av_log(ctx, AV_LOG_INFO, "SDR ch%d: %g dB\n", ch, 20. * log10(s->chs[ch].u / s->chs[ch].uv)); | |
| 223 | 229 | } else if (!strcmp(ctx->filter->name, "asisdr")) { |
| 224 | 230 | for (int ch = 0; ch < s->channels; ch++) { |
| 225 | − double scale = s->sum_uv[ch] / s->sum_v[ch]; | |
| 226 | − double sisdr = s->sum_u[ch] / (s->sum_u[ch] + scale*scale*s->sum_v[ch] - 2.0*scale*s->sum_uv[ch]); | |
| 231 | + double scale = s->chs[ch].uv / s->chs[ch].v; | |
| 232 | + double sisdr = s->chs[ch].u / fmax(0., s->chs[ch].u + scale*scale*s->chs[ch].v - 2.0*scale*s->chs[ch].uv); | |
| 227 | 233 | |
| 228 | 234 | av_log(ctx, AV_LOG_INFO, "SI-SDR ch%d: %g dB\n", ch, 10. * log10(sisdr)); |
| 229 | 235 | } |
| 230 | 236 | } else { |
| 231 | 237 | for (int ch = 0; ch < s->channels; ch++) { |
| 232 | − double psnr = s->sum_uv[ch] > 0.0 ? 2.0 * log(s->max) - log(s->nb_samples / s->sum_uv[ch]) : INFINITY; | |
| 238 | + double psnr = s->chs[ch].uv > 0.0 ? 2.0 * log(s->max) - log(s->nb_samples / s->chs[ch].uv) : INFINITY; | |
| 233 | 239 | |
| 234 | 240 | av_log(ctx, AV_LOG_INFO, "PSNR ch%d: %g dB\n", ch, psnr); |
| 235 | 241 | } |
| @@ -238,9 +244,7 @@ static av_cold void uninit(AVFilterContext *ctx) · 2 unmodified lines | ||
| 238 | 244 | av_frame_free(&s->cache[0]); |
| 239 | 245 | av_frame_free(&s->cache[1]); |
| 240 | 246 | |
| 241 | − av_freep(&s->sum_u); | |
| 242 | − av_freep(&s->sum_v); | |
| 243 | − av_freep(&s->sum_uv); | |
| 247 | + av_freep(&s->chs); | |
| 244 | 248 | } |
| 245 | 249 | |
| 246 | 250 | static const AVFilterPad inputs[] = { |