MPD  0.20.18
DecoderControl.hxx
Go to the documentation of this file.
1 /*
2  * Copyright 2003-2017 The Music Player Daemon Project
3  * http://www.musicpd.org
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #ifndef MPD_DECODER_CONTROL_HXX
21 #define MPD_DECODER_CONTROL_HXX
22 
23 #include "DecoderCommand.hxx"
24 #include "AudioFormat.hxx"
25 #include "MixRampInfo.hxx"
26 #include "thread/Mutex.hxx"
27 #include "thread/Cond.hxx"
28 #include "thread/Thread.hxx"
29 #include "Chrono.hxx"
30 #include "ReplayGainConfig.hxx"
31 #include "ReplayGainMode.hxx"
32 
33 #include <exception>
34 
35 #include <utility>
36 
37 #include <assert.h>
38 #include <stdint.h>
39 
40 /* damn you, windows.h! */
41 #ifdef ERROR
42 #undef ERROR
43 #endif
44 
45 class DetachedSong;
46 class MusicBuffer;
47 class MusicPipe;
48 
49 enum class DecoderState : uint8_t {
50  STOP = 0,
51  START,
52  DECODE,
53 
60  ERROR,
61 };
62 
68 
78 
85 
93 
96 
103  std::exception_ptr error;
104 
105  bool quit;
106 
112  bool client_is_waiting = false;
113 
115  bool seekable;
117 
122 
125 
128 
137  DetachedSong *song = nullptr;
138 
146 
154 
156 
159 
165 
168 
169  float replay_gain_db = 0;
171 
173 
178  DecoderControl(Mutex &_mutex, Cond &_client_cond,
179  const AudioFormat _configured_audio_format,
180  const ReplayGainConfig &_replay_gain_config);
181  ~DecoderControl();
182 
186  void Lock() const {
187  mutex.lock();
188  }
189 
193  void Unlock() const {
194  mutex.unlock();
195  }
196 
202  void Signal() {
203  cond.signal();
204  }
205 
211  void Wait() {
212  cond.wait(mutex);
213  }
214 
222  void WaitForDecoder();
223 
224  bool IsIdle() const {
225  return state == DecoderState::STOP ||
227  }
228 
229  gcc_pure
230  bool LockIsIdle() const noexcept {
231  const std::lock_guard<Mutex> protect(mutex);
232  return IsIdle();
233  }
234 
235  bool IsStarting() const noexcept {
236  return state == DecoderState::START;
237  }
238 
239  gcc_pure
240  bool LockIsStarting() const noexcept {
241  const std::lock_guard<Mutex> protect(mutex);
242  return IsStarting();
243  }
244 
245  bool HasFailed() const noexcept {
246  assert(command == DecoderCommand::NONE);
247 
248  return state == DecoderState::ERROR;
249  }
250 
251  gcc_pure
252  bool LockHasFailed() const noexcept {
253  const std::lock_guard<Mutex> protect(mutex);
254  return HasFailed();
255  }
256 
263  void SetReady(const AudioFormat audio_format,
264  bool _seekable, SignedSongTime _duration);
265 
272  void CheckRethrowError() const {
273  assert(command == DecoderCommand::NONE);
274  assert(state != DecoderState::ERROR || error);
275 
276  if (state == DecoderState::ERROR)
277  std::rethrow_exception(error);
278  }
279 
283  void LockCheckRethrowError() const {
284  const std::lock_guard<Mutex> protect(mutex);
286  }
287 
293  void ClearError() {
294  if (state == DecoderState::ERROR) {
295  error = std::exception_ptr();
297  }
298  }
299 
307  gcc_pure
308  bool IsCurrentSong(const DetachedSong &_song) const noexcept;
309 
310  gcc_pure
311  bool LockIsCurrentSong(const DetachedSong &_song) const noexcept {
312  const std::lock_guard<Mutex> protect(mutex);
313  return IsCurrentSong(_song);
314  }
315 
316 private:
323  void WaitCommandLocked() {
324  while (command != DecoderCommand::NONE)
325  WaitForDecoder();
326  }
327 
335  void SynchronousCommandLocked(DecoderCommand cmd) {
336  command = cmd;
337  Signal();
338  WaitCommandLocked();
339  }
340 
348  void LockSynchronousCommand(DecoderCommand cmd) {
349  const std::lock_guard<Mutex> protect(mutex);
350  ClearError();
351  SynchronousCommandLocked(cmd);
352  }
353 
354  void LockAsynchronousCommand(DecoderCommand cmd) {
355  const std::lock_guard<Mutex> protect(mutex);
356  command = cmd;
357  Signal();
358  }
359 
360 public:
369  assert(command != DecoderCommand::NONE);
370 
373  }
374 
387 
388  void Stop();
389 
393  void Seek(SongTime t);
394 
395  void Quit();
396 
397  const char *GetMixRampStart() const {
398  return mix_ramp.GetStart();
399  }
400 
401  const char *GetMixRampEnd() const {
402  return mix_ramp.GetEnd();
403  }
404 
405  const char *GetMixRampPreviousEnd() const {
406  return previous_mix_ramp.GetEnd();
407  }
408 
409  void SetMixRamp(MixRampInfo &&new_value) {
410  mix_ramp = std::move(new_value);
411  }
412 
417  void CycleMixRamp();
418 
419 private:
420  void RunThread();
421 };
422 
423 #endif
void Wait()
Waits for a signal on the DecoderControl object.
void ClearError()
Clear the error condition and free the #Error object (if any).
ReplayGainMode
gcc_pure const char * GetEnd() const noexcept
Definition: MixRampInfo.hxx:50
This structure describes the format of a raw PCM stream.
Definition: AudioFormat.hxx:37
gcc_pure bool LockHasFailed() const noexcept
SignedSongTime total_time
std::exception_ptr error
The error that occurred in the decoder thread.
gcc_pure bool IsCurrentSong(const DetachedSong &_song) const noexcept
Check if the specified song is currently being decoded.
A queue of MusicChunk objects.
Definition: MusicPipe.hxx:39
void CycleMixRamp()
Move mixramp_end to mixramp_prev_end and clear mixramp_start/mixramp_end.
const char * GetMixRampPreviousEnd() const
A time stamp within a song.
Definition: Chrono.hxx:31
DetachedSong * song
The song currently being decoded.
void wait(PosixMutex &mutex)
Definition: PosixCond.hxx:73
void Signal()
Signals the object.
AudioFormat in_audio_format
the format of the song file
Cond cond
Trigger this object after you have modified command.
Definition: Cond.hxx:41
Definition: Mutex.hxx:43
MixRampInfo previous_mix_ramp
Thread thread
The handle of the decoder thread.
gcc_pure bool LockIsIdle() const noexcept
SongTime end_time
The decoder will stop when it reaches this position.
void Seek(SongTime t)
Throws #std::runtime_error on error.
An allocator for MusicChunk objects.
Definition: MusicBuffer.hxx:31
void SetReady(const AudioFormat audio_format, bool _seekable, SignedSongTime _duration)
Transition this obejct from DecoderState::START to DecoderState::DECODE.
MusicBuffer * buffer
the MusicChunk allocator
gcc_pure bool LockIsStarting() const noexcept
gcc_pure bool LockIsCurrentSong(const DetachedSong &_song) const noexcept
void Unlock() const
Unlocks the object.
ReplayGainMode replay_gain_mode
gcc_pure const char * GetStart() const noexcept
Definition: MixRampInfo.hxx:45
void CommandFinishedLocked()
Marks the current command as "finished" and notifies the client (= player thread).
MusicPipe * pipe
The destination pipe for decoded chunks.
void SetMixRamp(MixRampInfo &&new_value)
MixRampInfo mix_ramp
DecoderControl(Mutex &_mutex, Cond &_client_cond, const AudioFormat _configured_audio_format, const ReplayGainConfig &_replay_gain_config)
void Lock() const
Locks the object.
The last "START" command failed, because there was an I/O error or because no decoder was able to dec...
void LockCheckRethrowError() const
Like CheckRethrowError(), but locks and unlocks the object.
Mutex & mutex
This lock protects state and command.
bool client_is_waiting
Is the client currently waiting for the DecoderThread? If false, the DecoderThread may omit invoking ...
bool IsStarting() const noexcept
DecoderState state
void unlock()
Definition: PosixMutex.hxx:71
void signal()
Definition: PosixCond.hxx:65
bool HasFailed() const noexcept
const char * GetMixRampEnd() const
DecoderCommand
A variant of SongTime that is based on a signed integer.
Definition: Chrono.hxx:115
const char * GetMixRampStart() const
bool IsIdle() const
#define gcc_pure
Definition: Compiler.h:116
void Start(DetachedSong *song, SongTime start_time, SongTime end_time, MusicBuffer &buffer, MusicPipe &pipe)
Start the decoder.
void lock()
Definition: PosixMutex.hxx:63
DecoderCommand command
Cond & client_cond
The trigger of this object&#39;s client.
const AudioFormat configured_audio_format
The "audio_output_format" setting.
AudioFormat out_audio_format
the format being sent to the music pipe
const ReplayGainConfig replay_gain_config
void CheckRethrowError() const
Checks whether an error has occurred, and if so, rethrows it.
DecoderState
SongTime start_time
The initial seek position, e.g.
void WaitForDecoder()
Waits for a signal from the decoder thread.