/* Handle STREAM_PAUSE */
static void stream_on_pause(void)
{
    int status = stream_mgr.status;

    stream_mgr_lock();

    /* Reply with previous state */
    stream_mgr_reply_msg(status);

    if (status == STREAM_PLAYING)
    {
        /* Pause the clock */
        pcm_output_play_pause(false);

        /* Pause each active stream */
        actl_stream_broadcast(STREAM_PAUSE, 0);

        /* Pause the disk buffer - buffer may continue filling */
        disk_buf_send_msg(STREAM_PAUSE, false);

        /* Unboost the CPU */
        cancel_cpu_boost();

        /* Offically paused */
        stream_mgr.status = STREAM_PAUSED;
    }

    stream_mgr_unlock();
}
static void stream_start_playback(uint32_t time, bool fill_buffer)
{
    if (stream_mgr.seeked)
    {
        /* Clear any seeked status */
        stream_mgr.seeked = false;

        /* Flush old PCM data */
        pcm_output_flush();

        /* Set the master clock */
        set_stream_clock(time);

        /* Make sure streams are back in active pool */
        move_strl_to_actl();

        /* Prepare the parser and associated streams */
        parser_prepare_streaming();
    }

    /* Start buffer which optional force fill */
    disk_buf_send_msg(STREAM_PLAY, fill_buffer);

    /* Tell each stream to start - may generate end of stream signals
     * now - we'll handle this when finished */
    actl_stream_broadcast(STREAM_PLAY, 0);

    /* Actually start the clock */
    pcm_output_play_pause(true);
}
/* Clear any particular notification for which a stream registered */
void stream_clear_notify(struct stream *str, int for_msg)
{
    switch (for_msg)
    {
    case DISK_BUF_DATA_NOTIFY:
        disk_buf_send_msg(DISK_BUF_CLEAR_DATA_NOTIFY, (intptr_t)str);
        break;
    }
}
Esempio n. 4
0
/* Handle seeking details if playing or paused */
static uint32_t stream_seek_intl(uint32_t time, int whence,
                                 int status, bool *was_buffering)
{
    if (status != STREAM_STOPPED)
    {
        bool wb;

        /* Place streams in a non-running state - keep them on actl */
        actl_stream_broadcast(STREAM_STOP, 0);

        /* Stop all buffering or else risk clobbering random-access data */
        wb = disk_buf_send_msg(STREAM_STOP, 0);

        if (was_buffering != NULL)
            *was_buffering = wb;
    }

    time = time_from_whence(time, whence);

    stream_mgr.seeked = true;

    return parser_seek_time(time);
}
/* Handle STREAM_STOP */
static void stream_on_stop(bool reply)
{
    int status = stream_mgr.status;

    stream_mgr_lock();

    if (reply)
        stream_mgr_reply_msg(status);

    if (status != STREAM_STOPPED)
    {
        /* Pause the clock */
        pcm_output_play_pause(false);

        /* Update the resume time info */
        stream_remember_resume_time();

        /* Not stopped = paused or playing */
        stream_mgr.seeked = false;

        /* Stop buffering */
        disk_buf_send_msg(STREAM_STOP, 0);

        /* Clear any still-active streams and remove from actl */
        actl_stream_broadcast(STREAM_STOP, 1);

        /* Stop PCM output (and clock) */
        pcm_output_stop();

        /* Cancel our processor boost */
        cancel_cpu_boost();

        stream_mgr.status = STREAM_STOPPED;
    }

    stream_mgr_unlock();
}
int str_next_data_not_ready(struct stream *str)
{
    /* Save the current window since it actually might be ready by the time
     * the registration is received by buffering. */
    off_t win_right = str->hdr.win_right;

    if (str->hdr.win_right < disk_buf.filesize - MIN_BUFAHEAD &&
        disk_buf.filesize > MIN_BUFAHEAD)
    {
        /* Set right edge to where probing left off + the minimum margin */
        str->hdr.win_right += MIN_BUFAHEAD;
    }
    else
    {
        /* Request would be passed the end of the file */
        str->hdr.win_right = disk_buf.filesize;
    }

    switch (disk_buf_send_msg(DISK_BUF_DATA_NOTIFY, (intptr_t)str))
    {
    case DISK_BUF_NOTIFY_OK:
        /* Was ready - restore window and process */
        str->hdr.win_right = win_right;
        return STREAM_OK;

    case DISK_BUF_NOTIFY_ERROR:
        /* Error - quit parsing */
        str_end_of_stream(str);
        return STREAM_DATA_END;

    default:
        /* Not ready - go wait for notification from buffering. */
        str->pkt_flags = 0;
        return STREAM_DATA_NOT_READY;
    }
}