Browse code

Merge commit 'aaab192df24a90f4450285cfb73b395cf495b462'

* commit 'aaab192df24a90f4450285cfb73b395cf495b462':
af_volume: implement replaygain clipping prevention

Conflicts:
doc/filters.texi

Merged-by: Michael Niedermayer <michaelni@gmx.at>

Michael Niedermayer authored on 2014/04/13 21:39:51
Showing 3 changed files
... ...
@@ -1911,6 +1911,11 @@ The command accepts the same syntax of the corresponding option.
1911 1911
 
1912 1912
 If the specified expression is not valid, it is kept at its current
1913 1913
 value.
1914
+@item replaygain_noclip
1915
+Prevent clipping by limiting the gain applied.
1916
+
1917
+Default value for @var{replaygain_noclip} is 1.
1918
+
1914 1919
 @end table
1915 1920
 
1916 1921
 @subsection Examples
... ...
@@ -81,6 +81,8 @@ static const AVOption volume_options[] = {
81 81
         { "album",  "album gain is preferred",         0, AV_OPT_TYPE_CONST, { .i64 = REPLAYGAIN_ALBUM  }, 0, 0, A, "replaygain" },
82 82
     { "replaygain_preamp", "Apply replaygain pre-amplification",
83 83
             OFFSET(replaygain_preamp), AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, -15.0, 15.0, A },
84
+    { "replaygain_noclip", "Apply replaygain clipping prevention",
85
+            OFFSET(replaygain_noclip), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, A },
84 86
     { NULL },
85 87
 };
86 88
 
... ...
@@ -342,25 +344,34 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
342 342
     if (sd && vol->replaygain != REPLAYGAIN_IGNORE) {
343 343
         if (vol->replaygain != REPLAYGAIN_DROP) {
344 344
             AVReplayGain *replaygain = (AVReplayGain*)sd->data;
345
-            int32_t gain;
346
-            float g;
345
+            int32_t gain  = 100000;
346
+            uint32_t peak = 100000;
347
+            float g, p;
347 348
 
348 349
             if (vol->replaygain == REPLAYGAIN_TRACK &&
349
-                replaygain->track_gain != INT32_MIN)
350
+                replaygain->track_gain != INT32_MIN) {
350 351
                 gain = replaygain->track_gain;
351
-            else if (replaygain->album_gain != INT32_MIN)
352
+
353
+                if (replaygain->track_peak != 0)
354
+                    peak = replaygain->track_peak;
355
+            } else if (replaygain->album_gain != INT32_MIN) {
352 356
                 gain = replaygain->album_gain;
353
-            else {
357
+
358
+                if (replaygain->album_peak != 0)
359
+                    peak = replaygain->album_peak;
360
+            } else {
354 361
                 av_log(inlink->dst, AV_LOG_WARNING, "Both ReplayGain gain "
355 362
                        "values are unknown.\n");
356
-                gain = 100000;
357 363
             }
358 364
             g = gain / 100000.0f;
365
+            p = peak / 100000.0f;
359 366
 
360 367
             av_log(inlink->dst, AV_LOG_VERBOSE,
361 368
                    "Using gain %f dB from replaygain side data.\n", g);
362 369
 
363 370
             vol->volume   = pow(10, (g + vol->replaygain_preamp) / 20);
371
+            if (vol->replaygain_noclip)
372
+                vol->volume = FFMIN(vol->volume, 1.0 / p);
364 373
             vol->volume_i = (int)(vol->volume * 256 + 0.5);
365 374
 
366 375
             volume_init(vol);
... ...
@@ -76,6 +76,7 @@ typedef struct VolumeContext {
76 76
 
77 77
     enum ReplayGainType replaygain;
78 78
     double replaygain_preamp;
79
+    int    replaygain_noclip;
79 80
     double volume;
80 81
     int    volume_i;
81 82
     int    channels;