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>
This commit is contained in:
commit
8de75f703a
@ -1830,6 +1830,23 @@ precision of the volume scaling.
|
|||||||
64-bit floating-point; limits input sample format to DBL.
|
64-bit floating-point; limits input sample format to DBL.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
@item replaygain
|
||||||
|
Behaviour on encountering ReplayGain side data in input frames.
|
||||||
|
|
||||||
|
@table @option
|
||||||
|
@item drop
|
||||||
|
Remove ReplayGain side data, ignoring its contents (the default).
|
||||||
|
|
||||||
|
@item ignore
|
||||||
|
Ignore ReplayGain side data, but leave it in the frame.
|
||||||
|
|
||||||
|
@item track
|
||||||
|
Prefer track gain, if present.
|
||||||
|
|
||||||
|
@item album
|
||||||
|
Prefer album gain, if present.
|
||||||
|
@end table
|
||||||
|
|
||||||
@item eval
|
@item eval
|
||||||
Set when the volume expression is evaluated.
|
Set when the volume expression is evaluated.
|
||||||
|
|
||||||
|
@ -28,7 +28,10 @@
|
|||||||
#include "libavutil/common.h"
|
#include "libavutil/common.h"
|
||||||
#include "libavutil/eval.h"
|
#include "libavutil/eval.h"
|
||||||
#include "libavutil/float_dsp.h"
|
#include "libavutil/float_dsp.h"
|
||||||
|
#include "libavutil/intreadwrite.h"
|
||||||
#include "libavutil/opt.h"
|
#include "libavutil/opt.h"
|
||||||
|
#include "libavutil/replaygain.h"
|
||||||
|
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
#include "avfilter.h"
|
#include "avfilter.h"
|
||||||
#include "formats.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" },
|
{ "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" },
|
{ "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" },
|
{ "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);
|
AVFILTER_DEFINE_CLASS(volume);
|
||||||
@ -325,8 +334,38 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
|
|||||||
int nb_samples = buf->nb_samples;
|
int nb_samples = buf->nb_samples;
|
||||||
AVFrame *out_buf;
|
AVFrame *out_buf;
|
||||||
int64_t pos;
|
int64_t pos;
|
||||||
|
AVFrameSideData *sd = av_frame_get_side_data(buf, AV_FRAME_DATA_REPLAYGAIN);
|
||||||
int ret;
|
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])) {
|
if (isnan(vol->var_values[VAR_STARTPTS])) {
|
||||||
vol->var_values[VAR_STARTPTS] = TS2D(buf->pts);
|
vol->var_values[VAR_STARTPTS] = TS2D(buf->pts);
|
||||||
vol->var_values[VAR_STARTT ] = TS2T(buf->pts, inlink->time_base);
|
vol->var_values[VAR_STARTT ] = TS2T(buf->pts, inlink->time_base);
|
||||||
|
@ -58,6 +58,13 @@ enum VolumeVarName {
|
|||||||
VAR_VARS_NB
|
VAR_VARS_NB
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ReplayGainType {
|
||||||
|
REPLAYGAIN_DROP,
|
||||||
|
REPLAYGAIN_IGNORE,
|
||||||
|
REPLAYGAIN_TRACK,
|
||||||
|
REPLAYGAIN_ALBUM,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct VolumeContext {
|
typedef struct VolumeContext {
|
||||||
const AVClass *class;
|
const AVClass *class;
|
||||||
AVFloatDSPContext fdsp;
|
AVFloatDSPContext fdsp;
|
||||||
@ -67,6 +74,7 @@ typedef struct VolumeContext {
|
|||||||
AVExpr *volume_pexpr;
|
AVExpr *volume_pexpr;
|
||||||
double var_values[VAR_VARS_NB];
|
double var_values[VAR_VARS_NB];
|
||||||
|
|
||||||
|
enum ReplayGainType replaygain;
|
||||||
double volume;
|
double volume;
|
||||||
int volume_i;
|
int volume_i;
|
||||||
int channels;
|
int channels;
|
||||||
|
Loading…
Reference in New Issue
Block a user