From fc1796f3e8f2df6f7d4c94e43df853d45e9590f6 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 10 Dec 2014 13:05:16 +0100 Subject: decoder/ffmpeg: support ReplayGain and MixRamp --- src/decoder/plugins/FfmpegDecoderPlugin.cxx | 56 +++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'src/decoder') diff --git a/src/decoder/plugins/FfmpegDecoderPlugin.cxx b/src/decoder/plugins/FfmpegDecoderPlugin.cxx index 7adbb5899..9010b7402 100644 --- a/src/decoder/plugins/FfmpegDecoderPlugin.cxx +++ b/src/decoder/plugins/FfmpegDecoderPlugin.cxx @@ -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 -- cgit v1.2.3