mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
af_volume: support using replaygain frame side data
This commit is contained in:
parent
d161ae0a37
commit
06c3cd3c01
@ -616,6 +616,23 @@ precision of the volume scaling.
|
||||
@item double
|
||||
64-bit floating-point; limits input sample format to DBL.
|
||||
@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
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
|
@ -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"
|
||||
@ -50,6 +53,12 @@ static const AVOption options[] = {
|
||||
{ "fixed", "8-bit fixed-point.", 0, AV_OPT_TYPE_CONST, { .i64 = PRECISION_FIXED }, INT_MIN, INT_MAX, A, "precision" },
|
||||
{ "float", "32-bit floating-point.", 0, AV_OPT_TYPE_CONST, { .i64 = PRECISION_FLOAT }, INT_MIN, INT_MAX, A, "precision" },
|
||||
{ "double", "64-bit floating-point.", 0, AV_OPT_TYPE_CONST, { .i64 = PRECISION_DOUBLE }, INT_MIN, INT_MAX, A, "precision" },
|
||||
{ "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 },
|
||||
};
|
||||
|
||||
@ -229,8 +238,38 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
|
||||
AVFilterLink *outlink = inlink->dst->outputs[0];
|
||||
int nb_samples = buf->nb_samples;
|
||||
AVFrame *out_buf;
|
||||
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 (vol->volume == 1.0 || vol->volume_i == 256)
|
||||
return ff_filter_frame(outlink, buf);
|
||||
|
||||
|
@ -35,10 +35,18 @@ enum PrecisionType {
|
||||
PRECISION_DOUBLE,
|
||||
};
|
||||
|
||||
enum ReplayGainType {
|
||||
REPLAYGAIN_DROP,
|
||||
REPLAYGAIN_IGNORE,
|
||||
REPLAYGAIN_TRACK,
|
||||
REPLAYGAIN_ALBUM,
|
||||
};
|
||||
|
||||
typedef struct VolumeContext {
|
||||
const AVClass *class;
|
||||
AVFloatDSPContext fdsp;
|
||||
enum PrecisionType precision;
|
||||
enum ReplayGainType replaygain;
|
||||
double volume;
|
||||
int volume_i;
|
||||
int channels;
|
||||
|
Loading…
Reference in New Issue
Block a user