DecoderInternal: allocate PcmConvert dynamically
Reduce header dependencies and allow it to be nullptr to disable it.
This commit is contained in:
parent
a80b5cf19b
commit
f1ca61d7d7
@ -20,6 +20,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "DecoderAPI.hxx"
|
#include "DecoderAPI.hxx"
|
||||||
#include "DecoderError.hxx"
|
#include "DecoderError.hxx"
|
||||||
|
#include "pcm/PcmConvert.hxx"
|
||||||
#include "AudioConfig.hxx"
|
#include "AudioConfig.hxx"
|
||||||
#include "ReplayGainConfig.hxx"
|
#include "ReplayGainConfig.hxx"
|
||||||
#include "MusicChunk.hxx"
|
#include "MusicChunk.hxx"
|
||||||
@ -47,6 +48,7 @@ decoder_initialized(Decoder &decoder,
|
|||||||
|
|
||||||
assert(dc.state == DecoderState::START);
|
assert(dc.state == DecoderState::START);
|
||||||
assert(dc.pipe != nullptr);
|
assert(dc.pipe != nullptr);
|
||||||
|
assert(decoder.convert == nullptr);
|
||||||
assert(decoder.stream_tag == nullptr);
|
assert(decoder.stream_tag == nullptr);
|
||||||
assert(decoder.decoder_tag == nullptr);
|
assert(decoder.decoder_tag == nullptr);
|
||||||
assert(!decoder.seeking);
|
assert(!decoder.seeking);
|
||||||
@ -59,19 +61,22 @@ decoder_initialized(Decoder &decoder,
|
|||||||
dc.seekable = seekable;
|
dc.seekable = seekable;
|
||||||
dc.total_time = total_time;
|
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",
|
FormatDebug(decoder_domain, "audio_format=%s, seekable=%s",
|
||||||
audio_format_to_string(dc.in_audio_format, &af_string),
|
audio_format_to_string(dc.in_audio_format, &af_string),
|
||||||
seekable ? "true" : "false");
|
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",
|
FormatDebug(decoder_domain, "converting to %s",
|
||||||
audio_format_to_string(dc.out_audio_format,
|
audio_format_to_string(dc.out_audio_format,
|
||||||
&af_string));
|
&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;
|
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;
|
Error error;
|
||||||
data = decoder.conv_state.Convert(dc.in_audio_format,
|
data = decoder.convert->Convert(dc.in_audio_format,
|
||||||
data, length,
|
data, length,
|
||||||
dc.out_audio_format,
|
dc.out_audio_format,
|
||||||
&length,
|
&length,
|
||||||
error);
|
error);
|
||||||
if (data == nullptr) {
|
if (data == nullptr) {
|
||||||
/* the PCM conversion has failed - stop
|
/* the PCM conversion has failed - stop
|
||||||
playback, since we have no better way to
|
playback, since we have no better way to
|
||||||
@ -402,6 +409,8 @@ decoder_data(Decoder &decoder,
|
|||||||
LogError(error);
|
LogError(error);
|
||||||
return DecoderCommand::STOP;
|
return DecoderCommand::STOP;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
assert(dc.in_audio_format == dc.out_audio_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (length > 0) {
|
while (length > 0) {
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "DecoderInternal.hxx"
|
#include "DecoderInternal.hxx"
|
||||||
#include "DecoderControl.hxx"
|
#include "DecoderControl.hxx"
|
||||||
|
#include "pcm/PcmConvert.hxx"
|
||||||
#include "MusicPipe.hxx"
|
#include "MusicPipe.hxx"
|
||||||
#include "MusicBuffer.hxx"
|
#include "MusicBuffer.hxx"
|
||||||
#include "MusicChunk.hxx"
|
#include "MusicChunk.hxx"
|
||||||
@ -32,6 +33,7 @@ Decoder::~Decoder()
|
|||||||
/* caller must flush the chunk */
|
/* caller must flush the chunk */
|
||||||
assert(chunk == nullptr);
|
assert(chunk == nullptr);
|
||||||
|
|
||||||
|
delete convert;
|
||||||
delete song_tag;
|
delete song_tag;
|
||||||
delete stream_tag;
|
delete stream_tag;
|
||||||
delete decoder_tag;
|
delete decoder_tag;
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
#define MPD_DECODER_INTERNAL_HXX
|
#define MPD_DECODER_INTERNAL_HXX
|
||||||
|
|
||||||
#include "DecoderCommand.hxx"
|
#include "DecoderCommand.hxx"
|
||||||
#include "pcm/PcmConvert.hxx"
|
|
||||||
#include "ReplayGainInfo.hxx"
|
#include "ReplayGainInfo.hxx"
|
||||||
|
|
||||||
|
class PcmConvert;
|
||||||
struct DecoderControl;
|
struct DecoderControl;
|
||||||
struct InputStream;
|
struct InputStream;
|
||||||
struct Tag;
|
struct Tag;
|
||||||
@ -31,7 +31,11 @@ struct Tag;
|
|||||||
struct Decoder {
|
struct Decoder {
|
||||||
DecoderControl &dc;
|
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.
|
* 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)
|
Decoder(DecoderControl &_dc, bool _initial_seek_pending, Tag *_tag)
|
||||||
:dc(_dc),
|
:dc(_dc),
|
||||||
|
convert(nullptr),
|
||||||
timestamp(0),
|
timestamp(0),
|
||||||
initial_seek_pending(_initial_seek_pending),
|
initial_seek_pending(_initial_seek_pending),
|
||||||
initial_seek_running(false),
|
initial_seek_running(false),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user