player, decoder, output: wrap MusicPipe in std::shared_ptr/std::unique_ptr

This commit is contained in:
Max Kellermann 2018-06-23 18:45:57 +02:00
parent 82954d1d6f
commit efb8a9bd2c
5 changed files with 26 additions and 29 deletions

View File

@ -92,16 +92,17 @@ DecoderControl::IsCurrentSong(const DetachedSong &_song) const noexcept
void void
DecoderControl::Start(std::unique_ptr<DetachedSong> _song, DecoderControl::Start(std::unique_ptr<DetachedSong> _song,
SongTime _start_time, SongTime _end_time, SongTime _start_time, SongTime _end_time,
MusicBuffer &_buffer, MusicPipe &_pipe) noexcept MusicBuffer &_buffer,
std::shared_ptr<MusicPipe> _pipe) noexcept
{ {
assert(_song != nullptr); assert(_song != nullptr);
assert(_pipe.IsEmpty()); assert(_pipe->IsEmpty());
song = std::move(_song); song = std::move(_song);
start_time = _start_time; start_time = _start_time;
end_time = _end_time; end_time = _end_time;
buffer = &_buffer; buffer = &_buffer;
pipe = &_pipe; pipe = std::move(_pipe);
ClearError(); ClearError();
SynchronousCommandLocked(DecoderCommand::START); SynchronousCommandLocked(DecoderCommand::START);

View File

@ -159,7 +159,7 @@ struct DecoderControl final : InputStreamHandler {
* The destination pipe for decoded chunks. The caller thread * The destination pipe for decoded chunks. The caller thread
* owns this object, and is responsible for freeing it. * owns this object, and is responsible for freeing it.
*/ */
MusicPipe *pipe; std::shared_ptr<MusicPipe> pipe;
const ReplayGainConfig replay_gain_config; const ReplayGainConfig replay_gain_config;
ReplayGainMode replay_gain_mode = ReplayGainMode::OFF; ReplayGainMode replay_gain_mode = ReplayGainMode::OFF;
@ -383,7 +383,8 @@ public:
*/ */
void Start(std::unique_ptr<DetachedSong> song, void Start(std::unique_ptr<DetachedSong> song,
SongTime start_time, SongTime end_time, SongTime start_time, SongTime end_time,
MusicBuffer &buffer, MusicPipe &pipe) noexcept; MusicBuffer &buffer,
std::shared_ptr<MusicPipe> pipe) noexcept;
/** /**
* Caller must lock the object. * Caller must lock the object.

View File

@ -230,7 +230,7 @@ MultipleOutputs::Open(const AudioFormat audio_format)
assert(pipe == nullptr || pipe->CheckFormat(audio_format)); assert(pipe == nullptr || pipe->CheckFormat(audio_format));
if (pipe == nullptr) if (pipe == nullptr)
pipe = new MusicPipe(); pipe = std::make_unique<MusicPipe>();
else else
/* if the pipe hasn't been cleared, the the audio /* if the pipe hasn't been cleared, the the audio
format must not have changed */ format must not have changed */
@ -402,8 +402,7 @@ MultipleOutputs::Close() noexcept
for (auto *ao : outputs) for (auto *ao : outputs)
ao->LockCloseWait(); ao->LockCloseWait();
delete pipe; pipe.reset();
pipe = nullptr;
input_audio_format.Clear(); input_audio_format.Clear();
@ -416,8 +415,7 @@ MultipleOutputs::Release() noexcept
for (auto *ao : outputs) for (auto *ao : outputs)
ao->LockRelease(); ao->LockRelease();
delete pipe; pipe.reset();
pipe = nullptr;
input_audio_format.Clear(); input_audio_format.Clear();

View File

@ -55,7 +55,7 @@ class MultipleOutputs final : public PlayerOutputs {
* The #MusicPipe object which feeds all audio outputs. It is * The #MusicPipe object which feeds all audio outputs. It is
* filled by Play(). * filled by Play().
*/ */
MusicPipe *pipe = nullptr; std::unique_ptr<MusicPipe> pipe;
/** /**
* The "elapsed_time" stamp of the most recently finished * The "elapsed_time" stamp of the most recently finished

View File

@ -36,6 +36,7 @@
#include "Log.hxx" #include "Log.hxx"
#include <exception> #include <exception>
#include <memory>
#include <string.h> #include <string.h>
@ -48,7 +49,7 @@ class Player {
MusicBuffer &buffer; MusicBuffer &buffer;
MusicPipe *pipe; std::shared_ptr<MusicPipe> pipe;
/** /**
* the song currently being played * the song currently being played
@ -169,10 +170,10 @@ private:
xfade_state = CrossFadeState::UNKNOWN; xfade_state = CrossFadeState::UNKNOWN;
} }
void ReplacePipe(MusicPipe *_pipe) noexcept { template<typename P>
void ReplacePipe(P &&_pipe) noexcept {
ResetCrossFade(); ResetCrossFade();
delete pipe; pipe = std::forward<P>(_pipe);
pipe = _pipe;
} }
/** /**
@ -180,7 +181,7 @@ private:
* *
* Caller must lock the mutex. * Caller must lock the mutex.
*/ */
void StartDecoder(MusicPipe &pipe) noexcept; void StartDecoder(std::shared_ptr<MusicPipe> pipe) noexcept;
/** /**
* The decoder has acknowledged the "START" command (see * The decoder has acknowledged the "START" command (see
@ -325,7 +326,7 @@ public:
}; };
void void
Player::StartDecoder(MusicPipe &_pipe) noexcept Player::StartDecoder(std::shared_ptr<MusicPipe> _pipe) noexcept
{ {
assert(queued || pc.command == PlayerCommand::SEEK); assert(queued || pc.command == PlayerCommand::SEEK);
assert(pc.next_song != nullptr); assert(pc.next_song != nullptr);
@ -337,7 +338,7 @@ Player::StartDecoder(MusicPipe &_pipe) noexcept
dc.Start(std::make_unique<DetachedSong>(*pc.next_song), dc.Start(std::make_unique<DetachedSong>(*pc.next_song),
start_time, pc.next_song->GetEndTime(), start_time, pc.next_song->GetEndTime(),
buffer, _pipe); buffer, std::move(_pipe));
} }
void void
@ -351,11 +352,7 @@ Player::StopDecoder() noexcept
/* clear and free the decoder pipe */ /* clear and free the decoder pipe */
dc.pipe->Clear(); dc.pipe->Clear();
dc.pipe.reset();
if (dc.pipe != pipe)
delete dc.pipe;
dc.pipe = nullptr;
/* just in case we've been cross-fading: cancel it /* just in case we've been cross-fading: cancel it
now, because we just deleted the new song's decoder now, because we just deleted the new song's decoder
@ -577,7 +574,7 @@ Player::SeekDecoder() noexcept
pipe->Clear(); pipe->Clear();
/* re-start the decoder */ /* re-start the decoder */
StartDecoder(*pipe); StartDecoder(pipe);
ActivateDecoder(); ActivateDecoder();
pc.seeking = true; pc.seeking = true;
@ -655,7 +652,7 @@ Player::ProcessCommand() noexcept
pc.CommandFinished(); pc.CommandFinished();
if (dc.IsIdle()) if (dc.IsIdle())
StartDecoder(*new MusicPipe()); StartDecoder(std::make_shared<MusicPipe>());
break; break;
@ -926,11 +923,11 @@ Player::SongBorder() noexcept
inline void inline void
Player::Run() noexcept Player::Run() noexcept
{ {
pipe = new MusicPipe(); pipe = std::make_shared<MusicPipe>();
const std::lock_guard<Mutex> lock(pc.mutex); const std::lock_guard<Mutex> lock(pc.mutex);
StartDecoder(*pipe); StartDecoder(pipe);
ActivateDecoder(); ActivateDecoder();
pc.state = PlayerState::PLAY; pc.state = PlayerState::PLAY;
@ -973,7 +970,7 @@ Player::Run() noexcept
assert(dc.pipe == nullptr || dc.pipe == pipe); assert(dc.pipe == nullptr || dc.pipe == pipe);
StartDecoder(*new MusicPipe()); StartDecoder(std::make_shared<MusicPipe>());
} }
if (/* no cross-fading if MPD is going to pause at the if (/* no cross-fading if MPD is going to pause at the
@ -1057,7 +1054,7 @@ Player::Run() noexcept
CancelPendingSeek(); CancelPendingSeek();
StopDecoder(); StopDecoder();
delete pipe; pipe.reset();
cross_fade_tag.reset(); cross_fade_tag.reset();