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
|
||||
* tags
|
||||
- ape: drop support for non-standard tag "album artist"
|
||||
* decoder
|
||||
- ffmpeg: support ReplayGain
|
||||
* output
|
||||
- pulse: set channel map to WAVE-EX
|
||||
* mixer
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include "../DecoderAPI.hxx"
|
||||
#include "FfmpegMetaData.hxx"
|
||||
#include "tag/TagHandler.hxx"
|
||||
#include "tag/ReplayGain.hxx"
|
||||
#include "tag/MixRamp.hxx"
|
||||
#include "input/InputStream.hxx"
|
||||
#include "CheckAudioFormat.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
@ -437,6 +439,58 @@ ffmpeg_probe(Decoder *decoder, InputStream &is)
|
|||
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
|
||||
ffmpeg_decode(Decoder &decoder, InputStream &input)
|
||||
{
|
||||
|
@ -541,6 +595,8 @@ ffmpeg_decode(Decoder &decoder, InputStream &input)
|
|||
decoder_initialized(decoder, audio_format,
|
||||
input.IsSeekable(), total_time);
|
||||
|
||||
FfmpegParseMetaData(decoder, *format_context, audio_stream);
|
||||
|
||||
#if LIBAVUTIL_VERSION_MAJOR >= 53
|
||||
AVFrame *frame = av_frame_alloc();
|
||||
#else
|
||||
|
|
Loading…
Reference in New Issue