/* Handle STREAM_SEEK */ static void stream_on_seek(struct stream_seek_data *skd) { uint32_t time = skd->time; int whence = skd->whence; switch (whence) { case SEEK_SET: case SEEK_CUR: case SEEK_END: if (stream_mgr.filename == NULL) break; /* Keep things spinning if already doing so */ stream_keep_disk_active(); /* Have data - reply in order to acquire lock */ stream_mgr_reply_msg(STREAM_OK); stream_mgr_lock(); /* Either seeking must be possible or a full rewind must be done */ if (stream_can_seek() || time_from_whence(time, whence) == 0) { bool buffer; if (stream_mgr.status == STREAM_PLAYING) { /* Keep clock from advancing while seeking */ pcm_output_play_pause(false); } time = stream_seek_intl(time, whence, stream_mgr.status, &buffer); stream_remember_resume_time(); if (stream_mgr.status == STREAM_PLAYING) { /* Sync and restart - no force buffering */ stream_start_playback(time, buffer); } } stream_mgr_unlock(); return; } /* Invalid parameter or no file */ stream_mgr_reply_msg(STREAM_ERROR); }
/* 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); }