Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(566)

Side by Side Diff: third_party/WebKit/Source/core/html/HTMLMediaElement.cpp

Issue 1522463003: Refactor resource load and resource selection algorithms as per spec (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: keep function name as prepareForLoad Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/html/HTMLMediaElement.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 464
465 removeElementFromDocumentMap(this, &oldDocument); 465 removeElementFromDocumentMap(this, &oldDocument);
466 addElementToDocumentMap(this, &document()); 466 addElementToDocumentMap(this, &document());
467 467
468 // FIXME: This is a temporary fix to prevent this object from causing the 468 // FIXME: This is a temporary fix to prevent this object from causing the
469 // MediaPlayer to dereference LocalFrame and FrameLoader pointers from the 469 // MediaPlayer to dereference LocalFrame and FrameLoader pointers from the
470 // previous document. This restarts the load, as if the src attribute had be en set. 470 // previous document. This restarts the load, as if the src attribute had be en set.
471 // A proper fix would provide a mechanism to allow this object to refresh 471 // A proper fix would provide a mechanism to allow this object to refresh
472 // the MediaPlayer's LocalFrame and FrameLoader references on 472 // the MediaPlayer's LocalFrame and FrameLoader references on
473 // document changes so that playback can be resumed properly. 473 // document changes so that playback can be resumed properly.
474 clearMediaPlayer(LoadMediaResource); 474 prepareForLoad();
philipj_slow 2015/12/18 15:12:24 I think that this bit is made worse by this CL, ex
475 scheduleDelayedAction(LoadMediaResource); 475 m_pendingActionFlags |= LoadMediaResource;
476 if (!m_loadTimer.isActive())
477 m_loadTimer.startOneShot(0, BLINK_FROM_HERE);
476 478
477 // Decrement the load event delay count on oldDocument now that m_webMediaPl ayer has been destroyed 479 // Decrement the load event delay count on oldDocument now that m_webMediaPl ayer has been destroyed
478 // and there is no risk of dispatching a load event from within the destruct or. 480 // and there is no risk of dispatching a load event from within the destruct or.
479 oldDocument.decrementLoadEventDelayCount(); 481 oldDocument.decrementLoadEventDelayCount();
480 482
481 ActiveDOMObject::didMoveToNewExecutionContext(&document()); 483 ActiveDOMObject::didMoveToNewExecutionContext(&document());
482 HTMLElement::didMoveToNewDocument(oldDocument); 484 HTMLElement::didMoveToNewDocument(oldDocument);
483 } 485 }
484 486
485 bool HTMLMediaElement::supportsFocus() const 487 bool HTMLMediaElement::supportsFocus() const
486 { 488 {
487 if (ownerDocument()->isMediaDocument()) 489 if (ownerDocument()->isMediaDocument())
488 return false; 490 return false;
489 491
490 // If no controls specified, we should still be able to focus the element if it has tabIndex. 492 // If no controls specified, we should still be able to focus the element if it has tabIndex.
491 return shouldShowControls() || HTMLElement::supportsFocus(); 493 return shouldShowControls() || HTMLElement::supportsFocus();
492 } 494 }
493 495
494 bool HTMLMediaElement::isMouseFocusable() const 496 bool HTMLMediaElement::isMouseFocusable() const
495 { 497 {
496 return false; 498 return false;
497 } 499 }
498 500
499 void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& oldValue, const AtomicString& value) 501 void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& oldValue, const AtomicString& value)
500 { 502 {
501 if (name == srcAttr) { 503 if (name == srcAttr) {
502 // Trigger a reload, as long as the 'src' attribute is present. 504 // Trigger a reload, as long as the 'src' attribute is present.
503 if (!value.isNull()) { 505 if (!value.isNull()) {
504 clearMediaPlayer(LoadMediaResource); 506 prepareForLoad();
505 scheduleDelayedAction(LoadMediaResource); 507 m_pendingActionFlags |= LoadMediaResource;
508 if (!m_loadTimer.isActive())
509 m_loadTimer.startOneShot(0, BLINK_FROM_HERE);
506 } 510 }
507 } else if (name == controlsAttr) { 511 } else if (name == controlsAttr) {
508 configureMediaControls(); 512 configureMediaControls();
509 } else if (name == preloadAttr) { 513 } else if (name == preloadAttr) {
510 setPlayerPreload(); 514 setPlayerPreload();
511 } else { 515 } else {
512 HTMLElement::parseAttribute(name, oldValue, value); 516 HTMLElement::parseAttribute(name, oldValue, value);
513 } 517 }
514 } 518 }
515 519
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 712
709 prepareForLoad(); 713 prepareForLoad();
710 loadInternal(); 714 loadInternal();
711 prepareToPlay(); 715 prepareToPlay();
712 } 716 }
713 717
714 void HTMLMediaElement::prepareForLoad() 718 void HTMLMediaElement::prepareForLoad()
715 { 719 {
716 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad(%p)", this); 720 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad(%p)", this);
717 721
718 // Perform the cleanup required for the resource load algorithm to run. 722 NetworkState networkState = m_networkState;
719 stopPeriodicTimers(); 723 resetMediaElement(LoadMediaResource);
720 m_loadTimer.stop();
721 cancelDeferredLoad();
722 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if nec essary and set m_pendingActionFlags to 0 here.
723 m_pendingActionFlags &= ~LoadMediaResource;
724 m_sentEndEvent = false;
725 m_sentStalledEvent = false;
726 m_haveFiredLoadedData = false;
727 m_completelyLoaded = false;
728 m_havePreparedToPlay = false;
729 m_displayMode = Unknown;
730 724
731 // 1 - Abort any already-running instance of the resource selection algorith m for this element. 725 // 1 - Abort any already-running instance of the resource selection algorith m for this element.
732 m_loadState = WaitingForSource; 726 m_loadState = WaitingForSource;
733 m_currentSourceNode = nullptr; 727 m_currentSourceNode = nullptr;
734 728
735 // 2 - If there are any tasks from the media element's media element event t ask source in 729 // 2 - If there are any tasks from the media element's media element event t ask source in
736 // one of the task queues, then remove those tasks. 730 // one of the task queues, then remove those tasks.
737 cancelPendingEventsAndCallbacks(); 731 cancelPendingEventsAndCallbacks();
738 732
739 // 3 - If the media element's networkState is set to NETWORK_LOADING or NETW ORK_IDLE, queue 733 // 3 - If the media element's networkState is set to NETWORK_LOADING or NETW ORK_IDLE, queue
740 // a task to fire a simple event named abort at the media element. 734 // a task to fire a simple event named abort at the media element.
741 if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE) 735 if (networkState == NETWORK_LOADING || networkState == NETWORK_IDLE)
742 scheduleEvent(EventTypeNames::abort); 736 scheduleEvent(EventTypeNames::abort);
743 737
744 resetMediaPlayerAndMediaSource();
745
746 // 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps 738 // 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps
747 if (m_networkState != NETWORK_EMPTY) { 739 if (networkState != NETWORK_EMPTY) {
748 // 4.1 - Queue a task to fire a simple event named emptied at the media element. 740 // 4.1 - Queue a task to fire a simple event named emptied at the media element.
749 scheduleEvent(EventTypeNames::emptied); 741 scheduleEvent(EventTypeNames::emptied);
750 742
751 // 4.2 - If a fetching process is in progress for the media element, the user agent should stop it. 743 // 4.2 - If a fetching process is in progress for the media element, the user agent should stop it.
752 setNetworkState(NETWORK_EMPTY); 744 setNetworkState(NETWORK_EMPTY);
753 745
754 // 4.3 - Forget the media element's media-resource-specific tracks. 746 // 4.3 - Forget the media element's media-resource-specific tracks.
755 forgetResourceSpecificTracks(); 747 forgetResourceSpecificTracks();
756 748
757 // 4.4 - If readyState is not set to HAVE_NOTHING, then set it to that s tate. 749 // 4.4 - If readyState is not set to HAVE_NOTHING, then set it to that s tate.
(...skipping 2221 matching lines...) Expand 10 before | Expand all | Expand 10 after
2979 audioSourceProvider().setClient(nullptr); 2971 audioSourceProvider().setClient(nullptr);
2980 #endif 2972 #endif
2981 if (m_webMediaPlayer) { 2973 if (m_webMediaPlayer) {
2982 #if ENABLE(WEB_AUDIO) 2974 #if ENABLE(WEB_AUDIO)
2983 m_audioSourceProvider.wrap(nullptr); 2975 m_audioSourceProvider.wrap(nullptr);
2984 #endif 2976 #endif
2985 m_webMediaPlayer.clear(); 2977 m_webMediaPlayer.clear();
2986 } 2978 }
2987 } 2979 }
2988 2980
2989 void HTMLMediaElement::clearMediaPlayer(int flags) 2981 void HTMLMediaElement::resetMediaElement(int flags)
2990 { 2982 {
2991 forgetResourceSpecificTracks(); 2983 forgetResourceSpecificTracks();
2992 2984
2993 closeMediaSource(); 2985 closeMediaSource();
2994 2986
2995 cancelDeferredLoad(); 2987 cancelDeferredLoad();
2996 2988
2997 { 2989 {
2998 AudioSourceProviderClientLockScope scope(*this); 2990 AudioSourceProviderClientLockScope scope(*this);
2999 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); 2991 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking();
3000 } 2992 }
3001 2993
2994 #if ENABLE(WEB_AUDIO)
2995 if (m_audioSourceNode)
2996 audioSourceProvider().setClient(m_audioSourceNode);
2997 #endif
2998
3002 stopPeriodicTimers(); 2999 stopPeriodicTimers();
3003 m_loadTimer.stop(); 3000 m_loadTimer.stop();
3004 3001
3005 m_pendingActionFlags &= ~flags; 3002 m_pendingActionFlags &= ~flags;
3006 m_loadState = WaitingForSource; 3003 m_loadState = WaitingForSource;
3007 3004
3008 // We can't cast if we don't have a media player. 3005 // We can't cast if we don't have a media player.
3009 m_remoteRoutesAvailable = false; 3006 m_remoteRoutesAvailable = false;
3010 m_playingRemotely = false; 3007 m_playingRemotely = false;
3008
3009 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if nec essary and set m_pendingActionFlags to 0 here.
3010 m_sentEndEvent = false;
3011 m_sentStalledEvent = false;
3012 m_haveFiredLoadedData = false;
3013 m_completelyLoaded = false;
3014 m_havePreparedToPlay = false;
3015 m_displayMode = Unknown;
3016
3017 m_readyState = HAVE_NOTHING;
3018 m_readyStateMaximum = HAVE_NOTHING;
3019 setNetworkState(NETWORK_EMPTY);
3020 setShouldDelayLoadEvent(false);
3021 m_currentSourceNode = nullptr;
3022 invalidateCachedTime();
3023 cueTimeline().updateActiveCues(0);
3024 m_playing = false;
3025 m_paused = true;
3026 m_seeking = false;
3027
3011 if (mediaControls()) 3028 if (mediaControls())
3012 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); 3029 mediaControls()->refreshCastButtonVisibilityWithoutUpdate();
3013 3030
3014 if (layoutObject()) 3031 if (layoutObject())
3015 layoutObject()->setShouldDoFullPaintInvalidation(); 3032 layoutObject()->setShouldDoFullPaintInvalidation();
3016 } 3033 }
3017 3034
3018 void HTMLMediaElement::stop() 3035 void HTMLMediaElement::stop()
3019 { 3036 {
3020 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); 3037 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this);
3021 3038
3022 recordMetricsIfPausing(); 3039 recordMetricsIfPausing();
3023 3040
3024 // Close the async event queue so that no events are enqueued. 3041 // Close the async event queue so that no events are enqueued.
3025 cancelPendingEventsAndCallbacks(); 3042 cancelPendingEventsAndCallbacks();
3026 m_asyncEventQueue->close(); 3043 m_asyncEventQueue->close();
3027 3044
3028 // Stop the playback without generating events 3045 // Clear everything in the Media Element
3029 clearMediaPlayer(-1); 3046 resetMediaElement(-1);
3030 m_readyState = HAVE_NOTHING;
3031 m_readyStateMaximum = HAVE_NOTHING;
3032 setNetworkState(NETWORK_EMPTY);
3033 setShouldDelayLoadEvent(false);
3034 m_currentSourceNode = nullptr;
3035 invalidateCachedTime();
3036 cueTimeline().updateActiveCues(0);
3037 m_playing = false;
3038 m_paused = true;
3039 m_seeking = false;
3040 3047
3041 if (layoutObject()) 3048 if (layoutObject())
3042 layoutObject()->updateFromElement(); 3049 layoutObject()->updateFromElement();
3043 3050
3044 stopPeriodicTimers();
3045
3046 // Ensure that hasPendingActivity() is not preventing garbage collection, si nce otherwise this 3051 // Ensure that hasPendingActivity() is not preventing garbage collection, si nce otherwise this
3047 // media element will simply leak. 3052 // media element will simply leak.
3048 ASSERT(!hasPendingActivity()); 3053 ASSERT(!hasPendingActivity());
3049 } 3054 }
3050 3055
3051 bool HTMLMediaElement::hasPendingActivity() const 3056 bool HTMLMediaElement::hasPendingActivity() const
3052 { 3057 {
3053 // The delaying-the-load-event flag is set by resource selection algorithm w hen looking for a 3058 // The delaying-the-load-event flag is set by resource selection algorithm w hen looking for a
3054 // resource to load, before networkState has reached to NETWORK_LOADING. 3059 // resource to load, before networkState has reached to NETWORK_LOADING.
3055 if (m_shouldDelayLoadEvent) 3060 if (m_shouldDelayLoadEvent)
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
3384 } 3389 }
3385 3390
3386 void* HTMLMediaElement::preDispatchEventHandler(Event* event) 3391 void* HTMLMediaElement::preDispatchEventHandler(Event* event)
3387 { 3392 {
3388 if (event && event->type() == EventTypeNames::webkitfullscreenchange) 3393 if (event && event->type() == EventTypeNames::webkitfullscreenchange)
3389 configureMediaControls(); 3394 configureMediaControls();
3390 3395
3391 return nullptr; 3396 return nullptr;
3392 } 3397 }
3393 3398
3394 // TODO(srirama.m): Refactor this and clearMediaPlayer to the extent possible. 3399 // TODO(srirama.m): Merge it to resetMediaElement if possible and remove it.
3395 void HTMLMediaElement::resetMediaPlayerAndMediaSource() 3400 void HTMLMediaElement::resetMediaPlayerAndMediaSource()
3396 { 3401 {
3397 closeMediaSource(); 3402 closeMediaSource();
3398 3403
3399 { 3404 {
3400 AudioSourceProviderClientLockScope scope(*this); 3405 AudioSourceProviderClientLockScope scope(*this);
3401 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); 3406 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking();
3402 } 3407 }
3403 3408
3404 // We haven't yet found out if any remote routes are available. 3409 // We haven't yet found out if any remote routes are available.
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
3632 visitor->trace(m_client); 3637 visitor->trace(m_client);
3633 } 3638 }
3634 3639
3635 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) 3640 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl)
3636 { 3641 {
3637 visitor->trace(m_client); 3642 visitor->trace(m_client);
3638 } 3643 }
3639 #endif 3644 #endif
3640 3645
3641 } 3646 }
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/HTMLMediaElement.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698