History

avfilter/f_ebur128: split off C implementation to separate function

I decided to separate out the peak measurement loop to avoid bloating the signature, and since it's only conditionally used.

Niklas Haas committed 1 year ago

Commit deab15e1 parent c7d2b0a2 files · +52 −34Browse files

Unified · Split

2 files
  1. libavfilter/f_ebur128.c +49 −34
  2. libavfilter/f_ebur128.h +3 −0
libavfilter/f_ebur128.c+49−34
@@ -609,11 +609,48 @@ static int gate_update(struct integrator *integ, double power, · 608 unmodified lines
609 return gate_hist_pos;609 return gate_hist_pos;
610}610}
611 611
612void ff_ebur128_filter_channels_c(const EBUR128DSPContext *dsp,
613 const double *restrict samples,
614 double *restrict cache_400,
615 double *restrict cache_3000,
616 double *restrict sum_400,
617 double *restrict sum_3000,
618 const int nb_channels)
619{
620 const EBUR128Biquad pre = dsp->pre;
621 const EBUR128Biquad rlb = dsp->rlb;
622
623 for (int ch = 0; ch < nb_channels; ch++) {
624 /* Y[i] = X[i]*b0 + X[i-1]*b1 + X[i-2]*b2 - Y[i-1]*a1 - Y[i-2]*a2 */
625#define FILTER(DST, SRC, FILT) do { \
626 const double tmp = DST[0] = FILT.b0 * SRC + DST[1]; \
627 DST[1] = FILT.b1 * SRC + DST[2] - FILT.a1 * tmp; \
628 DST[2] = FILT.b2 * SRC - FILT.a2 * tmp; \
629} while (0)
630
631 const double x = samples[ch];
632 double *restrict y = &dsp->y[3 * ch];
633 double *restrict z = &dsp->z[3 * ch];
634
635 // TODO: merge both filters in one?
636 FILTER(y, x, pre); // apply pre-filter
637 FILTER(z, *y, rlb); // apply RLB-filter
638
639 /* add the new value, and limit the sum to the cache size (400ms or 3s)
640 * by removing the oldest one */
641 const double bin = *z * *z;
642 sum_400 [ch] += bin - cache_400[ch];
643 sum_3000[ch] += bin - cache_3000[ch];
644 cache_400[ch] = cache_3000[ch] = bin;
645 }
646}
647
612static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)648static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
613{649{
614 int i, ch, idx_insample, ret;650 int i, ch, idx_insample, ret;
615 AVFilterContext *ctx = inlink->dst;651 AVFilterContext *ctx = inlink->dst;
616 EBUR128Context *ebur128 = ctx->priv;652 EBUR128Context *ebur128 = ctx->priv;
653 const EBUR128DSPContext *dsp = &ebur128->dsp;
617 const int nb_channels = ebur128->nb_channels;654 const int nb_channels = ebur128->nb_channels;
618 const int nb_samples = insamples->nb_samples;655 const int nb_samples = insamples->nb_samples;
619 const double *samples = (double *)insamples->data[0];656 const double *samples = (double *)insamples->data[0];
@@ -639,14 +676,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) · 19 unmodified lines
639 }676 }
640#endif677#endif
641 678
642 const EBUR128Biquad pre = ebur128->dsp.pre;
643 const EBUR128Biquad rlb = ebur128->dsp.rlb;
644
645 for (idx_insample = ebur128->idx_insample; idx_insample < nb_samples; idx_insample++) {679 for (idx_insample = ebur128->idx_insample; idx_insample < nb_samples; idx_insample++) {
646 const int bin_id_400 = ebur128->i400.cache_pos;680 const int bin_id_400 = ebur128->i400.cache_pos;
647 const int bin_id_3000 = ebur128->i3000.cache_pos;681 const int bin_id_3000 = ebur128->i3000.cache_pos;
648 double *restrict cache_400 = &ebur128->i400.cache[bin_id_400 * nb_channels];
649 double *restrict cache_3000 = &ebur128->i3000.cache[bin_id_3000 * nb_channels];
650 682
651#define MOVE_TO_NEXT_CACHED_ENTRY(time) do { \683#define MOVE_TO_NEXT_CACHED_ENTRY(time) do { \
652 ebur128->i##time.cache_pos++; \684 ebur128->i##time.cache_pos++; \
@@ -660,35 +692,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) · 7 unmodified lines
660 MOVE_TO_NEXT_CACHED_ENTRY(400);692 MOVE_TO_NEXT_CACHED_ENTRY(400);
661 MOVE_TO_NEXT_CACHED_ENTRY(3000);693 MOVE_TO_NEXT_CACHED_ENTRY(3000);
662 694
663 for (ch = 0; ch < nb_channels; ch++) {695 ff_ebur128_filter_channels_c(dsp, &samples[idx_insample * nb_channels],
664 if (ebur128->peak_mode & PEAK_MODE_SAMPLES_PEAKS)696 &ebur128->i400.cache[bin_id_400 * nb_channels],
665 ebur128->sample_peaks[ch] = FFMAX(ebur128->sample_peaks[ch], fabs(samples[idx_insample * nb_channels + ch]));697 &ebur128->i3000.cache[bin_id_3000 * nb_channels],
666 698 ebur128->i400.sum, ebur128->i3000.sum,
667 if (!ebur128->ch_weighting[ch])699 nb_channels);
668 continue;
669
670 /* Y[i] = X[i]*b0 + X[i-1]*b1 + X[i-2]*b2 - Y[i-1]*a1 - Y[i-2]*a2 */
671#define FILTER(DST, SRC, FILT) do { \
672 const double tmp = DST[0] = FILT.b0 * SRC + DST[1]; \
673 DST[1] = FILT.b1 * SRC + DST[2] - FILT.a1 * tmp; \
674 DST[2] = FILT.b2 * SRC - FILT.a2 * tmp; \
675} while (0)
676
677 const double x = samples[idx_insample * nb_channels + ch];
678 double *restrict y = &ebur128->dsp.y[3 * ch];
679 double *restrict z = &ebur128->dsp.z[3 * ch];
680
681 // TODO: merge both filters in one?
682 FILTER(y, x, pre); // apply pre-filter
683 FILTER(z, *y, rlb); // apply RLB-filter
684
685 /* add the new value, and limit the sum to the cache size (400ms or 3s)
686 * by removing the oldest one */
687 const double bin = *z * *z;
688 ebur128->i400.sum [ch] += bin - cache_400[ch];
689 ebur128->i3000.sum[ch] += bin - cache_3000[ch];
690 cache_400[ch] = cache_3000[ch] = bin;
691 }
692 700
693#define FIND_PEAK(global, sp, ptype) do { \701#define FIND_PEAK(global, sp, ptype) do { \
694 int ch; \702 int ch; \
@@ -701,6 +709,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) · 6 unmodified lines
701 } \709 } \
702} while (0)710} while (0)
703 711
712 if (ebur128->peak_mode & PEAK_MODE_SAMPLES_PEAKS) {
713 for (ch = 0; ch < nb_channels; ch++) {
714 const double sample = samples[idx_insample * nb_channels + ch];
715 ebur128->sample_peaks[ch] = FFMAX(ebur128->sample_peaks[ch], fabs(sample));
716 }
717 }
718
704 FIND_PEAK(ebur128->sample_peak, ebur128->sample_peaks, SAMPLES);719 FIND_PEAK(ebur128->sample_peak, ebur128->sample_peaks, SAMPLES);
705 FIND_PEAK(ebur128->true_peak, ebur128->true_peaks, TRUE);720 FIND_PEAK(ebur128->true_peak, ebur128->true_peaks, TRUE);
706 721
libavfilter/f_ebur128.h+3−0
@@ -37,4 +37,7 @@ typedef struct EBUR128DSPContext { · 36 unmodified lines
37 double *z; /* after RLB-filter */37 double *z; /* after RLB-filter */
38} EBUR128DSPContext;38} EBUR128DSPContext;
39 39
40void ff_ebur128_filter_channels_c(const EBUR128DSPContext *, const double *,
41 double *, double *, double *, double *, int);
42
40#endif /* AVFILTER_F_EBUR128_H */43#endif /* AVFILTER_F_EBUR128_H */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t