Commit eb54337c authored by Max Kellermann's avatar Max Kellermann

decoder_control: duplicate the song object

Make sure the decoder "owns" the song object, so nobody else can free it.
parent 916a0201
...@@ -41,6 +41,8 @@ dc_new(GCond *client_cond) ...@@ -41,6 +41,8 @@ dc_new(GCond *client_cond)
dc->state = DECODE_STATE_STOP; dc->state = DECODE_STATE_STOP;
dc->command = DECODE_COMMAND_NONE; dc->command = DECODE_COMMAND_NONE;
dc->song = NULL;
dc->replay_gain_db = 0; dc->replay_gain_db = 0;
dc->replay_gain_prev_db = 0; dc->replay_gain_prev_db = 0;
dc->mixramp_start = NULL; dc->mixramp_start = NULL;
...@@ -55,6 +57,9 @@ dc_free(struct decoder_control *dc) ...@@ -55,6 +57,9 @@ dc_free(struct decoder_control *dc)
{ {
dc_clear_error(dc); dc_clear_error(dc);
if (dc->song != NULL)
song_free(dc->song);
g_cond_free(dc->cond); g_cond_free(dc->cond);
g_mutex_free(dc->mutex); g_mutex_free(dc->mutex);
g_free(dc->mixramp_start); g_free(dc->mixramp_start);
...@@ -129,6 +134,9 @@ dc_start(struct decoder_control *dc, struct song *song, ...@@ -129,6 +134,9 @@ dc_start(struct decoder_control *dc, struct song *song,
assert(pipe != NULL); assert(pipe != NULL);
assert(music_pipe_empty(pipe)); assert(music_pipe_empty(pipe));
if (dc->song != NULL)
song_free(dc->song);
dc->song = song; dc->song = song;
dc->start_ms = start_ms; dc->start_ms = start_ms;
dc->end_ms = end_ms; dc->end_ms = end_ms;
......
...@@ -90,8 +90,11 @@ struct decoder_control { ...@@ -90,8 +90,11 @@ struct decoder_control {
* The song currently being decoded. This attribute is set by * The song currently being decoded. This attribute is set by
* the player thread, when it sends the #DECODE_COMMAND_START * the player thread, when it sends the #DECODE_COMMAND_START
* command. * command.
*
* This is a duplicate, and must be freed when this attribute
* is cleared.
*/ */
const struct song *song; struct song *song;
/** /**
* The initial seek position (in milliseconds), e.g. to the * The initial seek position (in milliseconds), e.g. to the
...@@ -303,7 +306,8 @@ decoder_lock_is_current_song(struct decoder_control *dc, ...@@ -303,7 +306,8 @@ decoder_lock_is_current_song(struct decoder_control *dc,
* Start the decoder. * Start the decoder.
* *
* @param the decoder * @param the decoder
* @param song the song to be decoded * @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 start_ms see #decoder_control
* @param end_ms see #decoder_control * @param end_ms see #decoder_control
* @param pipe the pipe which receives the decoded chunks (owned by * @param pipe the pipe which receives the decoded chunks (owned by
......
...@@ -162,7 +162,7 @@ player_dc_start(struct player *player, struct music_pipe *pipe) ...@@ -162,7 +162,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, pc->next_song, dc_start(dc, 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);
} }
......
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