OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 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 17 matching lines...) Expand all Loading... | |
28 #include "bindings/core/v8/ExceptionState.h" | 28 #include "bindings/core/v8/ExceptionState.h" |
29 #include "bindings/core/v8/ExceptionStatePlaceholder.h" | 29 #include "bindings/core/v8/ExceptionStatePlaceholder.h" |
30 #include "bindings/core/v8/ScriptController.h" | 30 #include "bindings/core/v8/ScriptController.h" |
31 #include "bindings/core/v8/ScriptEventListener.h" | 31 #include "bindings/core/v8/ScriptEventListener.h" |
32 #include "bindings/core/v8/ScriptPromiseResolver.h" | 32 #include "bindings/core/v8/ScriptPromiseResolver.h" |
33 #include "core/HTMLNames.h" | 33 #include "core/HTMLNames.h" |
34 #include "core/css/MediaList.h" | 34 #include "core/css/MediaList.h" |
35 #include "core/dom/Attribute.h" | 35 #include "core/dom/Attribute.h" |
36 #include "core/dom/ElementTraversal.h" | 36 #include "core/dom/ElementTraversal.h" |
37 #include "core/dom/Fullscreen.h" | 37 #include "core/dom/Fullscreen.h" |
38 #include "core/dom/Microtask.h" | |
38 #include "core/dom/shadow/ShadowRoot.h" | 39 #include "core/dom/shadow/ShadowRoot.h" |
39 #include "core/events/Event.h" | 40 #include "core/events/Event.h" |
40 #include "core/frame/LocalFrame.h" | 41 #include "core/frame/LocalFrame.h" |
41 #include "core/frame/Settings.h" | 42 #include "core/frame/Settings.h" |
42 #include "core/frame/UseCounter.h" | 43 #include "core/frame/UseCounter.h" |
43 #include "core/frame/csp/ContentSecurityPolicy.h" | 44 #include "core/frame/csp/ContentSecurityPolicy.h" |
44 #include "core/html/HTMLMediaSource.h" | 45 #include "core/html/HTMLMediaSource.h" |
45 #include "core/html/HTMLSourceElement.h" | 46 #include "core/html/HTMLSourceElement.h" |
46 #include "core/html/HTMLTrackElement.h" | 47 #include "core/html/HTMLTrackElement.h" |
47 #include "core/html/MediaError.h" | 48 #include "core/html/MediaError.h" |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
261 case WebMediaPlayer::PreloadAuto: | 262 case WebMediaPlayer::PreloadAuto: |
262 return "auto"; | 263 return "auto"; |
263 } | 264 } |
264 | 265 |
265 ASSERT_NOT_REACHED(); | 266 ASSERT_NOT_REACHED(); |
266 return String(); | 267 return String(); |
267 } | 268 } |
268 | 269 |
269 } // anonymous namespace | 270 } // anonymous namespace |
270 | 271 |
272 class HTMLMediaElement::Task : public WebTaskRunner::Task { | |
philipj_slow
2016/03/23 07:27:18
It looks like it should be possible to use Cancell
Srirama
2016/03/29 11:26:29
I haven't tried that, do you want me to give a try
philipj_slow
2016/03/29 12:39:32
Yeah, sure, I wouldn't assume that the ScriptState
Srirama
2016/03/30 11:35:39
Done.
| |
273 public: | |
274 static PassOwnPtr<Task> create(HTMLMediaElement* mediaElement) | |
275 { | |
276 return adoptPtr(new Task(mediaElement)); | |
277 } | |
278 | |
279 Task(HTMLMediaElement* mediaElement) | |
280 : m_mediaElement(mediaElement) | |
281 , m_weakFactory(this) | |
282 { | |
283 v8::Isolate* isolate = V8PerIsolateData::mainThreadIsolate(); | |
284 v8::HandleScope scope(isolate); | |
285 if (ScriptState::hasCurrentScriptState(isolate)) | |
286 m_scriptState = ScriptState::current(isolate); | |
287 else | |
288 m_scriptState = ScriptState::forMainWorld(m_mediaElement->document() .frame()); | |
289 } | |
290 | |
291 void run() override | |
292 { | |
293 WTF_LOG(Media, "HTMLMediaElement::Task::run(%p)", m_mediaElement.get()); | |
294 if (!m_mediaElement) | |
295 return; | |
296 | |
297 if (m_scriptState->contextIsValid()) { | |
298 ScriptState::Scope scope(m_scriptState.get()); | |
philipj_slow
2016/03/24 04:43:05
What break if there is no ScriptState::Scope here?
Srirama
2016/03/29 11:26:29
Tested locally by removing and no cases are failin
| |
299 m_mediaElement->continueResourceSelectionAlgorithm(); | |
300 } else { | |
301 m_mediaElement->continueResourceSelectionAlgorithm(); | |
302 } | |
303 } | |
304 | |
305 void clearTaskInfo() | |
306 { | |
307 m_mediaElement = nullptr; | |
308 m_scriptState.clear(); | |
309 } | |
310 | |
311 WeakPtr<Task> createWeakPtr() | |
312 { | |
313 return m_weakFactory.createWeakPtr(); | |
314 } | |
315 | |
316 private: | |
317 RawPtrWillBeWeakPersistent<HTMLMediaElement> m_mediaElement; | |
318 RefPtr<ScriptState> m_scriptState; | |
319 WeakPtrFactory<Task> m_weakFactory; | |
320 }; | |
321 | |
271 void HTMLMediaElement::recordAutoplayMetric(AutoplayMetrics metric) | 322 void HTMLMediaElement::recordAutoplayMetric(AutoplayMetrics metric) |
272 { | 323 { |
273 DEFINE_STATIC_LOCAL(EnumerationHistogram, autoplayHistogram, ("Blink.MediaEl ement.Autoplay", NumberOfAutoplayMetrics)); | 324 DEFINE_STATIC_LOCAL(EnumerationHistogram, autoplayHistogram, ("Blink.MediaEl ement.Autoplay", NumberOfAutoplayMetrics)); |
274 autoplayHistogram.count(metric); | 325 autoplayHistogram.count(metric); |
275 } | 326 } |
276 | 327 |
277 WebMimeRegistry::SupportsType HTMLMediaElement::supportsType(const ContentType& contentType) | 328 WebMimeRegistry::SupportsType HTMLMediaElement::supportsType(const ContentType& contentType) |
278 { | 329 { |
279 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); | 330 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); |
280 | 331 |
(...skipping 22 matching lines...) Expand all Loading... | |
303 } | 354 } |
304 | 355 |
305 bool HTMLMediaElement::isMediaStreamURL(const String& url) | 356 bool HTMLMediaElement::isMediaStreamURL(const String& url) |
306 { | 357 { |
307 return s_mediaStreamRegistry ? s_mediaStreamRegistry->contains(url) : false; | 358 return s_mediaStreamRegistry ? s_mediaStreamRegistry->contains(url) : false; |
308 } | 359 } |
309 | 360 |
310 HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum ent) | 361 HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum ent) |
311 : HTMLElement(tagName, document) | 362 : HTMLElement(tagName, document) |
312 , ActiveDOMObject(&document) | 363 , ActiveDOMObject(&document) |
313 , m_loadTimer(this, &HTMLMediaElement::loadTimerFired) | 364 , m_textTrackLoadTimer(this, &HTMLMediaElement::textTrackLoadTimerFired) |
314 , m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired) | 365 , m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired) |
315 , m_playbackProgressTimer(this, &HTMLMediaElement::playbackProgressTimerFire d) | 366 , m_playbackProgressTimer(this, &HTMLMediaElement::playbackProgressTimerFire d) |
316 , m_audioTracksTimer(this, &HTMLMediaElement::audioTracksTimerFired) | 367 , m_audioTracksTimer(this, &HTMLMediaElement::audioTracksTimerFired) |
317 , m_playedTimeRanges() | 368 , m_playedTimeRanges() |
318 , m_asyncEventQueue(GenericEventQueue::create(this)) | 369 , m_asyncEventQueue(GenericEventQueue::create(this)) |
319 , m_playbackRate(1.0f) | 370 , m_playbackRate(1.0f) |
320 , m_defaultPlaybackRate(1.0f) | 371 , m_defaultPlaybackRate(1.0f) |
321 , m_networkState(NETWORK_EMPTY) | 372 , m_networkState(NETWORK_EMPTY) |
322 , m_readyState(HAVE_NOTHING) | 373 , m_readyState(HAVE_NOTHING) |
323 , m_readyStateMaximum(HAVE_NOTHING) | 374 , m_readyStateMaximum(HAVE_NOTHING) |
324 , m_volume(1.0f) | 375 , m_volume(1.0f) |
325 , m_lastSeekTime(0) | 376 , m_lastSeekTime(0) |
326 , m_previousProgressTime(std::numeric_limits<double>::max()) | 377 , m_previousProgressTime(std::numeric_limits<double>::max()) |
327 , m_duration(std::numeric_limits<double>::quiet_NaN()) | 378 , m_duration(std::numeric_limits<double>::quiet_NaN()) |
328 , m_lastTimeUpdateEventWallTime(0) | 379 , m_lastTimeUpdateEventWallTime(0) |
329 , m_lastTimeUpdateEventMovieTime(0) | 380 , m_lastTimeUpdateEventMovieTime(0) |
330 , m_defaultPlaybackStartPosition(0) | 381 , m_defaultPlaybackStartPosition(0) |
331 , m_loadState(WaitingForSource) | 382 , m_loadState(WaitingForSource) |
332 , m_deferredLoadState(NotDeferred) | 383 , m_deferredLoadState(NotDeferred) |
333 , m_deferredLoadTimer(this, &HTMLMediaElement::deferredLoadTimerFired) | 384 , m_deferredLoadTimer(this, &HTMLMediaElement::deferredLoadTimerFired) |
334 , m_webLayer(nullptr) | 385 , m_webLayer(nullptr) |
335 , m_displayMode(Unknown) | 386 , m_displayMode(Unknown) |
336 , m_cachedTime(std::numeric_limits<double>::quiet_NaN()) | 387 , m_cachedTime(std::numeric_limits<double>::quiet_NaN()) |
337 , m_fragmentEndTime(std::numeric_limits<double>::quiet_NaN()) | 388 , m_fragmentEndTime(std::numeric_limits<double>::quiet_NaN()) |
338 , m_pendingActionFlags(0) | |
339 , m_userGestureRequiredForPlay(false) | 389 , m_userGestureRequiredForPlay(false) |
340 , m_playing(false) | 390 , m_playing(false) |
341 , m_shouldDelayLoadEvent(false) | 391 , m_shouldDelayLoadEvent(false) |
342 , m_haveFiredLoadedData(false) | 392 , m_haveFiredLoadedData(false) |
343 , m_autoplaying(true) | 393 , m_autoplaying(true) |
344 , m_muted(false) | 394 , m_muted(false) |
345 , m_paused(true) | 395 , m_paused(true) |
346 , m_seeking(false) | 396 , m_seeking(false) |
347 , m_sentStalledEvent(false) | 397 , m_sentStalledEvent(false) |
348 , m_sentEndEvent(false) | 398 , m_sentEndEvent(false) |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
391 | 441 |
392 setShouldDelayLoadEvent(false); | 442 setShouldDelayLoadEvent(false); |
393 | 443 |
394 if (m_textTracks) | 444 if (m_textTracks) |
395 m_textTracks->clearOwner(); | 445 m_textTracks->clearOwner(); |
396 m_audioTracks->shutdown(); | 446 m_audioTracks->shutdown(); |
397 m_videoTracks->shutdown(); | 447 m_videoTracks->shutdown(); |
398 | 448 |
399 closeMediaSource(); | 449 closeMediaSource(); |
400 | 450 |
451 if (m_pendingTask) | |
452 m_pendingTask->clearTaskInfo(); | |
453 | |
401 removeElementFromDocumentMap(this, &document()); | 454 removeElementFromDocumentMap(this, &document()); |
402 | 455 |
403 // Destroying the player may cause a resource load to be canceled, | 456 // Destroying the player may cause a resource load to be canceled, |
404 // which could result in LocalDOMWindow::dispatchWindowLoadEvent() being | 457 // which could result in LocalDOMWindow::dispatchWindowLoadEvent() being |
405 // called via ResourceFetch::didLoadResource() then | 458 // called via ResourceFetch::didLoadResource() then |
406 // FrameLoader::checkCompleted(). To prevent load event dispatching during | 459 // FrameLoader::checkCompleted(). To prevent load event dispatching during |
407 // object destruction, we use Document::incrementLoadEventDelayCount(). | 460 // object destruction, we use Document::incrementLoadEventDelayCount(). |
408 // See http://crbug.com/275223 for more details. | 461 // See http://crbug.com/275223 for more details. |
409 document().incrementLoadEventDelayCount(); | 462 document().incrementLoadEventDelayCount(); |
410 | 463 |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
593 void HTMLMediaElement::didRecalcStyle(StyleRecalcChange) | 646 void HTMLMediaElement::didRecalcStyle(StyleRecalcChange) |
594 { | 647 { |
595 if (layoutObject()) | 648 if (layoutObject()) |
596 layoutObject()->updateFromElement(); | 649 layoutObject()->updateFromElement(); |
597 } | 650 } |
598 | 651 |
599 void HTMLMediaElement::scheduleTextTrackResourceLoad() | 652 void HTMLMediaElement::scheduleTextTrackResourceLoad() |
600 { | 653 { |
601 WTF_LOG(Media, "HTMLMediaElement::scheduleTextTrackResourceLoad(%p)", this); | 654 WTF_LOG(Media, "HTMLMediaElement::scheduleTextTrackResourceLoad(%p)", this); |
602 | 655 |
603 m_pendingActionFlags |= LoadTextTrackResource; | 656 if (!m_textTrackLoadTimer.isActive()) |
604 | 657 m_textTrackLoadTimer.startOneShot(0, BLINK_FROM_HERE); |
605 if (!m_loadTimer.isActive()) | |
606 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); | |
607 } | |
608 | |
609 void HTMLMediaElement::scheduleNextSourceChild() | |
610 { | |
611 // Schedule the timer to try the next <source> element WITHOUT resetting sta te ala invokeLoadAlgorithm. | |
612 m_pendingActionFlags |= LoadMediaResource; | |
613 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); | |
614 } | 658 } |
615 | 659 |
616 void HTMLMediaElement::scheduleEvent(const AtomicString& eventName) | 660 void HTMLMediaElement::scheduleEvent(const AtomicString& eventName) |
617 { | 661 { |
618 scheduleEvent(Event::createCancelable(eventName)); | 662 scheduleEvent(Event::createCancelable(eventName)); |
619 } | 663 } |
620 | 664 |
621 void HTMLMediaElement::scheduleEvent(PassRefPtrWillBeRawPtr<Event> event) | 665 void HTMLMediaElement::scheduleEvent(PassRefPtrWillBeRawPtr<Event> event) |
622 { | 666 { |
623 #if LOG_MEDIA_EVENTS | 667 #if LOG_MEDIA_EVENTS |
624 WTF_LOG(Media, "HTMLMediaElement::scheduleEvent(%p) - scheduling '%s'", this , event->type().ascii().data()); | 668 WTF_LOG(Media, "HTMLMediaElement::scheduleEvent(%p) - scheduling '%s'", this , event->type().ascii().data()); |
625 #endif | 669 #endif |
626 m_asyncEventQueue->enqueueEvent(event); | 670 m_asyncEventQueue->enqueueEvent(event); |
627 } | 671 } |
628 | 672 |
629 void HTMLMediaElement::loadTimerFired(Timer<HTMLMediaElement>*) | 673 void HTMLMediaElement::textTrackLoadTimerFired(Timer<HTMLMediaElement>*) |
630 { | 674 { |
631 if (m_pendingActionFlags & LoadTextTrackResource) | 675 WTF_LOG(Media, "HTMLMediaElement::textTrackLoadTimerFired(%p)", this); |
632 honorUserPreferencesForAutomaticTextTrackSelection(); | 676 honorUserPreferencesForAutomaticTextTrackSelection(); |
633 | |
634 if (m_pendingActionFlags & LoadMediaResource) { | |
635 if (m_loadState == LoadingFromSourceElement) | |
636 loadNextSourceChild(); | |
637 else | |
638 loadInternal(); | |
639 } | |
640 | |
641 m_pendingActionFlags = 0; | |
642 } | 677 } |
643 | 678 |
644 MediaError* HTMLMediaElement::error() const | 679 MediaError* HTMLMediaElement::error() const |
645 { | 680 { |
646 return m_error; | 681 return m_error; |
647 } | 682 } |
648 | 683 |
649 void HTMLMediaElement::setSrc(const AtomicString& url) | 684 void HTMLMediaElement::setSrc(const AtomicString& url) |
650 { | 685 { |
651 setAttribute(srcAttr, url); | 686 setAttribute(srcAttr, url); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
728 // TODO(srirama.m): Currently m_ignorePreloadNone is reset before calling | 763 // TODO(srirama.m): Currently m_ignorePreloadNone is reset before calling |
729 // invokeLoadAlgorithm() in all places except load(). Move it inside here | 764 // invokeLoadAlgorithm() in all places except load(). Move it inside here |
730 // once microtask is implemented for "Await a stable state" step | 765 // once microtask is implemented for "Await a stable state" step |
731 // in resource selection algorithm. | 766 // in resource selection algorithm. |
732 void HTMLMediaElement::invokeLoadAlgorithm() | 767 void HTMLMediaElement::invokeLoadAlgorithm() |
733 { | 768 { |
734 WTF_LOG(Media, "HTMLMediaElement::invokeLoadAlgorithm(%p)", this); | 769 WTF_LOG(Media, "HTMLMediaElement::invokeLoadAlgorithm(%p)", this); |
735 | 770 |
736 // Perform the cleanup required for the resource load algorithm to run. | 771 // Perform the cleanup required for the resource load algorithm to run. |
737 stopPeriodicTimers(); | 772 stopPeriodicTimers(); |
738 m_loadTimer.stop(); | |
739 cancelDeferredLoad(); | 773 cancelDeferredLoad(); |
740 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if nec essary and set m_pendingActionFlags to 0 here. | |
741 m_pendingActionFlags &= ~LoadMediaResource; | |
742 m_sentEndEvent = false; | 774 m_sentEndEvent = false; |
743 m_sentStalledEvent = false; | 775 m_sentStalledEvent = false; |
744 m_haveFiredLoadedData = false; | 776 m_haveFiredLoadedData = false; |
745 m_displayMode = Unknown; | 777 m_displayMode = Unknown; |
746 | 778 |
747 // 1 - Abort any already-running instance of the resource selection algorith m for this element. | 779 // 1 - Abort any already-running instance of the resource selection algorith m for this element. |
748 m_loadState = WaitingForSource; | 780 m_loadState = WaitingForSource; |
749 m_currentSourceNode = nullptr; | 781 m_currentSourceNode = nullptr; |
782 if (m_pendingTask) { | |
783 m_pendingTask->clearTaskInfo(); | |
784 m_pendingTask.clear(); | |
785 } | |
750 | 786 |
751 // 2 - If there are any tasks from the media element's media element event t ask source in | 787 // 2 - If there are any tasks from the media element's media element event t ask source in |
752 // one of the task queues, then remove those tasks. | 788 // one of the task queues, then remove those tasks. |
753 cancelPendingEventsAndCallbacks(); | 789 cancelPendingEventsAndCallbacks(); |
754 | 790 |
755 rejectPlayPromises(AbortError, "The play() request was interrupted by a new load request."); | 791 rejectPlayPromises(AbortError, "The play() request was interrupted by a new load request."); |
756 | 792 |
757 // 3 - If the media element's networkState is set to NETWORK_LOADING or NETW ORK_IDLE, queue | 793 // 3 - If the media element's networkState is set to NETWORK_LOADING or NETW ORK_IDLE, queue |
758 // a task to fire a simple event named abort at the media element. | 794 // a task to fire a simple event named abort at the media element. |
759 if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE) | 795 if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE) |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
826 // so they are closer to the relevant spec steps. | 862 // so they are closer to the relevant spec steps. |
827 m_lastSeekTime = 0; | 863 m_lastSeekTime = 0; |
828 m_duration = std::numeric_limits<double>::quiet_NaN(); | 864 m_duration = std::numeric_limits<double>::quiet_NaN(); |
829 | 865 |
830 // 3 - Set the media element's delaying-the-load-event flag to true (this de lays the load event) | 866 // 3 - Set the media element's delaying-the-load-event flag to true (this de lays the load event) |
831 setShouldDelayLoadEvent(true); | 867 setShouldDelayLoadEvent(true); |
832 if (mediaControls()) | 868 if (mediaControls()) |
833 mediaControls()->reset(); | 869 mediaControls()->reset(); |
834 | 870 |
835 // 4 - Await a stable state, allowing the task that invoked this algorithm t o continue | 871 // 4 - Await a stable state, allowing the task that invoked this algorithm t o continue |
836 // TODO(srirama.m): Remove scheduleNextSourceChild() and post a microtask in stead. | 872 enqueueMicrotask(); |
837 // See http://crbug.com/593289 for more details. | 873 } |
838 scheduleNextSourceChild(); | 874 |
875 void HTMLMediaElement::continueResourceSelectionAlgorithm() | |
876 { | |
877 m_pendingTask.clear(); | |
878 | |
879 if (m_textTrackLoadTimer.isActive()) { | |
Srirama
2016/03/18 07:38:11
This is required to keep the order of honorUser...
philipj_slow
2016/03/23 07:12:02
Hmm, which test case is that?
Srirama
2016/03/29 11:26:29
Sorry, couldn't remember exactly which one is fail
| |
880 m_textTrackLoadTimer.stop(); | |
881 honorUserPreferencesForAutomaticTextTrackSelection(); | |
882 } | |
883 | |
884 if (m_loadState == LoadingFromSourceElement) | |
philipj_slow
2016/03/24 04:43:05
This doesn't look right. The spec decides whether
Srirama
2016/03/29 11:26:29
Hmm, probably this can simply be loadInternal() ba
| |
885 loadNextSourceChild(); | |
886 else | |
887 loadInternal(); | |
888 } | |
889 | |
890 void HTMLMediaElement::enqueueMicrotask() | |
891 { | |
892 OwnPtr<Task> task = Task::create(this); | |
893 m_pendingTask = task->createWeakPtr(); | |
894 Microtask::enqueueMicrotask(task.release()); | |
839 } | 895 } |
840 | 896 |
841 void HTMLMediaElement::loadInternal() | 897 void HTMLMediaElement::loadInternal() |
842 { | 898 { |
843 // HTMLMediaElement::textTracksAreReady will need "... the text tracks whose mode was not in the | 899 // HTMLMediaElement::textTracksAreReady will need "... the text tracks whose mode was not in the |
844 // disabled state when the element's resource selection algorithm last start ed". | 900 // disabled state when the element's resource selection algorithm last start ed". |
845 m_textTracksWhenResourceSelectionBegan.clear(); | 901 m_textTracksWhenResourceSelectionBegan.clear(); |
846 if (m_textTracks) { | 902 if (m_textTracks) { |
847 for (unsigned i = 0; i < m_textTracks->length(); ++i) { | 903 for (unsigned i = 0; i < m_textTracks->length(); ++i) { |
848 TextTrack* track = m_textTracks->anonymousIndexedGetter(i); | 904 TextTrack* track = m_textTracks->anonymousIndexedGetter(i); |
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1365 else | 1421 else |
1366 WTF_LOG(Media, "HTMLMediaElement::setNetworkState(%p) - error event not sent, <source> was removed", this); | 1422 WTF_LOG(Media, "HTMLMediaElement::setNetworkState(%p) - error event not sent, <source> was removed", this); |
1367 | 1423 |
1368 // 9.Otherwise.10 - Asynchronously await a stable state. The synchronous section consists of all the remaining steps of this algorithm until the algorit hm says the synchronous section has ended. | 1424 // 9.Otherwise.10 - Asynchronously await a stable state. The synchronous section consists of all the remaining steps of this algorithm until the algorit hm says the synchronous section has ended. |
1369 | 1425 |
1370 // 9.Otherwise.11 - Forget the media element's media-resource-specific t racks. | 1426 // 9.Otherwise.11 - Forget the media element's media-resource-specific t racks. |
1371 forgetResourceSpecificTracks(); | 1427 forgetResourceSpecificTracks(); |
1372 | 1428 |
1373 if (havePotentialSourceChild()) { | 1429 if (havePotentialSourceChild()) { |
1374 WTF_LOG(Media, "HTMLMediaElement::setNetworkState(%p) - scheduling n ext <source>", this); | 1430 WTF_LOG(Media, "HTMLMediaElement::setNetworkState(%p) - scheduling n ext <source>", this); |
1375 scheduleNextSourceChild(); | 1431 enqueueMicrotask(); |
philipj_slow
2016/03/24 04:43:05
I guess this is the "Await a stable state" after "
Srirama
2016/03/29 11:26:29
Probably some more refactoring is needed before i
philipj_slow
2016/03/29 12:39:32
Which bits do you mean for "m_loadState is already
Srirama
2016/03/29 12:49:12
This is actually part of mediaLoadingFailed() and
philipj_slow
2016/03/29 12:57:51
Oh OK. Yeah in that case it would obviously make n
Srirama
2016/03/30 11:35:39
Done. Tried removing WaitingForSource blindly and
| |
1376 } else { | 1432 } else { |
1377 WTF_LOG(Media, "HTMLMediaElement::setNetworkState(%p) - no more <sou rce> elements, waiting", this); | 1433 WTF_LOG(Media, "HTMLMediaElement::setNetworkState(%p) - no more <sou rce> elements, waiting", this); |
1378 waitForSourceChange(); | 1434 waitForSourceChange(); |
1379 } | 1435 } |
1380 | 1436 |
1381 return; | 1437 return; |
1382 } | 1438 } |
1383 | 1439 |
1384 if (error == WebMediaPlayer::NetworkStateNetworkError && m_readyState >= HAV E_METADATA) | 1440 if (error == WebMediaPlayer::NetworkStateNetworkError && m_readyState >= HAV E_METADATA) |
1385 mediaEngineError(MediaError::create(MediaError::MEDIA_ERR_NETWORK)); | 1441 mediaEngineError(MediaError::create(MediaError::MEDIA_ERR_NETWORK)); |
(...skipping 1379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2765 // 22. Asynchronously await a stable state... | 2821 // 22. Asynchronously await a stable state... |
2766 // 23. Set the element's delaying-the-load-event flag back to true (this del ays the load event again, in case | 2822 // 23. Set the element's delaying-the-load-event flag back to true (this del ays the load event again, in case |
2767 // it hasn't been fired yet). | 2823 // it hasn't been fired yet). |
2768 setShouldDelayLoadEvent(true); | 2824 setShouldDelayLoadEvent(true); |
2769 | 2825 |
2770 // 24. Set the networkState back to NETWORK_LOADING. | 2826 // 24. Set the networkState back to NETWORK_LOADING. |
2771 setNetworkState(NETWORK_LOADING); | 2827 setNetworkState(NETWORK_LOADING); |
2772 | 2828 |
2773 // 25. Jump back to the find next candidate step above. | 2829 // 25. Jump back to the find next candidate step above. |
2774 m_nextChildNodeToConsider = source; | 2830 m_nextChildNodeToConsider = source; |
2775 scheduleNextSourceChild(); | 2831 enqueueMicrotask(); |
philipj_slow
2016/03/24 04:43:05
This should actually synchronously jump to the "Fi
Srirama
2016/03/29 11:26:29
This looks a bit confusing, this function sourceWa
philipj_slow
2016/03/29 12:39:32
Yes, the spec expresses this as a single big algor
Srirama
2016/03/30 11:35:39
I thought loadNextSourceChild() is more appropriat
| |
2776 } | 2832 } |
2777 | 2833 |
2778 void HTMLMediaElement::sourceWasRemoved(HTMLSourceElement* source) | 2834 void HTMLMediaElement::sourceWasRemoved(HTMLSourceElement* source) |
2779 { | 2835 { |
2780 WTF_LOG(Media, "HTMLMediaElement::sourceWasRemoved(%p, %p)", this, source); | 2836 WTF_LOG(Media, "HTMLMediaElement::sourceWasRemoved(%p, %p)", this, source); |
2781 | 2837 |
2782 #if !LOG_DISABLED | 2838 #if !LOG_DISABLED |
2783 KURL url = source->getNonEmptyURLAttribute(srcAttr); | 2839 KURL url = source->getNonEmptyURLAttribute(srcAttr); |
2784 WTF_LOG(Media, "HTMLMediaElement::sourceWasRemoved(%p) - 'src' is %s", this, urlForLoggingMedia(url).utf8().data()); | 2840 WTF_LOG(Media, "HTMLMediaElement::sourceWasRemoved(%p) - 'src' is %s", this, urlForLoggingMedia(url).utf8().data()); |
2785 #endif | 2841 #endif |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3103 closeMediaSource(); | 3159 closeMediaSource(); |
3104 | 3160 |
3105 cancelDeferredLoad(); | 3161 cancelDeferredLoad(); |
3106 | 3162 |
3107 { | 3163 { |
3108 AudioSourceProviderClientLockScope scope(*this); | 3164 AudioSourceProviderClientLockScope scope(*this); |
3109 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); | 3165 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); |
3110 } | 3166 } |
3111 | 3167 |
3112 stopPeriodicTimers(); | 3168 stopPeriodicTimers(); |
3113 m_loadTimer.stop(); | 3169 m_textTrackLoadTimer.stop(); |
3114 | 3170 |
3115 m_pendingActionFlags = 0; | |
3116 m_loadState = WaitingForSource; | 3171 m_loadState = WaitingForSource; |
3117 | 3172 |
3118 // We can't cast if we don't have a media player. | 3173 // We can't cast if we don't have a media player. |
3119 m_remoteRoutesAvailable = false; | 3174 m_remoteRoutesAvailable = false; |
3120 m_playingRemotely = false; | 3175 m_playingRemotely = false; |
3121 if (mediaControls()) | 3176 if (mediaControls()) |
3122 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); | 3177 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); |
3123 | 3178 |
3124 if (layoutObject()) | 3179 if (layoutObject()) |
3125 layoutObject()->setShouldDoFullPaintInvalidation(); | 3180 layoutObject()->setShouldDoFullPaintInvalidation(); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3179 | 3234 |
3180 // When connected to a MediaSource, e.g. setting MediaSource.duration will c ause a | 3235 // When connected to a MediaSource, e.g. setting MediaSource.duration will c ause a |
3181 // durationchange event to be fired. | 3236 // durationchange event to be fired. |
3182 if (m_mediaSource) | 3237 if (m_mediaSource) |
3183 return true; | 3238 return true; |
3184 | 3239 |
3185 // Wait for any pending events to be fired. | 3240 // Wait for any pending events to be fired. |
3186 if (m_asyncEventQueue->hasPendingEvents()) | 3241 if (m_asyncEventQueue->hasPendingEvents()) |
3187 return true; | 3242 return true; |
3188 | 3243 |
3244 // Wait for any pending microtask to be fired. | |
3245 if (m_pendingTask) | |
3246 return true; | |
3247 | |
3189 return false; | 3248 return false; |
3190 } | 3249 } |
3191 | 3250 |
3192 bool HTMLMediaElement::isFullscreen() const | 3251 bool HTMLMediaElement::isFullscreen() const |
3193 { | 3252 { |
3194 return Fullscreen::isActiveFullScreenElement(*this); | 3253 return Fullscreen::isActiveFullScreenElement(*this); |
3195 } | 3254 } |
3196 | 3255 |
3197 void HTMLMediaElement::enterFullscreen() | 3256 void HTMLMediaElement::enterFullscreen() |
3198 { | 3257 { |
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3804 { | 3863 { |
3805 visitor->trace(m_client); | 3864 visitor->trace(m_client); |
3806 } | 3865 } |
3807 | 3866 |
3808 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) | 3867 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) |
3809 { | 3868 { |
3810 visitor->trace(m_client); | 3869 visitor->trace(m_client); |
3811 } | 3870 } |
3812 | 3871 |
3813 } // namespace blink | 3872 } // namespace blink |
OLD | NEW |