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

Unified Diff: third_party/WebKit/Source/core/html/HTMLMediaElement.cpp

Issue 1810513002: Media element resource selection algorithm should "await a stable state" Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: changed loadtimer to texttrackloadtimer Created 4 years, 9 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/core/html/HTMLMediaElement.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
index 5a14ea40e1bed286a555021ffa380d58d79e775f..542bc0236722e043c9f6ab855df929afb8aaf5e7 100644
--- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -35,6 +35,7 @@
#include "core/dom/Attribute.h"
#include "core/dom/ElementTraversal.h"
#include "core/dom/Fullscreen.h"
+#include "core/dom/Microtask.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/events/Event.h"
#include "core/frame/LocalFrame.h"
@@ -268,6 +269,56 @@ String preloadTypeToString(WebMediaPlayer::Preload preloadType)
} // anonymous namespace
+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.
+public:
+ static PassOwnPtr<Task> create(HTMLMediaElement* mediaElement)
+ {
+ return adoptPtr(new Task(mediaElement));
+ }
+
+ Task(HTMLMediaElement* mediaElement)
+ : m_mediaElement(mediaElement)
+ , m_weakFactory(this)
+ {
+ v8::Isolate* isolate = V8PerIsolateData::mainThreadIsolate();
+ v8::HandleScope scope(isolate);
+ if (ScriptState::hasCurrentScriptState(isolate))
+ m_scriptState = ScriptState::current(isolate);
+ else
+ m_scriptState = ScriptState::forMainWorld(m_mediaElement->document().frame());
+ }
+
+ void run() override
+ {
+ WTF_LOG(Media, "HTMLMediaElement::Task::run(%p)", m_mediaElement.get());
+ if (!m_mediaElement)
+ return;
+
+ if (m_scriptState->contextIsValid()) {
+ 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
+ m_mediaElement->continueResourceSelectionAlgorithm();
+ } else {
+ m_mediaElement->continueResourceSelectionAlgorithm();
+ }
+ }
+
+ void clearTaskInfo()
+ {
+ m_mediaElement = nullptr;
+ m_scriptState.clear();
+ }
+
+ WeakPtr<Task> createWeakPtr()
+ {
+ return m_weakFactory.createWeakPtr();
+ }
+
+private:
+ RawPtrWillBeWeakPersistent<HTMLMediaElement> m_mediaElement;
+ RefPtr<ScriptState> m_scriptState;
+ WeakPtrFactory<Task> m_weakFactory;
+};
+
void HTMLMediaElement::recordAutoplayMetric(AutoplayMetrics metric)
{
DEFINE_STATIC_LOCAL(EnumerationHistogram, autoplayHistogram, ("Blink.MediaElement.Autoplay", NumberOfAutoplayMetrics));
@@ -310,7 +361,7 @@ bool HTMLMediaElement::isMediaStreamURL(const String& url)
HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& document)
: HTMLElement(tagName, document)
, ActiveDOMObject(&document)
- , m_loadTimer(this, &HTMLMediaElement::loadTimerFired)
+ , m_textTrackLoadTimer(this, &HTMLMediaElement::textTrackLoadTimerFired)
, m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired)
, m_playbackProgressTimer(this, &HTMLMediaElement::playbackProgressTimerFired)
, m_audioTracksTimer(this, &HTMLMediaElement::audioTracksTimerFired)
@@ -335,7 +386,6 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum
, m_displayMode(Unknown)
, m_cachedTime(std::numeric_limits<double>::quiet_NaN())
, m_fragmentEndTime(std::numeric_limits<double>::quiet_NaN())
- , m_pendingActionFlags(0)
, m_userGestureRequiredForPlay(false)
, m_playing(false)
, m_shouldDelayLoadEvent(false)
@@ -398,6 +448,9 @@ HTMLMediaElement::~HTMLMediaElement()
closeMediaSource();
+ if (m_pendingTask)
+ m_pendingTask->clearTaskInfo();
+
removeElementFromDocumentMap(this, &document());
// Destroying the player may cause a resource load to be canceled,
@@ -600,17 +653,8 @@ void HTMLMediaElement::scheduleTextTrackResourceLoad()
{
WTF_LOG(Media, "HTMLMediaElement::scheduleTextTrackResourceLoad(%p)", this);
- m_pendingActionFlags |= LoadTextTrackResource;
-
- if (!m_loadTimer.isActive())
- m_loadTimer.startOneShot(0, BLINK_FROM_HERE);
-}
-
-void HTMLMediaElement::scheduleNextSourceChild()
-{
- // Schedule the timer to try the next <source> element WITHOUT resetting state ala invokeLoadAlgorithm.
- m_pendingActionFlags |= LoadMediaResource;
- m_loadTimer.startOneShot(0, BLINK_FROM_HERE);
+ if (!m_textTrackLoadTimer.isActive())
+ m_textTrackLoadTimer.startOneShot(0, BLINK_FROM_HERE);
}
void HTMLMediaElement::scheduleEvent(const AtomicString& eventName)
@@ -626,19 +670,10 @@ void HTMLMediaElement::scheduleEvent(PassRefPtrWillBeRawPtr<Event> event)
m_asyncEventQueue->enqueueEvent(event);
}
-void HTMLMediaElement::loadTimerFired(Timer<HTMLMediaElement>*)
+void HTMLMediaElement::textTrackLoadTimerFired(Timer<HTMLMediaElement>*)
{
- if (m_pendingActionFlags & LoadTextTrackResource)
- honorUserPreferencesForAutomaticTextTrackSelection();
-
- if (m_pendingActionFlags & LoadMediaResource) {
- if (m_loadState == LoadingFromSourceElement)
- loadNextSourceChild();
- else
- loadInternal();
- }
-
- m_pendingActionFlags = 0;
+ WTF_LOG(Media, "HTMLMediaElement::textTrackLoadTimerFired(%p)", this);
+ honorUserPreferencesForAutomaticTextTrackSelection();
}
MediaError* HTMLMediaElement::error() const
@@ -735,10 +770,7 @@ void HTMLMediaElement::invokeLoadAlgorithm()
// Perform the cleanup required for the resource load algorithm to run.
stopPeriodicTimers();
- m_loadTimer.stop();
cancelDeferredLoad();
- // FIXME: Figure out appropriate place to reset LoadTextTrackResource if necessary and set m_pendingActionFlags to 0 here.
- m_pendingActionFlags &= ~LoadMediaResource;
m_sentEndEvent = false;
m_sentStalledEvent = false;
m_haveFiredLoadedData = false;
@@ -747,6 +779,10 @@ void HTMLMediaElement::invokeLoadAlgorithm()
// 1 - Abort any already-running instance of the resource selection algorithm for this element.
m_loadState = WaitingForSource;
m_currentSourceNode = nullptr;
+ if (m_pendingTask) {
+ m_pendingTask->clearTaskInfo();
+ m_pendingTask.clear();
+ }
// 2 - If there are any tasks from the media element's media element event task source in
// one of the task queues, then remove those tasks.
@@ -833,9 +869,29 @@ void HTMLMediaElement::invokeResourceSelectionAlgorithm()
mediaControls()->reset();
// 4 - Await a stable state, allowing the task that invoked this algorithm to continue
- // TODO(srirama.m): Remove scheduleNextSourceChild() and post a microtask instead.
- // See http://crbug.com/593289 for more details.
- scheduleNextSourceChild();
+ enqueueMicrotask();
+}
+
+void HTMLMediaElement::continueResourceSelectionAlgorithm()
+{
+ m_pendingTask.clear();
+
+ 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
+ m_textTrackLoadTimer.stop();
+ honorUserPreferencesForAutomaticTextTrackSelection();
+ }
+
+ 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
+ loadNextSourceChild();
+ else
+ loadInternal();
+}
+
+void HTMLMediaElement::enqueueMicrotask()
+{
+ OwnPtr<Task> task = Task::create(this);
+ m_pendingTask = task->createWeakPtr();
+ Microtask::enqueueMicrotask(task.release());
}
void HTMLMediaElement::loadInternal()
@@ -1372,7 +1428,7 @@ void HTMLMediaElement::mediaLoadingFailed(WebMediaPlayer::NetworkState error)
if (havePotentialSourceChild()) {
WTF_LOG(Media, "HTMLMediaElement::setNetworkState(%p) - scheduling next <source>", this);
- scheduleNextSourceChild();
+ 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
} else {
WTF_LOG(Media, "HTMLMediaElement::setNetworkState(%p) - no more <source> elements, waiting", this);
waitForSourceChange();
@@ -2772,7 +2828,7 @@ void HTMLMediaElement::sourceWasAdded(HTMLSourceElement* source)
// 25. Jump back to the find next candidate step above.
m_nextChildNodeToConsider = source;
- scheduleNextSourceChild();
+ 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
}
void HTMLMediaElement::sourceWasRemoved(HTMLSourceElement* source)
@@ -3110,9 +3166,8 @@ void HTMLMediaElement::clearMediaPlayer()
}
stopPeriodicTimers();
- m_loadTimer.stop();
+ m_textTrackLoadTimer.stop();
- m_pendingActionFlags = 0;
m_loadState = WaitingForSource;
// We can't cast if we don't have a media player.
@@ -3186,6 +3241,10 @@ bool HTMLMediaElement::hasPendingActivity() const
if (m_asyncEventQueue->hasPendingEvents())
return true;
+ // Wait for any pending microtask to be fired.
+ if (m_pendingTask)
+ return true;
+
return false;
}
« 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