OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights | 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights |
3 * reserved. | 3 * reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 | 518 |
519 SetHasCustomStyleCallbacks(); | 519 SetHasCustomStyleCallbacks(); |
520 AddElementToDocumentMap(this, &document); | 520 AddElementToDocumentMap(this, &document); |
521 | 521 |
522 UseCounter::Count(document, UseCounter::kHTMLMediaElement); | 522 UseCounter::Count(document, UseCounter::kHTMLMediaElement); |
523 } | 523 } |
524 | 524 |
525 HTMLMediaElement::~HTMLMediaElement() { | 525 HTMLMediaElement::~HTMLMediaElement() { |
526 BLINK_MEDIA_LOG << "~HTMLMediaElement(" << (void*)this << ")"; | 526 BLINK_MEDIA_LOG << "~HTMLMediaElement(" << (void*)this << ")"; |
527 | 527 |
528 // m_audioSourceNode is explicitly cleared by AudioNode::dispose(). | 528 // audio_source_node_ is explicitly cleared by AudioNode::dispose(). |
529 // Since AudioNode::dispose() is guaranteed to be always called before | 529 // Since AudioNode::dispose() is guaranteed to be always called before |
530 // the AudioNode is destructed, m_audioSourceNode is explicitly cleared | 530 // the AudioNode is destructed, audio_source_node_ is explicitly cleared |
531 // even if the AudioNode and the HTMLMediaElement die together. | 531 // even if the AudioNode and the HTMLMediaElement die together. |
532 DCHECK(!audio_source_node_); | 532 DCHECK(!audio_source_node_); |
533 } | 533 } |
534 | 534 |
535 void HTMLMediaElement::Dispose() { | 535 void HTMLMediaElement::Dispose() { |
536 CloseMediaSource(); | 536 CloseMediaSource(); |
537 | 537 |
538 // Destroying the player may cause a resource load to be canceled, | 538 // Destroying the player may cause a resource load to be canceled, |
539 // which could result in LocalDOMWindow::dispatchWindowLoadEvent() being | 539 // which could result in LocalDOMWindow::dispatchWindowLoadEvent() being |
540 // called via ResourceFetch::didLoadResource(), then | 540 // called via ResourceFetch::didLoadResource(), then |
(...skipping 20 matching lines...) Expand all Loading... |
561 check_viewport_intersection_timer_.MoveToNewTaskRunner( | 561 check_viewport_intersection_timer_.MoveToNewTaskRunner( |
562 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); | 562 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); |
563 deferred_load_timer_.MoveToNewTaskRunner( | 563 deferred_load_timer_.MoveToNewTaskRunner( |
564 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); | 564 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); |
565 | 565 |
566 autoplay_policy_->DidMoveToNewDocument(old_document); | 566 autoplay_policy_->DidMoveToNewDocument(old_document); |
567 | 567 |
568 if (should_delay_load_event_) { | 568 if (should_delay_load_event_) { |
569 GetDocument().IncrementLoadEventDelayCount(); | 569 GetDocument().IncrementLoadEventDelayCount(); |
570 // Note: Keeping the load event delay count increment on oldDocument that | 570 // Note: Keeping the load event delay count increment on oldDocument that |
571 // was added when m_shouldDelayLoadEvent was set so that destruction of | 571 // was added when should_delay_load_event_ was set so that destruction of |
572 // m_webMediaPlayer can not cause load event dispatching in oldDocument. | 572 // web_media_player_ can not cause load event dispatching in oldDocument. |
573 } else { | 573 } else { |
574 // Incrementing the load event delay count so that destruction of | 574 // Incrementing the load event delay count so that destruction of |
575 // m_webMediaPlayer can not cause load event dispatching in oldDocument. | 575 // web_media_player_ can not cause load event dispatching in oldDocument. |
576 old_document.IncrementLoadEventDelayCount(); | 576 old_document.IncrementLoadEventDelayCount(); |
577 } | 577 } |
578 | 578 |
579 RemoveElementFromDocumentMap(this, &old_document); | 579 RemoveElementFromDocumentMap(this, &old_document); |
580 AddElementToDocumentMap(this, &GetDocument()); | 580 AddElementToDocumentMap(this, &GetDocument()); |
581 | 581 |
582 // FIXME: This is a temporary fix to prevent this object from causing the | 582 // FIXME: This is a temporary fix to prevent this object from causing the |
583 // MediaPlayer to dereference LocalFrame and FrameLoader pointers from the | 583 // MediaPlayer to dereference LocalFrame and FrameLoader pointers from the |
584 // previous document. This restarts the load, as if the src attribute had been | 584 // previous document. This restarts the load, as if the src attribute had been |
585 // set. A proper fix would provide a mechanism to allow this object to | 585 // set. A proper fix would provide a mechanism to allow this object to |
586 // refresh the MediaPlayer's LocalFrame and FrameLoader references on document | 586 // refresh the MediaPlayer's LocalFrame and FrameLoader references on document |
587 // changes so that playback can be resumed properly. | 587 // changes so that playback can be resumed properly. |
588 ignore_preload_none_ = false; | 588 ignore_preload_none_ = false; |
589 InvokeLoadAlgorithm(); | 589 InvokeLoadAlgorithm(); |
590 | 590 |
591 // Decrement the load event delay count on oldDocument now that | 591 // Decrement the load event delay count on oldDocument now that |
592 // m_webMediaPlayer has been destroyed and there is no risk of dispatching a | 592 // web_media_player_ has been destroyed and there is no risk of dispatching a |
593 // load event from within the destructor. | 593 // load event from within the destructor. |
594 old_document.DecrementLoadEventDelayCount(); | 594 old_document.DecrementLoadEventDelayCount(); |
595 | 595 |
596 SuspendableObject::DidMoveToNewExecutionContext(&GetDocument()); | 596 SuspendableObject::DidMoveToNewExecutionContext(&GetDocument()); |
597 HTMLElement::DidMoveToNewDocument(old_document); | 597 HTMLElement::DidMoveToNewDocument(old_document); |
598 } | 598 } |
599 | 599 |
600 bool HTMLMediaElement::SupportsFocus() const { | 600 bool HTMLMediaElement::SupportsFocus() const { |
601 if (ownerDocument()->IsMediaDocument()) | 601 if (ownerDocument()->IsMediaDocument()) |
602 return false; | 602 return false; |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 pending_action_flags_ |= kLoadMediaResource; | 728 pending_action_flags_ |= kLoadMediaResource; |
729 load_timer_.StartOneShot(0, BLINK_FROM_HERE); | 729 load_timer_.StartOneShot(0, BLINK_FROM_HERE); |
730 } | 730 } |
731 | 731 |
732 void HTMLMediaElement::ScheduleEvent(const AtomicString& event_name) { | 732 void HTMLMediaElement::ScheduleEvent(const AtomicString& event_name) { |
733 ScheduleEvent(Event::CreateCancelable(event_name)); | 733 ScheduleEvent(Event::CreateCancelable(event_name)); |
734 } | 734 } |
735 | 735 |
736 void HTMLMediaElement::ScheduleEvent(Event* event) { | 736 void HTMLMediaElement::ScheduleEvent(Event* event) { |
737 #if LOG_MEDIA_EVENTS | 737 #if LOG_MEDIA_EVENTS |
738 BLINK_MEDIA_LOG << "scheduleEvent(" << (void*)this << ")" | 738 BLINK_MEDIA_LOG << "ScheduleEvent(" << (void*)this << ")" |
739 << " - scheduling '" << event->type() << "'"; | 739 << " - scheduling '" << event->type() << "'"; |
740 #endif | 740 #endif |
741 async_event_queue_->EnqueueEvent(event); | 741 async_event_queue_->EnqueueEvent(event); |
742 } | 742 } |
743 | 743 |
744 void HTMLMediaElement::LoadTimerFired(TimerBase*) { | 744 void HTMLMediaElement::LoadTimerFired(TimerBase*) { |
745 if (pending_action_flags_ & kLoadTextTrackResource) | 745 if (pending_action_flags_ & kLoadTextTrackResource) |
746 HonorUserPreferencesForAutomaticTextTrackSelection(); | 746 HonorUserPreferencesForAutomaticTextTrackSelection(); |
747 | 747 |
748 if (pending_action_flags_ & kLoadMediaResource) { | 748 if (pending_action_flags_ & kLoadMediaResource) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
799 | 799 |
800 void HTMLMediaElement::load() { | 800 void HTMLMediaElement::load() { |
801 BLINK_MEDIA_LOG << "load(" << (void*)this << ")"; | 801 BLINK_MEDIA_LOG << "load(" << (void*)this << ")"; |
802 | 802 |
803 autoplay_policy_->TryUnlockingUserGesture(); | 803 autoplay_policy_->TryUnlockingUserGesture(); |
804 | 804 |
805 ignore_preload_none_ = true; | 805 ignore_preload_none_ = true; |
806 InvokeLoadAlgorithm(); | 806 InvokeLoadAlgorithm(); |
807 } | 807 } |
808 | 808 |
809 // TODO(srirama.m): Currently m_ignorePreloadNone is reset before calling | 809 // TODO(srirama.m): Currently ignore_preload_none_ is reset before calling |
810 // invokeLoadAlgorithm() in all places except load(). Move it inside here | 810 // invokeLoadAlgorithm() in all places except load(). Move it inside here |
811 // once microtask is implemented for "Await a stable state" step | 811 // once microtask is implemented for "Await a stable state" step |
812 // in resource selection algorithm. | 812 // in resource selection algorithm. |
813 void HTMLMediaElement::InvokeLoadAlgorithm() { | 813 void HTMLMediaElement::InvokeLoadAlgorithm() { |
814 BLINK_MEDIA_LOG << "invokeLoadAlgorithm(" << (void*)this << ")"; | 814 BLINK_MEDIA_LOG << "invokeLoadAlgorithm(" << (void*)this << ")"; |
815 | 815 |
816 // Perform the cleanup required for the resource load algorithm to run. | 816 // Perform the cleanup required for the resource load algorithm to run. |
817 StopPeriodicTimers(); | 817 StopPeriodicTimers(); |
818 load_timer_.Stop(); | 818 load_timer_.Stop(); |
819 CancelDeferredLoad(); | 819 CancelDeferredLoad(); |
820 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if | 820 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if |
821 // necessary and set m_pendingActionFlags to 0 here. | 821 // necessary and set pending_action_flags_ to 0 here. |
822 pending_action_flags_ &= ~kLoadMediaResource; | 822 pending_action_flags_ &= ~kLoadMediaResource; |
823 sent_stalled_event_ = false; | 823 sent_stalled_event_ = false; |
824 have_fired_loaded_data_ = false; | 824 have_fired_loaded_data_ = false; |
825 display_mode_ = kUnknown; | 825 display_mode_ = kUnknown; |
826 | 826 |
827 // 1 - Abort any already-running instance of the resource selection algorithm | 827 // 1 - Abort any already-running instance of the resource selection algorithm |
828 // for this element. | 828 // for this element. |
829 load_state_ = kWaitingForSource; | 829 load_state_ = kWaitingForSource; |
830 current_source_node_ = nullptr; | 830 current_source_node_ = nullptr; |
831 | 831 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
942 BLINK_MEDIA_LOG << "invokeResourceSelectionAlgorithm(" << (void*)this << ")"; | 942 BLINK_MEDIA_LOG << "invokeResourceSelectionAlgorithm(" << (void*)this << ")"; |
943 // The resource selection algorithm | 943 // The resource selection algorithm |
944 // 1 - Set the networkState to NETWORK_NO_SOURCE | 944 // 1 - Set the networkState to NETWORK_NO_SOURCE |
945 SetNetworkState(kNetworkNoSource); | 945 SetNetworkState(kNetworkNoSource); |
946 | 946 |
947 // 2 - Set the element's show poster flag to true | 947 // 2 - Set the element's show poster flag to true |
948 // TODO(srirama.m): Introduce show poster flag and update it as per spec | 948 // TODO(srirama.m): Introduce show poster flag and update it as per spec |
949 | 949 |
950 played_time_ranges_ = TimeRanges::Create(); | 950 played_time_ranges_ = TimeRanges::Create(); |
951 | 951 |
952 // FIXME: Investigate whether these can be moved into m_networkState != | 952 // FIXME: Investigate whether these can be moved into network_state_ != |
953 // kNetworkEmpty block above | 953 // kNetworkEmpty block above |
954 // so they are closer to the relevant spec steps. | 954 // so they are closer to the relevant spec steps. |
955 last_seek_time_ = 0; | 955 last_seek_time_ = 0; |
956 duration_ = std::numeric_limits<double>::quiet_NaN(); | 956 duration_ = std::numeric_limits<double>::quiet_NaN(); |
957 | 957 |
958 // 3 - Set the media element's delaying-the-load-event flag to true (this | 958 // 3 - Set the media element's delaying-the-load-event flag to true (this |
959 // delays the load event) | 959 // delays the load event) |
960 SetShouldDelayLoadEvent(true); | 960 SetShouldDelayLoadEvent(true); |
961 if (GetMediaControls()) | 961 if (GetMediaControls()) |
962 GetMediaControls()->Reset(); | 962 GetMediaControls()->Reset(); |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1117 if (!frame) { | 1117 if (!frame) { |
1118 MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError, | 1118 MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError, |
1119 BuildElementErrorMessage( | 1119 BuildElementErrorMessage( |
1120 "Resource load failure: document has no frame")); | 1120 "Resource load failure: document has no frame")); |
1121 return; | 1121 return; |
1122 } | 1122 } |
1123 | 1123 |
1124 // The resource fetch algorithm | 1124 // The resource fetch algorithm |
1125 SetNetworkState(kNetworkLoading); | 1125 SetNetworkState(kNetworkLoading); |
1126 | 1126 |
1127 // Set m_currentSrc *before* changing to the cache url, the fact that we are | 1127 // Set current_src_ *before* changing to the cache url, the fact that we are |
1128 // loading from the app cache is an internal detail not exposed through the | 1128 // loading from the app cache is an internal detail not exposed through the |
1129 // media element API. | 1129 // media element API. |
1130 current_src_ = url; | 1130 current_src_ = url; |
1131 | 1131 |
1132 if (audio_source_node_) | 1132 if (audio_source_node_) |
1133 audio_source_node_->OnCurrentSrcChanged(current_src_); | 1133 audio_source_node_->OnCurrentSrcChanged(current_src_); |
1134 | 1134 |
1135 BLINK_MEDIA_LOG << "loadResource(" << (void*)this << ") - m_currentSrc -> " | 1135 BLINK_MEDIA_LOG << "loadResource(" << (void*)this << ") - current_src_ -> " |
1136 << UrlForLoggingMedia(current_src_); | 1136 << UrlForLoggingMedia(current_src_); |
1137 | 1137 |
1138 StartProgressEventTimer(); | 1138 StartProgressEventTimer(); |
1139 | 1139 |
1140 // Reset display mode to force a recalculation of what to show because we are | 1140 // Reset display mode to force a recalculation of what to show because we are |
1141 // resetting the player. | 1141 // resetting the player. |
1142 SetDisplayMode(kUnknown); | 1142 SetDisplayMode(kUnknown); |
1143 | 1143 |
1144 SetPlayerPreload(); | 1144 SetPlayerPreload(); |
1145 | 1145 |
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1677 | 1677 |
1678 void HTMLMediaElement::ReadyStateChanged() { | 1678 void HTMLMediaElement::ReadyStateChanged() { |
1679 SetReadyState(static_cast<ReadyState>(GetWebMediaPlayer()->GetReadyState())); | 1679 SetReadyState(static_cast<ReadyState>(GetWebMediaPlayer()->GetReadyState())); |
1680 } | 1680 } |
1681 | 1681 |
1682 void HTMLMediaElement::SetReadyState(ReadyState state) { | 1682 void HTMLMediaElement::SetReadyState(ReadyState state) { |
1683 BLINK_MEDIA_LOG << "setReadyState(" << (void*)this << ", " | 1683 BLINK_MEDIA_LOG << "setReadyState(" << (void*)this << ", " |
1684 << static_cast<int>(state) << ") - current state is " | 1684 << static_cast<int>(state) << ") - current state is " |
1685 << static_cast<int>(ready_state_); | 1685 << static_cast<int>(ready_state_); |
1686 | 1686 |
1687 // Set "wasPotentiallyPlaying" BEFORE updating m_readyState, | 1687 // Set "wasPotentiallyPlaying" BEFORE updating ready_state_, |
1688 // potentiallyPlaying() uses it | 1688 // potentiallyPlaying() uses it |
1689 bool was_potentially_playing = PotentiallyPlaying(); | 1689 bool was_potentially_playing = PotentiallyPlaying(); |
1690 | 1690 |
1691 ReadyState old_state = ready_state_; | 1691 ReadyState old_state = ready_state_; |
1692 ReadyState new_state = state; | 1692 ReadyState new_state = state; |
1693 | 1693 |
1694 bool tracks_are_ready = TextTracksAreReady(); | 1694 bool tracks_are_ready = TextTracksAreReady(); |
1695 | 1695 |
1696 if (new_state == old_state && tracks_are_ready_ == tracks_are_ready) | 1696 if (new_state == old_state && tracks_are_ready_ == tracks_are_ready) |
1697 return; | 1697 return; |
(...skipping 25 matching lines...) Expand all Loading... |
1723 // will be fired at the element. | 1723 // will be fired at the element. |
1724 if (was_potentially_playing && ready_state_ < kHaveFutureData) | 1724 if (was_potentially_playing && ready_state_ < kHaveFutureData) |
1725 ScheduleEvent(EventTypeNames::waiting); | 1725 ScheduleEvent(EventTypeNames::waiting); |
1726 | 1726 |
1727 // 4.8.12.9 steps 12-14 | 1727 // 4.8.12.9 steps 12-14 |
1728 if (ready_state_ >= kHaveCurrentData) | 1728 if (ready_state_ >= kHaveCurrentData) |
1729 FinishSeek(); | 1729 FinishSeek(); |
1730 } else { | 1730 } else { |
1731 if (was_potentially_playing && ready_state_ < kHaveFutureData) { | 1731 if (was_potentially_playing && ready_state_ < kHaveFutureData) { |
1732 // Force an update to official playback position. Automatic updates from | 1732 // Force an update to official playback position. Automatic updates from |
1733 // currentPlaybackPosition() will be blocked while m_readyState remains | 1733 // currentPlaybackPosition() will be blocked while ready_state_ remains |
1734 // < kHaveFutureData. This blocking is desired after 'waiting' has been | 1734 // < kHaveFutureData. This blocking is desired after 'waiting' has been |
1735 // fired, but its good to update it one final time to accurately reflect | 1735 // fired, but its good to update it one final time to accurately reflect |
1736 // media time at the moment we ran out of data to play. | 1736 // media time at the moment we ran out of data to play. |
1737 SetOfficialPlaybackPosition(CurrentPlaybackPosition()); | 1737 SetOfficialPlaybackPosition(CurrentPlaybackPosition()); |
1738 | 1738 |
1739 // 4.8.12.8 | 1739 // 4.8.12.8 |
1740 ScheduleTimeupdateEvent(false); | 1740 ScheduleTimeupdateEvent(false); |
1741 ScheduleEvent(EventTypeNames::waiting); | 1741 ScheduleEvent(EventTypeNames::waiting); |
1742 } | 1742 } |
1743 } | 1743 } |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1871 void HTMLMediaElement::SetIgnorePreloadNone() { | 1871 void HTMLMediaElement::SetIgnorePreloadNone() { |
1872 BLINK_MEDIA_LOG << "setIgnorePreloadNone(" << (void*)this << ")"; | 1872 BLINK_MEDIA_LOG << "setIgnorePreloadNone(" << (void*)this << ")"; |
1873 ignore_preload_none_ = true; | 1873 ignore_preload_none_ = true; |
1874 SetPlayerPreload(); | 1874 SetPlayerPreload(); |
1875 } | 1875 } |
1876 | 1876 |
1877 void HTMLMediaElement::Seek(double time) { | 1877 void HTMLMediaElement::Seek(double time) { |
1878 BLINK_MEDIA_LOG << "seek(" << (void*)this << ", " << time << ")"; | 1878 BLINK_MEDIA_LOG << "seek(" << (void*)this << ", " << time << ")"; |
1879 | 1879 |
1880 // 2 - If the media element's readyState is HAVE_NOTHING, abort these steps. | 1880 // 2 - If the media element's readyState is HAVE_NOTHING, abort these steps. |
1881 // FIXME: remove m_webMediaPlayer check once we figure out how | 1881 // FIXME: remove web_media_player_ check once we figure out how |
1882 // m_webMediaPlayer is going out of sync with readystate. | 1882 // web_media_player_ is going out of sync with readystate. |
1883 // m_webMediaPlayer is cleared but readystate is not set to HAVE_NOTHING. | 1883 // web_media_player_ is cleared but readystate is not set to HAVE_NOTHING. |
1884 if (!web_media_player_ || ready_state_ == kHaveNothing) | 1884 if (!web_media_player_ || ready_state_ == kHaveNothing) |
1885 return; | 1885 return; |
1886 | 1886 |
1887 // Ignore preload none and start load if necessary. | 1887 // Ignore preload none and start load if necessary. |
1888 SetIgnorePreloadNone(); | 1888 SetIgnorePreloadNone(); |
1889 | 1889 |
1890 // Get the current time before setting m_seeking, m_lastSeekTime is returned | 1890 // Get the current time before setting seeking_, last_seek_time_ is returned |
1891 // once it is set. | 1891 // once it is set. |
1892 double now = currentTime(); | 1892 double now = currentTime(); |
1893 | 1893 |
1894 // 3 - If the element's seeking IDL attribute is true, then another instance | 1894 // 3 - If the element's seeking IDL attribute is true, then another instance |
1895 // of this algorithm is already running. Abort that other instance of the | 1895 // of this algorithm is already running. Abort that other instance of the |
1896 // algorithm without waiting for the step that it is running to complete. | 1896 // algorithm without waiting for the step that it is running to complete. |
1897 // Nothing specific to be done here. | 1897 // Nothing specific to be done here. |
1898 | 1898 |
1899 // 4 - Set the seeking IDL attribute to true. | 1899 // 4 - Set the seeking IDL attribute to true. |
1900 // The flag will be cleared when the engine tells us the time has actually | 1900 // The flag will be cleared when the engine tells us the time has actually |
1901 // changed. | 1901 // changed. |
1902 seeking_ = true; | 1902 seeking_ = true; |
1903 | 1903 |
1904 // 6 - If the new playback position is later than the end of the media | 1904 // 6 - If the new playback position is later than the end of the media |
1905 // resource, then let it be the end of the media resource instead. | 1905 // resource, then let it be the end of the media resource instead. |
1906 time = std::min(time, duration()); | 1906 time = std::min(time, duration()); |
1907 | 1907 |
1908 // 7 - If the new playback position is less than the earliest possible | 1908 // 7 - If the new playback position is less than the earliest possible |
1909 // position, let it be that position instead. | 1909 // position, let it be that position instead. |
1910 time = std::max(time, EarliestPossiblePosition()); | 1910 time = std::max(time, EarliestPossiblePosition()); |
1911 | 1911 |
1912 // Ask the media engine for the time value in the movie's time scale before | 1912 // Ask the media engine for the time value in the movie's time scale before |
1913 // comparing with current time. This is necessary because if the seek time is | 1913 // comparing with current time. This is necessary because if the seek time is |
1914 // not equal to currentTime but the delta is less than the movie's time scale, | 1914 // not equal to currentTime but the delta is less than the movie's time scale, |
1915 // we will ask the media engine to "seek" to the current movie time, which may | 1915 // we will ask the media engine to "seek" to the current movie time, which may |
1916 // be a noop and not generate a timechanged callback. This means m_seeking | 1916 // be a noop and not generate a timechanged callback. This means seeking_ |
1917 // will never be cleared and we will never fire a 'seeked' event. | 1917 // will never be cleared and we will never fire a 'seeked' event. |
1918 double media_time = GetWebMediaPlayer()->MediaTimeForTimeValue(time); | 1918 double media_time = GetWebMediaPlayer()->MediaTimeForTimeValue(time); |
1919 if (time != media_time) { | 1919 if (time != media_time) { |
1920 BLINK_MEDIA_LOG << "seek(" << (void*)this << ", " << time | 1920 BLINK_MEDIA_LOG << "seek(" << (void*)this << ", " << time |
1921 << ") - media timeline equivalent is " << media_time; | 1921 << ") - media timeline equivalent is " << media_time; |
1922 time = media_time; | 1922 time = media_time; |
1923 } | 1923 } |
1924 | 1924 |
1925 // 8 - If the (possibly now changed) new playback position is not in one of | 1925 // 8 - If the (possibly now changed) new playback position is not in one of |
1926 // the ranges given in the seekable attribute, then let it be the position in | 1926 // the ranges given in the seekable attribute, then let it be the position in |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1993 double HTMLMediaElement::EarliestPossiblePosition() const { | 1993 double HTMLMediaElement::EarliestPossiblePosition() const { |
1994 TimeRanges* seekable_ranges = seekable(); | 1994 TimeRanges* seekable_ranges = seekable(); |
1995 if (seekable_ranges && seekable_ranges->length() > 0) | 1995 if (seekable_ranges && seekable_ranges->length() > 0) |
1996 return seekable_ranges->start(0, ASSERT_NO_EXCEPTION); | 1996 return seekable_ranges->start(0, ASSERT_NO_EXCEPTION); |
1997 | 1997 |
1998 return CurrentPlaybackPosition(); | 1998 return CurrentPlaybackPosition(); |
1999 } | 1999 } |
2000 | 2000 |
2001 double HTMLMediaElement::CurrentPlaybackPosition() const { | 2001 double HTMLMediaElement::CurrentPlaybackPosition() const { |
2002 // "Official" playback position won't take updates from "current" playback | 2002 // "Official" playback position won't take updates from "current" playback |
2003 // position until m_readyState > kHaveMetadata, but other callers (e.g. | 2003 // position until ready_state_ > kHaveMetadata, but other callers (e.g. |
2004 // pauseInternal) may still request currentPlaybackPosition at any time. | 2004 // pauseInternal) may still request currentPlaybackPosition at any time. |
2005 // From spec: "Media elements have a current playback position, which must | 2005 // From spec: "Media elements have a current playback position, which must |
2006 // initially (i.e., in the absence of media data) be zero seconds." | 2006 // initially (i.e., in the absence of media data) be zero seconds." |
2007 if (ready_state_ == kHaveNothing) | 2007 if (ready_state_ == kHaveNothing) |
2008 return 0; | 2008 return 0; |
2009 | 2009 |
2010 if (GetWebMediaPlayer()) | 2010 if (GetWebMediaPlayer()) |
2011 return GetWebMediaPlayer()->CurrentTime(); | 2011 return GetWebMediaPlayer()->CurrentTime(); |
2012 | 2012 |
2013 if (ready_state_ >= kHaveMetadata) { | 2013 if (ready_state_ >= kHaveMetadata) { |
(...skipping 11 matching lines...) Expand all Loading... |
2025 // currentTime (e.g. as samples in the last rendered audio buffer are played | 2025 // currentTime (e.g. as samples in the last rendered audio buffer are played |
2026 // played out), but advancing currentTime while paused/waiting sends a mixed | 2026 // played out), but advancing currentTime while paused/waiting sends a mixed |
2027 // signal about the state of playback. | 2027 // signal about the state of playback. |
2028 bool waiting_for_data = ready_state_ <= kHaveCurrentData; | 2028 bool waiting_for_data = ready_state_ <= kHaveCurrentData; |
2029 if (official_playback_position_needs_update_ && !paused_ && | 2029 if (official_playback_position_needs_update_ && !paused_ && |
2030 !waiting_for_data) { | 2030 !waiting_for_data) { |
2031 SetOfficialPlaybackPosition(CurrentPlaybackPosition()); | 2031 SetOfficialPlaybackPosition(CurrentPlaybackPosition()); |
2032 } | 2032 } |
2033 | 2033 |
2034 #if LOG_OFFICIAL_TIME_STATUS | 2034 #if LOG_OFFICIAL_TIME_STATUS |
2035 static const double minCachedDeltaForWarning = 0.01; | 2035 static const double kMinCachedDeltaForWarning = 0.01; |
2036 double delta = | 2036 double delta = |
2037 std::abs(m_officialPlaybackPosition - currentPlaybackPosition()); | 2037 std::abs(official_playback_position_ - CurrentPlaybackPosition()); |
2038 if (delta > minCachedDeltaForWarning) { | 2038 if (delta > kMinCachedDeltaForWarning) { |
2039 BLINK_MEDIA_LOG << "currentTime(" << (void*)this | 2039 BLINK_MEDIA_LOG << "CurrentTime(" << (void*)this |
2040 << ") - WARNING, cached time is " << delta | 2040 << ") - WARNING, cached time is " << delta |
2041 << "seconds off of media time when paused/waiting"; | 2041 << "seconds off of media time when paused/waiting"; |
2042 } | 2042 } |
2043 #endif | 2043 #endif |
2044 | 2044 |
2045 return official_playback_position_; | 2045 return official_playback_position_; |
2046 } | 2046 } |
2047 | 2047 |
2048 void HTMLMediaElement::SetOfficialPlaybackPosition(double position) const { | 2048 void HTMLMediaElement::SetOfficialPlaybackPosition(double position) const { |
2049 #if LOG_OFFICIAL_TIME_STATUS | 2049 #if LOG_OFFICIAL_TIME_STATUS |
2050 BLINK_MEDIA_LOG << "setOfficialPlaybackPosition(" << (void*)this | 2050 BLINK_MEDIA_LOG << "SetOfficialPlaybackPosition(" << (void*)this |
2051 << ") was:" << m_officialPlaybackPosition | 2051 << ") was:" << official_playback_position_ |
2052 << " now:" << position; | 2052 << " now:" << position; |
2053 #endif | 2053 #endif |
2054 | 2054 |
2055 // Internal player position may advance slightly beyond duration because | 2055 // Internal player position may advance slightly beyond duration because |
2056 // many files use imprecise duration. Clamp official position to duration when | 2056 // many files use imprecise duration. Clamp official position to duration when |
2057 // known. Duration may be unknown when readyState < HAVE_METADATA. | 2057 // known. Duration may be unknown when readyState < HAVE_METADATA. |
2058 official_playback_position_ = | 2058 official_playback_position_ = |
2059 std::isnan(duration()) ? position : std::min(duration(), position); | 2059 std::isnan(duration()) ? position : std::min(duration(), position); |
2060 | 2060 |
2061 if (official_playback_position_ != position) { | 2061 if (official_playback_position_ != position) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2137 | 2137 |
2138 UpdatePlaybackRate(); | 2138 UpdatePlaybackRate(); |
2139 } | 2139 } |
2140 | 2140 |
2141 HTMLMediaElement::DirectionOfPlayback HTMLMediaElement::GetDirectionOfPlayback() | 2141 HTMLMediaElement::DirectionOfPlayback HTMLMediaElement::GetDirectionOfPlayback() |
2142 const { | 2142 const { |
2143 return playback_rate_ >= 0 ? kForward : kBackward; | 2143 return playback_rate_ >= 0 ? kForward : kBackward; |
2144 } | 2144 } |
2145 | 2145 |
2146 void HTMLMediaElement::UpdatePlaybackRate() { | 2146 void HTMLMediaElement::UpdatePlaybackRate() { |
2147 // FIXME: remove m_webMediaPlayer check once we figure out how | 2147 // FIXME: remove web_media_player_ check once we figure out how |
2148 // m_webMediaPlayer is going out of sync with readystate. | 2148 // web_media_player_ is going out of sync with readystate. |
2149 // m_webMediaPlayer is cleared but readystate is not set to kHaveNothing. | 2149 // web_media_player_ is cleared but readystate is not set to kHaveNothing. |
2150 if (web_media_player_ && PotentiallyPlaying()) | 2150 if (web_media_player_ && PotentiallyPlaying()) |
2151 GetWebMediaPlayer()->SetRate(playbackRate()); | 2151 GetWebMediaPlayer()->SetRate(playbackRate()); |
2152 } | 2152 } |
2153 | 2153 |
2154 bool HTMLMediaElement::ended() const { | 2154 bool HTMLMediaElement::ended() const { |
2155 // 4.8.12.8 Playing the media resource | 2155 // 4.8.12.8 Playing the media resource |
2156 // The ended attribute must return true if the media element has ended | 2156 // The ended attribute must return true if the media element has ended |
2157 // playback and the direction of playback is forwards, and false otherwise. | 2157 // playback and the direction of playback is forwards, and false otherwise. |
2158 return EndedPlayback() && GetDirectionOfPlayback() == kForward; | 2158 return EndedPlayback() && GetDirectionOfPlayback() == kForward; |
2159 } | 2159 } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2232 WebMediaPlayer::Preload preload = PreloadType(); | 2232 WebMediaPlayer::Preload preload = PreloadType(); |
2233 if (ignore_preload_none_ && preload == WebMediaPlayer::kPreloadNone) | 2233 if (ignore_preload_none_ && preload == WebMediaPlayer::kPreloadNone) |
2234 return WebMediaPlayer::kPreloadMetaData; | 2234 return WebMediaPlayer::kPreloadMetaData; |
2235 | 2235 |
2236 return preload; | 2236 return preload; |
2237 } | 2237 } |
2238 | 2238 |
2239 ScriptPromise HTMLMediaElement::playForBindings(ScriptState* script_state) { | 2239 ScriptPromise HTMLMediaElement::playForBindings(ScriptState* script_state) { |
2240 // We have to share the same logic for internal and external callers. The | 2240 // We have to share the same logic for internal and external callers. The |
2241 // internal callers do not want to receive a Promise back but when ::play() | 2241 // internal callers do not want to receive a Promise back but when ::play() |
2242 // is called, |m_playPromiseResolvers| needs to be populated. What this code | 2242 // is called, |play_promise_resolvers_| needs to be populated. What this code |
2243 // does is to populate |m_playPromiseResolvers| before calling ::play() and | 2243 // does is to populate |play_promise_resolvers_| before calling ::play() and |
2244 // remove the Promise if ::play() failed. | 2244 // remove the Promise if ::play() failed. |
2245 ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); | 2245 ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); |
2246 ScriptPromise promise = resolver->Promise(); | 2246 ScriptPromise promise = resolver->Promise(); |
2247 play_promise_resolvers_.push_back(resolver); | 2247 play_promise_resolvers_.push_back(resolver); |
2248 | 2248 |
2249 Nullable<ExceptionCode> code = Play(); | 2249 Nullable<ExceptionCode> code = Play(); |
2250 if (!code.IsNull()) { | 2250 if (!code.IsNull()) { |
2251 DCHECK(!play_promise_resolvers_.IsEmpty()); | 2251 DCHECK(!play_promise_resolvers_.IsEmpty()); |
2252 play_promise_resolvers_.pop_back(); | 2252 play_promise_resolvers_.pop_back(); |
2253 | 2253 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2346 InvokeResourceSelectionAlgorithm(); | 2346 InvokeResourceSelectionAlgorithm(); |
2347 | 2347 |
2348 can_autoplay_ = false; | 2348 can_autoplay_ = false; |
2349 | 2349 |
2350 if (!paused_) { | 2350 if (!paused_) { |
2351 paused_ = true; | 2351 paused_ = true; |
2352 ScheduleTimeupdateEvent(false); | 2352 ScheduleTimeupdateEvent(false); |
2353 ScheduleEvent(EventTypeNames::pause); | 2353 ScheduleEvent(EventTypeNames::pause); |
2354 | 2354 |
2355 // Force an update to official playback position. Automatic updates from | 2355 // Force an update to official playback position. Automatic updates from |
2356 // currentPlaybackPosition() will be blocked while m_paused = true. This | 2356 // currentPlaybackPosition() will be blocked while paused_ = true. This |
2357 // blocking is desired while paused, but its good to update it one final | 2357 // blocking is desired while paused, but its good to update it one final |
2358 // time to accurately reflect movie time at the moment we paused. | 2358 // time to accurately reflect movie time at the moment we paused. |
2359 SetOfficialPlaybackPosition(CurrentPlaybackPosition()); | 2359 SetOfficialPlaybackPosition(CurrentPlaybackPosition()); |
2360 | 2360 |
2361 ScheduleRejectPlayPromises(kAbortError); | 2361 ScheduleRejectPlayPromises(kAbortError); |
2362 } | 2362 } |
2363 | 2363 |
2364 UpdatePlayState(); | 2364 UpdatePlayState(); |
2365 } | 2365 } |
2366 | 2366 |
(...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2980 // at all. | 2980 // at all. |
2981 if (FastHasAttribute(srcAttr)) | 2981 if (FastHasAttribute(srcAttr)) |
2982 return; | 2982 return; |
2983 | 2983 |
2984 // 4.8.8 - If a source element is inserted as a child of a media element that | 2984 // 4.8.8 - If a source element is inserted as a child of a media element that |
2985 // has no src attribute and whose networkState has the value NETWORK_EMPTY, | 2985 // has no src attribute and whose networkState has the value NETWORK_EMPTY, |
2986 // the user agent must invoke the media element's resource selection | 2986 // the user agent must invoke the media element's resource selection |
2987 // algorithm. | 2987 // algorithm. |
2988 if (getNetworkState() == HTMLMediaElement::kNetworkEmpty) { | 2988 if (getNetworkState() == HTMLMediaElement::kNetworkEmpty) { |
2989 InvokeResourceSelectionAlgorithm(); | 2989 InvokeResourceSelectionAlgorithm(); |
2990 // Ignore current |m_nextChildNodeToConsider| and consider |source|. | 2990 // Ignore current |next_child_node_to_consider_| and consider |source|. |
2991 next_child_node_to_consider_ = source; | 2991 next_child_node_to_consider_ = source; |
2992 return; | 2992 return; |
2993 } | 2993 } |
2994 | 2994 |
2995 if (current_source_node_ && source == current_source_node_->nextSibling()) { | 2995 if (current_source_node_ && source == current_source_node_->nextSibling()) { |
2996 BLINK_MEDIA_LOG << "sourceWasAdded(" << (void*)this | 2996 BLINK_MEDIA_LOG << "sourceWasAdded(" << (void*)this |
2997 << ") - <source> inserted immediately after current source"; | 2997 << ") - <source> inserted immediately after current source"; |
2998 // Ignore current |m_nextChildNodeToConsider| and consider |source|. | 2998 // Ignore current |next_child_node_to_consider_| and consider |source|. |
2999 next_child_node_to_consider_ = source; | 2999 next_child_node_to_consider_ = source; |
3000 return; | 3000 return; |
3001 } | 3001 } |
3002 | 3002 |
3003 // Consider current |m_nextChildNodeToConsider| as it is already in the middle | 3003 // Consider current |next_child_node_to_consider_| as it is already in the |
3004 // of processing. | 3004 // middle of processing. |
3005 if (next_child_node_to_consider_) | 3005 if (next_child_node_to_consider_) |
3006 return; | 3006 return; |
3007 | 3007 |
3008 if (load_state_ != kWaitingForSource) | 3008 if (load_state_ != kWaitingForSource) |
3009 return; | 3009 return; |
3010 | 3010 |
3011 // 4.8.9.5, resource selection algorithm, source elements section: | 3011 // 4.8.9.5, resource selection algorithm, source elements section: |
3012 // 21. Wait until the node after pointer is a node other than the end of the | 3012 // 21. Wait until the node after pointer is a node other than the end of the |
3013 // list. (This step might wait forever.) | 3013 // list. (This step might wait forever.) |
3014 // 22. Asynchronously await a stable state... | 3014 // 22. Asynchronously await a stable state... |
(...skipping 17 matching lines...) Expand all Loading... |
3032 BLINK_MEDIA_LOG << "sourceWasRemoved(" << (void*)this << ") - 'src' is " | 3032 BLINK_MEDIA_LOG << "sourceWasRemoved(" << (void*)this << ") - 'src' is " |
3033 << UrlForLoggingMedia(url); | 3033 << UrlForLoggingMedia(url); |
3034 | 3034 |
3035 if (source != current_source_node_ && source != next_child_node_to_consider_) | 3035 if (source != current_source_node_ && source != next_child_node_to_consider_) |
3036 return; | 3036 return; |
3037 | 3037 |
3038 if (source == next_child_node_to_consider_) { | 3038 if (source == next_child_node_to_consider_) { |
3039 if (current_source_node_) | 3039 if (current_source_node_) |
3040 next_child_node_to_consider_ = current_source_node_->nextSibling(); | 3040 next_child_node_to_consider_ = current_source_node_->nextSibling(); |
3041 BLINK_MEDIA_LOG << "sourceWasRemoved(" << (void*)this | 3041 BLINK_MEDIA_LOG << "sourceWasRemoved(" << (void*)this |
3042 << ") - m_nextChildNodeToConsider set to " | 3042 << ") - next_child_node_to_consider_ set to " |
3043 << next_child_node_to_consider_.Get(); | 3043 << next_child_node_to_consider_.Get(); |
3044 } else if (source == current_source_node_) { | 3044 } else if (source == current_source_node_) { |
3045 // Clear the current source node pointer, but don't change the movie as the | 3045 // Clear the current source node pointer, but don't change the movie as the |
3046 // spec says: | 3046 // spec says: |
3047 // 4.8.8 - Dynamically modifying a source element and its attribute when the | 3047 // 4.8.8 - Dynamically modifying a source element and its attribute when the |
3048 // element is already inserted in a video or audio element will have no | 3048 // element is already inserted in a video or audio element will have no |
3049 // effect. | 3049 // effect. |
3050 current_source_node_ = nullptr; | 3050 current_source_node_ = nullptr; |
3051 BLINK_MEDIA_LOG << "sourceWasRemoved(" << (void*)this | 3051 BLINK_MEDIA_LOG << "SourceWasRemoved(" << (void*)this |
3052 << ") - m_currentSourceNode set to 0"; | 3052 << ") - current_source_node_ set to 0"; |
3053 } | 3053 } |
3054 } | 3054 } |
3055 | 3055 |
3056 void HTMLMediaElement::TimeChanged() { | 3056 void HTMLMediaElement::TimeChanged() { |
3057 BLINK_MEDIA_LOG << "timeChanged(" << (void*)this << ")"; | 3057 BLINK_MEDIA_LOG << "timeChanged(" << (void*)this << ")"; |
3058 | 3058 |
3059 GetCueTimeline().UpdateActiveCues(currentTime()); | 3059 GetCueTimeline().UpdateActiveCues(currentTime()); |
3060 | 3060 |
3061 // 4.8.12.9 steps 12-14. Needed if no ReadyState change is associated with the | 3061 // 4.8.12.9 steps 12-14. Needed if no ReadyState change is associated with the |
3062 // seek. | 3062 // seek. |
(...skipping 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4081 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE); | 4081 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE); |
4082 } | 4082 } |
4083 | 4083 |
4084 void HTMLMediaElement::ViewportFillDebouncerTimerFired(TimerBase*) { | 4084 void HTMLMediaElement::ViewportFillDebouncerTimerFired(TimerBase*) { |
4085 mostly_filling_viewport_ = true; | 4085 mostly_filling_viewport_ = true; |
4086 if (web_media_player_) | 4086 if (web_media_player_) |
4087 web_media_player_->BecameDominantVisibleContent(mostly_filling_viewport_); | 4087 web_media_player_->BecameDominantVisibleContent(mostly_filling_viewport_); |
4088 } | 4088 } |
4089 | 4089 |
4090 } // namespace blink | 4090 } // namespace blink |
OLD | NEW |