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..c273ad9de4fa8aac98614c947e3cb3bf4b601b41 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 { |
+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()); |
+ 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)); |
@@ -398,6 +449,9 @@ HTMLMediaElement::~HTMLMediaElement() |
closeMediaSource(); |
+ if (m_pendingTask) |
+ m_pendingTask->clearTaskInfo(); |
+ |
removeElementFromDocumentMap(this, &document()); |
// Destroying the player may cause a resource load to be canceled, |
@@ -747,6 +801,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 +891,26 @@ 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(); |
+ OwnPtr<Task> task = Task::create(this); |
+ m_pendingTask = task->createWeakPtr(); |
+ Microtask::enqueueMicrotask(task.release()); |
philipj_slow
2016/03/16 13:40:20
If you have a look at RTCPeerConnection.cpp and HT
philipj_slow
2016/03/16 15:35:10
OK, so one problem could be where the spec says "A
Srirama
2016/03/16 17:41:17
Infact when i started i just copied it from ImageL
philipj_slow
2016/03/17 11:30:55
OK. So this problem has come up several times rece
|
+ m_pendingActionFlags |= LoadMediaResource; |
+} |
+ |
+void HTMLMediaElement::continueResourceSelectionAlgorithm() |
philipj_slow
2016/03/16 13:40:20
All of this method looks a bit strange, should it
Srirama
2016/03/16 14:25:40
Without these changes all the media/track test cas
Srirama
2016/03/16 14:35:23
loadtimer started by scheduleTextTrackResourceLoad
philipj_slow
2016/03/16 15:35:10
I think that really honorUserPreferencesForAutomat
Srirama
2016/03/16 17:41:17
Even i was going through it and wondering why it w
|
+{ |
+ m_pendingTask.clear(); |
+ if (m_pendingActionFlags & LoadTextTrackResource) |
+ honorUserPreferencesForAutomaticTextTrackSelection(); |
+ |
+ if (m_pendingActionFlags & LoadMediaResource) { |
+ if (m_loadState == LoadingFromSourceElement) |
+ loadNextSourceChild(); |
+ else |
+ loadInternal(); |
+ } |
+ |
+ m_pendingActionFlags = 0; |
} |
void HTMLMediaElement::loadInternal() |
@@ -3186,6 +3261,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; |
} |