Changeset 261341 in webkit
- Timestamp:
- May 7, 2020, 4:05:40 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r261334 r261341 1 2020-05-07 Eric Carlson <eric.carlson@apple.com> 2 3 Poster set after playback begins should be ignored 4 https://bugs.webkit.org/show_bug.cgi?id=211464 5 6 Reviewed by Jer Noble. 7 8 * media/video-poster-set-after-playback-expected.txt: Added. 9 * media/video-poster-set-after-playback.html: Added. 10 1 11 2020-05-07 Simon Fraser <simon.fraser@apple.com> 2 12 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/the-video-element/intrinsic_sizes-expected.txt
r242595 r261341 6 6 PASS default height is half the width 7 7 PASS default width is twice the height 8 FAIL default object size after src is removed assert_equals: expected "3 20px" but got "300px"8 FAIL default object size after src is removed assert_equals: expected "300px" but got "320px" 9 9 FAIL default object size after poster is removed assert_equals: expected "102px" but got "300px" 10 10 -
trunk/Source/WebCore/ChangeLog
r261338 r261341 1 2020-05-07 Eric Carlson <eric.carlson@apple.com> 2 3 Poster set after playback begins should be ignored 4 https://bugs.webkit.org/show_bug.cgi?id=211464 5 6 Reviewed by Jer Noble. 7 8 Redo the poster frame logic to use the `show poster flag` logic from the spec. 9 10 Test: media/video-poster-set-after-playback.html 11 12 * html/HTMLMediaElement.cpp: 13 (WebCore::HTMLMediaElement::HTMLMediaElement): Initialize m_showPoster. 14 (WebCore::HTMLMediaElement::prepareForLoad): m_displayMode was removed. 15 (WebCore::HTMLMediaElement::selectMediaResource): Call setShowPosterFlag. 16 (WebCore::HTMLMediaElement::loadResource): Remove calls to setDisplayMode and updateDisplayState, 17 they have been deleted. 18 (WebCore::HTMLMediaElement::waitForSourceChange): Call setShowPosterFlag. Update spec text. 19 (WebCore::HTMLMediaElement::noneSupported): Call setShowPosterFlag. 20 (WebCore::HTMLMediaElement::mediaLoadingFailed): Remove call to updateDisplayState. 21 (WebCore::HTMLMediaElement::setReadyState): Ditto. 22 (WebCore::HTMLMediaElement::seekWithTolerance): Call setShowPosterFlag. 23 (WebCore::HTMLMediaElement::seekTask): Check m_showPoster, not displayMode. 24 (WebCore::HTMLMediaElement::playInternal): Call setShowPosterFlag. 25 (WebCore::HTMLMediaElement::mediaPlayerCharacteristicChanged): Don't check displayMode. 26 (WebCore::HTMLMediaElement::updatePlayState): No more setDisplayMode. 27 (WebCore::HTMLMediaElement::userCancelledLoad): Call setShowPosterFlag. 28 (WebCore::HTMLMediaElement::mediaPlayerFirstVideoFrameAvailable): Deleted. 29 * html/HTMLMediaElement.h: 30 (WebCore::HTMLMediaElement::showPosterFlag const): 31 (WebCore::HTMLMediaElement::setShowPosterFlag): 32 (WebCore::HTMLMediaElement::displayMode const): Deleted. 33 (WebCore::HTMLMediaElement::setDisplayMode): Deleted. 34 (WebCore::HTMLMediaElement::updateDisplayState): Deleted. 35 36 * html/HTMLVideoElement.cpp: 37 (WebCore::HTMLVideoElement::didAttachRenderers): No more updateDisplayState. 38 (WebCore::HTMLVideoElement::parseAttribute): Ditto. Call updateFromElement when poster is removed. 39 (WebCore::HTMLVideoElement::shouldDisplayPosterImage const): New. 40 (WebCore::HTMLVideoElement::mediaPlayerFirstVideoFrameAvailable): New, update player and 41 renderer if the poster isn't supposed to be visible. 42 (WebCore::HTMLVideoElement::setDisplayMode): Deleted. 43 (WebCore::HTMLVideoElement::updateDisplayState): Deleted. 44 * html/HTMLVideoElement.h: 45 46 * rendering/RenderVideo.cpp: 47 (WebCore::RenderVideo::failedToLoadPosterImage const): New. 48 * rendering/RenderVideo.h: 49 50 * testing/Internals.cpp: 51 (WebCore::Internals::elementShouldDisplayPosterImage const): 52 * testing/Internals.h: 53 * testing/Internals.idl: 54 1 55 2020-05-07 Jack Lee <shihchieh_lee@apple.com> 2 56 -
trunk/Source/WebCore/html/HTMLMediaElement.cpp
r261004 r261341 448 448 , m_haveSetUpCaptionContainer(false) 449 449 , m_isScrubbingRemotely(false) 450 , m_showPoster(true) 450 451 #if ENABLE(VIDEO_TRACK) 451 452 , m_tracksAreReady(true) … … 1141 1142 m_completelyLoaded = false; 1142 1143 m_havePreparedToPlay = false; 1143 m_displayMode = Unknown;1144 1144 m_currentSrc = URL(); 1145 1145 … … 1247 1247 1248 1248 // 2. Set the element’s show poster flag to true. 1249 set DisplayMode(Poster);1249 setShowPosterFlag(true); 1250 1250 1251 1251 // 3. Set the media element’s delaying-the-load-event flag to true (this delays the load event). … … 1495 1495 m_player->setPrivateBrowsingMode(privateMode); 1496 1496 1497 // Reset display mode to force a recalculation of what to show because we are resetting the player.1498 setDisplayMode(Unknown);1499 1500 1497 if (!autoplay() && !m_havePreparedToPlay) 1501 1498 m_player->setPreload(m_mediaSession->effectivePreloadForElement()); … … 1551 1548 mediaLoadingFailed(MediaPlayer::NetworkState::FormatError); 1552 1549 1553 // If there is no poster to display, allow the media engine to render video frames as soon as 1554 // they are available. 1555 updateDisplayState(); 1556 1557 updateRenderer(); 1550 mediaPlayerRenderingModeChanged(); 1558 1551 } 1559 1552 … … 2048 2041 m_networkState = NETWORK_NO_SOURCE; 2049 2042 2050 // 6.18 - Set the element's delaying-the-load-event flag to false. This stops delaying the load event. 2043 // 6.18 - Set the element's show poster flag to true. 2044 setShowPosterFlag(true); 2045 2046 // 6.19 - Queue a media element task given the media element given the element to set the 2047 // element's delaying-the-load-event flag to false. This stops delaying the load event. 2048 // FIXME: this should be done in a task queue 2051 2049 setShouldDelayLoadEvent(false); 2052 2050 2053 updateDisplayState();2054 2051 updateRenderer(); 2055 2052 } … … 2080 2077 m_networkState = NETWORK_NO_SOURCE; 2081 2078 2079 // 6.4 - Set the element's show poster flag to true. 2080 setShowPosterFlag(true); 2081 2082 2082 // 7 - Queue a task to fire a simple event named error at the media element. 2083 2083 scheduleEvent(eventNames().errorEvent); … … 2095 2095 // the element won't attempt to load another resource. 2096 2096 2097 updateDisplayState();2098 2097 updateRenderer(); 2099 2098 } … … 2208 2207 else if ((error == MediaPlayer::NetworkState::FormatError || error == MediaPlayer::NetworkState::NetworkError) && m_loadState == LoadingFromSrcAttr) 2209 2208 noneSupported(); 2210 2211 updateDisplayState();2212 2209 2213 2210 ERROR_LOG(LOGIDENTIFIER, "error = ", static_cast<int>(error)); … … 2417 2414 } 2418 2415 2419 bool shouldUpdateDisplayState = false;2420 2421 2416 if (m_readyState >= HAVE_CURRENT_DATA && oldState < HAVE_CURRENT_DATA) { 2422 2417 if (!m_haveFiredLoadedData) { … … 2426 2421 // because m_haveFiredLoadedData is already true. At one time we were skipping 2427 2422 // the call to setShouldDelayLoadEvent, which was definitely incorrect. 2428 shouldUpdateDisplayState = true;2429 2423 applyMediaFragmentURI(); 2430 2424 } … … 2432 2426 } 2433 2427 2434 if (m_readyState == HAVE_FUTURE_DATA && oldState <= HAVE_CURRENT_DATA && tracksAreReady) {2428 if (m_readyState == HAVE_FUTURE_DATA && oldState <= HAVE_CURRENT_DATA && tracksAreReady) 2435 2429 scheduleEvent(eventNames().canplayEvent); 2436 shouldUpdateDisplayState = true;2437 }2438 2430 2439 2431 if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA && tracksAreReady) { … … 2446 2438 if (success) { 2447 2439 m_paused = false; 2440 setShowPosterFlag(false); 2448 2441 invalidateCachedTime(); 2449 2442 setAutoplayEventPlaybackState(AutoplayEventPlaybackState::StartedWithoutUserGesture); … … 2454 2447 setAutoplayEventPlaybackState(AutoplayEventPlaybackState::PreventedAutoplay); 2455 2448 } 2456 2457 shouldUpdateDisplayState = true;2458 2449 } 2459 2450 … … 2468 2459 setAutoplayEventPlaybackState(AutoplayEventPlaybackState::PreventedAutoplay); 2469 2460 } 2470 2471 if (shouldUpdateDisplayState)2472 updateDisplayState();2473 2461 2474 2462 updatePlayState(); … … 2895 2883 2896 2884 // 1 - Set the media element's show poster flag to false. 2897 set DisplayMode(Video);2885 setShowPosterFlag(false); 2898 2886 2899 2887 // 2 - If the media element's readyState is HAVE_NOTHING, abort these steps. … … 2994 2982 // poster display), or 2) if there is a pending fast seek, or 3) if this seek is not an exact seek 2995 2983 SeekType thisSeekType = (negativeTolerance == MediaTime::zeroTime() && positiveTolerance == MediaTime::zeroTime()) ? Precise : Fast; 2996 if (!noSeekRequired && time == now && thisSeekType == Precise && m_pendingSeekType != Fast && displayMode() != Poster)2984 if (!noSeekRequired && time == now && thisSeekType == Precise && m_pendingSeekType != Fast && !showPosterFlag()) 2997 2985 noSeekRequired = true; 2998 2986 … … 3475 3463 if (m_paused) { 3476 3464 m_paused = false; 3465 setShowPosterFlag(false); 3477 3466 invalidateCachedTime(); 3478 3467 … … 4940 4929 { 4941 4930 beginProcessingMediaPlayerCallback(); 4942 updateDisplayState();4943 4931 if (auto* renderer = this->renderer()) 4944 4932 renderer->repaint(); … … 5065 5053 } 5066 5054 5067 void HTMLMediaElement::mediaPlayerFirstVideoFrameAvailable()5068 {5069 INFO_LOG(LOGIDENTIFIER, "current display mode = ", (int)displayMode());5070 5071 beginProcessingMediaPlayerCallback();5072 if (displayMode() == PosterWaitingForVideo) {5073 setDisplayMode(Video);5074 mediaPlayerRenderingModeChanged();5075 }5076 endProcessingMediaPlayerCallback();5077 }5078 5079 5055 void HTMLMediaElement::mediaPlayerCharacteristicChanged() 5080 5056 { … … 5088 5064 #endif 5089 5065 5090 if (potentiallyPlaying() && displayMode() == PosterWaitingForVideo) { 5091 setDisplayMode(Video); 5066 if (potentiallyPlaying()) 5092 5067 mediaPlayerRenderingModeChanged(); 5093 }5094 5068 5095 5069 updateRenderer(); … … 5332 5306 schedulePlaybackControlsManagerUpdate(); 5333 5307 5334 setDisplayMode(Video);5335 5308 invalidateCachedTime(); 5336 5309 … … 5469 5442 5470 5443 // 4 - If the media element's readyState attribute has a value equal to HAVE_NOTHING, set the 5471 // element's networkState attribute to the NETWORK_EMPTY value and queue a task to fire a 5472 // simple event named emptied at the element. Otherwise, set the element's networkState 5473 // attribute to the NETWORK_IDLE value. 5444 // element's networkState attribute to the NETWORK_EMPTY value, set the element's show poster 5445 // flag to true, and fire an event named emptied at the element. 5474 5446 if (m_readyState == HAVE_NOTHING) { 5475 5447 m_networkState = NETWORK_EMPTY; 5448 setShowPosterFlag(true); 5476 5449 scheduleEvent(eventNames().emptiedEvent); 5477 5450 } -
trunk/Source/WebCore/html/HTMLMediaElement.h
r261004 r261341 600 600 void didMoveToNewDocument(Document& oldDocument, Document& newDocument) override; 601 601 602 enum DisplayMode { Unknown, None, Poster, PosterWaitingForVideo, Video };603 DisplayMode displayMode() const { return m_displayMode; }604 virtual void setDisplayMode(DisplayMode mode) { m_displayMode = mode; }605 606 602 bool isMediaElement() const final { return true; } 607 603 … … 615 611 616 612 void scheduleEvent(const AtomString&); 613 614 bool showPosterFlag() const { return m_showPoster; } 615 void setShowPosterFlag(bool flag) { m_showPoster = flag; } 617 616 618 617 private: … … 644 643 void visibilityStateChanged() final; 645 644 646 virtual void updateDisplayState() { }647 648 645 void setReadyState(MediaPlayer::ReadyState); 649 646 void setNetworkState(MediaPlayer::NetworkState); … … 671 668 void mediaEngineWasUpdated(); 672 669 673 void mediaPlayerFirstVideoFrameAvailable() final;674 670 void mediaPlayerCharacteristicChanged() final; 675 671 … … 1035 1031 MediaPlayer::Preload m_preload { Preload::Auto }; 1036 1032 1037 DisplayMode m_displayMode { Unknown };1038 1039 1033 // Counter incremented while processing a callback from the media player, so we can avoid 1040 1034 // calling the media engine recursively. … … 1114 1108 bool m_waitingToEnterFullscreen : 1; 1115 1109 1110 bool m_showPoster : 1; 1111 1116 1112 #if ENABLE(VIDEO_TRACK) 1117 1113 bool m_tracksAreReady : 1; -
trunk/Source/WebCore/html/HTMLVideoElement.cpp
r260259 r261341 103 103 HTMLMediaElement::didAttachRenderers(); 104 104 105 updateDisplayState();106 105 if (shouldDisplayPosterImage()) { 107 106 if (!m_imageLoader) … … 133 132 { 134 133 if (name == posterAttr) { 135 // Force a poster recalc by setting m_displayMode to Unknown directly before calling updateDisplayState.136 HTMLMediaElement::setDisplayMode(Unknown);137 updateDisplayState();138 139 134 if (shouldDisplayPosterImage()) { 140 135 if (!m_imageLoader) … … 142 137 m_imageLoader->updateFromElementIgnoringPreviousError(); 143 138 } else { 144 if (auto* renderer = this->renderer()) 139 if (auto* renderer = this->renderer()) { 145 140 renderer->imageResource().setCachedImage(nullptr); 141 renderer->updateFromElement(); 142 } 146 143 } 147 144 } … … 162 159 #endif 163 160 } 164 165 161 } 166 162 … … 252 248 } 253 249 254 void HTMLVideoElement::setDisplayMode(DisplayMode mode) 255 { 256 DisplayMode oldMode = displayMode(); 257 URL poster = posterImageURL(); 258 259 if (!poster.isEmpty()) { 260 // We have a poster path, but only show it until the user triggers display by playing or seeking and the 261 // media engine has something to display. 262 if (mode == Video) { 263 if (oldMode != Video && player()) 264 player()->prepareForRendering(); 265 if (!hasAvailableVideoFrame()) 266 mode = PosterWaitingForVideo; 267 } 268 } else if (oldMode != Video && player()) 269 player()->prepareForRendering(); 270 271 HTMLMediaElement::setDisplayMode(mode); 272 273 if (auto* renderer = this->renderer()) { 274 if (displayMode() != oldMode) 275 renderer->updateFromElement(); 276 } 277 } 278 279 void HTMLVideoElement::updateDisplayState() 280 { 250 bool HTMLVideoElement::shouldDisplayPosterImage() const 251 { 252 if (!showPosterFlag()) 253 return false; 254 281 255 if (posterImageURL().isEmpty()) 282 setDisplayMode(Video); 283 else if (displayMode() < Poster) 284 setDisplayMode(Poster); 256 return false; 257 258 auto* renderer = this->renderer(); 259 if (renderer && renderer->failedToLoadPosterImage()) 260 return false; 261 262 return true; 263 } 264 265 void HTMLVideoElement::mediaPlayerFirstVideoFrameAvailable() 266 { 267 INFO_LOG(LOGIDENTIFIER, "m_showPoster = ", showPosterFlag()); 268 269 if (showPosterFlag()) 270 return; 271 272 invalidateStyleAndLayerComposition(); 273 274 if (auto player = this->player()) 275 player->prepareForRendering(); 276 277 if (auto* renderer = this->renderer()) 278 renderer->updateFromElement(); 285 279 } 286 280 -
trunk/Source/WebCore/html/HTMLVideoElement.h
r260259 r261341 77 77 bool copyVideoTextureToPlatformTexture(GraphicsContextGLOpenGL*, PlatformGLObject texture, GCGLenum target, GCGLint level, GCGLenum internalFormat, GCGLenum format, GCGLenum type, bool premultiplyAlpha, bool flipY); 78 78 79 bool shouldDisplayPosterImage() const { return displayMode() == Poster || displayMode() == PosterWaitingForVideo; }79 WEBCORE_EXPORT bool shouldDisplayPosterImage() const; 80 80 81 81 URL posterImageURL() const; … … 123 123 const AtomString& imageSourceURL() const final; 124 124 125 void didMoveToNewDocument(Document& oldDocument, Document& newDocument) final; 126 125 127 bool hasAvailableVideoFrame() const; 126 void updateDisplayState() final; 127 void didMoveToNewDocument(Document& oldDocument, Document& newDocument) final; 128 void setDisplayMode(DisplayMode) final; 128 void mediaPlayerFirstVideoFrameAvailable() final; 129 129 130 130 PlatformMediaSession::MediaType presentationType() const final { return PlatformMediaSession::MediaType::Video; } -
trunk/Source/WebCore/rendering/RenderVideo.cpp
r260851 r261341 180 180 } 181 181 182 bool RenderVideo::failedToLoadPosterImage() const 183 { 184 return imageResource().errorOccurred(); 185 } 186 182 187 void RenderVideo::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset) 183 188 { -
trunk/Source/WebCore/rendering/RenderVideo.h
r228908 r261341 51 51 52 52 bool shouldDisplayVideo() const; 53 bool failedToLoadPosterImage() const; 53 54 54 55 void updateFromElement() final; -
trunk/Source/WebCore/testing/Internals.cpp
r261336 r261341 4334 4334 } 4335 4335 4336 ExceptionOr<bool> Internals::elementShouldDisplayPosterImage(HTMLVideoElement& element) const 4337 { 4338 #if ENABLE(VIDEO) 4339 return element.shouldDisplayPosterImage(); 4340 #else 4341 UNUSED_PARAM(element); 4342 return Exception { InvalidAccessError }; 4343 #endif 4344 } 4336 4345 4337 4346 #if ENABLE(WIRELESS_PLAYBACK_TARGET) -
trunk/Source/WebCore/testing/Internals.h
r261296 r261341 865 865 ExceptionOr<MediaUsageState> mediaUsageState(HTMLMediaElement&) const; 866 866 867 ExceptionOr<bool> elementShouldDisplayPosterImage(HTMLVideoElement&) const; 868 867 869 #if ENABLE(VIDEO) 868 870 using PlaybackControlsPurpose = MediaElementSession::PlaybackControlsPurpose; -
trunk/Source/WebCore/testing/Internals.idl
r261296 r261341 841 841 842 842 [Conditional=VIDEO, MayThrowException] MediaUsageState mediaUsageState(HTMLMediaElement element); 843 [Conditional=VIDEO, MayThrowException] boolean elementShouldDisplayPosterImage(HTMLVideoElement element); 843 844 844 845 DOMString ongoingLoadsDescriptions();
Note:
See TracChangeset
for help on using the changeset viewer.