decoder/ffmpeg: support ReplayGain and MixRamp

This commit is contained in:
Max Kellermann 2014-12-10 13:05:16 +01:00
parent d8926ea5eb
commit fc1796f3e8
2 changed files with 58 additions and 0 deletions

2
NEWS
View File

@ -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

View File

@ -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