Changeset 212311 in webkit
- Timestamp:
- Feb 14, 2017, 11:17:14 AM (9 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 3 deleted
- 16 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/fast/mediastream/MediaStream-MediaElement-setObject-null-expected.txt (added)
-
LayoutTests/fast/mediastream/MediaStream-MediaElement-setObject-null.html (added)
-
LayoutTests/fast/mediastream/MediaStream-video-element-expected.txt (modified) (1 diff)
-
LayoutTests/fast/mediastream/MediaStream-video-element-track-stop-expected.txt (modified) (1 diff)
-
LayoutTests/fast/mediastream/MediaStream-video-element-track-stop.html (modified) (1 diff)
-
LayoutTests/fast/mediastream/MediaStream-video-element.html (modified) (1 diff)
-
Source/WebCore/CMakeLists.txt (modified) (2 diffs)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/DerivedSources.cpp (modified) (1 diff)
-
Source/WebCore/DerivedSources.make (modified) (1 diff)
-
Source/WebCore/Modules/mediastream/HTMLMediaElementMediaStream.cpp (deleted)
-
Source/WebCore/Modules/mediastream/HTMLMediaElementMediaStream.h (deleted)
-
Source/WebCore/Modules/mediastream/HTMLMediaElementMediaStream.idl (deleted)
-
Source/WebCore/WebCore.xcodeproj/project.pbxproj (modified) (4 diffs)
-
Source/WebCore/bindings/scripts/IDLParser.pm (modified) (1 diff)
-
Source/WebCore/html/HTMLAudioElement.cpp (modified) (1 diff)
-
Source/WebCore/html/HTMLMediaElement.cpp (modified) (32 diffs)
-
Source/WebCore/html/HTMLMediaElement.h (modified) (6 diffs)
-
Source/WebCore/html/HTMLMediaElement.idl (modified) (2 diffs)
-
Source/WebCore/platform/ContentType.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r212304 r212311 1 2017-02-14 Jer Noble <jer.noble@apple.com> 2 3 Video elements with MediaSource objects set by srcObject are not cleared when srcObject is set to null 4 https://bugs.webkit.org/show_bug.cgi?id=168268 5 6 Reviewed by Eric Carlson. 7 8 * fast/mediastream/MediaStream-MediaElement-setObject-null-expected.txt: Added. 9 * fast/mediastream/MediaStream-MediaElement-setObject-null.html: Added. 10 * fast/mediastream/MediaStream-video-element-expected.txt: 11 * fast/mediastream/MediaStream-video-element-track-stop-expected.txt: 12 * fast/mediastream/MediaStream-video-element-track-stop.html: 13 * fast/mediastream/MediaStream-video-element.html: 14 1 15 2017-02-14 Antoine Quint <graouts@apple.com> 2 16 -
trunk/LayoutTests/fast/mediastream/MediaStream-video-element-expected.txt
r208559 r212311 25 25 PASS video.videoHeight is mediaStream.getVideoTracks()[0].getSettings().height 26 26 PASS video.src.indexOf("blob:") is 0 27 PASS video.srcObject is mediaStream28 27 29 28 **** check video tracks **** -
trunk/LayoutTests/fast/mediastream/MediaStream-video-element-track-stop-expected.txt
r208559 r212311 26 26 PASS video.videoHeight is mediaStream.getVideoTracks()[0].getSettings().height 27 27 PASS video.src.indexOf("blob:") is 0 28 PASS video.srcObject is mediaStream29 28 30 29 PASS video.videoTracks.length is 1 -
trunk/LayoutTests/fast/mediastream/MediaStream-video-element-track-stop.html
r192954 r212311 64 64 shouldBe('video.videoHeight', 'mediaStream.getVideoTracks()[0].getSettings().height'); 65 65 shouldBe('video.src.indexOf("blob:")', '0'); 66 shouldBe('video.srcObject', 'mediaStream');67 66 68 67 debug(""); -
trunk/LayoutTests/fast/mediastream/MediaStream-video-element.html
r192954 r212311 60 60 shouldBe('video.videoHeight', 'mediaStream.getVideoTracks()[0].getSettings().height'); 61 61 shouldBe('video.src.indexOf("blob:")', '0'); 62 shouldBe('video.srcObject', 'mediaStream'); 63 62 64 63 debug("<br>**** check video tracks ****"); 65 64 shouldBe('video.videoTracks.length', '1'); -
trunk/Source/WebCore/CMakeLists.txt
r212252 r212311 212 212 Modules/mediastream/DOMURLMediaStream.idl 213 213 Modules/mediastream/DoubleRange.idl 214 Modules/mediastream/HTMLMediaElementMediaStream.idl215 214 Modules/mediastream/LongRange.idl 216 215 Modules/mediastream/MediaDeviceInfo.idl … … 897 896 898 897 Modules/mediastream/DOMURLMediaStream.cpp 899 Modules/mediastream/HTMLMediaElementMediaStream.cpp900 898 Modules/mediastream/MediaConstraintsImpl.cpp 901 899 Modules/mediastream/MediaDeviceInfo.cpp -
trunk/Source/WebCore/ChangeLog
r212307 r212311 1 2017-02-14 Jer Noble <jer.noble@apple.com> 2 3 Video elements with MediaSource objects set by srcObject are not cleared when srcObject is set to null 4 https://bugs.webkit.org/show_bug.cgi?id=168268 5 6 Reviewed by Eric Carlson. 7 8 Test: fast/mediastream/MediaStream-MediaElement-setObject-null.html 9 10 Make the setSrcObject() operation compliant with the HTML spec. Since the specification defines 11 srcObject in terms of either a MediaSource, MediaStream, or Blob object, add the variant typedef 12 to HTMLMediaElement and move the definition out of the Modules/mediastream extension IDL and into 13 HTMLMediaElement.idl. Then bring the "media elements load" and "resource selection" algorithms up 14 to their most recent definitions in the HTML5 spec. 15 16 Drive-by fix: Allow the (admittedly weird) single-element-union type in IDL. 17 18 * CMakeLists.txt: 19 * DerivedSources.cpp: 20 * DerivedSources.make: 21 * Modules/mediastream/HTMLMediaElementMediaStream.cpp: Removed. 22 * Modules/mediastream/HTMLMediaElementMediaStream.h: Removed. 23 * Modules/mediastream/HTMLMediaElementMediaStream.idl: Removed. 24 * WebCore.xcodeproj/project.pbxproj: 25 * bindings/scripts/IDLParser.pm: 26 (parseUnionType): 27 * html/HTMLAudioElement.cpp: 28 (WebCore::HTMLAudioElement::createForJSConstructor): 29 * html/HTMLMediaElement.cpp: 30 (WebCore::actionName): 31 (WebCore::HTMLMediaElement::parseAttribute): 32 (WebCore::HTMLMediaElement::insertedInto): 33 (WebCore::HTMLMediaElement::scheduleDelayedAction): 34 (WebCore::HTMLMediaElement::scheduleNextSourceChild): 35 (WebCore::HTMLMediaElement::pendingActionTimerFired): 36 (WebCore::HTMLMediaElement::setSrcObject): 37 (WebCore::HTMLMediaElement::load): 38 (WebCore::HTMLMediaElement::prepareForLoad): 39 (WebCore::HTMLMediaElement::selectMediaResource): 40 (WebCore::HTMLMediaElement::loadResource): 41 (WebCore::HTMLMediaElement::playInternal): 42 (WebCore::HTMLMediaElement::pauseInternal): 43 (WebCore::HTMLMediaElement::sourceWasAdded): 44 (WebCore::HTMLMediaElement::clearMediaPlayer): 45 (WebCore::HTMLMediaElement::resume): 46 (WebCore::HTMLMediaElement::mediaCanStart): 47 (WebCore::HTMLMediaElement::createMediaPlayer): 48 (WebCore::HTMLMediaElement::loadInternal): Deleted. 49 * html/HTMLMediaElement.h: 50 (WebCore::HTMLMediaElement::srcObject): 51 * html/HTMLMediaElement.idl: 52 * platform/ContentType.h: 53 1 54 2017-02-14 Aakash Jain <aakash_jain@apple.com> 2 55 -
trunk/Source/WebCore/DerivedSources.cpp
r212193 r212311 264 264 #include "JSHTMLMediaElement.cpp" 265 265 #include "JSHTMLMediaElementMediaSession.cpp" 266 #include "JSHTMLMediaElementMediaStream.cpp"267 266 #include "JSHTMLMenuElement.cpp" 268 267 #include "JSHTMLMetaElement.cpp" -
trunk/Source/WebCore/DerivedSources.make
r212193 r212311 153 153 $(WebCore)/Modules/mediastream/DOMURLMediaStream.idl \ 154 154 $(WebCore)/Modules/mediastream/DoubleRange.idl \ 155 $(WebCore)/Modules/mediastream/HTMLMediaElementMediaStream.idl \156 155 $(WebCore)/Modules/mediastream/LongRange.idl \ 157 156 $(WebCore)/Modules/mediastream/MediaDeviceInfo.idl \ -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r212302 r212311 163 163 077664FC183E6B5C00133B92 /* JSQuickTimePluginReplacement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 077664FA183E6B5C00133B92 /* JSQuickTimePluginReplacement.cpp */; }; 164 164 077664FD183E6B5C00133B92 /* JSQuickTimePluginReplacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 077664FB183E6B5C00133B92 /* JSQuickTimePluginReplacement.h */; }; 165 0779BF0D18453168000B6AE7 /* HTMLMediaElementMediaStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0779BF0A18453168000B6AE7 /* HTMLMediaElementMediaStream.cpp */; };166 165 0779BF0E18453168000B6AE7 /* HTMLMediaElementMediaStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 0779BF0B18453168000B6AE7 /* HTMLMediaElementMediaStream.h */; }; 167 166 077AF14018F4AE400001ED61 /* SerializedPlatformRepresentation.h in Headers */ = {isa = PBXBuildFile; fileRef = 077AF13E18F4AE400001ED61 /* SerializedPlatformRepresentation.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 7291 7290 077664FA183E6B5C00133B92 /* JSQuickTimePluginReplacement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSQuickTimePluginReplacement.cpp; sourceTree = "<group>"; }; 7292 7291 077664FB183E6B5C00133B92 /* JSQuickTimePluginReplacement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSQuickTimePluginReplacement.h; sourceTree = "<group>"; }; 7293 0779BF0A18453168000B6AE7 /* HTMLMediaElementMediaStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLMediaElementMediaStream.cpp; sourceTree = "<group>"; };7294 7292 0779BF0B18453168000B6AE7 /* HTMLMediaElementMediaStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLMediaElementMediaStream.h; sourceTree = "<group>"; }; 7295 7293 0779BF0C18453168000B6AE7 /* HTMLMediaElementMediaStream.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = HTMLMediaElementMediaStream.idl; sourceTree = "<group>"; }; … … 15298 15296 93A806111E03B51C008A1F26 /* DoubleRange.h */, 15299 15297 93A806121E03B51C008A1F26 /* DoubleRange.idl */, 15300 0779BF0A18453168000B6AE7 /* HTMLMediaElementMediaStream.cpp */,15301 15298 0779BF0B18453168000B6AE7 /* HTMLMediaElementMediaStream.h */, 15302 15299 0779BF0C18453168000B6AE7 /* HTMLMediaElementMediaStream.idl */, … … 30045 30042 E44613A40CD6331000FADA75 /* HTMLMediaElement.cpp in Sources */, 30046 30043 C968B2E81B1E778100EF1F81 /* HTMLMediaElementMediaSession.cpp in Sources */, 30047 0779BF0D18453168000B6AE7 /* HTMLMediaElementMediaStream.cpp in Sources */,30048 30044 A8EA79F80A1916DF00A8EF5F /* HTMLMenuElement.cpp in Sources */, 30049 30045 2BE8E2C912A58A0100FAD550 /* HTMLMetaCharsetParser.cpp in Sources */, -
trunk/Source/WebCore/bindings/scripts/IDLParser.pm
r211409 r212311 2019 2019 2020 2020 push(@{$unionType->subtypes}, $self->parseUnionMemberType()); 2021 2022 $self->assertTokenValue($self->getToken(), "or", __LINE__);2023 2024 push(@{$unionType->subtypes}, $self->parseUnionMemberType());2025 2021 push(@{$unionType->subtypes}, $self->parseUnionMemberTypes()); 2026 2022 -
trunk/Source/WebCore/html/HTMLAudioElement.cpp
r177996 r212311 51 51 Ref<HTMLAudioElement> audio = adoptRef(*new HTMLAudioElement(audioTag, document, false)); 52 52 audio->setPreload("auto"); 53 if (!src.isNull()) {53 if (!src.isNull()) 54 54 audio->setSrc(src); 55 audio->scheduleDelayedAction(HTMLMediaElement::LoadMediaResource);56 }57 55 audio->suspendIfNeeded(); 58 56 return audio; -
trunk/Source/WebCore/html/HTMLMediaElement.cpp
r212289 r212311 32 32 #include "ApplicationCacheResource.h" 33 33 #include "Attribute.h" 34 #include "Blob.h" 34 35 #include "CSSPropertyNames.h" 35 36 #include "CSSValueKeywords.h" … … 204 205 } \ 205 206 206 ACTION(LoadMediaResource);207 207 ACTION(ConfigureTextTracks); 208 208 ACTION(TextTrackChangesNotification); … … 743 743 { 744 744 if (name == srcAttr) { 745 // https://html.spec.whatwg.org/multipage/embedded-content.html#location-of-the-media-resource 746 // Location of the Media Resource 747 // 12 February 2017 748 749 // If a src attribute of a media element is set or changed, the user 750 // agent must invoke the media element's media element load algorithm. 745 751 #if PLATFORM(IOS) 746 752 // Note, unless the restriction on requiring user action has been removed, … … 748 754 if (!value.isNull() && m_mediaSession->dataLoadingPermitted(*this)) 749 755 #else 750 // Trigger a reload, as long as the 'src' attribute is present.751 756 if (!value.isNull()) 752 757 #endif 753 { 754 clearMediaPlayer(LoadMediaResource); 755 scheduleDelayedAction(LoadMediaResource); 756 } 758 prepareForLoad(); 757 759 } else if (name == controlsAttr) 758 760 configureMediaControls(); … … 771 773 772 774 // The attribute must be ignored if the autoplay attribute is present 773 if (!autoplay() && m_player)775 if (!autoplay() && !m_havePreparedToPlay && m_player) 774 776 m_player->setPreload(m_mediaSession->effectivePreloadForElement(*this)); 775 777 … … 831 833 if (m_networkState == NETWORK_EMPTY && !attributeWithoutSynchronization(srcAttr).isEmpty()) 832 834 #endif 833 scheduleDelayedAction(LoadMediaResource);835 prepareForLoad(); 834 836 } 835 837 … … 931 933 LOG(Media, "HTMLMediaElement::scheduleDelayedAction(%p) - setting %s flag", this, actionName(actionType).utf8().data()); 932 934 933 if ((actionType & LoadMediaResource) && !(m_pendingActionFlags & LoadMediaResource)) {934 prepareForLoad();935 setFlags(m_pendingActionFlags, LoadMediaResource);936 }937 938 935 #if ENABLE(VIDEO_TRACK) 939 936 if (actionType & ConfigureTextTracks) … … 961 958 { 962 959 // Schedule the timer to try the next <source> element WITHOUT resetting state ala prepareForLoad. 963 LOG(Media, "HTMLMediaElement::scheduleNextSourceChild(%p) - setting %s flag", this, actionName(LoadMediaResource).utf8().data());964 setFlags(m_pendingActionFlags, LoadMediaResource);965 m_pendingActionTimer.startOneShot(0);960 m_resourceSelectionTaskQueue.enqueueTask([this] { 961 loadNextSourceChild(); 962 }); 966 963 } 967 964 … … 1036 1033 configureTextTracks(); 1037 1034 #endif 1038 1039 if (pendingActions & LoadMediaResource) {1040 if (m_loadState == LoadingFromSourceElement)1041 loadNextSourceChild();1042 else1043 loadInternal();1044 }1045 1035 1046 1036 #if ENABLE(WIRELESS_PLAYBACK_TARGET) … … 1072 1062 } 1073 1063 1074 #if ENABLE(MEDIA_STREAM) 1075 void HTMLMediaElement::setSrcObject(ScriptExecutionContext& context, MediaStream* mediaStream) 1064 void HTMLMediaElement::setSrcObject(MediaProvider&& mediaProvider) 1076 1065 { 1077 1066 // FIXME: Setting the srcObject attribute may cause other changes to the media element's internal state: … … 1082 1071 // https://bugs.webkit.org/show_bug.cgi?id=124896 1083 1072 1084 m_mediaStreamSrcObject = mediaStream; 1085 if (mediaStream) {1086 m_settingMediaStreamSrcObject = true;1087 setSrc(DOMURL::createPublicURL(context, *mediaStream));1088 m_settingMediaStreamSrcObject = false;1089 }1090 } 1091 #endif 1073 1074 // https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-srcobject 1075 // 4.7.14.2. Location of the media resource 1076 // srcObject: On setting, it must set the element’s assigned media provider object to the new 1077 // value, and then invoke the element’s media element load algorithm. 1078 m_mediaProvider = WTFMove(mediaProvider); 1079 prepareForLoad(); 1080 } 1092 1081 1093 1082 void HTMLMediaElement::setCrossOrigin(const AtomicString& value) … … 1143 1132 void HTMLMediaElement::load() 1144 1133 { 1145 Ref<HTMLMediaElement> protectedThis(*this); // loadInternalmay result in a 'beforeload' event, which can make arbitrary DOM mutations.1134 Ref<HTMLMediaElement> protectedThis(*this); // prepareForLoad may result in a 'beforeload' event, which can make arbitrary DOM mutations. 1146 1135 1147 1136 LOG(Media, "HTMLMediaElement::load(%p)", this); … … 1153 1142 1154 1143 prepareForLoad(); 1155 loadInternal(); 1156 prepareToPlay(); 1144 m_resourceSelectionTaskQueue.enqueueTask([this] { 1145 prepareToPlay(); 1146 }); 1157 1147 } 1158 1148 1159 1149 void HTMLMediaElement::prepareForLoad() 1160 1150 { 1151 // https://html.spec.whatwg.org/multipage/embedded-content.html#media-element-load-algorithm 1152 // The Media Element Load Algorithm 1153 // 12 February 2017 1154 1161 1155 LOG(Media, "HTMLMediaElement::prepareForLoad(%p)", this); 1162 1156 1157 // 1 - Abort any already-running instance of the resource selection algorithm for this element. 1163 1158 // Perform the cleanup required for the resource load algorithm to run. 1164 1159 stopPeriodicTimers(); 1165 1160 m_pendingActionTimer.stop(); 1161 m_resourceSelectionTaskQueue.cancelAllTasks(); 1166 1162 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if necessary and set m_pendingActionFlags to 0 here. 1167 m_pendingActionFlags &= ~LoadMediaResource;1168 1163 m_sentEndEvent = false; 1169 1164 m_sentStalledEvent = false; … … 1178 1173 #endif 1179 1174 1180 // 1 - Abort any already-running instance of the resource selection algorithm for this element.1181 1175 m_loadState = WaitingForSource; 1182 1176 m_currentSourceNode = nullptr; 1183 1177 1184 // 2 - If there are any tasks from the media element's media element event task source in 1185 // one of the task queues, then remove those tasks. 1178 createMediaPlayer(); 1179 1180 // 2 - Let pending tasks be a list of all tasks from the media element's media element event task source in one of the task queues. 1181 // 3 - For each task in pending tasks that would resolve pending play promises or reject pending play promises, immediately resolve or reject those promises in the order the corresponding tasks were queued. 1182 // 4 - Remove each task in pending tasks from its task queue 1186 1183 cancelPendingEventsAndCallbacks(); 1187 1184 1188 // 3- If the media element's networkState is set to NETWORK_LOADING or NETWORK_IDLE, queue1185 // 5 - If the media element's networkState is set to NETWORK_LOADING or NETWORK_IDLE, queue 1189 1186 // a task to fire a simple event named abort at the media element. 1190 1187 if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE) 1191 1188 scheduleEvent(eventNames().abortEvent); 1192 1189 1190 // 6 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps 1191 if (m_networkState != NETWORK_EMPTY) { 1192 // 6.1 - Queue a task to fire a simple event named emptied at the media element. 1193 scheduleEvent(eventNames().emptiedEvent); 1194 1195 // 6.2 - If a fetching process is in progress for the media element, the user agent should stop it. 1196 m_networkState = NETWORK_EMPTY; 1197 1198 // 6.3 - If the media element’s assigned media provider object is a MediaSource object, then detach it. 1193 1199 #if ENABLE(MEDIA_SOURCE) 1194 detachMediaSource(); 1195 #endif 1196 1197 createMediaPlayer(); 1198 1199 // 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps 1200 if (m_networkState != NETWORK_EMPTY) { 1201 // 4.1 - Queue a task to fire a simple event named emptied at the media element. 1202 scheduleEvent(eventNames().emptiedEvent); 1203 1204 // 4.2 - If a fetching process is in progress for the media element, the user agent should stop it. 1205 m_networkState = NETWORK_EMPTY; 1206 1207 // 4.3 - Forget the media element's media-resource-specific tracks. 1200 detachMediaSource(); 1201 #endif 1202 1203 // 6.4 - Forget the media element's media-resource-specific tracks. 1208 1204 forgetResourceSpecificTracks(); 1209 1205 1210 // 4.4- If readyState is not set to HAVE_NOTHING, then set it to that state.1206 // 6.5 - If readyState is not set to HAVE_NOTHING, then set it to that state. 1211 1207 m_readyState = HAVE_NOTHING; 1212 1208 m_readyStateMaximum = HAVE_NOTHING; 1213 1209 1214 // 4.5- If the paused attribute is false, then set it to true.1210 // 6.6 - If the paused attribute is false, then set it to true. 1215 1211 m_paused = true; 1216 1212 1217 // 4.6- If seeking is true, set it to false.1213 // 6.7 - If seeking is true, set it to false. 1218 1214 clearSeeking(); 1219 1215 1220 // 4.7- Set the current playback position to 0.1216 // 6.8 - Set the current playback position to 0. 1221 1217 // Set the official playback position to 0. 1222 1218 // If this changed the official playback position, then queue a task to fire a simple event named timeupdate at the media element. 1219 m_lastSeekTime = MediaTime::zeroTime(); 1220 m_playedTimeRanges = TimeRanges::create(); 1223 1221 // FIXME: Add support for firing this event. e.g., scheduleEvent(eventNames().timeUpdateEvent); 1224 1222 1225 // 4. 8- Set the initial playback position to 0.1223 // 4.9 - Set the initial playback position to 0. 1226 1224 // FIXME: Make this less subtle. The position only becomes 0 because of the createMediaPlayer() call 1227 1225 // above. … … 1230 1228 invalidateCachedTime(); 1231 1229 1232 // 4. 9- Set the timeline offset to Not-a-Number (NaN).1233 // 4.1 0- Update the duration attribute to Not-a-Number (NaN).1230 // 4.10 - Set the timeline offset to Not-a-Number (NaN). 1231 // 4.11 - Update the duration attribute to Not-a-Number (NaN). 1234 1232 1235 1233 updateMediaController(); … … 1239 1237 } 1240 1238 1241 // 5- Set the playbackRate attribute to the value of the defaultPlaybackRate attribute.1239 // 7 - Set the playbackRate attribute to the value of the defaultPlaybackRate attribute. 1242 1240 setPlaybackRate(defaultPlaybackRate()); 1243 1241 1244 // 6- Set the error attribute to null and the autoplaying flag to true.1242 // 8 - Set the error attribute to null and the autoplaying flag to true. 1245 1243 m_error = nullptr; 1246 1244 m_autoplaying = true; 1247 1245 mediaSession().clientWillBeginAutoplaying(); 1248 1246 1249 // 7 - Invoke the media element's resource selection algorithm. 1250 1251 // 8 - Note: Playback of any previously playing media resource for this element stops. 1252 1253 // The resource selection algorithm 1254 // 1 - Set the networkState to NETWORK_NO_SOURCE 1247 // 9 - Invoke the media element's resource selection algorithm. 1248 selectMediaResource(); 1249 1250 // 10 - Note: Playback of any previously playing media resource for this element stops. 1251 1252 configureMediaControls(); 1253 } 1254 1255 void HTMLMediaElement::selectMediaResource() 1256 { 1257 // https://www.w3.org/TR/2016/REC-html51-20161101/semantics-embedded-content.html#resource-selection-algorithm 1258 // The Resource Selection Algorithm 1259 1260 // 1. Set the element’s networkState attribute to the NETWORK_NO_SOURCE value. 1255 1261 m_networkState = NETWORK_NO_SOURCE; 1256 1262 1257 // 2 - Asynchronously await a stable state. 1258 1259 m_playedTimeRanges = TimeRanges::create(); 1260 1261 // FIXME: Investigate whether these can be moved into m_networkState != NETWORK_EMPTY block above 1262 // so they are closer to the relevant spec steps. 1263 m_lastSeekTime = MediaTime::zeroTime(); 1264 1265 // The spec doesn't say to block the load event until we actually run the asynchronous section 1266 // algorithm, but do it now because we won't start that until after the timer fires and the 1267 // event may have already fired by then. 1268 MediaPlayer::Preload effectivePreload = m_mediaSession->effectivePreloadForElement(*this); 1269 if (effectivePreload != MediaPlayer::None) 1270 setShouldDelayLoadEvent(true); 1271 1272 #if PLATFORM(IOS) 1273 if (effectivePreload != MediaPlayer::None && m_mediaSession->allowsAutomaticMediaDataLoading(*this)) 1274 prepareToPlay(); 1275 #endif 1276 1277 configureMediaControls(); 1278 } 1279 1280 void HTMLMediaElement::loadInternal() 1281 { 1282 LOG(Media, "HTMLMediaElement::loadInternal(%p)", this); 1283 1284 // Some of the code paths below this function dispatch the BeforeLoad event. This ASSERT helps 1285 // us catch those bugs more quickly without needing all the branches to align to actually 1286 // trigger the event. 1287 ASSERT(NoEventDispatchAssertion::isEventAllowedInMainThread()); 1288 1289 // If we can't start a load right away, start it later. 1263 // 2. Set the element’s show poster flag to true. 1264 setDisplayMode(Poster); 1265 1266 // 3. Set the media element’s delaying-the-load-event flag to true (this delays the load event). 1267 setShouldDelayLoadEvent(true); 1268 1269 // 4. in parallel await a stable state, allowing the task that invoked this algorithm to continue. 1270 if (m_resourceSelectionTaskQueue.hasPendingTasks()) 1271 return; 1272 1290 1273 if (!m_mediaSession->pageAllowsDataLoading(*this)) { 1291 LOG(Media, "HTMLMediaElement:: loadInternal(%p) - not allowed to load in background, waiting", this);1274 LOG(Media, "HTMLMediaElement::selectMediaResource(%p) - not allowed to load in background, waiting", this); 1292 1275 setShouldDelayLoadEvent(false); 1293 1276 if (m_isWaitingUntilMediaCanStart) … … 1298 1281 } 1299 1282 1300 clearFlags(m_pendingActionFlags, LoadMediaResource); 1301 1302 // Once the page has allowed an element to load media, it is free to load at will. This allows a 1303 // playlist that starts in a foreground tab to continue automatically if the tab is subsequently 1283 // Once the page has allowed an element to load media, it is free to load at will. This allows a 1284 // playlist that starts in a foreground tab to continue automatically if the tab is subsequently 1304 1285 // put into the background. 1305 1286 m_mediaSession->removeBehaviorRestriction(MediaElementSession::RequirePageConsentToLoadMedia); 1306 1287 1288 1289 m_resourceSelectionTaskQueue.enqueueTask([this] { 1290 // 5. If the media element’s blocked-on-parser flag is false, then populate the list of pending text tracks. 1307 1291 #if ENABLE(VIDEO_TRACK) 1308 if (hasMediaControls()) 1309 mediaControls()->changedClosedCaptionsVisibility(); 1310 1311 // HTMLMediaElement::textTracksAreReady will need "... the text tracks whose mode was not in the 1312 // disabled state when the element's resource selection algorithm last started". 1313 m_textTracksWhenResourceSelectionBegan.clear(); 1314 if (m_textTracks) { 1315 for (unsigned i = 0; i < m_textTracks->length(); ++i) { 1316 TextTrack* track = m_textTracks->item(i); 1317 if (track->mode() != TextTrack::Mode::Disabled) 1318 m_textTracksWhenResourceSelectionBegan.append(track); 1292 if (hasMediaControls()) 1293 mediaControls()->changedClosedCaptionsVisibility(); 1294 1295 // HTMLMediaElement::textTracksAreReady will need "... the text tracks whose mode was not in the 1296 // disabled state when the element's resource selection algorithm last started". 1297 // FIXME: Update this to match "populate the list of pending text tracks" step. 1298 m_textTracksWhenResourceSelectionBegan.clear(); 1299 if (m_textTracks) { 1300 for (unsigned i = 0; i < m_textTracks->length(); ++i) { 1301 TextTrack* track = m_textTracks->item(i); 1302 if (track->mode() != TextTrack::Mode::Disabled) 1303 m_textTracksWhenResourceSelectionBegan.append(track); 1304 } 1319 1305 } 1320 } 1321 #endif 1322 1323 selectMediaResource(); 1324 } 1325 1326 void HTMLMediaElement::selectMediaResource() 1327 { 1328 LOG(Media, "HTMLMediaElement::selectMediaResource(%p)", this); 1329 1330 ASSERT(m_player); 1331 if (!m_player) 1332 return; 1333 1334 enum Mode { attribute, children }; 1335 1336 // 3 - If the media element has a src attribute, then let mode be attribute. 1337 Mode mode = attribute; 1338 if (!hasAttributeWithoutSynchronization(srcAttr)) { 1339 // Otherwise, if the media element does not have a src attribute but has a source 1340 // element child, then let mode be children and let candidate be the first such 1341 // source element child in tree order. 1342 if (auto firstSource = childrenOfType<HTMLSourceElement>(*this).first()) { 1343 mode = children; 1306 #endif 1307 1308 enum Mode { None, Object, Attribute, Children }; 1309 Mode mode = None; 1310 1311 if (m_mediaProvider) { 1312 // 6. If the media element has an assigned media provider object, then let mode be object. 1313 mode = Object; 1314 } else if (hasAttributeWithoutSynchronization(srcAttr)) { 1315 // Otherwise, if the media element has no assigned media provider object but has a src attribute, then let mode be attribute. 1316 mode = Attribute; 1317 } else if (auto firstSource = childrenOfType<HTMLSourceElement>(*this).first()) { 1318 // Otherwise, if the media element does not have an assigned media provider object and does not have a src attribute, 1319 // but does have a source element child, then let mode be children and let candidate be the first such source element 1320 // child in tree order. 1321 mode = Children; 1344 1322 m_nextChildNodeToConsider = firstSource; 1345 1323 m_currentSourceNode = nullptr; 1346 1324 } else { 1347 // Otherwise the media element has neither a src attribute nor a source element 1348 // child: set the networkState to NETWORK_EMPTY, and abort these steps; the 1349 // synchronous section ends. 1325 // Otherwise the media element has no assigned media provider object and has neither a src attribute nor a source 1326 // element child: set the networkState to NETWORK_EMPTY, and abort these steps; the synchronous section ends. 1350 1327 m_loadState = WaitingForSource; 1351 1328 setShouldDelayLoadEvent(false); … … 1355 1332 return; 1356 1333 } 1357 } 1358 1359 // 4 - Set the media element's delaying-the-load-event flag to true (this delays the load event), 1360 // and set its networkState to NETWORK_LOADING. 1361 setShouldDelayLoadEvent(true); 1362 m_networkState = NETWORK_LOADING; 1363 1364 // 5 - Queue a task to fire a simple event named loadstart at the media element. 1365 scheduleEvent(eventNames().loadstartEvent); 1366 1367 // 6 - If mode is attribute, then run these substeps 1368 if (mode == attribute) { 1369 m_loadState = LoadingFromSrcAttr; 1370 1371 // If the src attribute's value is the empty string ... jump down to the failed step below 1372 URL mediaURL = getNonEmptyURLAttribute(srcAttr); 1373 if (mediaURL.isEmpty()) { 1374 mediaLoadingFailed(MediaPlayer::FormatError); 1375 LOG(Media, "HTMLMediaElement::selectMediaResource(%p) - empty 'src'", this); 1334 1335 // 7. Set the media element’s networkState to NETWORK_LOADING. 1336 m_networkState = NETWORK_LOADING; 1337 1338 // 8. Queue a task to fire a simple event named loadstart at the media element. 1339 scheduleEvent(eventNames().loadstartEvent); 1340 1341 // 9. Run the appropriate steps from the following list: 1342 // ↳ If mode is object 1343 if (mode == Object) { 1344 // 1. Set the currentSrc attribute to the empty string. 1345 m_currentSrc = URL(); 1346 1347 // 2. End the synchronous section, continuing the remaining steps in parallel. 1348 // 3. Run the resource fetch algorithm with the assigned media provider object. 1349 WTF::visit(WTF::makeVisitor( 1350 #if ENABLE(MEDIA_STREAM) 1351 [this](RefPtr<MediaStream> stream) { m_mediaStreamSrcObject = stream; }, 1352 #endif 1353 #if ENABLE(MEDIA_SOURCE) 1354 [this](RefPtr<MediaSource> source) { m_mediaSource = source; }, 1355 #endif 1356 [this](RefPtr<Blob> blob) { m_blob = blob; } 1357 ), m_mediaProvider.value()); 1358 1359 ContentType contentType; 1360 loadResource(URL(), contentType, String()); 1361 LOG(Media, "HTMLMediaElement::selectMediaResource(%p) - using 'srcObject' property", this); 1362 1363 // If that algorithm returns without aborting this one, then the load failed. 1364 // 4. Failed with media provider: Reaching this step indicates that the media resource 1365 // failed to load. Queue a task to run the dedicated media source failure steps. 1366 // 5. Wait for the task queued by the previous step to have executed. 1367 // 6. Abort these steps. The element won’t attempt to load another resource until this 1368 // algorithm is triggered again. 1376 1369 return; 1377 1370 } 1378 1371 1379 if (!isSafeToLoadURL(mediaURL, Complain) || !dispatchBeforeLoadEvent(mediaURL.string())) { 1380 mediaLoadingFailed(MediaPlayer::FormatError); 1372 // ↳ If mode is attribute 1373 if (mode == Attribute) { 1374 m_loadState = LoadingFromSrcAttr; 1375 1376 // 1. If the src attribute’s value is the empty string, then end the synchronous section, 1377 // and jump down to the failed with attribute step below. 1378 // 2. Let absolute URL be the absolute URL that would have resulted from parsing the URL 1379 // specified by the src attribute’s value relative to the media element when the src 1380 // attribute was last changed. 1381 URL absoluteURL = getNonEmptyURLAttribute(srcAttr); 1382 if (absoluteURL.isEmpty()) { 1383 mediaLoadingFailed(MediaPlayer::FormatError); 1384 LOG(Media, "HTMLMediaElement::selectMediaResource(%p) - empty 'src'", this); 1385 return; 1386 } 1387 1388 if (!isSafeToLoadURL(absoluteURL, Complain) || !dispatchBeforeLoadEvent(absoluteURL.string())) { 1389 mediaLoadingFailed(MediaPlayer::FormatError); 1390 return; 1391 } 1392 1393 // 3. If absolute URL was obtained successfully, set the currentSrc attribute to absolute URL. 1394 m_currentSrc = absoluteURL; 1395 1396 // 4. End the synchronous section, continuing the remaining steps in parallel. 1397 // 5. If absolute URL was obtained successfully, run the resource fetch algorithm with absolute 1398 // URL. If that algorithm returns without aborting this one, then the load failed. 1399 1400 // No type or key system information is available when the url comes 1401 // from the 'src' attribute so MediaPlayer 1402 // will have to pick a media engine based on the file extension. 1403 ContentType contentType; 1404 loadResource(absoluteURL, contentType, String()); 1405 LOG(Media, "HTMLMediaElement::selectMediaResource(%p) - using 'src' attribute url", this); 1406 1407 // 6. Failed with attribute: Reaching this step indicates that the media resource failed to load 1408 // or that the given URL could not be resolved. Queue a task to run the dedicated media source failure steps. 1409 // 7. Wait for the task queued by the previous step to have executed. 1410 // 8. Abort these steps. The element won’t attempt to load another resource until this algorithm is triggered again. 1381 1411 return; 1382 1412 } 1383 1413 1384 // No type or key system information is available when the url comes 1385 // from the 'src' attribute so MediaPlayer 1386 // will have to pick a media engine based on the file extension. 1387 ContentType contentType((String())); 1388 loadResource(mediaURL, contentType, String()); 1389 LOG(Media, "HTMLMediaElement::selectMediaResource(%p) - using 'src' attribute url", this); 1390 return; 1391 } 1392 1393 // Otherwise, the source elements will be used 1394 loadNextSourceChild(); 1414 // ↳ Otherwise (mode is children) 1415 // (Ctd. in loadNextSourceChild()) 1416 loadNextSourceChild(); 1417 }); 1395 1418 } 1396 1419 1397 1420 void HTMLMediaElement::loadNextSourceChild() 1398 1421 { 1399 ContentType contentType ((String()));1422 ContentType contentType; 1400 1423 String keySystem; 1401 1424 URL mediaURL = selectNextSourceChild(&contentType, &keySystem, Complain); … … 1414 1437 void HTMLMediaElement::loadResource(const URL& initialURL, ContentType& contentType, const String& keySystem) 1415 1438 { 1416 ASSERT(i sSafeToLoadURL(initialURL, Complain));1439 ASSERT(initialURL.isEmpty() || isSafeToLoadURL(initialURL, Complain)); 1417 1440 1418 1441 LOG(Media, "HTMLMediaElement::loadResource(%p) - %s, %s, %s", this, urlForLoggingMedia(initialURL).utf8().data(), contentType.raw().utf8().data(), keySystem.utf8().data()); … … 1431 1454 1432 1455 URL url = initialURL; 1433 if (! frame->loader().willLoadMediaElementURL(url)) {1456 if (!url.isEmpty() && !frame->loader().willLoadMediaElementURL(url)) { 1434 1457 mediaLoadingFailed(MediaPlayer::FormatError); 1435 1458 return; … … 1450 1473 // If the URL should be loaded from the application cache, pass the URL of the cached file to the media engine. 1451 1474 ApplicationCacheResource* resource = nullptr; 1452 if ( frame->loader().documentLoader()->applicationCacheHost().shouldLoadResourceFromApplicationCache(ResourceRequest(url), resource)) {1475 if (!url.isEmpty() && frame->loader().documentLoader()->applicationCacheHost().shouldLoadResourceFromApplicationCache(ResourceRequest(url), resource)) { 1453 1476 // Resources that are not present in the manifest will always fail to load (at least, after the 1454 1477 // cache has been primed the first time), making the testing of offline applications simpler. … … 1484 1507 setDisplayMode(Unknown); 1485 1508 1486 if (!autoplay() )1509 if (!autoplay() && !m_havePreparedToPlay) 1487 1510 m_player->setPreload(m_mediaSession->effectivePreloadForElement(*this)); 1488 1511 m_player->setPreservesPitch(m_webkitPreservesPitch); … … 1498 1521 bool loadAttempted = false; 1499 1522 #if ENABLE(MEDIA_SOURCE) 1500 ASSERT(!m_mediaSource); 1501 1502 if (url.protocolIs(mediaSourceBlobProtocol)) 1523 if (!m_mediaSource && url.protocolIs(mediaSourceBlobProtocol)) 1503 1524 m_mediaSource = MediaSource::lookup(url.string()); 1504 1525 1505 1526 if (m_mediaSource) { 1506 if (m_mediaSource->attachToElement(*this)) 1507 m_player->load(url, contentType, m_mediaSource.get()); 1508 else { 1527 loadAttempted = true; 1528 if (!m_mediaSource->attachToElement(*this) || !m_player->load(url, contentType, m_mediaSource.get())) { 1509 1529 // Forget our reference to the MediaSource, so we leave it alone 1510 1530 // while processing remainder of load failure. … … 1512 1532 mediaLoadingFailed(MediaPlayer::FormatError); 1513 1533 } 1514 loadAttempted = true;1515 1534 } 1516 1535 #endif … … 1528 1547 } 1529 1548 #endif 1549 1550 if (!loadAttempted && m_blob) { 1551 loadAttempted = true; 1552 if (!m_player->load(m_blob->url(), contentType, keySystem)) 1553 mediaLoadingFailed(MediaPlayer::FormatError); 1554 } 1530 1555 1531 1556 if (!loadAttempted && !m_player->load(url, contentType, keySystem)) … … 3122 3147 // 4.8.10.9. Playing the media resource 3123 3148 if (!m_player || m_networkState == NETWORK_EMPTY) 3124 scheduleDelayedAction(LoadMediaResource);3149 prepareForLoad(); 3125 3150 3126 3151 if (endedPlayback()) … … 3210 3235 if (!m_mediaSession->playbackPermitted(*this)) 3211 3236 return; 3212 scheduleDelayedAction(LoadMediaResource);3237 prepareForLoad(); 3213 3238 } 3214 3239 … … 4256 4281 // the media element's resource selection algorithm. 4257 4282 if (networkState() == HTMLMediaElement::NETWORK_EMPTY) { 4258 scheduleDelayedAction(LoadMediaResource);4259 4283 m_nextChildNodeToConsider = source; 4284 selectMediaResource(); 4260 4285 return; 4261 4286 } … … 5042 5067 #endif 5043 5068 5069 m_blob = nullptr; 5070 5044 5071 #if ENABLE(VIDEO_TRACK) 5045 5072 forgetResourceSpecificTracks(); … … 5204 5231 // This behavior is not specified but it seems like a sensible thing to do. 5205 5232 // As it is not safe to immedately start loading now, let's schedule a load. 5206 scheduleDelayedAction(LoadMediaResource);5233 prepareForLoad(); 5207 5234 } 5208 5235 … … 5729 5756 if (m_isWaitingUntilMediaCanStart) { 5730 5757 m_isWaitingUntilMediaCanStart = false; 5731 loadInternal();5758 selectMediaResource(); 5732 5759 } 5733 5760 if (m_pausedInternal) … … 6003 6030 6004 6031 #if ENABLE(MEDIA_SOURCE) 6005 if (m_mediaSource) 6006 m_mediaSource->detachFromElement(*this); 6032 detachMediaSource(); 6007 6033 #endif 6008 6034 -
trunk/Source/WebCore/html/HTMLMediaElement.h
r212289 r212311 58 58 class AudioTrackList; 59 59 class AudioTrackPrivate; 60 class Blob; 60 61 class DOMError; 61 62 class DeferredPromise; … … 93 94 #endif 94 95 96 using MediaProvider = std::optional<Variant< 97 #if ENABLE(MEDIA_STREAM) 98 RefPtr<MediaStream>, 99 #endif 100 #if ENABLE(MEDIA_SOURCE) 101 RefPtr<MediaSource>, 102 #endif 103 RefPtr<Blob>>>; 104 95 105 class HTMLMediaElement 96 106 : public HTMLElement … … 165 175 const URL& currentSrc() const { return m_currentSrc; } 166 176 167 #if ENABLE(MEDIA_STREAM) 168 MediaStream* srcObject() const { return m_mediaStreamSrcObject.get(); } 169 void setSrcObject(ScriptExecutionContext&, MediaStream*); 170 #endif 177 const MediaProvider& srcObject() const { return m_mediaProvider; } 178 void setSrcObject(MediaProvider&&); 171 179 172 180 WEBCORE_EXPORT void setCrossOrigin(const AtomicString&); … … 699 707 700 708 // These "internal" functions do not check user gesture restrictions. 701 void loadInternal();702 709 bool playInternal(); 703 710 void pauseInternal(); … … 829 836 GenericTaskQueue<Timer> m_updatePlaybackControlsManagerQueue; 830 837 GenericTaskQueue<Timer> m_playbackControlsManagerBehaviorRestrictionsQueue; 838 GenericTaskQueue<Timer> m_resourceSelectionTaskQueue; 831 839 RefPtr<TimeRanges> m_playedTimeRanges; 832 840 GenericEventQueue m_asyncEventQueue; … … 1013 1021 friend class TrackDisplayUpdateScope; 1014 1022 1023 RefPtr<Blob> m_blob; 1024 MediaProvider m_mediaProvider; 1025 1015 1026 #if ENABLE(LEGACY_ENCRYPTED_MEDIA) 1016 1027 RefPtr<WebKitMediaKeys> m_webKitMediaKeys; -
trunk/Source/WebCore/html/HTMLMediaElement.idl
r210780 r212311 24 24 */ 25 25 26 27 typedef ( 28 #if defined(ENABLE_MEDIA_STREAM) && ENABLE_MEDIA_STREAM 29 MediaStream or 30 #endif 31 #if defined(ENABLE_MEDIA_SOURCE) && ENABLE_MEDIA_SOURCE 32 MediaSource or 33 #endif 34 Blob) MediaProvider; 35 26 36 [ 27 37 ActiveDOMObject, … … 36 46 // network state 37 47 [Reflect, URL] attribute USVString src; 48 attribute MediaProvider? srcObject; 38 49 [URL] readonly attribute USVString currentSrc; 39 50 attribute DOMString? crossOrigin; -
trunk/Source/WebCore/platform/ContentType.h
r165676 r212311 35 35 public: 36 36 explicit ContentType(const String& type); 37 ContentType() = default; 37 38 38 39 String parameter(const String& parameterName) const;
Note:
See TracChangeset
for help on using the changeset viewer.