MPD: decoder/DecoderControl.hxx Source File

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
63 struct DecoderControl {
67 Thread thread;
68
77 Mutex &mutex;
78
84 Cond cond;
85
92 Cond &client_cond;
93
94 DecoderState state = DecoderState::STOP;
95 DecoderCommand command = DecoderCommand::NONE;
96
103 std::exception_ptr error;
104
105 bool quit;
106
112 bool client_is_waiting = false;
113
114 bool seek_error;
115 bool seekable;
116 SongTime seek_time;
117
121 const AudioFormat configured_audio_format;
122
124 AudioFormat in_audio_format;
125
127 AudioFormat out_audio_format;
128
137 DetachedSong *song = nullptr;
138
145 SongTime start_time;
146
153 SongTime end_time;
154
155 SignedSongTime total_time;
156
158 MusicBuffer *buffer;
159
164 MusicPipe *pipe;
165
166 const ReplayGainConfig replay_gain_config;
167 ReplayGainMode replay_gain_mode = ReplayGainMode::OFF;
168
169 float replay_gain_db = 0;
170 float replay_gain_prev_db = 0;
171
172 MixRampInfo mix_ramp, previous_mix_ramp;
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 ||
226 state == DecoderState::ERROR;
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);
285 CheckRethrowError();
286 }
287
293 void ClearError() {
294 if (state == DecoderState::ERROR) {
295 error = std::exception_ptr();
296 state = DecoderState::STOP;
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:
368 void CommandFinishedLocked() {
369 assert(command != DecoderCommand::NONE);
370
371 command = DecoderCommand::NONE;
372 client_cond.signal();
373 }
374
385 void Start(DetachedSong *song, SongTime start_time, SongTime end_time,
386 MusicBuffer &buffer, MusicPipe &pipe);
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
DecoderControl::Wait
void Wait()
Waits for a signal on the DecoderControl object.
Definition: DecoderControl.hxx:211
DecoderControl::ClearError
void ClearError()
Clear the error condition and free the #Error object (if any).
Definition: DecoderControl.hxx:293
ReplayGainMode
ReplayGainMode
Definition: ReplayGainMode.hxx:27
MixRampInfo::GetEnd
gcc_pure const char * GetEnd() const noexcept
Definition: MixRampInfo.hxx:50
AudioFormat
This structure describes the format of a raw PCM stream.
Definition: AudioFormat.hxx:37
DecoderControl::LockHasFailed
gcc_pure bool LockHasFailed() const noexcept
Definition: DecoderControl.hxx:252
DecoderControl::total_time
SignedSongTime total_time
Definition: DecoderControl.hxx:155
ReplayGainMode.hxx
DecoderControl::error
std::exception_ptr error
The error that occurred in the decoder thread.
Definition: DecoderControl.hxx:103
Chrono.hxx
DecoderControl::IsCurrentSong
gcc_pure bool IsCurrentSong(const DetachedSong &_song) const noexcept
Check if the specified song is currently being decoded.
MusicPipe
A queue of MusicChunk objects.
Definition: MusicPipe.hxx:39
DecoderControl::CycleMixRamp
void CycleMixRamp()
Move mixramp_end to mixramp_prev_end and clear mixramp_start/mixramp_end.
DecoderControl::GetMixRampPreviousEnd
const char * GetMixRampPreviousEnd() const
Definition: DecoderControl.hxx:405
AudioFormat.hxx
SongTime
A time stamp within a song.
Definition: Chrono.hxx:31
ReplayGainConfig
Definition: ReplayGainConfig.hxx:25
DecoderControl::quit
bool quit
Definition: DecoderControl.hxx:105
DecoderCommand::NONE
DecoderControl::song
DetachedSong * song
The song currently being decoded.
Definition: DecoderControl.hxx:137
PosixCond::wait
void wait(PosixMutex &mutex)
Definition: PosixCond.hxx:73
DecoderControl::Signal
void Signal()
Signals the object.
Definition: DecoderControl.hxx:202
DecoderControl::replay_gain_prev_db
float replay_gain_prev_db
Definition: DecoderControl.hxx:170
DecoderControl::in_audio_format
AudioFormat in_audio_format
the format of the song file
Definition: DecoderControl.hxx:124
DecoderControl::cond
Cond cond
Trigger this object after you have modified command.
Definition: DecoderControl.hxx:84
Cond
Definition: Cond.hxx:41
Mutex
Definition: Mutex.hxx:43
DecoderControl::previous_mix_ramp
MixRampInfo previous_mix_ramp
Definition: DecoderControl.hxx:172
DecoderControl::thread
Thread thread
The handle of the decoder thread.
Definition: DecoderControl.hxx:67
DecoderControl::LockIsIdle
gcc_pure bool LockIsIdle() const noexcept
Definition: DecoderControl.hxx:230
DecoderCommand::STOP
DecoderControl::Stop
void Stop()
DecoderControl::end_time
SongTime end_time
The decoder will stop when it reaches this position.
Definition: DecoderControl.hxx:153
DecoderControl
Definition: DecoderControl.hxx:63
DecoderControl::replay_gain_db
float replay_gain_db
Definition: DecoderControl.hxx:169
DecoderControl::Seek
void Seek(SongTime t)
Throws #std::runtime_error on error.
MusicBuffer
An allocator for MusicChunk objects.
Definition: MusicBuffer.hxx:31
MixRampInfo
Definition: MixRampInfo.hxx:28
Cond.hxx
DecoderControl::SetReady
void SetReady(const AudioFormat audio_format, bool _seekable, SignedSongTime _duration)
Transition this obejct from DecoderState::START to DecoderState::DECODE.
DecoderState::STOP
DecoderControl::buffer
MusicBuffer * buffer
the MusicChunk allocator
Definition: DecoderControl.hxx:158
Thread.hxx
DecoderControl::seek_time
SongTime seek_time
Definition: DecoderControl.hxx:116
DecoderCommand.hxx
DecoderControl::LockIsStarting
gcc_pure bool LockIsStarting() const noexcept
Definition: DecoderControl.hxx:240
DecoderControl::LockIsCurrentSong
gcc_pure bool LockIsCurrentSong(const DetachedSong &_song) const noexcept
Definition: DecoderControl.hxx:311
DecoderControl::Unlock
void Unlock() const
Unlocks the object.
Definition: DecoderControl.hxx:193
DecoderState::START
DecoderControl::replay_gain_mode
ReplayGainMode replay_gain_mode
Definition: DecoderControl.hxx:167
MixRampInfo::GetStart
gcc_pure const char * GetStart() const noexcept
Definition: MixRampInfo.hxx:45
DecoderControl::Quit
void Quit()
DecoderControl::CommandFinishedLocked
void CommandFinishedLocked()
Marks the current command as "finished" and notifies the client (= player thread).
Definition: DecoderControl.hxx:368
DecoderControl::pipe
MusicPipe * pipe
The destination pipe for decoded chunks.
Definition: DecoderControl.hxx:164
DecoderControl::SetMixRamp
void SetMixRamp(MixRampInfo &&new_value)
Definition: DecoderControl.hxx:409
DecoderControl::mix_ramp
MixRampInfo mix_ramp
Definition: DecoderControl.hxx:172
DecoderControl::seekable
bool seekable
Definition: DecoderControl.hxx:115
DecoderCommand::START
DecoderControl::DecoderControl
DecoderControl(Mutex &_mutex, Cond &_client_cond, const AudioFormat _configured_audio_format, const ReplayGainConfig &_replay_gain_config)
DecoderControl::Lock
void Lock() const
Locks the object.
Definition: DecoderControl.hxx:186
Mutex.hxx
ReplayGainConfig.hxx
DecoderState::ERROR
The last "START" command failed, because there was an I/O error or because no decoder was able to dec...
DecoderControl::LockCheckRethrowError
void LockCheckRethrowError() const
Like CheckRethrowError(), but locks and unlocks the object.
Definition: DecoderControl.hxx:283
DecoderControl::mutex
Mutex & mutex
This lock protects state and command.
Definition: DecoderControl.hxx:77
DecoderControl::client_is_waiting
bool client_is_waiting
Is the client currently waiting for the DecoderThread? If false, the DecoderThread may omit invoking ...
Definition: DecoderControl.hxx:112
DecoderControl::IsStarting
bool IsStarting() const noexcept
Definition: DecoderControl.hxx:235
DecoderControl::state
DecoderState state
Definition: DecoderControl.hxx:94
PosixMutex::unlock
void unlock()
Definition: PosixMutex.hxx:71
PosixCond::signal
void signal()
Definition: PosixCond.hxx:65
DecoderControl::HasFailed
bool HasFailed() const noexcept
Definition: DecoderControl.hxx:245
DecoderControl::GetMixRampEnd
const char * GetMixRampEnd() const
Definition: DecoderControl.hxx:401
DecoderCommand
DecoderCommand
Definition: DecoderCommand.hxx:25
SignedSongTime
A variant of SongTime that is based on a signed integer.
Definition: Chrono.hxx:115
ReplayGainMode::OFF
Thread
Definition: Thread.hxx:35
DecoderControl::GetMixRampStart
const char * GetMixRampStart() const
Definition: DecoderControl.hxx:397
DecoderControl::IsIdle
bool IsIdle() const
Definition: DecoderControl.hxx:224
DecoderState::DECODE
MixRampInfo.hxx
DecoderControl::seek_error
bool seek_error
Definition: DecoderControl.hxx:114
gcc_pure
#define gcc_pure
Definition: Compiler.h:116
DecoderControl::Start
void Start(DetachedSong *song, SongTime start_time, SongTime end_time, MusicBuffer &buffer, MusicPipe &pipe)
Start the decoder.
PosixMutex::lock
void lock()
Definition: PosixMutex.hxx:63
DecoderControl::command
DecoderCommand command
Definition: DecoderControl.hxx:95
DetachedSong
Definition: DetachedSong.hxx:37
DecoderControl::client_cond
Cond & client_cond
The trigger of this object&#39;s client.
Definition: DecoderControl.hxx:92
DecoderControl::~DecoderControl
~DecoderControl()
DecoderControl::configured_audio_format
const AudioFormat configured_audio_format
The "audio_output_format" setting.
Definition: DecoderControl.hxx:121
DecoderControl::out_audio_format
AudioFormat out_audio_format
the format being sent to the music pipe
Definition: DecoderControl.hxx:127
DecoderControl::replay_gain_config
const ReplayGainConfig replay_gain_config
Definition: DecoderControl.hxx:166
DecoderControl::CheckRethrowError
void CheckRethrowError() const
Checks whether an error has occurred, and if so, rethrows it.
Definition: DecoderControl.hxx:272
DecoderState
DecoderState
Definition: DecoderControl.hxx:49
DecoderControl::start_time
SongTime start_time
The initial seek position, e.g.
Definition: DecoderControl.hxx:145
DecoderControl::WaitForDecoder
void WaitForDecoder()
Waits for a signal from the decoder thread.