PlayerThread: move global MusicBuffer variable into the player object
This commit is contained in:
@@ -54,6 +54,8 @@ struct player {
|
|||||||
|
|
||||||
struct decoder_control *dc;
|
struct decoder_control *dc;
|
||||||
|
|
||||||
|
MusicBuffer &buffer;
|
||||||
|
|
||||||
MusicPipe *pipe;
|
MusicPipe *pipe;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -126,8 +128,9 @@ struct player {
|
|||||||
*/
|
*/
|
||||||
float elapsed_time;
|
float elapsed_time;
|
||||||
|
|
||||||
player(player_control *_pc, decoder_control *_dc)
|
player(player_control *_pc, decoder_control *_dc,
|
||||||
:pc(_pc), dc(_dc),
|
MusicBuffer &_buffer)
|
||||||
|
:pc(_pc), dc(_dc), buffer(_buffer),
|
||||||
buffering(false),
|
buffering(false),
|
||||||
decoder_starting(false),
|
decoder_starting(false),
|
||||||
paused(false),
|
paused(false),
|
||||||
@@ -141,8 +144,6 @@ struct player {
|
|||||||
elapsed_time(0.0) {}
|
elapsed_time(0.0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
static MusicBuffer *player_buffer;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
player_command_finished_locked(struct player_control *pc)
|
player_command_finished_locked(struct player_control *pc)
|
||||||
{
|
{
|
||||||
@@ -180,7 +181,7 @@ player_dc_start(struct player *player, MusicPipe &pipe)
|
|||||||
|
|
||||||
dc->Start(pc->next_song->DupDetached(),
|
dc->Start(pc->next_song->DupDetached(),
|
||||||
start_ms, pc->next_song->end_ms,
|
start_ms, pc->next_song->end_ms,
|
||||||
*player_buffer, pipe);
|
player->buffer, pipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -224,7 +225,7 @@ player_dc_stop(struct player *player)
|
|||||||
if (dc->pipe != NULL) {
|
if (dc->pipe != NULL) {
|
||||||
/* clear and free the decoder pipe */
|
/* clear and free the decoder pipe */
|
||||||
|
|
||||||
dc->pipe->Clear(*player_buffer);
|
dc->pipe->Clear(player->buffer);
|
||||||
|
|
||||||
if (dc->pipe != player->pipe)
|
if (dc->pipe != player->pipe)
|
||||||
delete dc->pipe;
|
delete dc->pipe;
|
||||||
@@ -328,7 +329,7 @@ player_open_output(struct player *player)
|
|||||||
pc->state == PLAYER_STATE_PAUSE);
|
pc->state == PLAYER_STATE_PAUSE);
|
||||||
|
|
||||||
Error error;
|
Error error;
|
||||||
if (audio_output_all_open(player->play_audio_format, *player_buffer,
|
if (audio_output_all_open(player->play_audio_format, player->buffer,
|
||||||
error)) {
|
error)) {
|
||||||
player->output_open = true;
|
player->output_open = true;
|
||||||
player->paused = false;
|
player->paused = false;
|
||||||
@@ -441,7 +442,7 @@ player_send_silence(struct player *player)
|
|||||||
assert(player->output_open);
|
assert(player->output_open);
|
||||||
assert(player->play_audio_format.IsDefined());
|
assert(player->play_audio_format.IsDefined());
|
||||||
|
|
||||||
struct music_chunk *chunk = player_buffer->Allocate();
|
struct music_chunk *chunk = player->buffer.Allocate();
|
||||||
if (chunk == NULL) {
|
if (chunk == NULL) {
|
||||||
g_warning("Failed to allocate silence buffer");
|
g_warning("Failed to allocate silence buffer");
|
||||||
return false;
|
return false;
|
||||||
@@ -463,7 +464,7 @@ player_send_silence(struct player *player)
|
|||||||
Error error;
|
Error error;
|
||||||
if (!audio_output_all_play(chunk, error)) {
|
if (!audio_output_all_play(chunk, error)) {
|
||||||
g_warning("%s", error.GetMessage());
|
g_warning("%s", error.GetMessage());
|
||||||
player_buffer->Return(chunk);
|
player->buffer.Return(chunk);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,7 +494,7 @@ static bool player_seek_decoder(struct player *player)
|
|||||||
|
|
||||||
/* clear music chunks which might still reside in the
|
/* clear music chunks which might still reside in the
|
||||||
pipe */
|
pipe */
|
||||||
player->pipe->Clear(*player_buffer);
|
player->pipe->Clear(player->buffer);
|
||||||
|
|
||||||
/* re-start the decoder */
|
/* re-start the decoder */
|
||||||
player_dc_start(player, *player->pipe);
|
player_dc_start(player, *player->pipe);
|
||||||
@@ -506,7 +507,7 @@ static bool player_seek_decoder(struct player *player)
|
|||||||
if (!player_dc_at_current_song(player)) {
|
if (!player_dc_at_current_song(player)) {
|
||||||
/* the decoder is already decoding the "next" song,
|
/* the decoder is already decoding the "next" song,
|
||||||
but it is the same song file; exchange the pipe */
|
but it is the same song file; exchange the pipe */
|
||||||
player->pipe->Clear(*player_buffer);
|
player->pipe->Clear(player->buffer);
|
||||||
delete player->pipe;
|
delete player->pipe;
|
||||||
player->pipe = dc->pipe;
|
player->pipe = dc->pipe;
|
||||||
}
|
}
|
||||||
@@ -686,6 +687,7 @@ update_song_tag(Song *song, const Tag &new_tag)
|
|||||||
static bool
|
static bool
|
||||||
play_chunk(struct player_control *pc,
|
play_chunk(struct player_control *pc,
|
||||||
Song *song, struct music_chunk *chunk,
|
Song *song, struct music_chunk *chunk,
|
||||||
|
MusicBuffer &buffer,
|
||||||
const AudioFormat format,
|
const AudioFormat format,
|
||||||
Error &error)
|
Error &error)
|
||||||
{
|
{
|
||||||
@@ -695,7 +697,7 @@ play_chunk(struct player_control *pc,
|
|||||||
update_song_tag(song, *chunk->tag);
|
update_song_tag(song, *chunk->tag);
|
||||||
|
|
||||||
if (chunk->length == 0) {
|
if (chunk->length == 0) {
|
||||||
player_buffer->Return(chunk);
|
buffer.Return(chunk);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -776,7 +778,7 @@ play_next_chunk(struct player *player)
|
|||||||
beginning of the new song, we can
|
beginning of the new song, we can
|
||||||
easily recover by throwing it away
|
easily recover by throwing it away
|
||||||
now */
|
now */
|
||||||
player_buffer->Return(other_chunk);
|
player->buffer.Return(other_chunk);
|
||||||
other_chunk = NULL;
|
other_chunk = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -819,11 +821,11 @@ play_next_chunk(struct player *player)
|
|||||||
/* play the current chunk */
|
/* play the current chunk */
|
||||||
|
|
||||||
Error error;
|
Error error;
|
||||||
if (!play_chunk(player->pc, player->song, chunk,
|
if (!play_chunk(player->pc, player->song, chunk, player->buffer,
|
||||||
player->play_audio_format, error)) {
|
player->play_audio_format, error)) {
|
||||||
g_warning("%s", error.GetMessage());
|
g_warning("%s", error.GetMessage());
|
||||||
|
|
||||||
player_buffer->Return(chunk);
|
player->buffer.Return(chunk);
|
||||||
|
|
||||||
pc->Lock();
|
pc->Lock();
|
||||||
|
|
||||||
@@ -847,7 +849,7 @@ play_next_chunk(struct player *player)
|
|||||||
dc->Lock();
|
dc->Lock();
|
||||||
if (!dc->IsIdle() &&
|
if (!dc->IsIdle() &&
|
||||||
dc->pipe->GetSize() <= (pc->buffered_before_play +
|
dc->pipe->GetSize() <= (pc->buffered_before_play +
|
||||||
player_buffer->GetSize() * 3) / 4)
|
player->buffer.GetSize() * 3) / 4)
|
||||||
dc->Signal();
|
dc->Signal();
|
||||||
dc->Unlock();
|
dc->Unlock();
|
||||||
|
|
||||||
@@ -902,9 +904,11 @@ player_song_border(struct player *player)
|
|||||||
* basically a state machine, which multiplexes data between the
|
* basically a state machine, which multiplexes data between the
|
||||||
* decoder thread and the output threads.
|
* decoder thread and the output threads.
|
||||||
*/
|
*/
|
||||||
static void do_play(struct player_control *pc, struct decoder_control *dc)
|
static void
|
||||||
|
do_play(struct player_control *pc, struct decoder_control *dc,
|
||||||
|
MusicBuffer &buffer)
|
||||||
{
|
{
|
||||||
player player(pc, dc);
|
player player(pc, dc, buffer);
|
||||||
|
|
||||||
pc->Unlock();
|
pc->Unlock();
|
||||||
|
|
||||||
@@ -1016,7 +1020,7 @@ static void do_play(struct player_control *pc, struct decoder_control *dc)
|
|||||||
dc->mixramp_prev_end,
|
dc->mixramp_prev_end,
|
||||||
dc->out_audio_format,
|
dc->out_audio_format,
|
||||||
player.play_audio_format,
|
player.play_audio_format,
|
||||||
player_buffer->GetSize() -
|
player.buffer.GetSize() -
|
||||||
pc->buffered_before_play);
|
pc->buffered_before_play);
|
||||||
if (player.cross_fade_chunks > 0) {
|
if (player.cross_fade_chunks > 0) {
|
||||||
player.xfade = XFADE_ENABLED;
|
player.xfade = XFADE_ENABLED;
|
||||||
@@ -1073,7 +1077,7 @@ static void do_play(struct player_control *pc, struct decoder_control *dc)
|
|||||||
|
|
||||||
player_dc_stop(&player);
|
player_dc_stop(&player);
|
||||||
|
|
||||||
player.pipe->Clear(*player_buffer);
|
player.pipe->Clear(player.buffer);
|
||||||
delete player.pipe;
|
delete player.pipe;
|
||||||
|
|
||||||
delete player.cross_fade_tag;
|
delete player.cross_fade_tag;
|
||||||
@@ -1106,7 +1110,7 @@ player_task(gpointer arg)
|
|||||||
struct decoder_control *dc = new decoder_control();
|
struct decoder_control *dc = new decoder_control();
|
||||||
decoder_thread_start(dc);
|
decoder_thread_start(dc);
|
||||||
|
|
||||||
player_buffer = new MusicBuffer(pc->buffer_chunks);
|
MusicBuffer buffer(pc->buffer_chunks);
|
||||||
|
|
||||||
pc->Lock();
|
pc->Lock();
|
||||||
|
|
||||||
@@ -1116,7 +1120,7 @@ player_task(gpointer arg)
|
|||||||
case PLAYER_COMMAND_QUEUE:
|
case PLAYER_COMMAND_QUEUE:
|
||||||
assert(pc->next_song != NULL);
|
assert(pc->next_song != NULL);
|
||||||
|
|
||||||
do_play(pc, dc);
|
do_play(pc, dc, buffer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PLAYER_COMMAND_STOP:
|
case PLAYER_COMMAND_STOP:
|
||||||
@@ -1143,7 +1147,7 @@ player_task(gpointer arg)
|
|||||||
pc->Lock();
|
pc->Lock();
|
||||||
player_command_finished_locked(pc);
|
player_command_finished_locked(pc);
|
||||||
|
|
||||||
assert(player_buffer->IsEmptyUnsafe());
|
assert(buffer.IsEmptyUnsafe());
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1160,7 +1164,6 @@ player_task(gpointer arg)
|
|||||||
dc->Quit();
|
dc->Quit();
|
||||||
delete dc;
|
delete dc;
|
||||||
audio_output_all_close();
|
audio_output_all_close();
|
||||||
delete player_buffer;
|
|
||||||
|
|
||||||
player_command_finished(pc);
|
player_command_finished(pc);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
Reference in New Issue
Block a user