diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-03-24 15:04:47 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-03-24 15:04:47 +0100 |
commit | 8de75f703adafced474ddf748c46d091ee0a8f4a (patch) | |
tree | 994e24bf92fa5c758a9b02e531aab8f947505d8f /libavfilter/af_volume.c | |
parent | 3e1f24131ac018c8b4bcc852a02ccfadf20d1dbb (diff) | |
parent | 06c3cd3c0186803619bc6aad2d8f06c3e9015d15 (diff) | |
download | ffmpeg-8de75f703adafced474ddf748c46d091ee0a8f4a.tar.gz |
Merge commit '06c3cd3c0186803619bc6aad2d8f06c3e9015d15'
* commit '06c3cd3c0186803619bc6aad2d8f06c3e9015d15':
af_volume: support using replaygain frame side data
Conflicts:
doc/filters.texi
libavfilter/af_volume.c
libavfilter/af_volume.h
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavfilter/af_volume.c')
-rw-r--r-- | libavfilter/af_volume.c | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/libavfilter/af_volume.c b/libavfilter/af_volume.c index 4ec78b1486..5dfec06fcf 100644 --- a/libavfilter/af_volume.c +++ b/libavfilter/af_volume.c @@ -28,7 +28,10 @@ #include "libavutil/common.h" #include "libavutil/eval.h" #include "libavutil/float_dsp.h" +#include "libavutil/intreadwrite.h" #include "libavutil/opt.h" +#include "libavutil/replaygain.h" + #include "audio.h" #include "avfilter.h" #include "formats.h" @@ -70,7 +73,13 @@ static const AVOption volume_options[] = { { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_ONCE}, 0, EVAL_MODE_NB-1, .flags = A|F, "eval" }, { "once", "eval volume expression once", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_ONCE}, .flags = A|F, .unit = "eval" }, { "frame", "eval volume expression per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = A|F, .unit = "eval" }, - { NULL } + { "replaygain", "Apply replaygain side data when present", + OFFSET(replaygain), AV_OPT_TYPE_INT, { .i64 = REPLAYGAIN_DROP }, REPLAYGAIN_DROP, REPLAYGAIN_ALBUM, A, "replaygain" }, + { "drop", "replaygain side data is dropped", 0, AV_OPT_TYPE_CONST, { .i64 = REPLAYGAIN_DROP }, 0, 0, A, "replaygain" }, + { "ignore", "replaygain side data is ignored", 0, AV_OPT_TYPE_CONST, { .i64 = REPLAYGAIN_IGNORE }, 0, 0, A, "replaygain" }, + { "track", "track gain is preferred", 0, AV_OPT_TYPE_CONST, { .i64 = REPLAYGAIN_TRACK }, 0, 0, A, "replaygain" }, + { "album", "album gain is preferred", 0, AV_OPT_TYPE_CONST, { .i64 = REPLAYGAIN_ALBUM }, 0, 0, A, "replaygain" }, + { NULL }, }; AVFILTER_DEFINE_CLASS(volume); @@ -325,8 +334,38 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) int nb_samples = buf->nb_samples; AVFrame *out_buf; int64_t pos; + AVFrameSideData *sd = av_frame_get_side_data(buf, AV_FRAME_DATA_REPLAYGAIN); int ret; + if (sd && vol->replaygain != REPLAYGAIN_IGNORE) { + if (vol->replaygain != REPLAYGAIN_DROP) { + AVReplayGain *replaygain = (AVReplayGain*)sd->data; + int32_t gain; + float g; + + if (vol->replaygain == REPLAYGAIN_TRACK && + replaygain->track_gain != INT32_MIN) + gain = replaygain->track_gain; + else if (replaygain->album_gain != INT32_MIN) + gain = replaygain->album_gain; + else { + av_log(inlink->dst, AV_LOG_WARNING, "Both ReplayGain gain " + "values are unknown.\n"); + gain = 100000; + } + g = gain / 100000.0f; + + av_log(inlink->dst, AV_LOG_VERBOSE, + "Using gain %f dB from replaygain side data.\n", g); + + vol->volume = pow(10, g / 20); + vol->volume_i = (int)(vol->volume * 256 + 0.5); + + volume_init(vol); + } + av_frame_remove_side_data(buf, AV_FRAME_DATA_REPLAYGAIN); + } + if (isnan(vol->var_values[VAR_STARTPTS])) { vol->var_values[VAR_STARTPTS] = TS2D(buf->pts); vol->var_values[VAR_STARTT ] = TS2T(buf->pts, inlink->time_base); |