[FFmpeg-devel] [PATCH] lavfi: EBU R.128 irreg time, ch weights, skip LFE

sedacca at comcast.net sedacca at comcast.net
Wed Jan 16 03:41:29 CET 2013


This suggested patch is for Ticket #2144 "libavfilter ebur128
loudness inaccuracy, irregular time interval, LFE interference".

(1) Correct the time interval between logged data rows to the expected 
value of 100 milliseconds by naming a new loop counter variable 
to be distinct from loop counters for inner loops. 

(2) Correct the recognition of channel layouts for good channel weight 
in the loudness computation. 

(3) Correct the advancement of a pointer to skip over LFE samples 
as intended in the loudness computation.

--- 
 libavfilter/f_ebur128.c |   32 +++++++++++++++++++------------- 
 1 file changed, 19 insertions(+), 13 deletions(-) 

diff --git a/libavfilter/f_ebur128.c b/libavfilter/f_ebur128.c 
index f9da80d..a84cb6e 100644 
--- a/libavfilter/f_ebur128.c 
+++ b/libavfilter/f_ebur128.c 
@@ -314,12 +314,15 @@ static int config_video_output(AVFilterLink *outlink) 
 static int config_audio_output(AVFilterLink *outlink) 
 { 
     int i; 
+    int idx_bitposn = 0; 
     AVFilterContext *ctx = outlink->src; 
     EBUR128Context *ebur128 = ctx->priv; 
     const int nb_channels = av_get_channel_layout_nb_channels(outlink->channel_layout); 
  
-#define BACK_MASK (AV_CH_BACK_LEFT    |AV_CH_BACK_CENTER    |AV_CH_BACK_RIGHT| \ 
-                   AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_CENTER|AV_CH_TOP_BACK_RIGHT) 
+#define BACK_MASK (AV_CH_BACK_LEFT    |AV_CH_BACK_CENTER    |AV_CH_BACK_RIGHT           | \ 
+                   AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_CENTER|AV_CH_TOP_BACK_RIGHT       | \ 
+                   AV_CH_SIDE_LEFT                          |AV_CH_SIDE_RIGHT           | \ 
+                   AV_CH_SURROUND_DIRECT_LEFT               |AV_CH_SURROUND_DIRECT_RIGHT) 
  
     ebur128->nb_channels  = nb_channels; 
     ebur128->ch_weighting = av_calloc(nb_channels, sizeof(*ebur128->ch_weighting)); 
@@ -328,13 +331,16 @@ static int config_audio_output(AVFilterLink *outlink) 
  
     for (i = 0; i < nb_channels; i++) { 
  
+        /* Find the next set bit starting from the right */ 
+        while ((outlink->channel_layout & 1ULL<<idx_bitposn) == 0 && idx_bitposn < 63) 
+            idx_bitposn++; 
+ 
         /* channel weighting */ 
-        if ((outlink->channel_layout & 1ULL<<i) == AV_CH_LOW_FREQUENCY) 
-            continue; 
-        if (outlink->channel_layout & 1ULL<<i & BACK_MASK) 
-            ebur128->ch_weighting[i] = 1.41; 
-        else 
-            ebur128->ch_weighting[i] = 1.0; 
+        ebur128->ch_weighting[i] = 1.0; 
+        if (1ULL<<idx_bitposn & AV_CH_LOW_FREQUENCY  ) ebur128->ch_weighting[i] = 0; 
+        if (1ULL<<idx_bitposn & AV_CH_LOW_FREQUENCY_2) ebur128->ch_weighting[i] = 0; 
+        if (1ULL<<idx_bitposn & BACK_MASK            ) ebur128->ch_weighting[i] = 1.41; 
+        idx_bitposn++; 
  
         /* bins buffer for the two integration window (400ms and 3s) */ 
         ebur128->i400.cache[i]  = av_calloc(I400_BINS,  sizeof(*ebur128->i400.cache[0])); 
@@ -438,7 +444,7 @@ static int gate_update(struct integrator *integ, double power, 
  
 static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples) 
 { 
-    int i, ch; 
+    int i, ch, idx_insample; 
     AVFilterContext *ctx = inlink->dst; 
     EBUR128Context *ebur128 = ctx->priv; 
     const int nb_channels = ebur128->nb_channels; 
@@ -446,7 +452,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples) 
     const double *samples = (double *)insamples->data[0]; 
     AVFilterBufferRef *pic = ebur128->outpicref; 
  
-    for (i = 0; i < nb_samples; i++) { 
+    for (idx_insample = 0; idx_insample < nb_samples; idx_insample++) { 
         const int bin_id_400  = ebur128->i400.cache_pos; 
         const int bin_id_3000 = ebur128->i3000.cache_pos; 
  
@@ -464,6 +470,8 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples) 
         for (ch = 0; ch < nb_channels; ch++) { 
             double bin; 
  
+            ebur128->x[ch * 3] = *samples++; // set X[i] 
+ 
             if (!ebur128->ch_weighting[ch]) 
                 continue; 
  
@@ -477,8 +485,6 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples) 
                                       - dst[1]*name##_A1 - dst[2]*name##_A2;    \ 
 } while (0) 
  
-            ebur128->x[ch * 3] = *samples++; // set X[i] 
- 
             // TODO: merge both filters in one? 
             FILTER(y, x, PRE);  // apply pre-filter 
             ebur128->x[ch * 3 + 2] = ebur128->x[ch * 3 + 1]; 
@@ -505,7 +511,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamples) 
             double power_400 = 1e-12, power_3000 = 1e-12; 
             AVFilterLink *outlink = ctx->outputs[0]; 
             const int64_t pts = insamples->pts + 
-                av_rescale_q(i, (AVRational){ 1, inlink->sample_rate }, 
+                av_rescale_q(idx_insample, (AVRational){ 1, inlink->sample_rate }, 
                              outlink->time_base); 
  
             ebur128->sample_count = 0; 
-- 
1.7.9.5 
  



More information about the ffmpeg-devel mailing list