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 | |
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')
-rw-r--r-- | libavfilter/af_volume.c | 41 | ||||
-rw-r--r-- | libavfilter/af_volume.h | 8 |
2 files changed, 48 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); diff --git a/libavfilter/af_volume.h b/libavfilter/af_volume.h index 10ef6fbda3..9f81790ec3 100644 --- a/libavfilter/af_volume.h +++ b/libavfilter/af_volume.h @@ -58,6 +58,13 @@ enum VolumeVarName { VAR_VARS_NB }; +enum ReplayGainType { + REPLAYGAIN_DROP, + REPLAYGAIN_IGNORE, + REPLAYGAIN_TRACK, + REPLAYGAIN_ALBUM, +}; + typedef struct VolumeContext { const AVClass *class; AVFloatDSPContext fdsp; @@ -67,6 +74,7 @@ typedef struct VolumeContext { AVExpr *volume_pexpr; double var_values[VAR_VARS_NB]; + enum ReplayGainType replaygain; double volume; int volume_i; int channels; |