示例#1
0
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;
}
示例#2
0
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);
}
示例#3
0
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, ");
//        }
    }

}