On Sun, Aug 13, 2023 at 05:14:48AM +0200, Paul B Mahol wrote:
> Attached.

>  af_asdr.c |   44 ++++++++++++++++++++++++--------------------
>  1 file changed, 24 insertions(+), 20 deletions(-)
> f0f248ba7e893a63a684b92a6d82ab246fc1995c  
> 0003-avfilter-af_asdr-use-single-structure-for-sums.patch
> From ad9def7fad58a75450176413564543a16965d165 Mon Sep 17 00:00:00 2001
> From: Paul B Mahol <one...@gmail.com>
> Date: Sun, 13 Aug 2023 05:03:00 +0200
> Subject: [PATCH 3/3] avfilter/af_asdr: use single structure for sums
> 
> Signed-off-by: Paul B Mahol <one...@gmail.com>
> ---
>  libavfilter/af_asdr.c | 44 +++++++++++++++++++++++--------------------
>  1 file changed, 24 insertions(+), 20 deletions(-)
> 
> diff --git a/libavfilter/af_asdr.c b/libavfilter/af_asdr.c
> index 53069427bf..dbbb7e3419 100644
> --- a/libavfilter/af_asdr.c
> +++ b/libavfilter/af_asdr.c
> @@ -27,13 +27,18 @@
>  #include "filters.h"
>  #include "internal.h"
>  
> +typedef struct ChanStats {
> +    double u;
> +    double v;
> +    double uv;
> +} ChanStats;
> +
>  typedef struct AudioSDRContext {
>      int channels;
>      uint64_t nb_samples;
>      double max;
> -    double *sum_u;
> -    double *sum_v;
> -    double *sum_uv;
> +
> +    ChanStats *chs;
>  
>      AVFrame *cache[2];
>  
> @@ -52,6 +57,7 @@ static int sdr_##name(AVFilterContext *ctx, void *arg, int 
> jobnr, int nb_jobs)\
>      const int nb_samples = u->nb_samples;                                    
>  \
>                                                                               
>  \
>      for (int ch = start; ch < end; ch++) {                                   
>  \
> +        ChanStats *chs = &s->chs[ch];                                        
>  \
>          const type *const us = (type *)u->extended_data[ch];                 
>  \
>          const type *const vs = (type *)v->extended_data[ch];                 
>  \
>          double sum_uv = 0.;                                                  
>  \
> @@ -62,8 +68,8 @@ static int sdr_##name(AVFilterContext *ctx, void *arg, int 
> jobnr, int nb_jobs)\
>              sum_uv += (us[n] - vs[n]) * (us[n] - vs[n]);                     
>  \
>          }                                                                    
>  \
>                                                                               
>  \
> -        s->sum_uv[ch] += sum_uv;                                             
>  \
> -        s->sum_u[ch]  += sum_u;                                              
>  \
> +        chs->uv += sum_uv;                                                   
>  \
> +        chs->u  += sum_u;                                                    
>  \
>      }                                                                        
>  \
>                                                                               
>  \
>      return 0;                                                                
>  \
> @@ -84,6 +90,7 @@ static int sisdr_##name(AVFilterContext *ctx, void *arg,int 
> jobnr,int nb_jobs)\
>      const int nb_samples = u->nb_samples;                                    
>  \
>                                                                               
>  \
>      for (int ch = start; ch < end; ch++) {                                   
>  \
> +        ChanStats *chs = &s->chs[ch];                                        
>  \
>          const type *const us = (type *)u->extended_data[ch];                 
>  \
>          const type *const vs = (type *)v->extended_data[ch];                 
>  \
>          double sum_uv = 0.;                                                  
>  \
> @@ -96,9 +103,9 @@ static int sisdr_##name(AVFilterContext *ctx, void 
> *arg,int jobnr,int nb_jobs)\
>              sum_uv += us[n] * vs[n];                                         
>  \
>          }                                                                    
>  \
>                                                                               
>  \
> -        s->sum_uv[ch] += sum_uv;                                             
>  \
> -        s->sum_u[ch]  += sum_u;                                              
>  \
> -        s->sum_v[ch]  += sum_v;                                              
>  \
> +        chs->uv += sum_uv;                                                   
>  \
> +        chs->u  += sum_u;                                                    
>  \
> +        chs->v  += sum_v;                                                    
>  \
>      }                                                                        
>  \
>                                                                               
>  \
>      return 0;                                                                
>  \
> @@ -119,6 +126,7 @@ static int psnr_##name(AVFilterContext *ctx, void *arg, 
> int jobnr,int nb_jobs)\
>      const int nb_samples = u->nb_samples;                                    
>  \
>                                                                               
>  \
>      for (int ch = start; ch < end; ch++) {                                   
>  \
> +        ChanStats *chs = &s->chs[ch];                                        
>  \
>          const type *const us = (type *)u->extended_data[ch];                 
>  \
>          const type *const vs = (type *)v->extended_data[ch];                 
>  \
>          double sum_uv = 0.;                                                  
>  \
> @@ -126,7 +134,7 @@ static int psnr_##name(AVFilterContext *ctx, void *arg, 
> int jobnr,int nb_jobs)\
>          for (int n = 0; n < nb_samples; n++)                                 
>  \
>              sum_uv += (us[n] - vs[n]) * (us[n] - vs[n]);                     
>  \
>                                                                               
>  \
> -        s->sum_uv[ch] += sum_uv;                                             
>  \
> +        chs->uv += sum_uv;                                                   
>  \
>      }                                                                        
>  \
>                                                                               
>  \
>      return 0;                                                                
>  \
> @@ -204,10 +212,8 @@ static int config_output(AVFilterLink *outlink)
>          s->filter = inlink->format == AV_SAMPLE_FMT_FLTP ? psnr_fltp : 
> psnr_dblp;
>      s->max = inlink->format == AV_SAMPLE_FMT_FLTP ? FLT_MAX : DBL_MAX;
>  
> -    s->sum_u  = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_u));
> -    s->sum_v  = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_v));
> -    s->sum_uv = av_calloc(outlink->ch_layout.nb_channels, 
> sizeof(*s->sum_uv));
> -    if (!s->sum_u || !s->sum_uv || !s->sum_v)
> +    s->chs  = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->chs));
> +    if (!s->chs)
>          return AVERROR(ENOMEM);
>  
>      return 0;
> @@ -219,17 +225,17 @@ static av_cold void uninit(AVFilterContext *ctx)
>  
>      if (!strcmp(ctx->filter->name, "asdr")) {
>          for (int ch = 0; ch < s->channels; ch++)
> -            av_log(ctx, AV_LOG_INFO, "SDR ch%d: %g dB\n", ch, 20. * 
> log10(s->sum_u[ch] / s->sum_uv[ch]));
> +            av_log(ctx, AV_LOG_INFO, "SDR ch%d: %g dB\n", ch, 20. * 
> log10(s->chs[ch].u / s->chs[ch].uv));
>      } else if (!strcmp(ctx->filter->name, "asisdr")) {
>          for (int ch = 0; ch < s->channels; ch++) {
> -            double scale = s->sum_uv[ch] / s->sum_v[ch];
> -            double sisdr = s->sum_u[ch] / (s->sum_u[ch] + 
> scale*scale*s->sum_v[ch] - 2.0*scale*s->sum_uv[ch]);
> +            double scale = s->chs[ch].uv / s->chs[ch].v;
> +            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);
>  
>              av_log(ctx, AV_LOG_INFO, "SI-SDR ch%d: %g dB\n", ch, 10. * 
> log10(sisdr));
>          }
>      } else {
>          for (int ch = 0; ch < s->channels; ch++) {
> -            double psnr = s->sum_uv[ch] > 0.0 ? 2.0 * log(s->max) - 
> log(s->nb_samples / s->sum_uv[ch]) : INFINITY;
> +            double psnr = s->chs[ch].uv > 0.0 ? 2.0 * log(s->max) - 
> log(s->nb_samples / s->chs[ch].uv) : INFINITY;
>  
>              av_log(ctx, AV_LOG_INFO, "PSNR ch%d: %g dB\n", ch, psnr);
>          }
> @@ -238,9 +244,7 @@ static av_cold void uninit(AVFilterContext *ctx)
>      av_frame_free(&s->cache[0]);
>      av_frame_free(&s->cache[1]);
>  
> -    av_freep(&s->sum_u);
> -    av_freep(&s->sum_v);
> -    av_freep(&s->sum_uv);
> +    av_freep(&s->chs);
>  }
>  
>  static const AVFilterPad inputs[] = {
> -- 
> 2.39.1
> 

>  doc/filters.texi         |    7 +++++
>  libavfilter/Makefile     |    1 
>  libavfilter/af_asdr.c    |   64 
> ++++++++++++++++++++++++++++++++++++++++++++++-
>  libavfilter/allfilters.c |    1 
>  4 files changed, 72 insertions(+), 1 deletion(-)
> 8ed085a8902fa86f0a99838bbd6c4b2645e187d6  
> 0002-avfilter-add-asisdr-filter.patch
> From dfb20b0f4d08428a43b38185776baf6819fc4336 Mon Sep 17 00:00:00 2001
> From: Paul B Mahol <one...@gmail.com>
> Date: Sun, 13 Aug 2023 04:19:08 +0200
> Subject: [PATCH 2/3] avfilter: add asisdr filter
> 
> Signed-off-by: Paul B Mahol <one...@gmail.com>
> ---
>  doc/filters.texi         |  7 +++++
>  libavfilter/Makefile     |  1 +
>  libavfilter/af_asdr.c    | 64 +++++++++++++++++++++++++++++++++++++++-
>  libavfilter/allfilters.c |  1 +
>  4 files changed, 72 insertions(+), 1 deletion(-)
> 
> diff --git a/doc/filters.texi b/doc/filters.texi
> index 1025917c63..159764bcb6 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -3197,6 +3197,13 @@ audio, the data is treated as if all the planes were 
> concatenated.
>  A list of Adler-32 checksums for each data plane.
>  @end table
>  
> +@section asisdr
> +Measure Audio Scaled-Invariant Signal-to-Distortion Ratio.
> +
> +This filter takes two audio streams for input, and outputs first
> +audio stream.
> +Results are in dB per channel at end of either input.
> +
>  @section asoftclip
>  Apply audio soft clipping.
>  
> diff --git a/libavfilter/Makefile b/libavfilter/Makefile
> index 90c30e3388..ba07f4ab1e 100644
> --- a/libavfilter/Makefile
> +++ b/libavfilter/Makefile
> @@ -103,6 +103,7 @@ OBJS-$(CONFIG_ASETRATE_FILTER)               += 
> af_asetrate.o
>  OBJS-$(CONFIG_ASETTB_FILTER)                 += settb.o
>  OBJS-$(CONFIG_ASHOWINFO_FILTER)              += af_ashowinfo.o
>  OBJS-$(CONFIG_ASIDEDATA_FILTER)              += f_sidedata.o
> +OBJS-$(CONFIG_ASISDR_FILTER)                 += af_asdr.o
>  OBJS-$(CONFIG_ASOFTCLIP_FILTER)              += af_asoftclip.o
>  OBJS-$(CONFIG_ASPECTRALSTATS_FILTER)         += af_aspectralstats.o
>  OBJS-$(CONFIG_ASPLIT_FILTER)                 += split.o
> diff --git a/libavfilter/af_asdr.c b/libavfilter/af_asdr.c
> index b0401804f6..53069427bf 100644
> --- a/libavfilter/af_asdr.c
> +++ b/libavfilter/af_asdr.c
> @@ -32,6 +32,7 @@ typedef struct AudioSDRContext {
>      uint64_t nb_samples;
>      double max;
>      double *sum_u;
> +    double *sum_v;
>      double *sum_uv;
>  
>      AVFrame *cache[2];
> @@ -71,6 +72,41 @@ static int sdr_##name(AVFilterContext *ctx, void *arg, int 
> jobnr, int nb_jobs)\
>  SDR_FILTER(fltp, float)
>  SDR_FILTER(dblp, double)
>  
> +#define SISDR_FILTER(name, type)                                             
>  \
> +static int sisdr_##name(AVFilterContext *ctx, void *arg,int jobnr,int 
> nb_jobs)\
> +{                                                                            
>  \
> +    AudioSDRContext *s = ctx->priv;                                          
>  \
> +    AVFrame *u = s->cache[0];                                                
>  \
> +    AVFrame *v = s->cache[1];                                                
>  \
> +    const int channels = u->ch_layout.nb_channels;                           
>  \
> +    const int start = (channels * jobnr) / nb_jobs;                          
>  \
> +    const int end = (channels * (jobnr+1)) / nb_jobs;                        
>  \
> +    const int nb_samples = u->nb_samples;                                    
>  \
> +                                                                             
>  \
> +    for (int ch = start; ch < end; ch++) {                                   
>  \
> +        const type *const us = (type *)u->extended_data[ch];                 
>  \
> +        const type *const vs = (type *)v->extended_data[ch];                 
>  \
> +        double sum_uv = 0.;                                                  
>  \
> +        double sum_u = 0.;                                                   
>  \
> +        double sum_v = 0.;                                                   
>  \
> +
\
> +        for (int n = 0; n < nb_samples; n++) {                               
>  \
> +            sum_u  += us[n] * us[n];                                         
>  \
> +            sum_v  += vs[n] * vs[n];                                         
>  \
> +            sum_uv += us[n] * vs[n];                                         
>  \
> +        }                                                                    
>  \

These should be handled by DSP code which can be asm optimized

> +                                                                             
>  \
> +        s->sum_uv[ch] += sum_uv;                                             
>  \
> +        s->sum_u[ch]  += sum_u;                                              
>  \
> +        s->sum_v[ch]  += sum_v;                                              
>  \
> +    }                                                                        
>  \
> +                                                                             
>  \
> +    return 0;                                                                
>  \
> +}
> +
> +SISDR_FILTER(fltp, float)
> +SISDR_FILTER(dblp, double)
[...]
> @@ -67,6 +71,34 @@ static int sdr_##name(AVFilterContext *ctx, void *arg, int 
> jobnr, int nb_jobs)\
>  SDR_FILTER(fltp, float)
>  SDR_FILTER(dblp, double)
>  
> +#define PSNR_FILTER(name, type)                                              
>  \
> +static int psnr_##name(AVFilterContext *ctx, void *arg, int jobnr,int 
> nb_jobs)\
> +{                                                                            
>  \
> +    AudioSDRContext *s = ctx->priv;                                          
>  \
> +    AVFrame *u = s->cache[0];                                                
>  \
> +    AVFrame *v = s->cache[1];                                                
>  \
> +    const int channels = u->ch_layout.nb_channels;                           
>  \
> +    const int start = (channels * jobnr) / nb_jobs;                          
>  \
> +    const int end = (channels * (jobnr+1)) / nb_jobs;                        
>  \
> +    const int nb_samples = u->nb_samples;                                    
>  \
> +                                                                             
>  \
> +    for (int ch = start; ch < end; ch++) {                                   
>  \
> +        const type *const us = (type *)u->extended_data[ch];                 
>  \
> +        const type *const vs = (type *)v->extended_data[ch];                 
>  \
> +        double sum_uv = 0.;                                                  
>  \
> +                                                                             
>  \
> +        for (int n = 0; n < nb_samples; n++)                                 
>  \
> +            sum_uv += (us[n] - vs[n]) * (us[n] - vs[n]);                     
>  \

These should be handled by DSP code which can be asm optimized


> +                                                                             
>  \
> +        s->sum_uv[ch] += sum_uv;                                             
>  \
> +    }                                                                        
>  \
> +                                                                             
>  \
> +    return 0;                                                                
>  \
> +}
> +
> +PSNR_FILTER(fltp, float)
> +PSNR_FILTER(dblp, double)
> +
>  static int activate(AVFilterContext *ctx)
>  {
>      AudioSDRContext *s = ctx->priv;

[...]

Thx

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Any man who breaks a law that conscience tells him is unjust and willingly 
accepts the penalty by staying in jail in order to arouse the conscience of 
the community on the injustice of the law is at that moment expressing the 
very highest respect for law. - Martin Luther King Jr

Attachment: signature.asc
Description: PGP signature

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to