static gpointer decoder_task(gpointer arg) { struct decoder_control *dc = arg; decoder_lock(dc); do { assert(dc->state == DECODE_STATE_STOP || dc->state == DECODE_STATE_ERROR); switch (dc->command) { case DECODE_COMMAND_START: g_debug("clearing mixramp tags"); dc_mixramp_start(dc, NULL); dc_mixramp_prev_end(dc, 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; /* fall through */ case DECODE_COMMAND_SEEK: decoder_run(dc); break; case DECODE_COMMAND_STOP: decoder_command_finished_locked(dc); break; case DECODE_COMMAND_NONE: decoder_wait(dc); break; } } while (dc->command != DECODE_COMMAND_NONE || !dc->quit); decoder_unlock(dc); return NULL; }
static void decoder_run_song(struct decoder_control *dc, const struct song *song, const char *uri) { struct decoder decoder = { .dc = dc, .initial_seek_pending = dc->start_ms > 0, .initial_seek_running = false, }; int ret; decoder.timestamp = 0.0; decoder.seeking = false; decoder.song_tag = song->tag != NULL && song_is_file(song) ? tag_dup(song->tag) : NULL; decoder.stream_tag = NULL; decoder.decoder_tag = NULL; decoder.chunk = NULL; dc->state = DECODE_STATE_START; decoder_command_finished_locked(dc); pcm_convert_init(&decoder.conv_state); ret = song_is_file(song) ? decoder_run_file(&decoder, uri) : decoder_run_stream(&decoder, uri); decoder_unlock(dc); pcm_convert_deinit(&decoder.conv_state); /* flush the last chunk */ if (decoder.chunk != NULL) decoder_flush_chunk(&decoder); if (decoder.song_tag != NULL) tag_free(decoder.song_tag); if (decoder.stream_tag != NULL) tag_free(decoder.stream_tag); if (decoder.decoder_tag != NULL) tag_free(decoder.decoder_tag); decoder_lock(dc); dc->state = ret ? DECODE_STATE_STOP : DECODE_STATE_ERROR; } static void decoder_run(struct decoder_control *dc) { const struct song *song = dc->song; char *uri; assert(song != NULL); if (song_is_file(song)) uri = map_song_fs(song); else uri = song_get_uri(song); if (uri == NULL) { dc->state = DECODE_STATE_ERROR; decoder_command_finished_locked(dc); return; } decoder_run_song(dc, song, uri); g_free(uri); } static gpointer decoder_task(gpointer arg) { struct decoder_control *dc = arg; decoder_lock(dc); do { assert(dc->state == DECODE_STATE_STOP || dc->state == DECODE_STATE_ERROR); switch (dc->command) { case DECODE_COMMAND_START: dc_mixramp_start(dc, NULL); dc_mixramp_prev_end(dc, 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; /* fall through */ case DECODE_COMMAND_SEEK: decoder_run(dc); break; case DECODE_COMMAND_STOP: decoder_command_finished_locked(dc); break; case DECODE_COMMAND_NONE: decoder_wait(dc); break; } } while (dc->command != DECODE_COMMAND_NONE || !dc->quit); decoder_unlock(dc); return NULL; } void decoder_thread_start(struct decoder_control *dc) { GError *e = NULL; assert(dc->thread == NULL); dc->quit = false; dc->thread = g_thread_create(decoder_task, dc, true, &e); if (dc->thread == NULL) MPD_ERROR("Failed to spawn decoder task: %s", e->message); }
void client_event_read(struct bufferevent *bev, void *arg) { log_debug("client_event_read"); client_t *c = (client_t*) arg; server_t *s = c->server; log_debug("Received read event from client socket %d", c->socket); if(c->msg == NULL) { c->msg = msg_init(c->worker->msg_buf); } int res = evbuffer_add_buffer(c->evbuf, bufferevent_get_input(bev)); char *line; while((line = evbuffer_readln(c->evbuf, NULL, EVBUFFER_EOL_CRLF)) != NULL) { log_debug("Read data : %s", line); decode_result res = decoder_run(c->msg, line); msg_print(c->msg); switch(res) { case DR_ERR_FORMAT: client_increase_req_err(c); worker_increase_req_err(c->worker); msg_clean(c->msg); log_debug("Wrong message format : %s", line); resp_error_wrong_msg_format(c->worker->msg_buf, c->socket); break; case DR_ERR_PARAM_FORMAT: client_increase_req_err(c); worker_increase_req_err(c->worker); msg_clean(c->msg); log_debug("Wrong parameter format : %s", line); resp_error_param_format(c->worker->msg_buf, c->socket); break; case DR_OK: log_debug("Data OK."); break; default: break; } enum cmd_func_ret cmd_ret; switch(msg_get_stat(c->msg)) { case MSG_STAT_DONE: log_debug("Message Done."); client_increase_req_ok(c); worker_increase_req_ok(c->worker); cmd_ret = command_proc(c, c->msg); if(cmd_ret != CMD_FUNC_DONE) { c->req_ok++; s->req_ok++; } msg_clean(c->msg); break; } // ic_trans_stat trans_stat = decoder_read_line(c, line); // log_debug("Trans stat : %d", trans_stat); // if(trans_stat == IC_TRANS_ALL_DONE) // { // log_debug("Trasfer done, "); // } } }