OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 : HTMLElement(tagName, doc) | 69 : HTMLElement(tagName, doc) |
70 , m_loadTimer(this, &HTMLMediaElement::loadTimerFired) | 70 , m_loadTimer(this, &HTMLMediaElement::loadTimerFired) |
71 , m_asyncEventTimer(this, &HTMLMediaElement::asyncEventTimerFired) | 71 , m_asyncEventTimer(this, &HTMLMediaElement::asyncEventTimerFired) |
72 , m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired) | 72 , m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired) |
73 , m_defaultPlaybackRate(1.0f) | 73 , m_defaultPlaybackRate(1.0f) |
74 , m_networkState(EMPTY) | 74 , m_networkState(EMPTY) |
75 , m_readyState(DATA_UNAVAILABLE) | 75 , m_readyState(DATA_UNAVAILABLE) |
76 , m_begun(false) | 76 , m_begun(false) |
77 , m_loadedFirstFrame(false) | 77 , m_loadedFirstFrame(false) |
78 , m_autoplaying(true) | 78 , m_autoplaying(true) |
79 , m_currentLoop(0) | |
80 , m_volume(1.0f) | 79 , m_volume(1.0f) |
81 , m_muted(false) | 80 , m_muted(false) |
82 , m_paused(true) | 81 , m_paused(true) |
83 , m_seeking(false) | 82 , m_seeking(false) |
84 , m_currentTimeDuringSeek(0) | 83 , m_currentTimeDuringSeek(0) |
85 , m_previousProgress(0) | 84 , m_previousProgress(0) |
86 , m_previousProgressTime(numeric_limits<double>::max()) | 85 , m_previousProgressTime(numeric_limits<double>::max()) |
87 , m_sentStalledEvent(false) | 86 , m_sentStalledEvent(false) |
88 , m_bufferingRate(0) | |
89 , m_loadNestingLevel(0) | 87 , m_loadNestingLevel(0) |
90 , m_terminateLoadBelowNestingLevel(0) | 88 , m_terminateLoadBelowNestingLevel(0) |
91 , m_pausedInternal(false) | 89 , m_pausedInternal(false) |
92 , m_inActiveDocument(true) | 90 , m_inActiveDocument(true) |
93 , m_player(0) | 91 , m_player(0) |
94 , m_restrictions(NoRestrictions) | 92 , m_restrictions(NoRestrictions) |
95 , m_processingMediaPlayerCallback(0) | 93 , m_processingMediaPlayerCallback(0) |
96 , m_sendProgressEvents(true) | 94 , m_sendProgressEvents(true) |
97 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) | 95 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) |
98 , m_needWidgetUpdate(false) | 96 , m_needWidgetUpdate(false) |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 String HTMLMediaElement::currentSrc() const | 290 String HTMLMediaElement::currentSrc() const |
293 { | 291 { |
294 return m_currentSrc; | 292 return m_currentSrc; |
295 } | 293 } |
296 | 294 |
297 HTMLMediaElement::NetworkState HTMLMediaElement::networkState() const | 295 HTMLMediaElement::NetworkState HTMLMediaElement::networkState() const |
298 { | 296 { |
299 return m_networkState; | 297 return m_networkState; |
300 } | 298 } |
301 | 299 |
302 float HTMLMediaElement::bufferingRate() | |
303 { | |
304 if (!m_player) | |
305 return 0; | |
306 return m_bufferingRate; | |
307 //return m_player->dataRate(); | |
308 } | |
309 | |
310 String HTMLMediaElement::canPlayType(const String& mimeType) const | 300 String HTMLMediaElement::canPlayType(const String& mimeType) const |
311 { | 301 { |
312 MediaPlayer::SupportsType support = MediaPlayer::supportsType(ContentType(mi
meType)); | 302 MediaPlayer::SupportsType support = MediaPlayer::supportsType(ContentType(mi
meType)); |
313 String canPlay; | 303 String canPlay; |
314 | 304 |
315 // 4.8.10.3 | 305 // 4.8.10.3 |
316 switch (support) | 306 switch (support) |
317 { | 307 { |
318 case MediaPlayer::IsNotSupported: | 308 case MediaPlayer::IsNotSupported: |
319 canPlay = "no"; | 309 canPlay = "no"; |
(...skipping 25 matching lines...) Expand all Loading... |
345 ContentType contentType(""); | 335 ContentType contentType(""); |
346 | 336 |
347 // 3.14.9.4. Loading the media resource | 337 // 3.14.9.4. Loading the media resource |
348 // 1 | 338 // 1 |
349 // if an event generated during load() ends up re-entering load(), terminate
previous instances | 339 // if an event generated during load() ends up re-entering load(), terminate
previous instances |
350 m_loadNestingLevel++; | 340 m_loadNestingLevel++; |
351 m_terminateLoadBelowNestingLevel = m_loadNestingLevel; | 341 m_terminateLoadBelowNestingLevel = m_loadNestingLevel; |
352 | 342 |
353 m_progressEventTimer.stop(); | 343 m_progressEventTimer.stop(); |
354 m_sentStalledEvent = false; | 344 m_sentStalledEvent = false; |
355 m_bufferingRate = 0; | |
356 | 345 |
357 m_loadTimer.stop(); | 346 m_loadTimer.stop(); |
358 | 347 |
359 // 2 | 348 // 2 |
360 if (m_begun) { | 349 if (m_begun) { |
361 m_begun = false; | 350 m_begun = false; |
362 m_error = MediaError::create(MediaError::MEDIA_ERR_ABORTED); | 351 m_error = MediaError::create(MediaError::MEDIA_ERR_ABORTED); |
363 if (m_sendProgressEvents) | 352 if (m_sendProgressEvents) |
364 initAndDispatchProgressEvent(eventNames().abortEvent); | 353 initAndDispatchProgressEvent(eventNames().abortEvent); |
365 if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel) | 354 if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel) |
(...skipping 11 matching lines...) Expand all Loading... |
377 // 5 | 366 // 5 |
378 if (networkState() != EMPTY) { | 367 if (networkState() != EMPTY) { |
379 m_networkState = EMPTY; | 368 m_networkState = EMPTY; |
380 m_readyState = DATA_UNAVAILABLE; | 369 m_readyState = DATA_UNAVAILABLE; |
381 m_paused = true; | 370 m_paused = true; |
382 m_seeking = false; | 371 m_seeking = false; |
383 if (m_player) { | 372 if (m_player) { |
384 m_player->pause(); | 373 m_player->pause(); |
385 m_player->seek(0); | 374 m_player->seek(0); |
386 } | 375 } |
387 m_currentLoop = 0; | |
388 dispatchEventForType(eventNames().emptiedEvent, false, true); | 376 dispatchEventForType(eventNames().emptiedEvent, false, true); |
389 if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel) | 377 if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel) |
390 goto end; | 378 goto end; |
391 } | 379 } |
392 | 380 |
393 // 6 | 381 // 6 |
394 mediaSrc = selectMediaURL(contentType); | 382 mediaSrc = selectMediaURL(contentType); |
395 if (mediaSrc.isEmpty()) { | 383 if (mediaSrc.isEmpty()) { |
396 ec = INVALID_STATE_ERR; | 384 ec = INVALID_STATE_ERR; |
397 goto end; | 385 goto end; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
464 | 452 |
465 // 3.14.9.4. Loading the media resource | 453 // 3.14.9.4. Loading the media resource |
466 // 14 | 454 // 14 |
467 if (state == MediaPlayer::LoadFailed) { | 455 if (state == MediaPlayer::LoadFailed) { |
468 //delete m_player; | 456 //delete m_player; |
469 //m_player = 0; | 457 //m_player = 0; |
470 // FIXME better error handling | 458 // FIXME better error handling |
471 m_error = MediaError::create(MediaError::MEDIA_ERR_NETWORK); | 459 m_error = MediaError::create(MediaError::MEDIA_ERR_NETWORK); |
472 m_begun = false; | 460 m_begun = false; |
473 m_progressEventTimer.stop(); | 461 m_progressEventTimer.stop(); |
474 m_bufferingRate = 0; | |
475 | 462 |
476 initAndDispatchProgressEvent(eventNames().errorEvent); | 463 initAndDispatchProgressEvent(eventNames().errorEvent); |
477 if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel) | 464 if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel) |
478 return; | 465 return; |
479 | 466 |
480 m_networkState = EMPTY; | 467 m_networkState = EMPTY; |
481 | 468 |
482 if (isVideo()) | 469 if (isVideo()) |
483 static_cast<HTMLVideoElement*>(this)->updatePosterImage(); | 470 static_cast<HTMLVideoElement*>(this)->updatePosterImage(); |
484 | 471 |
485 dispatchEventForType(eventNames().emptiedEvent, false, true); | 472 dispatchEventForType(eventNames().emptiedEvent, false, true); |
486 return; | 473 return; |
487 } | 474 } |
488 | 475 |
489 if (state >= MediaPlayer::Loading && m_networkState < LOADING) | 476 if (state >= MediaPlayer::Loading && m_networkState < LOADING) |
490 m_networkState = LOADING; | 477 m_networkState = LOADING; |
491 | 478 |
492 if (state >= MediaPlayer::LoadedMetaData && m_networkState < LOADED_METADATA
) { | 479 if (state >= MediaPlayer::LoadedMetaData && m_networkState < LOADED_METADATA
) { |
493 m_player->seek(effectiveStart()); | |
494 m_networkState = LOADED_METADATA; | 480 m_networkState = LOADED_METADATA; |
495 | 481 |
496 dispatchEventForType(eventNames().durationchangeEvent, false, true); | 482 dispatchEventForType(eventNames().durationchangeEvent, false, true); |
497 if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel) | 483 if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel) |
498 return; | 484 return; |
499 | 485 |
500 dispatchEventForType(eventNames().loadedmetadataEvent, false, true); | 486 dispatchEventForType(eventNames().loadedmetadataEvent, false, true); |
501 if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel) | 487 if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel) |
502 return; | 488 return; |
503 } | 489 } |
(...skipping 24 matching lines...) Expand all Loading... |
528 dispatchEventForType(eventNames().canshowcurrentframeEvent, false, true)
; | 514 dispatchEventForType(eventNames().canshowcurrentframeEvent, false, true)
; |
529 if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel) | 515 if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel) |
530 return; | 516 return; |
531 } | 517 } |
532 | 518 |
533 // 15 | 519 // 15 |
534 if (state == MediaPlayer::Loaded && m_networkState < LOADED) { | 520 if (state == MediaPlayer::Loaded && m_networkState < LOADED) { |
535 m_begun = false; | 521 m_begun = false; |
536 m_networkState = LOADED; | 522 m_networkState = LOADED; |
537 m_progressEventTimer.stop(); | 523 m_progressEventTimer.stop(); |
538 m_bufferingRate = 0; | |
539 initAndDispatchProgressEvent(eventNames().loadEvent); | 524 initAndDispatchProgressEvent(eventNames().loadEvent); |
540 } | 525 } |
541 } | 526 } |
542 | 527 |
543 void HTMLMediaElement::mediaPlayerReadyStateChanged(MediaPlayer*) | 528 void HTMLMediaElement::mediaPlayerReadyStateChanged(MediaPlayer*) |
544 { | 529 { |
545 beginProcessingMediaPlayerCallback(); | 530 beginProcessingMediaPlayerCallback(); |
546 | 531 |
547 MediaPlayer::ReadyState state = m_player->readyState(); | 532 MediaPlayer::ReadyState state = m_player->readyState(); |
548 setReadyState((ReadyState)state); | 533 setReadyState((ReadyState)state); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 } | 574 } |
590 updatePlayState(); | 575 updatePlayState(); |
591 } | 576 } |
592 | 577 |
593 void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*) | 578 void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*) |
594 { | 579 { |
595 ASSERT(m_player); | 580 ASSERT(m_player); |
596 unsigned progress = m_player->bytesLoaded(); | 581 unsigned progress = m_player->bytesLoaded(); |
597 double time = WTF::currentTime(); | 582 double time = WTF::currentTime(); |
598 double timedelta = time - m_previousProgressTime; | 583 double timedelta = time - m_previousProgressTime; |
599 if (timedelta) | |
600 m_bufferingRate = (float)(0.8 * m_bufferingRate + 0.2 * ((float)(progres
s - m_previousProgress)) / timedelta); | |
601 | 584 |
602 if (progress == m_previousProgress) { | 585 if (progress == m_previousProgress) { |
603 if (timedelta > 3.0 && !m_sentStalledEvent) { | 586 if (timedelta > 3.0 && !m_sentStalledEvent) { |
604 m_bufferingRate = 0; | |
605 initAndDispatchProgressEvent(eventNames().stalledEvent); | 587 initAndDispatchProgressEvent(eventNames().stalledEvent); |
606 m_sentStalledEvent = true; | 588 m_sentStalledEvent = true; |
607 } | 589 } |
608 } else { | 590 } else { |
609 initAndDispatchProgressEvent(eventNames().progressEvent); | 591 initAndDispatchProgressEvent(eventNames().progressEvent); |
610 m_previousProgress = progress; | 592 m_previousProgress = progress; |
611 m_previousProgressTime = time; | 593 m_previousProgressTime = time; |
612 m_sentStalledEvent = false; | 594 m_sentStalledEvent = false; |
613 } | 595 } |
614 } | 596 } |
615 | 597 |
616 void HTMLMediaElement::seek(float time, ExceptionCode& ec) | 598 void HTMLMediaElement::seek(float time, ExceptionCode& ec) |
617 { | 599 { |
618 // 3.14.9.8. Seeking | 600 // 3.14.9.8. Seeking |
619 // 1 | 601 // 1 |
620 if (networkState() < LOADED_METADATA) { | 602 if (networkState() < LOADED_METADATA) { |
621 ec = INVALID_STATE_ERR; | 603 ec = INVALID_STATE_ERR; |
622 return; | 604 return; |
623 } | 605 } |
624 | 606 |
625 // 2 | 607 time = min(time, duration()); |
626 float minTime; | 608 time = max(time, 0.0f); |
627 if (currentLoop() == 0) | |
628 minTime = effectiveStart(); | |
629 else | |
630 minTime = effectiveLoopStart(); | |
631 | |
632 // 3 | |
633 float maxTime = currentLoop() == playCount() - 1 ? effectiveEnd() : effectiv
eLoopEnd(); | |
634 | |
635 // 4 | |
636 time = min(time, maxTime); | |
637 | |
638 // 5 | |
639 time = max(time, minTime); | |
640 | 609 |
641 // 6 | 610 // 6 |
642 RefPtr<TimeRanges> seekableRanges = seekable(); | 611 RefPtr<TimeRanges> seekableRanges = seekable(); |
643 if (!seekableRanges->contain(time)) { | 612 if (!seekableRanges->contain(time)) { |
644 ec = INDEX_SIZE_ERR; | 613 ec = INDEX_SIZE_ERR; |
645 return; | 614 return; |
646 } | 615 } |
647 | 616 |
648 // 7 | 617 // 7 |
649 m_currentTimeDuringSeek = time; | 618 m_currentTimeDuringSeek = time; |
650 | 619 |
651 // 8 | 620 // 8 |
652 m_seeking = true; | 621 m_seeking = true; |
653 | 622 |
654 // 9 | 623 // 9 |
655 dispatchEventForType(eventNames().timeupdateEvent, false, true); | 624 dispatchEventForType(eventNames().timeupdateEvent, false, true); |
656 | 625 |
657 // 10 | 626 // 10 |
658 // As soon as the user agent has established whether or not the media data f
or the new playback position is available, | 627 // As soon as the user agent has established whether or not the media data f
or the new playback position is available, |
659 // and, if it is, decoded enough data to play back that position, the seekin
g DOM attribute must be set to false. | 628 // and, if it is, decoded enough data to play back that position, the seekin
g DOM attribute must be set to false. |
660 if (m_player) { | 629 if (m_player) |
661 m_player->setEndTime(maxTime); | |
662 m_player->seek(time); | 630 m_player->seek(time); |
663 } | |
664 } | 631 } |
665 | 632 |
666 HTMLMediaElement::ReadyState HTMLMediaElement::readyState() const | 633 HTMLMediaElement::ReadyState HTMLMediaElement::readyState() const |
667 { | 634 { |
668 return m_readyState; | 635 return m_readyState; |
669 } | 636 } |
670 | 637 |
671 bool HTMLMediaElement::seeking() const | 638 bool HTMLMediaElement::seeking() const |
672 { | 639 { |
673 return m_seeking; | 640 return m_seeking; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 { | 728 { |
762 // 3.14.9.7. Playing the media resource | 729 // 3.14.9.7. Playing the media resource |
763 if (!m_player || networkState() == EMPTY) { | 730 if (!m_player || networkState() == EMPTY) { |
764 ec = 0; | 731 ec = 0; |
765 load(ec); | 732 load(ec); |
766 if (ec) | 733 if (ec) |
767 return; | 734 return; |
768 } | 735 } |
769 ExceptionCode unused; | 736 ExceptionCode unused; |
770 if (endedPlayback()) { | 737 if (endedPlayback()) { |
771 m_currentLoop = 0; | 738 seek(0, unused); |
772 seek(effectiveStart(), unused); | |
773 } | 739 } |
774 setPlaybackRate(defaultPlaybackRate(), unused); | 740 setPlaybackRate(defaultPlaybackRate(), unused); |
775 | 741 |
776 if (m_paused) { | 742 if (m_paused) { |
777 m_paused = false; | 743 m_paused = false; |
778 dispatchEventAsync(eventNames().playEvent); | 744 dispatchEventAsync(eventNames().playEvent); |
779 } | 745 } |
780 | 746 |
781 m_autoplaying = false; | 747 m_autoplaying = false; |
782 | 748 |
(...skipping 25 matching lines...) Expand all Loading... |
808 m_paused = true; | 774 m_paused = true; |
809 dispatchEventAsync(eventNames().timeupdateEvent); | 775 dispatchEventAsync(eventNames().timeupdateEvent); |
810 dispatchEventAsync(eventNames().pauseEvent); | 776 dispatchEventAsync(eventNames().pauseEvent); |
811 } | 777 } |
812 | 778 |
813 m_autoplaying = false; | 779 m_autoplaying = false; |
814 | 780 |
815 updatePlayState(); | 781 updatePlayState(); |
816 } | 782 } |
817 | 783 |
818 unsigned HTMLMediaElement::playCount() const | 784 bool HTMLMediaElement::loop() const |
819 { | 785 { |
820 bool ok; | 786 return hasAttribute(loopAttr); |
821 unsigned count = getAttribute(playcountAttr).string().toUInt(&ok); | |
822 return (count > 0 && ok) ? count : 1; | |
823 } | 787 } |
824 | 788 |
825 void HTMLMediaElement::setPlayCount(unsigned count, ExceptionCode& ec) | 789 void HTMLMediaElement::setLoop(bool b) |
826 { | 790 { |
827 if (!count) { | 791 setBooleanAttribute(loopAttr, b); |
828 ec = INDEX_SIZE_ERR; | |
829 return; | |
830 } | |
831 setAttribute(playcountAttr, String::number(count)); | |
832 checkIfSeekNeeded(); | |
833 } | |
834 | |
835 float HTMLMediaElement::start() const | |
836 { | |
837 return getTimeOffsetAttribute(startAttr, 0); | |
838 } | |
839 | |
840 void HTMLMediaElement::setStart(float time) | |
841 { | |
842 setTimeOffsetAttribute(startAttr, time); | |
843 checkIfSeekNeeded(); | |
844 } | |
845 | |
846 float HTMLMediaElement::end() const | |
847 { | |
848 return getTimeOffsetAttribute(endAttr, std::numeric_limits<float>::infinity(
)); | |
849 } | |
850 | |
851 void HTMLMediaElement::setEnd(float time) | |
852 { | |
853 setTimeOffsetAttribute(endAttr, time); | |
854 checkIfSeekNeeded(); | |
855 } | |
856 | |
857 float HTMLMediaElement::loopStart() const | |
858 { | |
859 return getTimeOffsetAttribute(loopstartAttr, start()); | |
860 } | |
861 | |
862 void HTMLMediaElement::setLoopStart(float time) | |
863 { | |
864 setTimeOffsetAttribute(loopstartAttr, time); | |
865 checkIfSeekNeeded(); | |
866 } | |
867 | |
868 float HTMLMediaElement::loopEnd() const | |
869 { | |
870 return getTimeOffsetAttribute(loopendAttr, end()); | |
871 } | |
872 | |
873 void HTMLMediaElement::setLoopEnd(float time) | |
874 { | |
875 setTimeOffsetAttribute(loopendAttr, time); | |
876 checkIfSeekNeeded(); | |
877 } | |
878 | |
879 unsigned HTMLMediaElement::currentLoop() const | |
880 { | |
881 return m_currentLoop; | |
882 } | |
883 | |
884 void HTMLMediaElement::setCurrentLoop(unsigned currentLoop) | |
885 { | |
886 m_currentLoop = currentLoop; | |
887 } | 792 } |
888 | 793 |
889 bool HTMLMediaElement::controls() const | 794 bool HTMLMediaElement::controls() const |
890 { | 795 { |
891 Frame* frame = document()->frame(); | 796 Frame* frame = document()->frame(); |
892 | 797 |
893 // always show controls when scripting is disabled | 798 // always show controls when scripting is disabled |
894 if (frame && !frame->script()->isEnabled()) | 799 if (frame && !frame->script()->isEnabled()) |
895 return true; | 800 return true; |
896 | 801 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1001 mediaSrc = source->src().string(); | 906 mediaSrc = source->src().string(); |
1002 break; | 907 break; |
1003 } | 908 } |
1004 } | 909 } |
1005 } | 910 } |
1006 if (!mediaSrc.isEmpty()) | 911 if (!mediaSrc.isEmpty()) |
1007 mediaSrc = document()->completeURL(mediaSrc).string(); | 912 mediaSrc = document()->completeURL(mediaSrc).string(); |
1008 return mediaSrc; | 913 return mediaSrc; |
1009 } | 914 } |
1010 | 915 |
1011 void HTMLMediaElement::checkIfSeekNeeded() | |
1012 { | |
1013 // 3.14.9.5. Offsets into the media resource | |
1014 // 1 | |
1015 if (playCount() <= m_currentLoop) | |
1016 m_currentLoop = playCount() - 1; | |
1017 | |
1018 // 2 | |
1019 if (networkState() <= LOADING) | |
1020 return; | |
1021 | |
1022 // 3 | |
1023 ExceptionCode ec; | |
1024 float time = currentTime(); | |
1025 if (!m_currentLoop && time < effectiveStart()) | |
1026 seek(effectiveStart(), ec); | |
1027 | |
1028 // 4 | |
1029 if (m_currentLoop && time < effectiveLoopStart()) | |
1030 seek(effectiveLoopStart(), ec); | |
1031 | |
1032 // 5 | |
1033 if (m_currentLoop < playCount() - 1 && time > effectiveLoopEnd()) { | |
1034 seek(effectiveLoopStart(), ec); | |
1035 m_currentLoop++; | |
1036 } | |
1037 | |
1038 // 6 | |
1039 if (m_currentLoop == playCount() - 1 && time > effectiveEnd()) | |
1040 seek(effectiveEnd(), ec); | |
1041 | |
1042 updatePlayState(); | |
1043 } | |
1044 | |
1045 void HTMLMediaElement::mediaPlayerTimeChanged(MediaPlayer*) | 916 void HTMLMediaElement::mediaPlayerTimeChanged(MediaPlayer*) |
1046 { | 917 { |
1047 beginProcessingMediaPlayerCallback(); | 918 beginProcessingMediaPlayerCallback(); |
1048 | 919 |
1049 if (readyState() >= CAN_PLAY) | 920 if (readyState() >= CAN_PLAY) |
1050 m_seeking = false; | 921 m_seeking = false; |
1051 | 922 |
1052 float now = currentTime(); | 923 float now = currentTime(); |
1053 if (m_currentLoop < playCount() - 1 && now >= effectiveLoopEnd()) { | 924 if (now >= duration()) { |
1054 ExceptionCode ec; | 925 if (loop()) { |
1055 seek(effectiveLoopStart(), ec); | 926 ExceptionCode ec; |
1056 m_currentLoop++; | 927 seek(0, ec); |
1057 dispatchEventForType(eventNames().timeupdateEvent, false, true); | 928 dispatchEventForType(eventNames().timeupdateEvent, false, true); |
1058 } | 929 } else { |
1059 | 930 dispatchEventForType(eventNames().timeupdateEvent, false, true); |
1060 if (m_currentLoop == playCount() - 1 && now >= effectiveEnd()) { | 931 dispatchEventForType(eventNames().endedEvent, false, true); |
1061 dispatchEventForType(eventNames().timeupdateEvent, false, true); | 932 } |
1062 dispatchEventForType(eventNames().endedEvent, false, true); | |
1063 } | 933 } |
1064 | 934 |
1065 updatePlayState(); | 935 updatePlayState(); |
1066 | 936 |
1067 endProcessingMediaPlayerCallback(); | 937 endProcessingMediaPlayerCallback(); |
1068 } | 938 } |
1069 | 939 |
1070 void HTMLMediaElement::mediaPlayerRepaint(MediaPlayer*) | 940 void HTMLMediaElement::mediaPlayerRepaint(MediaPlayer*) |
1071 { | 941 { |
1072 beginProcessingMediaPlayerCallback(); | 942 beginProcessingMediaPlayerCallback(); |
(...skipping 24 matching lines...) Expand all Loading... |
1097 } | 967 } |
1098 | 968 |
1099 PassRefPtr<TimeRanges> HTMLMediaElement::seekable() const | 969 PassRefPtr<TimeRanges> HTMLMediaElement::seekable() const |
1100 { | 970 { |
1101 // FIXME real ranges support | 971 // FIXME real ranges support |
1102 if (!m_player || !m_player->maxTimeSeekable()) | 972 if (!m_player || !m_player->maxTimeSeekable()) |
1103 return TimeRanges::create(); | 973 return TimeRanges::create(); |
1104 return TimeRanges::create(0, m_player->maxTimeSeekable()); | 974 return TimeRanges::create(0, m_player->maxTimeSeekable()); |
1105 } | 975 } |
1106 | 976 |
1107 float HTMLMediaElement::effectiveStart() const | |
1108 { | |
1109 if (!m_player) | |
1110 return 0; | |
1111 return min(start(), m_player->duration()); | |
1112 } | |
1113 | |
1114 float HTMLMediaElement::effectiveEnd() const | |
1115 { | |
1116 if (!m_player) | |
1117 return 0; | |
1118 return min(max(end(), max(start(), loopStart())), m_player->duration()); | |
1119 } | |
1120 | |
1121 float HTMLMediaElement::effectiveLoopStart() const | |
1122 { | |
1123 if (!m_player) | |
1124 return 0; | |
1125 return min(loopStart(), m_player->duration()); | |
1126 } | |
1127 | |
1128 float HTMLMediaElement::effectiveLoopEnd() const | |
1129 { | |
1130 if (!m_player) | |
1131 return 0; | |
1132 return min(max(start(), max(loopStart(), loopEnd())), m_player->duration()); | |
1133 } | |
1134 | |
1135 bool HTMLMediaElement::activelyPlaying() const | 977 bool HTMLMediaElement::activelyPlaying() const |
1136 { | 978 { |
1137 return !paused() && readyState() >= CAN_PLAY && !endedPlayback(); // && !sto
ppedDueToErrors() && !pausedForUserInteraction(); | 979 return !paused() && readyState() >= CAN_PLAY && !endedPlayback(); // && !sto
ppedDueToErrors() && !pausedForUserInteraction(); |
1138 } | 980 } |
1139 | 981 |
1140 bool HTMLMediaElement::endedPlayback() const | 982 bool HTMLMediaElement::endedPlayback() const |
1141 { | 983 { |
1142 return networkState() >= LOADED_METADATA && currentTime() >= effectiveEnd()
&& currentLoop() == playCount() - 1; | 984 return networkState() >= LOADED_METADATA && currentTime() >= duration() && !
loop(); |
1143 } | 985 } |
1144 | 986 |
1145 void HTMLMediaElement::updateVolume() | 987 void HTMLMediaElement::updateVolume() |
1146 { | 988 { |
1147 if (!m_player) | 989 if (!m_player) |
1148 return; | 990 return; |
1149 | 991 |
1150 // Avoid recursion when the player reports volume changes. | 992 // Avoid recursion when the player reports volume changes. |
1151 if (!processingMediaPlayerCallback()) { | 993 if (!processingMediaPlayerCallback()) { |
1152 Page* page = document()->page(); | 994 Page* page = document()->page(); |
(...skipping 10 matching lines...) Expand all Loading... |
1163 { | 1005 { |
1164 if (!m_player) | 1006 if (!m_player) |
1165 return; | 1007 return; |
1166 | 1008 |
1167 if (m_pausedInternal) { | 1009 if (m_pausedInternal) { |
1168 if (!m_player->paused()) | 1010 if (!m_player->paused()) |
1169 m_player->pause(); | 1011 m_player->pause(); |
1170 return; | 1012 return; |
1171 } | 1013 } |
1172 | 1014 |
1173 m_player->setEndTime(currentLoop() == playCount() - 1 ? effectiveEnd() : eff
ectiveLoopEnd()); | 1015 bool shouldBePlaying = activelyPlaying(); |
1174 | |
1175 bool shouldBePlaying = activelyPlaying() && currentTime() < effectiveEnd(); | |
1176 if (shouldBePlaying && m_player->paused()) | 1016 if (shouldBePlaying && m_player->paused()) |
1177 m_player->play(); | 1017 m_player->play(); |
1178 else if (!shouldBePlaying && !m_player->paused()) | 1018 else if (!shouldBePlaying && !m_player->paused()) |
1179 m_player->pause(); | 1019 m_player->pause(); |
1180 | 1020 |
1181 if (renderer()) | 1021 if (renderer()) |
1182 renderer()->updateFromElement(); | 1022 renderer()->updateFromElement(); |
1183 } | 1023 } |
1184 | 1024 |
1185 void HTMLMediaElement::setPausedInternal(bool b) | 1025 void HTMLMediaElement::setPausedInternal(bool b) |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1298 | 1138 |
1299 document()->updateRendering(); | 1139 document()->updateRendering(); |
1300 if (m_needWidgetUpdate && renderer()) | 1140 if (m_needWidgetUpdate && renderer()) |
1301 static_cast<RenderPartObject*>(renderer())->updateWidget(true); | 1141 static_cast<RenderPartObject*>(renderer())->updateWidget(true); |
1302 } | 1142 } |
1303 #endif | 1143 #endif |
1304 | 1144 |
1305 } | 1145 } |
1306 | 1146 |
1307 #endif | 1147 #endif |
OLD | NEW |