summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2008-01-07 14:58:23 +0000
committerMichael Sevakis <jethead71@rockbox.org>2008-01-07 14:58:23 +0000
commit0e98d7e315bcbdee35bcda4fd01a82da9185ed93 (patch)
tree937e05e7d7028706075adb27d4a8665163298e55
parent9216d0f16a6c0c51bdae4fbfe9351d02beb1110c (diff)
mpegplayer: Misc seeking tweaks 1) Consolidate some code amongst functions. 2) Be sure times retured from stream_get_seek_time are never before the start of the movie 3) Stop PCM when clearing it so the current audio being sent to the audio device is also cleared.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16014 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/mpegplayer/pcm_output.c13
-rw-r--r--apps/plugins/mpegplayer/stream_mgr.c184
2 files changed, 85 insertions, 112 deletions
diff --git a/apps/plugins/mpegplayer/pcm_output.c b/apps/plugins/mpegplayer/pcm_output.c
index 281f7ddb72..ac89308af1 100644
--- a/apps/plugins/mpegplayer/pcm_output.c
+++ b/apps/plugins/mpegplayer/pcm_output.c
@@ -152,12 +152,25 @@ void pcm_output_add_data(void)
/* Flushes the buffer - clock keeps counting */
void pcm_output_flush(void)
{
+ bool playing, paused;
+
rb->pcm_play_lock();
+ playing = rb->pcm_is_playing();
+ paused = rb->pcm_is_paused();
+
+ /* Stop PCM to clear current buffer */
+ if (playing)
+ rb->pcm_play_stop();
+
pcmbuf_threshold = PCMOUT_PLAY_WM;
pcmbuf_read = pcmbuf_written = 0;
pcmbuf_head = pcmbuf_tail = pcm_buffer;
+ /* Restart if playing state was current */
+ if (playing && !paused)
+ rb->pcm_play_data(get_more, NULL, 0);
+
rb->pcm_play_unlock();
}
diff --git a/apps/plugins/mpegplayer/stream_mgr.c b/apps/plugins/mpegplayer/stream_mgr.c
index c473db3ce3..dbc8ce9427 100644
--- a/apps/plugins/mpegplayer/stream_mgr.c
+++ b/apps/plugins/mpegplayer/stream_mgr.c
@@ -247,6 +247,37 @@ static void set_stream_clock(uint32_t time)
pcm_output_set_clock(TS_TO_TICKS(time));
}
+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);
+}
+
/* Return the play time relative to the specified play time */
static uint32_t time_from_whence(uint32_t time, int whence)
{
@@ -286,62 +317,28 @@ static uint32_t time_from_whence(uint32_t time, int whence)
}
/* Handle seeking details if playing or paused */
-static uint32_t stream_seek_intl(uint32_t time, int whence, int status)
+static uint32_t stream_seek_intl(uint32_t time, int whence,
+ int status, bool *was_buffering)
{
- /* seek start time */
- bool was_buffering;
-
- if (status == STREAM_PLAYING)
- {
- /* Keep clock from advancing while seeking */
- pcm_output_play_pause(false);
- }
-
- /* 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 */
- was_buffering = disk_buf_send_msg(STREAM_STOP, 0);
-
- time = time_from_whence(time, whence);
- time = parser_seek_time(time);
-
- if (status == STREAM_PLAYING)
+ if (status != STREAM_STOPPED)
{
- /* Restart streams if currently playing */
-
- /* Clear any seeked status */
- stream_mgr.seeked = false;
-
- /* Flush old PCM data */
- pcm_output_flush();
-
- /* Set the master clock */
- set_stream_clock(time);
+ bool wb;
- /* Make sure streams are back in active pool */
- move_strl_to_actl();
+ /* Place streams in a non-running state - keep them on actl */
+ actl_stream_broadcast(STREAM_STOP, 0);
- /* Prepare the parser and associated streams */
- parser_prepare_streaming();
+ /* Stop all buffering or else risk clobbering random-access data */
+ wb = disk_buf_send_msg(STREAM_STOP, 0);
- /* Start buffer using previous buffering status */
- disk_buf_send_msg(STREAM_PLAY, was_buffering);
+ if (was_buffering != NULL)
+ *was_buffering = wb;
+ }
- /* Tell each stream to start - may generate end of stream signals
- * now - we'll handle this when finished */
- actl_stream_broadcast(STREAM_PLAY, 0);
+ time = time_from_whence(time, whence);
- /* Actually start the clock */
- pcm_output_play_pause(true);
- }
- else
- {
- /* Performed the seek - leave it at that until restarted */
- stream_mgr.seeked = true;
- }
+ stream_mgr.seeked = true;
- return time;
+ return parser_seek_time(time);
}
/* Handle STREAM_OPEN */
@@ -402,29 +399,11 @@ static void stream_on_play(void)
start = str_parser.last_seek_time - str_parser.start_pts;
stream_mgr.resume_time = start;
- start = stream_seek_intl(start, SEEK_SET, STREAM_STOPPED);
-
- /* Fill list of all streams that will be playing */
- move_strl_to_actl();
-
- /* Clear any seeked status */
- stream_mgr.seeked = false;
-
- /* Set the master clock */
- set_stream_clock(start);
-
- /* Prepare the parser and associated streams */
- parser_prepare_streaming();
+ /* Prepare seek to start point */
+ start = stream_seek_intl(start, SEEK_SET, STREAM_STOPPED, NULL);
- /* Force buffering */
- disk_buf_send_msg(STREAM_PLAY, true);
-
- /* 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);
+ /* Sync and start - force buffer fill */
+ stream_start_playback(start, true);
}
else
{
@@ -481,33 +460,8 @@ static void stream_on_resume(void)
/* Boost the CPU */
trigger_cpu_boost();
- if (stream_mgr.seeked)
- {
- /* Have to give the parser notice to sync up streams */
- stream_mgr.seeked = false;
-
- /* Flush old PCM data */
- pcm_output_flush();
-
- /* Set the master clock */
- set_stream_clock(str_parser.last_seek_time);
-
- /* Make sure streams are back in active pool */
- move_strl_to_actl();
-
- /* Prepare the parser and associated streams */
- parser_prepare_streaming();
- }
-
- /* Don't force buffering */
- disk_buf_send_msg(STREAM_PLAY, false);
-
- /* 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);
+ /* Sync and start - no force buffering */
+ stream_start_playback(str_parser.last_seek_time, false);
/* Officially playing */
stream_mgr.status = STREAM_PLAYING;
@@ -582,33 +536,30 @@ static void stream_on_seek(struct stream_seek_data *skd)
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();
if (stream_can_seek())
{
- if (stream_mgr.status != STREAM_STOPPED)
+ bool buffer;
+
+ if (stream_mgr.status == STREAM_PLAYING)
{
- if (stream_mgr.status != STREAM_PLAYING)
- {
- trigger_cpu_boost();
- }
+ /* Keep clock from advancing while seeking */
+ pcm_output_play_pause(false);
+ }
- stream_seek_intl(time, whence, stream_mgr.status);
+ time = stream_seek_intl(time, whence, stream_mgr.status, &buffer);
- if (stream_mgr.status != STREAM_PLAYING)
- {
- cancel_cpu_boost();
- }
- }
- else
+ if (stream_mgr.status == STREAM_PLAYING)
{
- stream_mgr.seeked = true;
- time = time_from_whence(time, whence);
- parser_seek_time(time);
+ /* Sync and restart - no force buffering */
+ stream_start_playback(time, buffer);
}
}
@@ -616,6 +567,7 @@ static void stream_on_seek(struct stream_seek_data *skd)
return;
}
+ /* Invalid parameter or no file */
stream_mgr_reply_msg(STREAM_ERROR);
}
@@ -904,10 +856,18 @@ uint32_t stream_get_seek_time(uint32_t *start)
stream_mgr_lock();
if (stream_mgr.seeked)
+ {
time = str_parser.last_seek_time;
+ }
else
+ {
time = TICKS_TO_TS(pcm_output_get_clock());
+ /* Clock can be start early so keep in range */
+ if (time < str_parser.start_pts)
+ time = str_parser.start_pts;
+ }
+
if (start != NULL)
*start = str_parser.start_pts;