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