Merge commit 'aaab192df24a90f4450285cfb73b395cf495b462'

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

Conflicts:
	doc/filters.texi

Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Michael Niedermayer 2014-04-13 14:39:51 +02:00
commit 878f8b0d26
3 changed files with 23 additions and 6 deletions

View File

@ -1911,6 +1911,11 @@ The command accepts the same syntax of the corresponding option.
If the specified expression is not valid, it is kept at its current If the specified expression is not valid, it is kept at its current
value. value.
@item replaygain_noclip
Prevent clipping by limiting the gain applied.
Default value for @var{replaygain_noclip} is 1.
@end table @end table
@subsection Examples @subsection Examples

View File

@ -81,6 +81,8 @@ static const AVOption volume_options[] = {
{ "album", "album gain is preferred", 0, AV_OPT_TYPE_CONST, { .i64 = REPLAYGAIN_ALBUM }, 0, 0, A, "replaygain" }, { "album", "album gain is preferred", 0, AV_OPT_TYPE_CONST, { .i64 = REPLAYGAIN_ALBUM }, 0, 0, A, "replaygain" },
{ "replaygain_preamp", "Apply replaygain pre-amplification", { "replaygain_preamp", "Apply replaygain pre-amplification",
OFFSET(replaygain_preamp), AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, -15.0, 15.0, A }, OFFSET(replaygain_preamp), AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, -15.0, 15.0, A },
{ "replaygain_noclip", "Apply replaygain clipping prevention",
OFFSET(replaygain_noclip), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, A },
{ NULL }, { NULL },
}; };
@ -342,25 +344,34 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
if (sd && vol->replaygain != REPLAYGAIN_IGNORE) { if (sd && vol->replaygain != REPLAYGAIN_IGNORE) {
if (vol->replaygain != REPLAYGAIN_DROP) { if (vol->replaygain != REPLAYGAIN_DROP) {
AVReplayGain *replaygain = (AVReplayGain*)sd->data; AVReplayGain *replaygain = (AVReplayGain*)sd->data;
int32_t gain; int32_t gain = 100000;
float g; uint32_t peak = 100000;
float g, p;
if (vol->replaygain == REPLAYGAIN_TRACK && if (vol->replaygain == REPLAYGAIN_TRACK &&
replaygain->track_gain != INT32_MIN) replaygain->track_gain != INT32_MIN) {
gain = replaygain->track_gain; gain = replaygain->track_gain;
else if (replaygain->album_gain != INT32_MIN)
if (replaygain->track_peak != 0)
peak = replaygain->track_peak;
} else if (replaygain->album_gain != INT32_MIN) {
gain = replaygain->album_gain; gain = replaygain->album_gain;
else {
if (replaygain->album_peak != 0)
peak = replaygain->album_peak;
} else {
av_log(inlink->dst, AV_LOG_WARNING, "Both ReplayGain gain " av_log(inlink->dst, AV_LOG_WARNING, "Both ReplayGain gain "
"values are unknown.\n"); "values are unknown.\n");
gain = 100000;
} }
g = gain / 100000.0f; g = gain / 100000.0f;
p = peak / 100000.0f;
av_log(inlink->dst, AV_LOG_VERBOSE, av_log(inlink->dst, AV_LOG_VERBOSE,
"Using gain %f dB from replaygain side data.\n", g); "Using gain %f dB from replaygain side data.\n", g);
vol->volume = pow(10, (g + vol->replaygain_preamp) / 20); vol->volume = pow(10, (g + vol->replaygain_preamp) / 20);
if (vol->replaygain_noclip)
vol->volume = FFMIN(vol->volume, 1.0 / p);
vol->volume_i = (int)(vol->volume * 256 + 0.5); vol->volume_i = (int)(vol->volume * 256 + 0.5);
volume_init(vol); volume_init(vol);

View File

@ -76,6 +76,7 @@ typedef struct VolumeContext {
enum ReplayGainType replaygain; enum ReplayGainType replaygain;
double replaygain_preamp; double replaygain_preamp;
int replaygain_noclip;
double volume; double volume;
int volume_i; int volume_i;
int channels; int channels;