Commit 32799fef authored by Max Kellermann's avatar Max Kellermann

DecoderControl: move functions into the class

parent e1b03b4a
......@@ -64,10 +64,10 @@ decoder_initialized(struct decoder *decoder,
dc->seekable = seekable;
dc->total_time = total_time;
decoder_lock(dc);
dc->Lock();
dc->state = DECODE_STATE_DECODE;
g_cond_signal(dc->client_cond);
decoder_unlock(dc);
dc->Unlock();
g_debug("audio_format=%s, seekable=%s",
audio_format_to_string(&dc->in_audio_format, &af_string),
......@@ -155,7 +155,7 @@ decoder_command_finished(struct decoder *decoder)
{
struct decoder_control *dc = decoder->dc;
decoder_lock(dc);
dc->Lock();
assert(dc->command != DECODE_COMMAND_NONE ||
decoder->initial_seek_running);
......@@ -171,7 +171,7 @@ decoder_command_finished(struct decoder *decoder)
decoder->initial_seek_running = false;
decoder->timestamp = dc->start_ms / 1000.;
decoder_unlock(dc);
dc->Unlock();
return;
}
......@@ -192,7 +192,7 @@ decoder_command_finished(struct decoder *decoder)
dc->command = DECODE_COMMAND_NONE;
g_cond_signal(dc->client_cond);
decoder_unlock(dc);
dc->Unlock();
}
double decoder_seek_where(G_GNUC_UNUSED struct decoder * decoder)
......@@ -377,9 +377,9 @@ decoder_data(struct decoder *decoder,
assert(dc->pipe != NULL);
assert(length % audio_format_frame_size(&dc->in_audio_format) == 0);
decoder_lock(dc);
dc->Lock();
cmd = decoder_get_virtual_command(decoder);
decoder_unlock(dc);
dc->Unlock();
if (cmd == DECODE_COMMAND_STOP || cmd == DECODE_COMMAND_SEEK ||
length == 0)
......@@ -564,6 +564,6 @@ decoder_mixramp(struct decoder *decoder,
struct decoder_control *dc = decoder->dc;
assert(dc != NULL);
dc_mixramp_start(dc, mixramp_start);
dc_mixramp_end(dc, mixramp_end);
dc->MixRampStart(mixramp_start);
dc->MixRampEnd(mixramp_end);
}
......@@ -27,46 +27,30 @@
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "decoder_control"
struct decoder_control *
dc_new()
decoder_control::decoder_control()
:thread(nullptr),
mutex(g_mutex_new()), cond(g_cond_new()),
client_cond(g_cond_new()),
state(DECODE_STATE_STOP),
command(DECODE_COMMAND_NONE),
song(nullptr),
replay_gain_db(0), replay_gain_prev_db(0),
mixramp_start(nullptr), mixramp_end(nullptr),
mixramp_prev_end(nullptr) {}
decoder_control::~decoder_control()
{
struct decoder_control *dc = g_new(struct decoder_control, 1);
ClearError();
dc->thread = NULL;
if (song != NULL)
song_free(song);
dc->mutex = g_mutex_new();
dc->cond = g_cond_new();
dc->client_cond = g_cond_new();
dc->state = DECODE_STATE_STOP;
dc->command = DECODE_COMMAND_NONE;
dc->song = NULL;
dc->replay_gain_db = 0;
dc->replay_gain_prev_db = 0;
dc->mixramp_start = NULL;
dc->mixramp_end = NULL;
dc->mixramp_prev_end = NULL;
return dc;
}
void
dc_free(struct decoder_control *dc)
{
dc_clear_error(dc);
if (dc->song != NULL)
song_free(dc->song);
g_cond_free(dc->client_cond);
g_cond_free(dc->cond);
g_mutex_free(dc->mutex);
g_free(dc->mixramp_start);
g_free(dc->mixramp_end);
g_free(dc->mixramp_prev_end);
g_free(dc);
g_cond_free(client_cond);
g_cond_free(cond);
g_mutex_free(mutex);
g_free(mixramp_start);
g_free(mixramp_end);
g_free(mixramp_prev_end);
}
static void
......@@ -80,45 +64,43 @@ static void
dc_command_locked(struct decoder_control *dc, enum decoder_command cmd)
{
dc->command = cmd;
decoder_signal(dc);
dc->Signal();
dc_command_wait_locked(dc);
}
static void
dc_command(struct decoder_control *dc, enum decoder_command cmd)
{
decoder_lock(dc);
dc_clear_error(dc);
dc->Lock();
dc->ClearError();
dc_command_locked(dc, cmd);
decoder_unlock(dc);
dc->Unlock();
}
static void
dc_command_async(struct decoder_control *dc, enum decoder_command cmd)
{
decoder_lock(dc);
dc->Lock();
dc->command = cmd;
decoder_signal(dc);
dc->Signal();
decoder_unlock(dc);
dc->Unlock();
}
bool
decoder_is_current_song(const struct decoder_control *dc,
const struct song *song)
decoder_control::IsCurrentSong(const struct song *_song) const
{
assert(dc != NULL);
assert(song != NULL);
assert(_song != NULL);
switch (dc->state) {
switch (state) {
case DECODE_STATE_STOP:
case DECODE_STATE_ERROR:
return false;
case DECODE_STATE_START:
case DECODE_STATE_DECODE:
return song_equals(dc->song, song);
return song_equals(song, _song);
}
assert(false);
......@@ -126,99 +108,91 @@ decoder_is_current_song(const struct decoder_control *dc,
}
void
dc_start(struct decoder_control *dc, struct song *song,
unsigned start_ms, unsigned end_ms,
struct music_buffer *buffer, struct music_pipe *pipe)
decoder_control::Start(struct song *_song,
unsigned _start_ms, unsigned _end_ms,
music_buffer *_buffer, music_pipe *_pipe)
{
assert(song != NULL);
assert(_song != NULL);
assert(buffer != NULL);
assert(pipe != NULL);
assert(music_pipe_empty(pipe));
if (dc->song != NULL)
song_free(dc->song);
if (song != nullptr)
song_free(song);
song = _song;
start_ms = _start_ms;
end_ms = _end_ms;
buffer = _buffer;
pipe = _pipe;
dc->song = song;
dc->start_ms = start_ms;
dc->end_ms = end_ms;
dc->buffer = buffer;
dc->pipe = pipe;
dc_command(dc, DECODE_COMMAND_START);
dc_command(this, DECODE_COMMAND_START);
}
void
dc_stop(struct decoder_control *dc)
decoder_control::Stop()
{
decoder_lock(dc);
Lock();
if (dc->command != DECODE_COMMAND_NONE)
if (command != DECODE_COMMAND_NONE)
/* Attempt to cancel the current command. If it's too
late and the decoder thread is already executing
the old command, we'll call STOP again in this
function (see below). */
dc_command_locked(dc, DECODE_COMMAND_STOP);
dc_command_locked(this, DECODE_COMMAND_STOP);
if (dc->state != DECODE_STATE_STOP && dc->state != DECODE_STATE_ERROR)
dc_command_locked(dc, DECODE_COMMAND_STOP);
if (state != DECODE_STATE_STOP && state != DECODE_STATE_ERROR)
dc_command_locked(this, DECODE_COMMAND_STOP);
decoder_unlock(dc);
Unlock();
}
bool
dc_seek(struct decoder_control *dc, double where)
decoder_control::Seek(double where)
{
assert(dc->state != DECODE_STATE_START);
assert(state != DECODE_STATE_START);
assert(where >= 0.0);
if (dc->state == DECODE_STATE_STOP ||
dc->state == DECODE_STATE_ERROR || !dc->seekable)
if (state == DECODE_STATE_STOP ||
state == DECODE_STATE_ERROR || !seekable)
return false;
dc->seek_where = where;
dc->seek_error = false;
dc_command(dc, DECODE_COMMAND_SEEK);
if (dc->seek_error)
return false;
seek_where = where;
seek_error = false;
dc_command(this, DECODE_COMMAND_SEEK);
return true;
return !seek_error;
}
void
dc_quit(struct decoder_control *dc)
decoder_control::Quit()
{
assert(dc->thread != NULL);
assert(thread != nullptr);
dc->quit = true;
dc_command_async(dc, DECODE_COMMAND_STOP);
quit = true;
dc_command_async(this, DECODE_COMMAND_STOP);
g_thread_join(dc->thread);
dc->thread = NULL;
g_thread_join(thread);
thread = nullptr;
}
void
dc_mixramp_start(struct decoder_control *dc, char *mixramp_start)
decoder_control::MixRampStart(char *_mixramp_start)
{
assert(dc != NULL);
g_free(dc->mixramp_start);
dc->mixramp_start = mixramp_start;
g_free(mixramp_start);
mixramp_start = _mixramp_start;
}
void
dc_mixramp_end(struct decoder_control *dc, char *mixramp_end)
decoder_control::MixRampEnd(char *_mixramp_end)
{
assert(dc != NULL);
g_free(dc->mixramp_end);
dc->mixramp_end = mixramp_end;
g_free(mixramp_end);
mixramp_end = _mixramp_end;
}
void
dc_mixramp_prev_end(struct decoder_control *dc, char *mixramp_prev_end)
decoder_control::MixRampPrevEnd(char *_mixramp_prev_end)
{
assert(dc != NULL);
g_free(dc->mixramp_prev_end);
dc->mixramp_prev_end = mixramp_prev_end;
g_free(mixramp_prev_end);
mixramp_prev_end = _mixramp_prev_end;
}
......@@ -130,6 +130,41 @@ struct decoder_control {
char *mixramp_end;
char *mixramp_prev_end;
decoder_control();
~decoder_control();
/**
* Locks the object.
*/
void Lock() const {
g_mutex_lock(mutex);
}
/**
* Unlocks the object.
*/
void Unlock() const {
g_mutex_unlock(mutex);
}
/**
* Signals the object. This function is only valid in the
* player thread. The object should be locked prior to
* calling this function.
*/
void Signal() {
g_cond_signal(cond);
}
/**
* Waits for a signal on the #decoder_control object. This function
* is only valid in the decoder thread. The object must be locked
* prior to calling this function.
*/
void Wait() {
g_cond_wait(cond, mutex);
}
/**
* Waits for a signal from the decoder thread. This object
* must be locked prior to calling this function. This method
......@@ -138,211 +173,123 @@ struct decoder_control {
void WaitForDecoder() {
g_cond_wait(client_cond, mutex);
}
};
G_GNUC_MALLOC
struct decoder_control *
dc_new();
void
dc_free(struct decoder_control *dc);
/**
* Locks the #decoder_control object.
*/
static inline void
decoder_lock(struct decoder_control *dc)
{
g_mutex_lock(dc->mutex);
}
/**
* Unlocks the #decoder_control object.
*/
static inline void
decoder_unlock(struct decoder_control *dc)
{
g_mutex_unlock(dc->mutex);
}
/**
* Waits for a signal on the #decoder_control object. This function
* is only valid in the decoder thread. The object must be locked
* prior to calling this function.
*/
static inline void
decoder_wait(struct decoder_control *dc)
{
g_cond_wait(dc->cond, dc->mutex);
}
/**
* Signals the #decoder_control object. This function is only valid
* in the player thread. The object should be locked prior to calling
* this function.
*/
static inline void
decoder_signal(struct decoder_control *dc)
{
g_cond_signal(dc->cond);
}
static inline bool
decoder_is_idle(const struct decoder_control *dc)
{
return dc->state == DECODE_STATE_STOP ||
dc->state == DECODE_STATE_ERROR;
}
static inline bool
decoder_is_starting(const struct decoder_control *dc)
{
return dc->state == DECODE_STATE_START;
}
static inline bool
decoder_has_failed(const struct decoder_control *dc)
{
assert(dc->command == DECODE_COMMAND_NONE);
return dc->state == DECODE_STATE_ERROR;
}
/**
* Checks whether an error has occurred, and if so, returns a newly
* allocated copy of the #GError object.
*
* Caller must lock the object.
*/
static inline GError *
dc_get_error(const struct decoder_control *dc)
{
assert(dc != NULL);
assert(dc->command == DECODE_COMMAND_NONE);
assert(dc->state != DECODE_STATE_ERROR || dc->error != NULL);
return dc->state == DECODE_STATE_ERROR
? g_error_copy(dc->error)
: NULL;
}
/**
* Like dc_get_error(), but locks and unlocks the object.
*/
static inline GError *
dc_lock_get_error(struct decoder_control *dc)
{
decoder_lock(dc);
GError *error = dc_get_error(dc);
decoder_unlock(dc);
return error;
}
/**
* Clear the error condition and free the #GError object (if any).
*
* Caller must lock the object.
*/
static inline void
dc_clear_error(struct decoder_control *dc)
{
if (dc->state == DECODE_STATE_ERROR) {
g_error_free(dc->error);
dc->state = DECODE_STATE_STOP;
bool IsIdle() const {
return state == DECODE_STATE_STOP ||
state == DECODE_STATE_ERROR;
}
}
static inline bool
decoder_lock_is_idle(struct decoder_control *dc)
{
bool ret;
gcc_pure
bool LockIsIdle() const {
Lock();
bool result = IsIdle();
Unlock();
return result;
}
decoder_lock(dc);
ret = decoder_is_idle(dc);
decoder_unlock(dc);
bool IsStarting() const {
return state == DECODE_STATE_START;
}
return ret;
}
gcc_pure
bool LockIsStarting() const {
Lock();
bool result = IsStarting();
Unlock();
return result;
}
static inline bool
decoder_lock_is_starting(struct decoder_control *dc)
{
bool ret;
bool HasFailed() const {
assert(command == DECODE_COMMAND_NONE);
decoder_lock(dc);
ret = decoder_is_starting(dc);
decoder_unlock(dc);
return state == DECODE_STATE_ERROR;
}
return ret;
}
gcc_pure
bool LockHasFailed() const {
Lock();
bool result = HasFailed();
Unlock();
return result;
}
static inline bool
decoder_lock_has_failed(struct decoder_control *dc)
{
bool ret;
/**
* Checks whether an error has occurred, and if so, returns a newly
* allocated copy of the #GError object.
*
* Caller must lock the object.
*/
GError *GetError() const {
assert(command == DECODE_COMMAND_NONE);
assert(state != DECODE_STATE_ERROR || error != nullptr);
decoder_lock(dc);
ret = decoder_has_failed(dc);
decoder_unlock(dc);
return state == DECODE_STATE_ERROR
? g_error_copy(error)
: nullptr;
}
return ret;
}
/**
* Like dc_get_error(), but locks and unlocks the object.
*/
GError *LockGetError() const {
Lock();
GError *result = GetError();
Unlock();
return result;
}
/**
* Check if the specified song is currently being decoded. If the
* decoder is not running currently (or being started), then this
* function returns false in any case.
*
* Caller must lock the object.
*/
gcc_pure
bool
decoder_is_current_song(const struct decoder_control *dc,
const struct song *song);
gcc_pure
static inline bool
decoder_lock_is_current_song(struct decoder_control *dc,
const struct song *song)
{
decoder_lock(dc);
const bool result = decoder_is_current_song(dc, song);
decoder_unlock(dc);
return result;
}
/**
* Start the decoder.
*
* @param the decoder
* @param song the song to be decoded; the given instance will be
* owned and freed by the decoder
* @param start_ms see #decoder_control
* @param end_ms see #decoder_control
* @param pipe the pipe which receives the decoded chunks (owned by
* the caller)
*/
void
dc_start(struct decoder_control *dc, struct song *song,
unsigned start_ms, unsigned end_ms,
struct music_buffer *buffer, struct music_pipe *pipe);
/**
* Clear the error condition and free the #GError object (if any).
*
* Caller must lock the object.
*/
void ClearError() {
if (state == DECODE_STATE_ERROR) {
g_error_free(error);
state = DECODE_STATE_STOP;
}
}
void
dc_stop(struct decoder_control *dc);
/**
* Check if the specified song is currently being decoded. If the
* decoder is not running currently (or being started), then this
* function returns false in any case.
*
* Caller must lock the object.
*/
gcc_pure
bool IsCurrentSong(const struct song *_song) const;
gcc_pure
bool LockIsCurrentSong(const struct song *_song) const {
Lock();
const bool result = IsCurrentSong(_song);
Unlock();
return result;
}
bool
dc_seek(struct decoder_control *dc, double where);
/**
* Start the decoder.
*
* @param song the song to be decoded; the given instance will be
* owned and freed by the decoder
* @param start_ms see #decoder_control
* @param end_ms see #decoder_control
* @param pipe the pipe which receives the decoded chunks (owned by
* the caller)
*/
void Start(struct song *song, unsigned start_ms, unsigned end_ms,
music_buffer *buffer, music_pipe *pipe);
void
dc_quit(struct decoder_control *dc);
void Stop();
void
dc_mixramp_start(struct decoder_control *dc, char *mixramp_start);
bool Seek(double where);
void
dc_mixramp_end(struct decoder_control *dc, char *mixramp_end);
void Quit();
void
dc_mixramp_prev_end(struct decoder_control *dc, char *mixramp_prev_end);
void MixRampStart(char *_mixramp_start);
void MixRampEnd(char *_mixramp_end);
void MixRampPrevEnd(char *_mixramp_prev_end);
};
#endif
......@@ -57,7 +57,7 @@ need_chunks(struct decoder_control *dc, bool do_wait)
return dc->command;
if (do_wait) {
decoder_wait(dc);
dc->Wait();
g_cond_signal(dc->client_cond);
return dc->command;
......@@ -89,9 +89,9 @@ decoder_get_chunk(struct decoder *decoder)
return decoder->chunk;
}
decoder_lock(dc);
dc->Lock();
cmd = need_chunks(dc, true);
decoder_unlock(dc);
dc->Unlock();
} while (cmd == DECODE_COMMAND_NONE);
return NULL;
......
......@@ -91,18 +91,18 @@ decoder_input_stream_open(struct decoder_control *dc, const char *uri)
/* wait for the input stream to become ready; its metadata
will be available then */
decoder_lock(dc);
dc->Lock();
input_stream_update(is);
while (!is->ready &&
dc->command != DECODE_COMMAND_STOP) {
decoder_wait(dc);
dc->Wait();
input_stream_update(is);
}
if (!input_stream_check(is, &error)) {
decoder_unlock(dc);
dc->Unlock();
g_warning("%s", error->message);
g_error_free(error);
......@@ -110,7 +110,7 @@ decoder_input_stream_open(struct decoder_control *dc, const char *uri)
return NULL;
}
decoder_unlock(dc);
dc->Unlock();
return is;
}
......@@ -137,11 +137,11 @@ decoder_stream_decode(const struct decoder_plugin *plugin,
/* rewind the stream, so each plugin gets a fresh start */
input_stream_seek(input_stream, 0, SEEK_SET, NULL);
decoder_unlock(decoder->dc);
decoder->dc->Unlock();
decoder_plugin_stream_decode(plugin, decoder, input_stream);
decoder_lock(decoder->dc);
decoder->dc->Lock();
assert(decoder->dc->state == DECODE_STATE_START ||
decoder->dc->state == DECODE_STATE_DECODE);
......@@ -167,11 +167,11 @@ decoder_file_decode(const struct decoder_plugin *plugin,
if (decoder->dc->command == DECODE_COMMAND_STOP)
return true;
decoder_unlock(decoder->dc);
decoder->dc->Unlock();
decoder_plugin_file_decode(plugin, decoder, path);
decoder_lock(decoder->dc);
decoder->dc->Lock();
assert(decoder->dc->state == DECODE_STATE_START ||
decoder->dc->state == DECODE_STATE_DECODE);
......@@ -280,15 +280,15 @@ decoder_run_stream(struct decoder *decoder, const char *uri)
struct input_stream *input_stream;
bool success;
decoder_unlock(dc);
dc->Unlock();
input_stream = decoder_input_stream_open(dc, uri);
if (input_stream == NULL) {
decoder_lock(dc);
dc->Lock();
return false;
}
decoder_lock(dc);
dc->Lock();
GSList *tried = NULL;
......@@ -305,9 +305,9 @@ decoder_run_stream(struct decoder *decoder, const char *uri)
g_slist_free(tried);
decoder_unlock(dc);
dc->Unlock();
input_stream_close(input_stream);
decoder_lock(dc);
dc->Lock();
return success;
}
......@@ -337,18 +337,18 @@ decoder_run_file(struct decoder *decoder, const char *path_fs)
if (suffix == NULL)
return false;
decoder_unlock(dc);
dc->Unlock();
decoder_load_replay_gain(decoder, path_fs);
while ((plugin = decoder_plugin_from_suffix(suffix, plugin)) != NULL) {
if (plugin->file_decode != NULL) {
decoder_lock(dc);
dc->Lock();
if (decoder_file_decode(plugin, decoder, path_fs))
return true;
decoder_unlock(dc);
dc->Unlock();
} else if (plugin->stream_decode != NULL) {
struct input_stream *input_stream;
bool success;
......@@ -357,23 +357,23 @@ decoder_run_file(struct decoder *decoder, const char *path_fs)
if (input_stream == NULL)
continue;
decoder_lock(dc);
dc->Lock();
success = decoder_stream_decode(plugin, decoder,
input_stream);
decoder_unlock(dc);
dc->Unlock();
input_stream_close(input_stream);
if (success) {
decoder_lock(dc);
dc->Lock();
return true;
}
}
}
decoder_lock(dc);
dc->Lock();
return false;
}
......@@ -394,14 +394,14 @@ decoder_run_song(struct decoder_control *dc,
? decoder_run_file(&decoder, uri)
: decoder_run_stream(&decoder, uri);
decoder_unlock(dc);
dc->Unlock();
/* flush the last chunk */
if (decoder.chunk != NULL)
decoder_flush_chunk(&decoder);
decoder_lock(dc);
dc->Lock();
if (ret)
dc->state = DECODE_STATE_STOP;
......@@ -424,7 +424,7 @@ decoder_run_song(struct decoder_control *dc,
static void
decoder_run(struct decoder_control *dc)
{
dc_clear_error(dc);
dc->ClearError();
const struct song *song = dc->song;
char *uri;
......@@ -455,7 +455,7 @@ decoder_task(gpointer arg)
{
struct decoder_control *dc = (struct decoder_control *)arg;
decoder_lock(dc);
dc->Lock();
do {
assert(dc->state == DECODE_STATE_STOP ||
......@@ -463,8 +463,8 @@ decoder_task(gpointer arg)
switch (dc->command) {
case DECODE_COMMAND_START:
dc_mixramp_start(dc, NULL);
dc_mixramp_prev_end(dc, dc->mixramp_end);
dc->MixRampStart(nullptr);
dc->MixRampPrevEnd(dc->mixramp_end);
dc->mixramp_end = NULL; /* Don't free, it's copied above. */
dc->replay_gain_prev_db = dc->replay_gain_db;
dc->replay_gain_db = 0;
......@@ -480,12 +480,12 @@ decoder_task(gpointer arg)
break;
case DECODE_COMMAND_NONE:
decoder_wait(dc);
dc->Wait();
break;
}
} while (dc->command != DECODE_COMMAND_NONE || !dc->quit);
decoder_unlock(dc);
dc->Unlock();
return NULL;
}
......
......@@ -176,9 +176,9 @@ player_dc_start(struct player *player, struct music_pipe *pipe)
if (pc->command == PLAYER_COMMAND_SEEK)
start_ms += (unsigned)(pc->seek_where * 1000);
dc_start(dc, song_dup_detached(pc->next_song),
start_ms, pc->next_song->end_ms,
player_buffer, pipe);
dc->Start(song_dup_detached(pc->next_song),
start_ms, pc->next_song->end_ms,
player_buffer, pipe);
}
/**
......@@ -217,7 +217,7 @@ player_dc_stop(struct player *player)
{
struct decoder_control *dc = player->dc;
dc_stop(dc);
dc->Stop();
if (dc->pipe != NULL) {
/* clear and free the decoder pipe */
......@@ -249,7 +249,7 @@ player_wait_for_decoder(struct player *player)
player->queued = false;
GError *error = dc_lock_get_error(dc);
GError *error = dc->LockGetError();
if (error != NULL) {
pc->Lock();
pc->SetError(PLAYER_ERROR_DECODER, error);
......@@ -369,22 +369,22 @@ player_check_decoder_startup(struct player *player)
assert(player->decoder_starting);
decoder_lock(dc);
dc->Lock();
GError *error = dc_get_error(dc);
GError *error = dc->GetError();
if (error != NULL) {
/* the decoder failed */
decoder_unlock(dc);
dc->Unlock();
pc->Lock();
pc->SetError(PLAYER_ERROR_DECODER, error);
pc->Unlock();
return false;
} else if (!decoder_is_starting(dc)) {
} else if (!dc->IsStarting()) {
/* the decoder is ready and ok */
decoder_unlock(dc);
dc->Unlock();
if (player->output_open &&
!audio_output_all_wait(pc, 1))
......@@ -414,7 +414,7 @@ player_check_decoder_startup(struct player *player)
/* the decoder is not yet ready; wait
some more */
dc->WaitForDecoder();
decoder_unlock(dc);
dc->Unlock();
return true;
}
......@@ -480,7 +480,7 @@ static bool player_seek_decoder(struct player *player)
const unsigned start_ms = song->start_ms;
if (!decoder_lock_is_current_song(dc, song)) {
if (!dc->LockIsCurrentSong(song)) {
/* the decoder is already decoding the "next" song -
stop it and start the previous song again */
......@@ -529,7 +529,7 @@ static bool player_seek_decoder(struct player *player)
if (where < 0.0)
where = 0.0;
if (!dc_seek(dc, where + start_ms / 1000.0)) {
if (!dc->Seek(where + start_ms / 1000.0)) {
/* decoder failure */
player_command_finished(pc);
return false;
......@@ -782,19 +782,19 @@ play_next_chunk(struct player *player)
} else {
/* there are not enough decoded chunks yet */
decoder_lock(dc);
dc->Lock();
if (decoder_is_idle(dc)) {
if (dc->IsIdle()) {
/* the decoder isn't running, abort
cross fading */
decoder_unlock(dc);
dc->Unlock();
player->xfade = XFADE_DISABLED;
} else {
/* wait for the decoder */
decoder_signal(dc);
dc->Signal();
dc->WaitForDecoder();
decoder_unlock(dc);
dc->Unlock();
return true;
}
......@@ -840,12 +840,12 @@ play_next_chunk(struct player *player)
/* this formula should prevent that the decoder gets woken up
with each chunk; it is more efficient to make it decode a
larger block at a time */
decoder_lock(dc);
if (!decoder_is_idle(dc) &&
dc->Lock();
if (!dc->IsIdle() &&
music_pipe_size(dc->pipe) <= (pc->buffered_before_play +
music_buffer_size(player_buffer) * 3) / 4)
decoder_signal(dc);
decoder_unlock(dc);
dc->Signal();
dc->Unlock();
return true;
}
......@@ -940,7 +940,7 @@ static void do_play(struct player_control *pc, struct decoder_control *dc)
prevent stuttering on slow machines */
if (music_pipe_size(player.pipe) < pc->buffered_before_play &&
!decoder_lock_is_idle(dc)) {
!dc->LockIsIdle()) {
/* not enough decoded buffer space yet */
if (!player.paused &&
......@@ -949,10 +949,10 @@ static void do_play(struct player_control *pc, struct decoder_control *dc)
!player_send_silence(&player))
break;
decoder_lock(dc);
dc->Lock();
/* XXX race condition: check decoder again */
dc->WaitForDecoder();
decoder_unlock(dc);
dc->Unlock();
pc->Lock();
continue;
} else {
......@@ -979,7 +979,7 @@ static void do_play(struct player_control *pc, struct decoder_control *dc)
*/
#endif
if (decoder_lock_is_idle(dc) && player.queued &&
if (dc->LockIsIdle() && player.queued &&
dc->pipe == player.pipe) {
/* the decoder has finished the current song;
make it decode the next song */
......@@ -994,7 +994,7 @@ static void do_play(struct player_control *pc, struct decoder_control *dc)
!pc->border_pause &&
player_dc_at_next_song(&player) &&
player.xfade == XFADE_UNKNOWN &&
!decoder_lock_is_starting(dc)) {
!dc->LockIsStarting()) {
/* enable cross fading in this song? if yes,
calculate how many chunks will be required
for it */
......@@ -1042,7 +1042,7 @@ static void do_play(struct player_control *pc, struct decoder_control *dc)
if (!player_song_border(&player))
break;
} else if (decoder_lock_is_idle(dc)) {
} else if (dc->LockIsIdle()) {
/* check the size of the pipe again, because
the decoder thread may have added something
since we last checked */
......@@ -1096,7 +1096,7 @@ player_task(gpointer arg)
{
struct player_control *pc = (struct player_control *)arg;
struct decoder_control *dc = dc_new();
struct decoder_control *dc = new decoder_control();
decoder_thread_start(dc);
player_buffer = music_buffer_new(pc->buffer_chunks);
......@@ -1156,8 +1156,8 @@ player_task(gpointer arg)
case PLAYER_COMMAND_EXIT:
pc->Unlock();
dc_quit(dc);
dc_free(dc);
dc->Quit();
delete dc;
audio_output_all_close();
music_buffer_free(player_buffer);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment