From a0d43dd87f0979aaf42ed10dc40fffd2034adf0f Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 16 Oct 2020 18:38:43 +0200 Subject: [PATCH] decoder/opus: submit output_gain even if there is no OpusTags packet --- NEWS | 2 ++ src/decoder/plugins/OpusDecoderPlugin.cxx | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/NEWS b/NEWS index e654211b3..dae8a13eb 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ ver 0.22.1 (not yet released) +* decoder + - opus: apply the OpusHead output gain even if there is no EBU R128 tag * output - alsa: don't deadlock when the ALSA driver is buggy - jack, pulse: reduce the delay when stopping or pausing playback diff --git a/src/decoder/plugins/OpusDecoderPlugin.cxx b/src/decoder/plugins/OpusDecoderPlugin.cxx index 4257b31e5..e3022d8fc 100644 --- a/src/decoder/plugins/OpusDecoderPlugin.cxx +++ b/src/decoder/plugins/OpusDecoderPlugin.cxx @@ -123,6 +123,14 @@ class MPDOpusDecoder final : public OggDecoder { */ ogg_int64_t granulepos; + /** + * Was DecoderClient::SubmitReplayGain() called? We need to + * keep track of this, because it will usually be called by + * HandleTags(), but if there is no OpusTags packet, we need + * to submit our #output_gain value from the OpusHead. + */ + bool submitted_replay_gain = false; + public: explicit MPDOpusDecoder(DecoderReader &reader) :OggDecoder(reader) {} @@ -269,6 +277,7 @@ MPDOpusDecoder::HandleTags(const ogg_packet &packet) return; client.SubmitReplayGain(&rgi); + submitted_replay_gain = true; if (!tag_builder.empty()) { Tag tag = tag_builder.Commit(); @@ -283,6 +292,18 @@ MPDOpusDecoder::HandleAudio(const ogg_packet &packet) { assert(opus_decoder != nullptr); + if (!submitted_replay_gain) { + /* if we didn't see an OpusTags packet with EBU R128 + values, we still need to apply the output gain + value from the OpusHead packet; submit it as "track + gain" value */ + ReplayGainInfo rgi; + rgi.Clear(); + rgi.track.gain = EbuR128ToReplayGain(output_gain); + client.SubmitReplayGain(&rgi); + submitted_replay_gain = true; + } + int nframes = opus_decode(opus_decoder, (const unsigned char*)packet.packet, packet.bytes,