/* Playback control thread */
static void stream_mgr_thread(void)
{
    struct queue_event ev;

    while (1)
    {
        rb->queue_wait(stream_mgr.q, &ev);

        switch (ev.id)
        {
        case STREAM_OPEN:
            stream_on_open((const char *)ev.data);
            break;

        case STREAM_CLOSE:
            stream_on_close();
            break;

        case STREAM_PLAY:
            stream_on_play();
            break;

        case STREAM_PAUSE:
            if (ev.data)
                stream_on_resume();
            else
                stream_on_pause();
            break;

        case STREAM_STOP:
            stream_on_stop(true);
            break;

        case STREAM_SEEK:
            stream_on_seek((struct stream_seek_data *)ev.data);
            break;

        case STREAM_EV_COMPLETE:
            stream_on_ev_complete((struct stream *)ev.data);
            break;

        case STREAM_QUIT:
            if (stream_mgr.status != STREAM_STOPPED)
                stream_on_stop(false);
            return;
        }
    }
}
/* Handle STREAM_CLOSE */
static int stream_on_close(void)
{
    int status = STREAM_STOPPED;

    stream_mgr_lock();

    /* Any open file that was accepted for playback? */
    if (stream_mgr.filename != NULL)
    {
        /* Yes - hide video */
        stream_show_vo(false);
        /* Stop any playback */
        status = stream_mgr.status;
        stream_on_stop(false);
        /* Tell parser file is finished */
        parser_close_stream();
        /* Reinitialize manager */
        stream_mgr_init_state();
    }

    /* Let disk buffer reset itself - file might be open even if no good */
    disk_buf_close();

    stream_mgr_unlock();

    return status;
}
/* Handle STREAM_CLOSE */
static int stream_on_close(void)
{
    int status = STREAM_STOPPED;

    stream_mgr_lock();

    /* Any open file? */
    if (stream_mgr.filename != NULL)
    {
        /* Yes - hide video */
        stream_show_vo(false);
        /* Stop any playback */
        status = stream_mgr.status;
        stream_on_stop(false);
        /* Tell parser file is finished */
        parser_close_stream();
        /* Close file */
        disk_buf_close();
        /* Reinitialize manager */
        stream_mgr_init_state();
    }

    stream_mgr_unlock();

    return status;
}
/* Handle STREAM_EV_COMPLETE */
static void stream_on_ev_complete(struct stream *str)
{
    stream_mgr_lock();

    /* Stream is active? */
    if (actl_stream_remove(str))
    {
        /* No - remove this stream from the active list */
        DEBUGF("  finished: 0x%02x\n", str->id);
        if (list_is_empty(stream_mgr.actl))
        {
            /* All streams have acked - stop playback */
            stream_on_stop(false);
            stream_mgr.resume_time = 0; /* Played to end - no resume */
        }
        else
        {
            /* Stream is done - stop it and place back in pool */
            str_send_msg(str, STREAM_STOP, 1);
        }
    }

    stream_mgr_unlock();
}