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)
downloadrockbox-0e98d7e315bcbdee35bcda4fd01a82da9185ed93.tar.gz
rockbox-0e98d7e315bcbdee35bcda4fd01a82da9185ed93.zip
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)
152/* Flushes the buffer - clock keeps counting */ 152/* Flushes the buffer - clock keeps counting */
153void pcm_output_flush(void) 153void pcm_output_flush(void)
154{ 154{
155 bool playing, paused;
156
155 rb->pcm_play_lock(); 157 rb->pcm_play_lock();
156 158
159 playing = rb->pcm_is_playing();
160 paused = rb->pcm_is_paused();
161
162 /* Stop PCM to clear current buffer */
163 if (playing)
164 rb->pcm_play_stop();
165
157 pcmbuf_threshold = PCMOUT_PLAY_WM; 166 pcmbuf_threshold = PCMOUT_PLAY_WM;
158 pcmbuf_read = pcmbuf_written = 0; 167 pcmbuf_read = pcmbuf_written = 0;
159 pcmbuf_head = pcmbuf_tail = pcm_buffer; 168 pcmbuf_head = pcmbuf_tail = pcm_buffer;
160 169
170 /* Restart if playing state was current */
171 if (playing && !paused)
172 rb->pcm_play_data(get_more, NULL, 0);
173
161 rb->pcm_play_unlock(); 174 rb->pcm_play_unlock();
162} 175}
163 176
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)
247 pcm_output_set_clock(TS_TO_TICKS(time)); 247 pcm_output_set_clock(TS_TO_TICKS(time));
248} 248}
249 249
250static void stream_start_playback(uint32_t time, bool fill_buffer)
251{
252 if (stream_mgr.seeked)
253 {
254 /* Clear any seeked status */
255 stream_mgr.seeked = false;
256
257 /* Flush old PCM data */
258 pcm_output_flush();
259
260 /* Set the master clock */
261 set_stream_clock(time);
262
263 /* Make sure streams are back in active pool */
264 move_strl_to_actl();
265
266 /* Prepare the parser and associated streams */
267 parser_prepare_streaming();
268 }
269
270 /* Start buffer which optional force fill */
271 disk_buf_send_msg(STREAM_PLAY, fill_buffer);
272
273 /* Tell each stream to start - may generate end of stream signals
274 * now - we'll handle this when finished */
275 actl_stream_broadcast(STREAM_PLAY, 0);
276
277 /* Actually start the clock */
278 pcm_output_play_pause(true);
279}
280
250/* Return the play time relative to the specified play time */ 281/* Return the play time relative to the specified play time */
251static uint32_t time_from_whence(uint32_t time, int whence) 282static uint32_t time_from_whence(uint32_t time, int whence)
252{ 283{
@@ -286,62 +317,28 @@ static uint32_t time_from_whence(uint32_t time, int whence)
286} 317}
287 318
288/* Handle seeking details if playing or paused */ 319/* Handle seeking details if playing or paused */
289static uint32_t stream_seek_intl(uint32_t time, int whence, int status) 320static uint32_t stream_seek_intl(uint32_t time, int whence,
321 int status, bool *was_buffering)
290{ 322{
291 /* seek start time */ 323 if (status != STREAM_STOPPED)
292 bool was_buffering;
293
294 if (status == STREAM_PLAYING)
295 {
296 /* Keep clock from advancing while seeking */
297 pcm_output_play_pause(false);
298 }
299
300 /* Place streams in a non-running state - keep them on actl */
301 actl_stream_broadcast(STREAM_STOP, 0);
302
303 /* Stop all buffering or else risk clobbering random-access data */
304 was_buffering = disk_buf_send_msg(STREAM_STOP, 0);
305
306 time = time_from_whence(time, whence);
307 time = parser_seek_time(time);
308
309 if (status == STREAM_PLAYING)
310 { 324 {
311 /* Restart streams if currently playing */ 325 bool wb;
312
313 /* Clear any seeked status */
314 stream_mgr.seeked = false;
315
316 /* Flush old PCM data */
317 pcm_output_flush();
318
319 /* Set the master clock */
320 set_stream_clock(time);
321 326
322 /* Make sure streams are back in active pool */ 327 /* Place streams in a non-running state - keep them on actl */
323 move_strl_to_actl(); 328 actl_stream_broadcast(STREAM_STOP, 0);
324 329
325 /* Prepare the parser and associated streams */ 330 /* Stop all buffering or else risk clobbering random-access data */
326 parser_prepare_streaming(); 331 wb = disk_buf_send_msg(STREAM_STOP, 0);
327 332
328 /* Start buffer using previous buffering status */ 333 if (was_buffering != NULL)
329 disk_buf_send_msg(STREAM_PLAY, was_buffering); 334 *was_buffering = wb;
335 }
330 336
331 /* Tell each stream to start - may generate end of stream signals 337 time = time_from_whence(time, whence);
332 * now - we'll handle this when finished */
333 actl_stream_broadcast(STREAM_PLAY, 0);
334 338
335 /* Actually start the clock */ 339 stream_mgr.seeked = true;
336 pcm_output_play_pause(true);
337 }
338 else
339 {
340 /* Performed the seek - leave it at that until restarted */
341 stream_mgr.seeked = true;
342 }
343 340
344 return time; 341 return parser_seek_time(time);
345} 342}
346 343
347/* Handle STREAM_OPEN */ 344/* Handle STREAM_OPEN */
@@ -402,29 +399,11 @@ static void stream_on_play(void)
402 start = str_parser.last_seek_time - str_parser.start_pts; 399 start = str_parser.last_seek_time - str_parser.start_pts;
403 stream_mgr.resume_time = start; 400 stream_mgr.resume_time = start;
404 401
405 start = stream_seek_intl(start, SEEK_SET, STREAM_STOPPED); 402 /* Prepare seek to start point */
406 403 start = stream_seek_intl(start, SEEK_SET, STREAM_STOPPED, NULL);
407 /* Fill list of all streams that will be playing */
408 move_strl_to_actl();
409
410 /* Clear any seeked status */
411 stream_mgr.seeked = false;
412
413 /* Set the master clock */
414 set_stream_clock(start);
415
416 /* Prepare the parser and associated streams */
417 parser_prepare_streaming();
418 404
419 /* Force buffering */ 405 /* Sync and start - force buffer fill */
420 disk_buf_send_msg(STREAM_PLAY, true); 406 stream_start_playback(start, true);
421
422 /* Tell each stream to start - may generate end of stream signals
423 * now - we'll handle this when finished */
424 actl_stream_broadcast(STREAM_PLAY, 0);
425
426 /* Actually start the clock */
427 pcm_output_play_pause(true);
428 } 407 }
429 else 408 else
430 { 409 {
@@ -481,33 +460,8 @@ static void stream_on_resume(void)
481 /* Boost the CPU */ 460 /* Boost the CPU */
482 trigger_cpu_boost(); 461 trigger_cpu_boost();
483 462
484 if (stream_mgr.seeked) 463 /* Sync and start - no force buffering */
485 { 464 stream_start_playback(str_parser.last_seek_time, false);
486 /* Have to give the parser notice to sync up streams */
487 stream_mgr.seeked = false;
488
489 /* Flush old PCM data */
490 pcm_output_flush();
491
492 /* Set the master clock */
493 set_stream_clock(str_parser.last_seek_time);
494
495 /* Make sure streams are back in active pool */
496 move_strl_to_actl();
497
498 /* Prepare the parser and associated streams */
499 parser_prepare_streaming();
500 }
501
502 /* Don't force buffering */
503 disk_buf_send_msg(STREAM_PLAY, false);
504
505 /* Tell each stream to start - may generate end of stream signals
506 * now - we'll handle this when finished */
507 actl_stream_broadcast(STREAM_PLAY, 0);
508
509 /* Actually start the clock */
510 pcm_output_play_pause(true);
511 465
512 /* Officially playing */ 466 /* Officially playing */
513 stream_mgr.status = STREAM_PLAYING; 467 stream_mgr.status = STREAM_PLAYING;
@@ -582,33 +536,30 @@ static void stream_on_seek(struct stream_seek_data *skd)
582 if (stream_mgr.filename == NULL) 536 if (stream_mgr.filename == NULL)
583 break; 537 break;
584 538
539 /* Keep things spinning if already doing so */
585 stream_keep_disk_active(); 540 stream_keep_disk_active();
586 541
542 /* Have data - reply in order to acquire lock */
587 stream_mgr_reply_msg(STREAM_OK); 543 stream_mgr_reply_msg(STREAM_OK);
588 544
589 stream_mgr_lock(); 545 stream_mgr_lock();
590 546
591 if (stream_can_seek()) 547 if (stream_can_seek())
592 { 548 {
593 if (stream_mgr.status != STREAM_STOPPED) 549 bool buffer;
550
551 if (stream_mgr.status == STREAM_PLAYING)
594 { 552 {
595 if (stream_mgr.status != STREAM_PLAYING) 553 /* Keep clock from advancing while seeking */
596 { 554 pcm_output_play_pause(false);
597 trigger_cpu_boost(); 555 }
598 }
599 556
600 stream_seek_intl(time, whence, stream_mgr.status); 557 time = stream_seek_intl(time, whence, stream_mgr.status, &buffer);
601 558
602 if (stream_mgr.status != STREAM_PLAYING) 559 if (stream_mgr.status == STREAM_PLAYING)
603 {
604 cancel_cpu_boost();
605 }
606 }
607 else
608 { 560 {
609 stream_mgr.seeked = true; 561 /* Sync and restart - no force buffering */
610 time = time_from_whence(time, whence); 562 stream_start_playback(time, buffer);
611 parser_seek_time(time);
612 } 563 }
613 } 564 }
614 565
@@ -616,6 +567,7 @@ static void stream_on_seek(struct stream_seek_data *skd)
616 return; 567 return;
617 } 568 }
618 569
570 /* Invalid parameter or no file */
619 stream_mgr_reply_msg(STREAM_ERROR); 571 stream_mgr_reply_msg(STREAM_ERROR);
620} 572}
621 573
@@ -904,10 +856,18 @@ uint32_t stream_get_seek_time(uint32_t *start)
904 stream_mgr_lock(); 856 stream_mgr_lock();
905 857
906 if (stream_mgr.seeked) 858 if (stream_mgr.seeked)
859 {
907 time = str_parser.last_seek_time; 860 time = str_parser.last_seek_time;
861 }
908 else 862 else
863 {
909 time = TICKS_TO_TS(pcm_output_get_clock()); 864 time = TICKS_TO_TS(pcm_output_get_clock());
910 865
866 /* Clock can be start early so keep in range */
867 if (time < str_parser.start_pts)
868 time = str_parser.start_pts;
869 }
870
911 if (start != NULL) 871 if (start != NULL)
912 *start = str_parser.start_pts; 872 *start = str_parser.start_pts;
913 873