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); }
/* 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(); }
/* 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(); }