mirror of https://github.com/mpv-player/mpv
demux: move metadata-based replaygain decoding out of af_volume
This commit is contained in:
parent
da984c3648
commit
60e24fa842
|
@ -43,60 +43,6 @@ struct priv {
|
|||
float cfg_volume;
|
||||
};
|
||||
|
||||
static int decode_float(char *str, float *out)
|
||||
{
|
||||
char *rest;
|
||||
float dec_val;
|
||||
|
||||
dec_val = strtod(str, &rest);
|
||||
if (!rest || (rest == str) || !isfinite(dec_val))
|
||||
return -1;
|
||||
|
||||
*out = dec_val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_gain(struct af_instance *af, const char *tag, float *out)
|
||||
{
|
||||
char *tag_val = NULL;
|
||||
float dec_val;
|
||||
|
||||
tag_val = mp_tags_get_str(af->metadata, tag);
|
||||
if (!tag_val) {
|
||||
mp_msg(af->log, MSGL_V, "Replaygain tags not found\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (decode_float(tag_val, &dec_val)) {
|
||||
mp_msg(af->log, MSGL_ERR, "Invalid replaygain value\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*out = dec_val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_peak(struct af_instance *af, const char *tag, float *out)
|
||||
{
|
||||
char *tag_val = NULL;
|
||||
float dec_val;
|
||||
|
||||
*out = 1.0;
|
||||
|
||||
tag_val = mp_tags_get_str(af->metadata, tag);
|
||||
if (!tag_val)
|
||||
return 0;
|
||||
|
||||
if (decode_float(tag_val, &dec_val))
|
||||
return 0;
|
||||
|
||||
if (dec_val == 0.0)
|
||||
return 0;
|
||||
|
||||
*out = dec_val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int control(struct af_instance *af, int cmd, void *arg)
|
||||
{
|
||||
struct priv *s = af->priv;
|
||||
|
@ -116,40 +62,23 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
|||
if (af_fmt_is_planar(in->format))
|
||||
mp_audio_set_format(af->data, af_fmt_to_planar(af->data->format));
|
||||
s->rgain = 1.0;
|
||||
if ((s->rgain_track || s->rgain_album) &&
|
||||
(af->replaygain_data || af->metadata)) {
|
||||
if ((s->rgain_track || s->rgain_album) && af->replaygain_data) {
|
||||
float gain, peak;
|
||||
char *gain_tag = NULL, *peak_tag = NULL;
|
||||
|
||||
if (s->rgain_track) {
|
||||
if (af->replaygain_data) {
|
||||
gain = af->replaygain_data->track_gain;
|
||||
peak = af->replaygain_data->track_peak;
|
||||
} else {
|
||||
gain_tag = "REPLAYGAIN_TRACK_GAIN";
|
||||
peak_tag = "REPLAYGAIN_TRACK_PEAK";
|
||||
}
|
||||
} else if (s->rgain_album) {
|
||||
if (af->replaygain_data) {
|
||||
gain = af->replaygain_data->album_gain;
|
||||
peak = af->replaygain_data->album_peak;
|
||||
} else {
|
||||
gain_tag = "REPLAYGAIN_ALBUM_GAIN";
|
||||
peak_tag = "REPLAYGAIN_ALBUM_PEAK";
|
||||
}
|
||||
}
|
||||
|
||||
if (af->replaygain_data ||
|
||||
(!decode_gain(af, gain_tag, &gain) &&
|
||||
!decode_peak(af, peak_tag, &peak)))
|
||||
{
|
||||
gain += s->rgain_preamp;
|
||||
af_from_dB(1, &gain, &s->rgain, 20.0, -200.0, 60.0);
|
||||
|
||||
if (!s->rgain_clip) // clipping prevention
|
||||
s->rgain = MPMIN(s->rgain, 1.0 / peak);
|
||||
}
|
||||
}
|
||||
if (s->detach && fabs(s->level + s->rgain - 2.0) < 0.00001)
|
||||
return AF_DETACH;
|
||||
return af_test_output(af, in);
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
@ -497,6 +499,81 @@ static const char *d_level(enum demux_check level)
|
|||
abort();
|
||||
}
|
||||
|
||||
static int decode_float(char *str, float *out)
|
||||
{
|
||||
char *rest;
|
||||
float dec_val;
|
||||
|
||||
dec_val = strtod(str, &rest);
|
||||
if (!rest || (rest == str) || !isfinite(dec_val))
|
||||
return -1;
|
||||
|
||||
*out = dec_val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_gain(demuxer_t *demuxer, const char *tag, float *out)
|
||||
{
|
||||
char *tag_val = NULL;
|
||||
float dec_val;
|
||||
|
||||
tag_val = mp_tags_get_str(demuxer->metadata, tag);
|
||||
if (!tag_val) {
|
||||
mp_msg(demuxer->log, MSGL_V, "Replaygain tags not found\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (decode_float(tag_val, &dec_val)) {
|
||||
mp_msg(demuxer->log, MSGL_ERR, "Invalid replaygain value\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*out = dec_val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_peak(demuxer_t *demuxer, const char *tag, float *out)
|
||||
{
|
||||
char *tag_val = NULL;
|
||||
float dec_val;
|
||||
|
||||
*out = 1.0;
|
||||
|
||||
tag_val = mp_tags_get_str(demuxer->metadata, tag);
|
||||
if (!tag_val)
|
||||
return 0;
|
||||
|
||||
if (decode_float(tag_val, &dec_val))
|
||||
return 0;
|
||||
|
||||
if (dec_val == 0.0)
|
||||
return 0;
|
||||
|
||||
*out = dec_val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void demux_export_replaygain(demuxer_t *demuxer)
|
||||
{
|
||||
float tg, tp, ag, ap;
|
||||
|
||||
if (!demuxer->replaygain_data &&
|
||||
!decode_gain(demuxer, "REPLAYGAIN_TRACK_GAIN", &tg) &&
|
||||
!decode_peak(demuxer, "REPLAYGAIN_TRACK_PEAK", &tp) &&
|
||||
!decode_gain(demuxer, "REPLAYGAIN_ALBUM_GAIN", &ag) &&
|
||||
!decode_peak(demuxer, "REPLAYGAIN_ALBUM_PEAK", &ap))
|
||||
{
|
||||
struct replaygain_data *rgain = talloc_ptrtype(demuxer, rgain);
|
||||
|
||||
rgain->track_gain = tg;
|
||||
rgain->track_peak = tp;
|
||||
rgain->album_gain = ag;
|
||||
rgain->album_peak = ap;
|
||||
|
||||
demuxer->replaygain_data = rgain;
|
||||
}
|
||||
}
|
||||
|
||||
static struct demuxer *open_given_type(struct mpv_global *global,
|
||||
struct mp_log *log,
|
||||
const struct demuxer_desc *desc,
|
||||
|
@ -546,6 +623,7 @@ static struct demuxer *open_given_type(struct mpv_global *global,
|
|||
add_stream_chapters(demuxer);
|
||||
demuxer_sort_chapters(demuxer);
|
||||
demux_info_update(demuxer);
|
||||
demux_export_replaygain(demuxer);
|
||||
// Pretend we can seek if we can't seek, but there's a cache.
|
||||
if (!demuxer->seekable && stream->uncached_stream) {
|
||||
mp_warn(log,
|
||||
|
|
Loading…
Reference in New Issue