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
609609 return gate_hist_pos;
610610 }
611611
612+void 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+
612648 static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
613649 {
614650 int i, ch, idx_insample, ret;
615651 AVFilterContext *ctx = inlink->dst;
616652 EBUR128Context *ebur128 = ctx->priv;
653+ const EBUR128DSPContext *dsp = &ebur128->dsp;
617654 const int nb_channels = ebur128->nb_channels;
618655 const int nb_samples = insamples->nb_samples;
619656 const double *samples = (double *)insamples->data[0];
@@ -639,14 +676,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) · 19 unmodified lines
639676 }
640677 #endif
641678
642− const EBUR128Biquad pre = ebur128->dsp.pre;
643− const EBUR128Biquad rlb = ebur128->dsp.rlb;
644−
645679 for (idx_insample = ebur128->idx_insample; idx_insample < nb_samples; idx_insample++) {
646680 const int bin_id_400 = ebur128->i400.cache_pos;
647681 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];
650682
651683 #define MOVE_TO_NEXT_CACHED_ENTRY(time) do { \
652684 ebur128->i##time.cache_pos++; \
@@ -660,35 +692,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) · 7 unmodified lines
660692 MOVE_TO_NEXT_CACHED_ENTRY(400);
661693 MOVE_TO_NEXT_CACHED_ENTRY(3000);
662694
663− for (ch = 0; ch < nb_channels; ch++) {
664− if (ebur128->peak_mode & PEAK_MODE_SAMPLES_PEAKS)
665− ebur128->sample_peaks[ch] = FFMAX(ebur128->sample_peaks[ch], fabs(samples[idx_insample * nb_channels + ch]));
666−
667− if (!ebur128->ch_weighting[ch])
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− }
695+ ff_ebur128_filter_channels_c(dsp, &samples[idx_insample * nb_channels],
696+ &ebur128->i400.cache[bin_id_400 * nb_channels],
697+ &ebur128->i3000.cache[bin_id_3000 * nb_channels],
698+ ebur128->i400.sum, ebur128->i3000.sum,
699+ nb_channels);
692700
693701 #define FIND_PEAK(global, sp, ptype) do { \
694702 int ch; \
@@ -701,6 +709,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) · 6 unmodified lines
701709 } \
702710 } while (0)
703711
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+
704719 FIND_PEAK(ebur128->sample_peak, ebur128->sample_peaks, SAMPLES);
705720 FIND_PEAK(ebur128->true_peak, ebur128->true_peaks, TRUE);
706721
libavfilter/f_ebur128.h+3−0
@@ -37,4 +37,7 @@ typedef struct EBUR128DSPContext { · 36 unmodified lines
3737 double *z; /* after RLB-filter */
3838 } EBUR128DSPContext;
3939
40+void ff_ebur128_filter_channels_c(const EBUR128DSPContext *, const double *,
41+ double *, double *, double *, double *, int);
42+
4043 #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