decoder/ffmpeg: support ReplayGain and MixRamp
This commit is contained in:
parent
d8926ea5eb
commit
fc1796f3e8
2
NEWS
2
NEWS
|
@ -5,6 +5,8 @@ ver 0.20 (not yet released)
|
||||||
- report song duration with milliseconds precision
|
- report song duration with milliseconds precision
|
||||||
* tags
|
* tags
|
||||||
- ape: drop support for non-standard tag "album artist"
|
- ape: drop support for non-standard tag "album artist"
|
||||||
|
* decoder
|
||||||
|
- ffmpeg: support ReplayGain
|
||||||
* output
|
* output
|
||||||
- pulse: set channel map to WAVE-EX
|
- pulse: set channel map to WAVE-EX
|
||||||
* mixer
|
* mixer
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#include "../DecoderAPI.hxx"
|
#include "../DecoderAPI.hxx"
|
||||||
#include "FfmpegMetaData.hxx"
|
#include "FfmpegMetaData.hxx"
|
||||||
#include "tag/TagHandler.hxx"
|
#include "tag/TagHandler.hxx"
|
||||||
|
#include "tag/ReplayGain.hxx"
|
||||||
|
#include "tag/MixRamp.hxx"
|
||||||
#include "input/InputStream.hxx"
|
#include "input/InputStream.hxx"
|
||||||
#include "CheckAudioFormat.hxx"
|
#include "CheckAudioFormat.hxx"
|
||||||
#include "util/Error.hxx"
|
#include "util/Error.hxx"
|
||||||
|
@ -437,6 +439,58 @@ ffmpeg_probe(Decoder *decoder, InputStream &is)
|
||||||
return av_probe_input_format(&avpd, true);
|
return av_probe_input_format(&avpd, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
FfmpegParseMetaData(AVDictionary &dict, ReplayGainInfo &rg, MixRampInfo &mr)
|
||||||
|
{
|
||||||
|
AVDictionaryEntry *i = nullptr;
|
||||||
|
|
||||||
|
while ((i = av_dict_get(&dict, "", i,
|
||||||
|
AV_DICT_IGNORE_SUFFIX)) != nullptr) {
|
||||||
|
const char *name = i->key;
|
||||||
|
const char *value = i->value;
|
||||||
|
|
||||||
|
if (!ParseReplayGainTag(rg, name, value))
|
||||||
|
ParseMixRampTag(mr, name, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
FfmpegParseMetaData(const AVStream &stream,
|
||||||
|
ReplayGainInfo &rg, MixRampInfo &mr)
|
||||||
|
{
|
||||||
|
FfmpegParseMetaData(*stream.metadata, rg, mr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
FfmpegParseMetaData(const AVFormatContext &format_context, int audio_stream,
|
||||||
|
ReplayGainInfo &rg, MixRampInfo &mr)
|
||||||
|
{
|
||||||
|
FfmpegParseMetaData(*format_context.metadata, rg, mr);
|
||||||
|
|
||||||
|
if (audio_stream >= 0)
|
||||||
|
FfmpegParseMetaData(*format_context.streams[audio_stream],
|
||||||
|
rg, mr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
FfmpegParseMetaData(Decoder &decoder,
|
||||||
|
const AVFormatContext &format_context, int audio_stream)
|
||||||
|
{
|
||||||
|
ReplayGainInfo rg;
|
||||||
|
rg.Clear();
|
||||||
|
|
||||||
|
MixRampInfo mr;
|
||||||
|
mr.Clear();
|
||||||
|
|
||||||
|
FfmpegParseMetaData(format_context, audio_stream, rg, mr);
|
||||||
|
|
||||||
|
if (rg.IsDefined())
|
||||||
|
decoder_replay_gain(decoder, &rg);
|
||||||
|
|
||||||
|
if (mr.IsDefined())
|
||||||
|
decoder_mixramp(decoder, std::move(mr));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ffmpeg_decode(Decoder &decoder, InputStream &input)
|
ffmpeg_decode(Decoder &decoder, InputStream &input)
|
||||||
{
|
{
|
||||||
|
@ -541,6 +595,8 @@ ffmpeg_decode(Decoder &decoder, InputStream &input)
|
||||||
decoder_initialized(decoder, audio_format,
|
decoder_initialized(decoder, audio_format,
|
||||||
input.IsSeekable(), total_time);
|
input.IsSeekable(), total_time);
|
||||||
|
|
||||||
|
FfmpegParseMetaData(decoder, *format_context, audio_stream);
|
||||||
|
|
||||||
#if LIBAVUTIL_VERSION_MAJOR >= 53
|
#if LIBAVUTIL_VERSION_MAJOR >= 53
|
||||||
AVFrame *frame = av_frame_alloc();
|
AVFrame *frame = av_frame_alloc();
|
||||||
#else
|
#else
|
||||||
|
|
Loading…
Reference in New Issue