| Index: Source/core/html/HTMLMediaElement.cpp
|
| diff --git a/Source/core/html/HTMLMediaElement.cpp b/Source/core/html/HTMLMediaElement.cpp
|
| index f93dbe4b0d94acb5431bbc00ec3acaa20cf1d4d4..cc8a723549ae605279e8cb8e84288094c58f82cf 100644
|
| --- a/Source/core/html/HTMLMediaElement.cpp
|
| +++ b/Source/core/html/HTMLMediaElement.cpp
|
| @@ -48,6 +48,7 @@
|
| #include "core/html/MediaController.h"
|
| #include "core/html/MediaError.h"
|
| #include "core/html/MediaFragmentURIParser.h"
|
| +#include "core/html/MediaProvider.h"
|
| #include "core/html/TimeRanges.h"
|
| #include "core/html/shadow/MediaControls.h"
|
| #include "core/html/track/AudioTrack.h"
|
| @@ -325,6 +326,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum
|
| , m_lastTimeUpdateEventWallTime(0)
|
| , m_defaultPlaybackStartPosition(0)
|
| , m_loadState(WaitingForSource)
|
| + , m_srcObject(nullptr)
|
| , m_deferredLoadState(NotDeferred)
|
| , m_deferredLoadTimer(this, &HTMLMediaElement::deferredLoadTimerFired)
|
| , m_webLayer(0)
|
| @@ -679,6 +681,19 @@ PassRefPtrWillBeRawPtr<MediaError> HTMLMediaElement::error() const
|
| return m_error;
|
| }
|
|
|
| +MediaProvider* HTMLMediaElement::srcObject() const
|
| +{
|
| + return m_srcObject.get();
|
| +}
|
| +
|
| +void HTMLMediaElement::setSrcObject(MediaProvider* mediaProvider)
|
| +{
|
| + WTF_LOG(Media, "HTMLMediaElement::setSrcObject(%p)", this);
|
| + m_srcObject = mediaProvider;
|
| + clearMediaPlayer(LoadMediaResource);
|
| + load();
|
| +}
|
| +
|
| void HTMLMediaElement::setSrc(const AtomicString& url)
|
| {
|
| setAttribute(srcAttr, url);
|
| @@ -850,67 +865,93 @@ void HTMLMediaElement::selectMediaResource()
|
| {
|
| WTF_LOG(Media, "HTMLMediaElement::selectMediaResource(%p)", this);
|
|
|
| - enum Mode { attribute, children };
|
| -
|
| - // 3 - If the media element has a src attribute, then let mode be attribute.
|
| - Mode mode = attribute;
|
| - if (!fastHasAttribute(srcAttr)) {
|
| - // Otherwise, if the media element does not have a src attribute but has a source
|
| - // element child, then let mode be children and let candidate be the first such
|
| - // source element child in tree order.
|
| - if (HTMLSourceElement* element = Traversal<HTMLSourceElement>::firstChild(*this)) {
|
| - mode = children;
|
| - m_nextChildNodeToConsider = element;
|
| - m_currentSourceNode = nullptr;
|
| - } else {
|
| - // Otherwise the media element has neither a src attribute nor a source element
|
| - // child: set the networkState to NETWORK_EMPTY, and abort these steps; the
|
| - // synchronous section ends.
|
| - m_loadState = WaitingForSource;
|
| - setShouldDelayLoadEvent(false);
|
| - m_networkState = NETWORK_EMPTY;
|
| + enum Mode { Object, Attribute, Children };
|
| +
|
| + // 6 - If the media element has an assigned media provider object, then let mode be object.
|
| + Mode mode;
|
| + if (srcObject()) {
|
| + mode = Object;
|
| + } else if (fastHasAttribute(srcAttr)) {
|
| + // Otherwise, if the media element has no assigned media provider object but has a src attribute, then let mode be attribute.
|
| + mode = Attribute;
|
| + } else if (Traversal<HTMLSourceElement>::firstChild(*this)) {
|
| + // Otherwise, if the media element does not have an assigned media provider object and does not have a src attribute,
|
| + // but does have a source element child, then let mode be children and let candidate be the first such source element child in tree order.
|
| + mode = Children;
|
| + HTMLSourceElement* element = Traversal<HTMLSourceElement>::firstChild(*this);
|
| + m_nextChildNodeToConsider = element;
|
| + m_currentSourceNode = nullptr;
|
| + } else {
|
| + // Otherwise the media element has no source.
|
| + // set the networkState to NETWORK_EMPTY, and abort these steps; the
|
| + // synchronous section ends.
|
| + m_loadState = WaitingForSource;
|
| + setShouldDelayLoadEvent(false);
|
| + m_networkState = NETWORK_EMPTY;
|
|
|
| - WTF_LOG(Media, "HTMLMediaElement::selectMediaResource(%p), nothing to load", this);
|
| - return;
|
| - }
|
| + WTF_LOG(Media, "HTMLMediaElement::selectMediaResource(%p), nothing to load", this);
|
| + return;
|
| }
|
|
|
| - // 4 - Set the media element's delaying-the-load-event flag to true (this delays the load event),
|
| + // 7 - Set the media element's delaying-the-load-event flag to true (this delays the load event),
|
| // and set its networkState to NETWORK_LOADING.
|
| setShouldDelayLoadEvent(true);
|
| m_networkState = NETWORK_LOADING;
|
|
|
| - // 5 - Queue a task to fire a simple event named loadstart at the media element.
|
| + // 8 - Queue a task to fire a simple event named loadstart at the media element.
|
| scheduleEvent(EventTypeNames::loadstart);
|
|
|
| - // 6 - If mode is attribute, then run these substeps
|
| - if (mode == attribute) {
|
| - m_loadState = LoadingFromSrcAttr;
|
| + // 9 - Run the appropriate steps from the following list.
|
| + switch (mode) {
|
| + case Object:
|
| + loadFromObject();
|
| + break;
|
| + case Attribute:
|
| + loadFromAttribute();
|
| + break;
|
| + case Children:
|
| + loadNextSourceChild();
|
| + break;
|
| + }
|
| +}
|
|
|
| - // If the src attribute's value is the empty string ... jump down to the failed step below
|
| - KURL mediaURL = getNonEmptyURLAttribute(srcAttr);
|
| - if (mediaURL.isEmpty()) {
|
| - mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError);
|
| - WTF_LOG(Media, "HTMLMediaElement::selectMediaResource(%p), empty 'src'", this);
|
| - return;
|
| - }
|
| +void HTMLMediaElement::loadFromObject()
|
| +{
|
| + m_loadState = LoadingFromSrcObject;
|
|
|
| - if (!isSafeToLoadURL(mediaURL, Complain)) {
|
| - mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError);
|
| - return;
|
| - }
|
| + KURL mediaURL = document().completeURL(m_srcObject->getObjectUrl());
|
| + ASSERT(isSafeToLoadURL(mediaURL, Complain));
|
| +
|
| + loadResource(mediaURL);
|
| +
|
| + // Set the currentSrc attribute to the empty string.
|
| + // FIXME |m_currentSrc| is set in loadResource and then reset here. The reason is that MediaProviders currently
|
| + // uses a url for loading, and uses the same algorithm as if the src attribute is set with createObjectURL.
|
| + m_currentSrc = KURL();
|
| + WTF_LOG(Media, "HTMLMediaElement::selectMediaResource, using 'srcObject' attribute.");
|
| + return;
|
| +}
|
| +
|
| +void HTMLMediaElement::loadFromAttribute()
|
| +{
|
| + m_loadState = LoadingFromSrcAttr;
|
|
|
| - // No type or key system information is available when the url comes
|
| - // from the 'src' attribute so MediaPlayer
|
| - // will have to pick a media engine based on the file extension.
|
| - ContentType contentType((String()));
|
| - loadResource(mediaURL, contentType, String());
|
| - WTF_LOG(Media, "HTMLMediaElement::selectMediaResource(%p), using 'src' attribute url", this);
|
| + // If the src attribute's value is the empty string ... jump down to the failed step below
|
| + KURL mediaURL = getNonEmptyURLAttribute(srcAttr);
|
| + if (mediaURL.isEmpty()) {
|
| + mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError);
|
| + WTF_LOG(Media, "HTMLMediaElement::selectMediaResource(%p), empty 'src'", this);
|
| + return;
|
| + }
|
| +
|
| + if (!isSafeToLoadURL(mediaURL, Complain)) {
|
| + mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError);
|
| return;
|
| }
|
|
|
| - // Otherwise, the source elements will be used
|
| - loadNextSourceChild();
|
| + loadResource(mediaURL);
|
| + WTF_LOG(Media, "HTMLMediaElement::selectMediaResource(%p), using 'src' attribute url", this);
|
| + return;
|
| }
|
|
|
| void HTMLMediaElement::loadNextSourceChild()
|
| @@ -930,6 +971,14 @@ void HTMLMediaElement::loadNextSourceChild()
|
| loadResource(mediaURL, contentType, keySystem);
|
| }
|
|
|
| +void HTMLMediaElement::loadResource(const KURL& url)
|
| +{
|
| + // No type or key system information is available when the url comes
|
| + // from the 'src' attribute or a srcObject.
|
| + ContentType contentType((String()));
|
| + loadResource(url, contentType, String());
|
| +}
|
| +
|
| void HTMLMediaElement::loadResource(const KURL& url, ContentType& contentType, const String& keySystem)
|
| {
|
| ASSERT(isSafeToLoadURL(url, Complain));
|
| @@ -3931,6 +3980,7 @@ void HTMLMediaElement::trace(Visitor* visitor)
|
| visitor->trace(m_playedTimeRanges);
|
| visitor->trace(m_asyncEventQueue);
|
| visitor->trace(m_error);
|
| + visitor->trace(m_srcObject);
|
| visitor->trace(m_currentSourceNode);
|
| visitor->trace(m_nextChildNodeToConsider);
|
| visitor->trace(m_mediaSource);
|
|
|