summaryrefslogtreecommitdiff
path: root/libavfilter/af_volume.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2014-03-24 15:04:47 +0100
committerMichael Niedermayer <michaelni@gmx.at>2014-03-24 15:04:47 +0100
commit8de75f703adafced474ddf748c46d091ee0a8f4a (patch)
tree994e24bf92fa5c758a9b02e531aab8f947505d8f /libavfilter/af_volume.c
parent3e1f24131ac018c8b4bcc852a02ccfadf20d1dbb (diff)
parent06c3cd3c0186803619bc6aad2d8f06c3e9015d15 (diff)
downloadffmpeg-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.c41
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);