diff options
author | Max Kellermann <max@duempel.org> | 2014-12-10 13:05:16 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2014-12-10 13:45:29 +0100 |
commit | fc1796f3e8f2df6f7d4c94e43df853d45e9590f6 (patch) | |
tree | df9b0fcea836d143e9d1adb0fee8d6dc22930c03 | |
parent | d8926ea5eb3314794db5a12ea8b09474a3c78cd1 (diff) |
decoder/ffmpeg: support ReplayGain and MixRamp
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | src/decoder/plugins/FfmpegDecoderPlugin.cxx | 56 |
2 files changed, 58 insertions, 0 deletions
@@ -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 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" @@ -438,6 +440,58 @@ ffmpeg_probe(Decoder *decoder, InputStream &is) } 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) { AVInputFormat *input_format = ffmpeg_probe(&decoder, 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 |