From f1ca61d7d7fac7a0a93daa244bf86c2ae7ebabd7 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 13 Nov 2013 19:10:43 +0100 Subject: DecoderInternal: allocate PcmConvert dynamically Reduce header dependencies and allow it to be nullptr to disable it. --- src/DecoderAPI.cxx | 33 +++++++++++++++++++++------------ src/DecoderInternal.cxx | 2 ++ src/DecoderInternal.hxx | 9 +++++++-- 3 files changed, 30 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/DecoderAPI.cxx b/src/DecoderAPI.cxx index 81d56fb06..a59999bb3 100644 --- a/src/DecoderAPI.cxx +++ b/src/DecoderAPI.cxx @@ -20,6 +20,7 @@ #include "config.h" #include "DecoderAPI.hxx" #include "DecoderError.hxx" +#include "pcm/PcmConvert.hxx" #include "AudioConfig.hxx" #include "ReplayGainConfig.hxx" #include "MusicChunk.hxx" @@ -47,6 +48,7 @@ decoder_initialized(Decoder &decoder, assert(dc.state == DecoderState::START); assert(dc.pipe != nullptr); + assert(decoder.convert == nullptr); assert(decoder.stream_tag == nullptr); assert(decoder.decoder_tag == nullptr); assert(!decoder.seeking); @@ -59,19 +61,22 @@ decoder_initialized(Decoder &decoder, dc.seekable = seekable; dc.total_time = total_time; - dc.Lock(); - dc.state = DecoderState::DECODE; - dc.client_cond.signal(); - dc.Unlock(); - FormatDebug(decoder_domain, "audio_format=%s, seekable=%s", audio_format_to_string(dc.in_audio_format, &af_string), seekable ? "true" : "false"); - if (dc.in_audio_format != dc.out_audio_format) + if (dc.in_audio_format != dc.out_audio_format) { FormatDebug(decoder_domain, "converting to %s", audio_format_to_string(dc.out_audio_format, &af_string)); + + decoder.convert = new PcmConvert(); + } + + dc.Lock(); + dc.state = DecoderState::DECODE; + dc.client_cond.signal(); + dc.Unlock(); } /** @@ -388,13 +393,15 @@ decoder_data(Decoder &decoder, return cmd; } - if (dc.in_audio_format != dc.out_audio_format) { + if (decoder.convert != nullptr) { + assert(dc.in_audio_format != dc.out_audio_format); + Error error; - data = decoder.conv_state.Convert(dc.in_audio_format, - data, length, - dc.out_audio_format, - &length, - error); + data = decoder.convert->Convert(dc.in_audio_format, + data, length, + dc.out_audio_format, + &length, + error); if (data == nullptr) { /* the PCM conversion has failed - stop playback, since we have no better way to @@ -402,6 +409,8 @@ decoder_data(Decoder &decoder, LogError(error); return DecoderCommand::STOP; } + } else { + assert(dc.in_audio_format == dc.out_audio_format); } while (length > 0) { diff --git a/src/DecoderInternal.cxx b/src/DecoderInternal.cxx index d4b125b29..26f91b2d9 100644 --- a/src/DecoderInternal.cxx +++ b/src/DecoderInternal.cxx @@ -20,6 +20,7 @@ #include "config.h" #include "DecoderInternal.hxx" #include "DecoderControl.hxx" +#include "pcm/PcmConvert.hxx" #include "MusicPipe.hxx" #include "MusicBuffer.hxx" #include "MusicChunk.hxx" @@ -32,6 +33,7 @@ Decoder::~Decoder() /* caller must flush the chunk */ assert(chunk == nullptr); + delete convert; delete song_tag; delete stream_tag; delete decoder_tag; diff --git a/src/DecoderInternal.hxx b/src/DecoderInternal.hxx index 37abb4427..e98e0aae3 100644 --- a/src/DecoderInternal.hxx +++ b/src/DecoderInternal.hxx @@ -21,9 +21,9 @@ #define MPD_DECODER_INTERNAL_HXX #include "DecoderCommand.hxx" -#include "pcm/PcmConvert.hxx" #include "ReplayGainInfo.hxx" +class PcmConvert; struct DecoderControl; struct InputStream; struct Tag; @@ -31,7 +31,11 @@ struct Tag; struct Decoder { DecoderControl &dc; - PcmConvert conv_state; + /** + * For converting input data to the configured audio format. + * nullptr means no conversion necessary. + */ + PcmConvert *convert; /** * The time stamp of the next data chunk, in seconds. @@ -85,6 +89,7 @@ struct Decoder { Decoder(DecoderControl &_dc, bool _initial_seek_pending, Tag *_tag) :dc(_dc), + convert(nullptr), timestamp(0), initial_seek_pending(_initial_seek_pending), initial_seek_running(false), -- cgit v1.2.3