WebKit Bugzilla
Attachment 368688 Details for
Bug 196979
: Define media buffering policy
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch for landing
bug-196979-20190501114315.patch (text/plain), 37.13 KB, created by
Eric Carlson
on 2019-05-01 11:43:16 PDT
(
hide
)
Description:
Patch for landing
Filename:
MIME Type:
Creator:
Eric Carlson
Created:
2019-05-01 11:43:16 PDT
Size:
37.13 KB
patch
obsolete
>Subversion Revision: 244820 >diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog >index cae119210fb456883b9324a889d9bb27db8f9d86..6fe49fd0bee251f15b3138848170b5a8f764ed46 100644 >--- a/Source/WTF/ChangeLog >+++ b/Source/WTF/ChangeLog >@@ -1,3 +1,13 @@ >+2019-04-16 Eric Carlson <eric.carlson@apple.com> >+ >+ Define media buffering policy >+ https://bugs.webkit.org/show_bug.cgi?id=196979 >+ <rdar://problem/28383861> >+ >+ Reviewed by Jer Noble. >+ >+ * wtf/Platform.h: >+ > 2019-04-30 John Wilander <wilander@apple.com> > > Add logging of Ad Click Attribution errors and events to a dedicated channel >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index a00aff979a2dedbf6d037ff5ef9ceb0b6786d912..8ef4491a8187757fa0ecc4ac0f3ecba4b77bbe3e 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,55 @@ >+2019-04-16 Eric Carlson <eric.carlson@apple.com> >+ >+ Define media buffering policy >+ https://bugs.webkit.org/show_bug.cgi?id=196979 >+ <rdar://problem/28383861> >+ >+ Reviewed by Jer Noble. >+ >+ Test: MediaBufferingPolicy API test. >+ >+ * html/HTMLMediaElement.cpp: >+ (WebCore::HTMLMediaElement::HTMLMediaElement): >+ (WebCore::HTMLMediaElement::suspend): >+ (WebCore::HTMLMediaElement::resume): >+ (WebCore::HTMLMediaElement::createMediaPlayer): >+ (WebCore::HTMLMediaElement::setBufferingPolicy): >+ (WebCore::HTMLMediaElement::purgeBufferedDataIfPossible): >+ (WebCore::HTMLMediaElement::bufferingPolicy const): >+ (WebCore::HTMLMediaElement::setShouldBufferData): Deleted. >+ * html/HTMLMediaElement.h: >+ (WebCore::HTMLMediaElement::shouldBufferData const): Deleted. >+ * html/MediaElementSession.cpp: >+ (WebCore::MediaElementSession::updateClientDataBuffering): >+ (WebCore::MediaElementSession::preferredBufferingPolicy const): >+ (WebCore::MediaElementSession::dataBufferingPermitted const): Deleted. >+ * html/MediaElementSession.h: >+ * platform/graphics/MediaPlayer.cpp: >+ (WebCore::MediaPlayer::setBufferingPolicy): >+ (WebCore::convertEnumerationToString): >+ (WebCore::MediaPlayer::setShouldBufferData): Deleted. >+ * platform/graphics/MediaPlayer.h: >+ * platform/graphics/MediaPlayerEnums.h: >+ (WTF::LogArgument<WebCore::MediaPlayerEnums::BufferingPolicy>::toString): >+ * platform/graphics/MediaPlayerPrivate.h: >+ (WebCore::MediaPlayerPrivateInterface::setBufferingPolicy): >+ (WebCore::MediaPlayerPrivateInterface::setShouldBufferData): Deleted. >+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h: >+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm: >+ (WebCore::MediaPlayerPrivateAVFoundationObjC::MediaPlayerPrivateAVFoundationObjC): >+ (WebCore::MediaPlayerPrivateAVFoundationObjC::setBufferingPolicy): >+ (WebCore::MediaPlayerPrivateAVFoundationObjC::setShouldBufferData): Deleted. >+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h: >+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm: >+ (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::setBufferingPolicy): >+ (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::flushAndRemoveVideoSampleBuffers): Deleted. >+ (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::setShouldBufferData): Deleted. >+ * testing/Internals.cpp: >+ (WebCore::Internals::elementShouldBufferData): >+ (WebCore::Internals::elementBufferingPolicy): >+ * testing/Internals.h: >+ * testing/Internals.idl: >+ > 2019-04-30 John Wilander <wilander@apple.com> > > Add logging of Ad Click Attribution errors and events to a dedicated channel >diff --git a/Source/WebCore/PAL/ChangeLog b/Source/WebCore/PAL/ChangeLog >index 72c230eeb750d1cb05fc8cdbaa683c88f31b803a..9c5753cf16c46c71a1e20bd5ffd6487c6d8a981b 100644 >--- a/Source/WebCore/PAL/ChangeLog >+++ b/Source/WebCore/PAL/ChangeLog >@@ -1,3 +1,13 @@ >+2019-04-16 Eric Carlson <eric.carlson@apple.com> >+ >+ Define media buffering policy >+ https://bugs.webkit.org/show_bug.cgi?id=196979 >+ <rdar://problem/28383861> >+ >+ Reviewed by Jer Noble. >+ >+ * pal/spi/mac/AVFoundationSPI.h: >+ > 2019-04-29 Alex Christensen <achristensen@webkit.org> > > <rdar://problem/50299396> Fix internal High Sierra build >diff --git a/Source/WTF/wtf/Platform.h b/Source/WTF/wtf/Platform.h >index 13faf6169702995e99762b28dbfac24f9dab9689..0d0e39fbfbfb3dd8beb137da656348d83e7d0389 100644 >--- a/Source/WTF/wtf/Platform.h >+++ b/Source/WTF/wtf/Platform.h >@@ -1527,3 +1527,8 @@ > #define HAVE_APP_LINKS_WITH_ISENABLED 1 > #define HAVE_ROUTE_SHARING_POLICY_LONG_FORM_VIDEO 1 > #endif >+ >+#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 130000) || (PLATFORM(WATCHOS) && __WATCH_OS_VERSION_MIN_REQUIRED >= 60000) || (PLATFORM(APPLETV) && __TV_OS_VERSION_MIN_REQUIRED >= 130000) >+#define HAVE_AVPLAYER_RESOURCE_CONSERVATION_LEVEL 1 >+#endif >+ >diff --git a/Source/WebCore/PAL/pal/spi/mac/AVFoundationSPI.h b/Source/WebCore/PAL/pal/spi/mac/AVFoundationSPI.h >index ff6bf8085e917918084e1d0db7615a9d4c8fe69c..f1bebf852cf9f9d4bf370e9466d46366af5cc0b8 100644 >--- a/Source/WebCore/PAL/pal/spi/mac/AVFoundationSPI.h >+++ b/Source/WebCore/PAL/pal/spi/mac/AVFoundationSPI.h >@@ -324,3 +324,16 @@ NS_ASSUME_NONNULL_BEGIN > NS_ASSUME_NONNULL_END > #endif > >+#if !USE(APPLE_INTERNAL_SDK) && HAVE(AVPLAYER_RESOURCE_CONSERVATION_LEVEL) >+@interface AVPlayer (AVPlayerPrivate) >+ >+@property (nonatomic) AVPlayerResourceConservationLevel resourceConservationLevelWhilePaused; >+ >+typedef NS_ENUM(NSInteger, AVPlayerResourceConservationLevel) { >+ AVPlayerResourceConservationLevelNone = 0, >+ AVPlayerResourceConservationLevelReduceReadAhead = 1, >+ AVPlayerResourceConservationLevelReuseActivePlayerResources = 2, >+ AVPlayerResourceConservationLevelRecycleBuffer = 3, >+}; >+@end >+#endif >diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp >index e3093f2320296199def96d126d054ff976ef787e..6d87bddeeaa33eafbd75ffe67c8e759ceb3852cf 100644 >--- a/Source/WebCore/html/HTMLMediaElement.cpp >+++ b/Source/WebCore/html/HTMLMediaElement.cpp >@@ -449,7 +449,6 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum > , m_completelyLoaded(false) > , m_havePreparedToPlay(false) > , m_parsingInProgress(createdByParser) >- , m_shouldBufferData(true) > , m_elementIsHidden(document.hidden()) > , m_creatingControls(false) > , m_receivedLayoutSizeChanged(false) >@@ -5779,7 +5778,7 @@ void HTMLMediaElement::suspend(ReasonForSuspension reason) > case ReasonForSuspension::PageCache: > stopWithoutDestroyingMediaPlayer(); > m_asyncEventQueue.suspend(); >- setShouldBufferData(false); >+ setBufferingPolicy(BufferingPolicy::MakeResourcesPurgeable); > m_mediaSession->addBehaviorRestriction(MediaElementSession::RequirePageConsentToResumeMedia); > break; > case ReasonForSuspension::PageWillBeSuspended: >@@ -5798,14 +5797,13 @@ void HTMLMediaElement::resume() > > m_asyncEventQueue.resume(); > >- setShouldBufferData(true); >- > if (!m_mediaSession->pageAllowsPlaybackAfterResuming()) > document().addMediaCanStartListener(*this); > else > setPausedInternal(false); > > m_mediaSession->removeBehaviorRestriction(MediaElementSession::RequirePageConsentToResumeMedia); >+ m_mediaSession->updateBufferingPolicy(); > > if (m_error && m_error->code() == MediaError::MEDIA_ERR_ABORTED && !m_resumeTaskQueue.hasPendingTask()) { > // Restart the load if it was aborted in the middle by moving the document to the page cache. >@@ -6705,7 +6703,7 @@ void HTMLMediaElement::createMediaPlayer() > #endif > > m_player = MediaPlayer::create(*this); >- m_player->setShouldBufferData(m_shouldBufferData); >+ m_player->setBufferingPolicy(m_bufferingPolicy); > schedulePlaybackControlsManagerUpdate(); > > #if ENABLE(WEB_AUDIO) >@@ -7882,20 +7880,23 @@ bool HTMLMediaElement::doesHaveAttribute(const AtomicString& attribute, AtomicSt > return true; > } > >-void HTMLMediaElement::setShouldBufferData(bool shouldBuffer) >+void HTMLMediaElement::setBufferingPolicy(BufferingPolicy policy) > { >- if (shouldBuffer == m_shouldBufferData) >+ if (policy == m_bufferingPolicy) > return; > >- m_shouldBufferData = shouldBuffer; >+ INFO_LOG(LOGIDENTIFIER, policy); >+ >+ m_bufferingPolicy = policy; > if (m_player) >- m_player->setShouldBufferData(shouldBuffer); >+ m_player->setBufferingPolicy(policy); > } > > void HTMLMediaElement::purgeBufferedDataIfPossible() > { >-#if PLATFORM(IOS_FAMILY) >- if (!MemoryPressureHandler::singleton().isUnderMemoryPressure() && m_mediaSession->dataBufferingPermitted()) >+ INFO_LOG(LOGIDENTIFIER); >+ >+ if (!MemoryPressureHandler::singleton().isUnderMemoryPressure() && m_mediaSession->preferredBufferingPolicy() == BufferingPolicy::Default) > return; > > if (isPlayingToExternalTarget()) { >@@ -7903,13 +7904,7 @@ void HTMLMediaElement::purgeBufferedDataIfPossible() > return; > } > >- // This is called to relieve memory pressure. Turning off buffering causes the media playback >- // daemon to release memory associated with queued-up video frames. >- // We turn it back on right away, but new frames won't get loaded unless playback is resumed. >- INFO_LOG(LOGIDENTIFIER, "toggling data buffering"); >- setShouldBufferData(false); >- setShouldBufferData(true); >-#endif >+ setBufferingPolicy(BufferingPolicy::PurgeResources); > } > > bool HTMLMediaElement::canSaveMediaData() const >@@ -8131,6 +8126,11 @@ void HTMLMediaElement::setInActiveDocument(bool inActiveDocument) > m_mediaSession->inActiveDocumentChanged(); > } > >+HTMLMediaElementEnums::BufferingPolicy HTMLMediaElement::bufferingPolicy() const >+{ >+ return m_bufferingPolicy; >+} >+ > } > > #endif >diff --git a/Source/WebCore/html/HTMLMediaElement.h b/Source/WebCore/html/HTMLMediaElement.h >index 2296c66df97bac4bcc9ea3c27b200fb30bb6e289..a09162633e4c6213fdb9867d71b82f1c60ac80e7 100644 >--- a/Source/WebCore/html/HTMLMediaElement.h >+++ b/Source/WebCore/html/HTMLMediaElement.h >@@ -268,13 +268,14 @@ public: > > WEBCORE_EXPORT void play() override; > WEBCORE_EXPORT void pause() override; >- void setShouldBufferData(bool); >- WEBCORE_EXPORT bool shouldBufferData() const { return m_shouldBufferData; } > WEBCORE_EXPORT void fastSeek(double); > double minFastReverseRate() const; > double maxFastForwardRate() const; > >- void purgeBufferedDataIfPossible(); >+ using HTMLMediaElementEnums::BufferingPolicy; >+ void setBufferingPolicy(BufferingPolicy); >+ WEBCORE_EXPORT BufferingPolicy bufferingPolicy() const; >+ WEBCORE_EXPORT void purgeBufferedDataIfPossible(); > > // captions > WEBCORE_EXPORT bool webkitHasClosedCaptions() const; >@@ -1072,6 +1073,8 @@ private: > ScanType m_scanType { Scan }; > ScanDirection m_scanDirection { Forward }; > >+ BufferingPolicy m_bufferingPolicy { BufferingPolicy::Default }; >+ > bool m_firstTimePlaying : 1; > bool m_playing : 1; > bool m_isWaitingUntilMediaCanStart : 1; >@@ -1099,7 +1102,6 @@ private: > bool m_completelyLoaded : 1; > bool m_havePreparedToPlay : 1; > bool m_parsingInProgress : 1; >- bool m_shouldBufferData : 1; > bool m_elementIsHidden : 1; > bool m_elementWasRemovedFromDOM : 1; > bool m_creatingControls : 1; >diff --git a/Source/WebCore/html/MediaElementSession.cpp b/Source/WebCore/html/MediaElementSession.cpp >index 7c3d009e1bcc776997736ed125f6da51217f18a4..ec48a24ecf795bc91fd3551f4ecc3cfafc5f568c 100644 >--- a/Source/WebCore/html/MediaElementSession.cpp >+++ b/Source/WebCore/html/MediaElementSession.cpp >@@ -216,7 +216,7 @@ void MediaElementSession::updateClientDataBuffering() > if (m_clientDataBufferingTimer.isActive()) > m_clientDataBufferingTimer.stop(); > >- m_element.setShouldBufferData(dataBufferingPermitted()); >+ m_element.setBufferingPolicy(preferredBufferingPolicy()); > } > > void MediaElementSession::addBehaviorRestriction(BehaviorRestrictions restrictions) >@@ -356,29 +356,29 @@ bool MediaElementSession::dataLoadingPermitted() const > return true; > } > >-bool MediaElementSession::dataBufferingPermitted() const >+MediaPlayer::BufferingPolicy MediaElementSession::preferredBufferingPolicy() const > { > if (isSuspended()) >- return false; >+ return MediaPlayer::BufferingPolicy::MakeResourcesPurgeable; > > if (bufferingSuspended()) >- return false; >+ return MediaPlayer::BufferingPolicy::LimitReadAhead; > > if (state() == PlatformMediaSession::Playing) >- return true; >+ return MediaPlayer::BufferingPolicy::Default; > > if (shouldOverrideBackgroundLoadingRestriction()) >- return true; >+ return MediaPlayer::BufferingPolicy::Default; > > #if ENABLE(WIRELESS_PLAYBACK_TARGET) > if (m_shouldPlayToPlaybackTarget) >- return true; >+ return MediaPlayer::BufferingPolicy::Default; > #endif > > if (m_elementIsHiddenUntilVisibleInViewport || m_elementIsHiddenBecauseItWasRemovedFromDOM || m_element.elementIsHidden()) >- return false; >+ return MediaPlayer::BufferingPolicy::MakeResourcesPurgeable; > >- return true; >+ return MediaPlayer::BufferingPolicy::Default; > } > > bool MediaElementSession::fullscreenPermitted() const >diff --git a/Source/WebCore/html/MediaElementSession.h b/Source/WebCore/html/MediaElementSession.h >index 0fa07604f523c9b4f7c66287723d51c62e972c0d..440e5b27e48ecdfb6e4bb86509d717286fef37b9 100644 >--- a/Source/WebCore/html/MediaElementSession.h >+++ b/Source/WebCore/html/MediaElementSession.h >@@ -73,7 +73,7 @@ public: > SuccessOr<MediaPlaybackDenialReason> playbackPermitted() const; > bool autoplayPermitted() const; > bool dataLoadingPermitted() const; >- bool dataBufferingPermitted() const; >+ MediaPlayer::BufferingPolicy preferredBufferingPolicy() const; > bool fullscreenPermitted() const; > bool pageAllowsDataLoading() const; > bool pageAllowsPlaybackAfterResuming() const; >@@ -104,6 +104,7 @@ public: > void suspendBuffering() override; > void resumeBuffering() override; > bool bufferingSuspended() const; >+ void updateBufferingPolicy() { scheduleClientDataBufferingCheck(); } > > // Restrictions to modify default behaviors. > enum BehaviorRestrictionFlags : unsigned { >diff --git a/Source/WebCore/platform/graphics/MediaPlayer.cpp b/Source/WebCore/platform/graphics/MediaPlayer.cpp >index 8bff2d7f074d1d03a22e4301cfa56644ffbdc77a..5a704b3222c5bc68ba4a61406c95d78cbb408334 100644 >--- a/Source/WebCore/platform/graphics/MediaPlayer.cpp >+++ b/Source/WebCore/platform/graphics/MediaPlayer.cpp >@@ -563,9 +563,9 @@ void MediaPlayer::pause() > m_private->pause(); > } > >-void MediaPlayer::setShouldBufferData(bool shouldBuffer) >+void MediaPlayer::setBufferingPolicy(BufferingPolicy policy) > { >- m_private->setShouldBufferData(shouldBuffer); >+ m_private->setBufferingPolicy(policy); > } > > #if ENABLE(LEGACY_ENCRYPTED_MEDIA) >@@ -1640,6 +1640,22 @@ String convertEnumerationToString(MediaPlayerEnums::SupportsType enumerationValu > return values[static_cast<size_t>(enumerationValue)]; > } > >+String convertEnumerationToString(MediaPlayerEnums::BufferingPolicy enumerationValue) >+{ >+ static const NeverDestroyed<String> values[] = { >+ MAKE_STATIC_STRING_IMPL("Default"), >+ MAKE_STATIC_STRING_IMPL("LimitReadAhead"), >+ MAKE_STATIC_STRING_IMPL("MakeResourcesPurgeable"), >+ MAKE_STATIC_STRING_IMPL("PurgeResources"), >+ }; >+ static_assert(!static_cast<size_t>(MediaPlayerEnums::BufferingPolicy::Default), "MediaPlayerEnums::Default is not 0 as expected"); >+ static_assert(static_cast<size_t>(MediaPlayerEnums::BufferingPolicy::LimitReadAhead) == 1, "MediaPlayerEnums::LimitReadAhead is not 1 as expected"); >+ static_assert(static_cast<size_t>(MediaPlayerEnums::BufferingPolicy::MakeResourcesPurgeable) == 2, "MediaPlayerEnums::MakeResourcesPurgeable is not 2 as expected"); >+ static_assert(static_cast<size_t>(MediaPlayerEnums::BufferingPolicy::PurgeResources) == 3, "MediaPlayerEnums::PurgeResources is not 3 as expected"); >+ ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values)); >+ return values[static_cast<size_t>(enumerationValue)]; >+} >+ > } > > #endif >diff --git a/Source/WebCore/platform/graphics/MediaPlayer.h b/Source/WebCore/platform/graphics/MediaPlayer.h >index efc15ba1cb6586e2606a93b041330b9bd7fdd22f..3e1263bbb63a387fe2c2fb4e16d0d07f7fce6de6 100644 >--- a/Source/WebCore/platform/graphics/MediaPlayer.h >+++ b/Source/WebCore/platform/graphics/MediaPlayer.h >@@ -312,7 +312,9 @@ public: > void prepareToPlay(); > void play(); > void pause(); >- void setShouldBufferData(bool); >+ >+ using MediaPlayerEnums::BufferingPolicy; >+ void setBufferingPolicy(BufferingPolicy); > > #if ENABLE(LEGACY_ENCRYPTED_MEDIA) > // Represents synchronous exceptions that can be thrown from the Encrypted Media methods. >diff --git a/Source/WebCore/platform/graphics/MediaPlayerEnums.h b/Source/WebCore/platform/graphics/MediaPlayerEnums.h >index 950e0ed287eb321a49a5423e63131aa09270cb60..0195c6976d4ec4a4983c42a476e1d45dd7a6198b 100644 >--- a/Source/WebCore/platform/graphics/MediaPlayerEnums.h >+++ b/Source/WebCore/platform/graphics/MediaPlayerEnums.h >@@ -43,12 +43,20 @@ public: > VideoFullscreenModePictureInPicture = 1 << 1, > }; > typedef uint32_t VideoFullscreenMode; >+ >+ enum class BufferingPolicy { >+ Default, >+ LimitReadAhead, >+ MakeResourcesPurgeable, >+ PurgeResources, >+ }; > }; > > WTF::String convertEnumerationToString(MediaPlayerEnums::ReadyState); > WTF::String convertEnumerationToString(MediaPlayerEnums::NetworkState); > WTF::String convertEnumerationToString(MediaPlayerEnums::Preload); > WTF::String convertEnumerationToString(MediaPlayerEnums::SupportsType); >+WTF::String convertEnumerationToString(MediaPlayerEnums::BufferingPolicy); > > } // namespace WebCore > >@@ -74,4 +82,12 @@ struct LogArgument<WebCore::MediaPlayerEnums::NetworkState> { > } > }; > >+template <> >+struct LogArgument<WebCore::MediaPlayerEnums::BufferingPolicy> { >+ static WTF::String toString(const WebCore::MediaPlayerEnums::BufferingPolicy policy) >+ { >+ return convertEnumerationToString(policy); >+ } >+}; >+ > }; // namespace WTF >diff --git a/Source/WebCore/platform/graphics/MediaPlayerPrivate.h b/Source/WebCore/platform/graphics/MediaPlayerPrivate.h >index 9700c0565098571c5903ef3ea342d8edb82e37c1..c79d48006d8584fab3281466c754e7f17e101ef0 100644 >--- a/Source/WebCore/platform/graphics/MediaPlayerPrivate.h >+++ b/Source/WebCore/platform/graphics/MediaPlayerPrivate.h >@@ -68,7 +68,7 @@ public: > > virtual void play() = 0; > virtual void pause() = 0; >- virtual void setShouldBufferData(bool) { } >+ virtual void setBufferingPolicy(MediaPlayer::BufferingPolicy) { } > > virtual bool supportsPictureInPicture() const { return false; } > virtual bool supportsFullscreen() const { return false; } >diff --git a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h b/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h >index e1b12dc5dff9d39194aaaf18ca12e9912fa00f9e..7587ad53021d9adef13e66a2b8513f14c1cf6986 100644 >--- a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h >+++ b/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h >@@ -121,7 +121,7 @@ public: > void canPlayFastReverseDidChange(bool); > void canPlayFastForwardDidChange(bool); > >- void setShouldBufferData(bool) override; >+ void setBufferingPolicy(MediaPlayerEnums::BufferingPolicy) override; > > #if HAVE(AVFOUNDATION_VIDEO_OUTPUT) > void outputMediaDataWillChange(AVPlayerItemVideoOutput*); >@@ -424,11 +424,11 @@ private: > mutable long long m_cachedTotalBytes; > unsigned m_pendingStatusChanges; > int m_cachedItemStatus; >+ MediaPlayer::BufferingPolicy m_bufferingPolicy { MediaPlayer::BufferingPolicy::Default }; > bool m_cachedLikelyToKeepUp; > bool m_cachedBufferEmpty; > bool m_cachedBufferFull; > bool m_cachedHasEnabledAudio; >- bool m_shouldBufferData; > bool m_cachedIsReadyForDisplay; > bool m_haveBeenAskedToCreateLayer; > bool m_cachedCanPlayFastForward; >diff --git a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm b/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm >index 4e5b82372e9b758c26d4a3e5d5801cfa7a1840bc..a80afbb4e39ffaafbbedd5585c75cb13b0639f1c 100644 >--- a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm >+++ b/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm >@@ -348,7 +348,6 @@ MediaPlayerPrivateAVFoundationObjC::MediaPlayerPrivateAVFoundationObjC(MediaPlay > , m_cachedBufferEmpty(false) > , m_cachedBufferFull(false) > , m_cachedHasEnabledAudio(false) >- , m_shouldBufferData(true) > , m_cachedIsReadyForDisplay(false) > , m_haveBeenAskedToCreateLayer(false) > #if ENABLE(WIRELESS_PLAYBACK_TARGET) >@@ -2859,19 +2858,43 @@ void MediaPlayerPrivateAVFoundationObjC::trackEnabledDidChange(bool) > updateStates(); > } > >-void MediaPlayerPrivateAVFoundationObjC::setShouldBufferData(bool shouldBuffer) >+void MediaPlayerPrivateAVFoundationObjC::setBufferingPolicy(MediaPlayer::BufferingPolicy policy) > { >- INFO_LOG(LOGIDENTIFIER, shouldBuffer); >+ ALWAYS_LOG(LOGIDENTIFIER, policy); > >- if (m_shouldBufferData == shouldBuffer) >+ if (m_bufferingPolicy == policy) > return; > >- m_shouldBufferData = shouldBuffer; >+ m_bufferingPolicy = policy; > > if (!m_avPlayer) > return; > >- setAVPlayerItem(shouldBuffer ? m_avPlayerItem.get() : nil); >+#if HAVE(AVPLAYER_RESOURCE_CONSERVATION_LEVEL) >+ static_assert(static_cast<size_t>(MediaPlayer::BufferingPolicy::Default) == AVPlayerResourceConservationLevelNone, "MediaPlayer::BufferingPolicy::Default is not AVPlayerResourceConservationLevelNone as expected"); >+ static_assert(static_cast<size_t>(MediaPlayer::BufferingPolicy::LimitReadAhead) == AVPlayerResourceConservationLevelReduceReadAhead, "MediaPlayer::BufferingPolicy::LimitReadAhead is not AVPlayerResourceConservationLevelReduceReadAhead as expected"); >+ static_assert(static_cast<size_t>(MediaPlayer::BufferingPolicy::MakeResourcesPurgeable) == AVPlayerResourceConservationLevelReuseActivePlayerResources, "MediaPlayer::BufferingPolicy::MakeResourcesPurgeable is not AVPlayerResourceConservationLevelReuseActivePlayerResources as expected"); >+ static_assert(static_cast<size_t>(MediaPlayer::BufferingPolicy::PurgeResources) == AVPlayerResourceConservationLevelRecycleBuffer, "MediaPlayer::BufferingPolicy::PurgeResources is not AVPlayerResourceConservationLevelRecycleBuffer as expected"); >+ >+ if ([m_avPlayer respondsToSelector:@selector(setResourceConservationLevelWhilePaused:)]) { >+ m_avPlayer.get().resourceConservationLevelWhilePaused = static_cast<AVPlayerResourceConservationLevel>(policy); >+ updateStates(); >+ return; >+ } >+#endif >+ >+ switch (policy) { >+ case MediaPlayer::BufferingPolicy::Default: >+ case MediaPlayer::BufferingPolicy::LimitReadAhead: >+ case MediaPlayer::BufferingPolicy::MakeResourcesPurgeable: >+ setAVPlayerItem(m_avPlayerItem.get()); >+ break; >+ case MediaPlayer::BufferingPolicy::PurgeResources: >+ setAVPlayerItem(nil); >+ setAVPlayerItem(m_avPlayerItem.get()); >+ break; >+ } >+ > updateStates(); > } > >diff --git a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h b/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h >index 795941136672ddc66dfe1bd12fa2be240c7aa198..ebdaeec499f39cab9a05bb4a175a28dfda3f06ed 100644 >--- a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h >+++ b/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h >@@ -154,7 +154,6 @@ private: > > void enqueueVideoSample(MediaStreamTrackPrivate&, MediaSample&); > void enqueueCorrectedVideoSample(MediaSample&); >- void flushAndRemoveVideoSampleBuffers(); > void requestNotificationWhenReadyForVideoData(); > > void paint(GraphicsContext&, const FloatRect&) override; >@@ -174,7 +173,7 @@ private: > > bool ended() const override { return m_ended; } > >- void setShouldBufferData(bool) override; >+ void setBufferingPolicy(MediaPlayer::BufferingPolicy) override; > > MediaPlayer::ReadyState currentReadyState(); > void updateReadyState(); >diff --git a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm b/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm >index cda97c91fda083def6acf5fac3ded2f448171d4c..fde0c1835631adcb0ebb9e26d1c377faf6ef8094 100644 >--- a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm >+++ b/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm >@@ -457,11 +457,6 @@ void MediaPlayerPrivateMediaStreamAVFObjC::flushRenderers() > [m_sampleBufferDisplayLayer flush]; > } > >-void MediaPlayerPrivateMediaStreamAVFObjC::flushAndRemoveVideoSampleBuffers() >-{ >- [m_sampleBufferDisplayLayer flushAndRemoveImage]; >-} >- > void MediaPlayerPrivateMediaStreamAVFObjC::ensureLayers() > { > if (m_sampleBufferDisplayLayer) >@@ -1149,10 +1144,10 @@ void MediaPlayerPrivateMediaStreamAVFObjC::setNetworkState(MediaPlayer::NetworkS > m_player->networkStateChanged(); > } > >-void MediaPlayerPrivateMediaStreamAVFObjC::setShouldBufferData(bool shouldBuffer) >+void MediaPlayerPrivateMediaStreamAVFObjC::setBufferingPolicy(MediaPlayer::BufferingPolicy policy) > { >- if (!shouldBuffer) >- flushAndRemoveVideoSampleBuffers(); >+ if (policy != MediaPlayer::BufferingPolicy::Default) >+ [m_sampleBufferDisplayLayer flushAndRemoveImage]; > } > > void MediaPlayerPrivateMediaStreamAVFObjC::scheduleDeferredTask(Function<void ()>&& function) >diff --git a/Source/WebCore/testing/Internals.cpp b/Source/WebCore/testing/Internals.cpp >index 10edd277b4797bbd24b31cdf662cb82157cbd61c..74b34217bbcc0d85a4453828afb065b00cb04f30 100644 >--- a/Source/WebCore/testing/Internals.cpp >+++ b/Source/WebCore/testing/Internals.cpp >@@ -3501,9 +3501,25 @@ void Internals::endSimulatedHDCPError(HTMLMediaElement& element) > > bool Internals::elementShouldBufferData(HTMLMediaElement& element) > { >- return element.shouldBufferData(); >+ return element.bufferingPolicy() < MediaPlayer::BufferingPolicy::LimitReadAhead; > } > >+String Internals::elementBufferingPolicy(HTMLMediaElement& element) >+{ >+ switch (element.bufferingPolicy()) { >+ case MediaPlayer::BufferingPolicy::Default: >+ return "Default"; >+ case MediaPlayer::BufferingPolicy::LimitReadAhead: >+ return "LimitReadAhead"; >+ case MediaPlayer::BufferingPolicy::MakeResourcesPurgeable: >+ return "MakeResourcesPurgeable"; >+ case MediaPlayer::BufferingPolicy::PurgeResources: >+ return "PurgeResources"; >+ } >+ >+ ASSERT_NOT_REACHED(); >+ return "UNKNOWN"; >+} > #endif > > bool Internals::isSelectPopupVisible(HTMLSelectElement& element) >diff --git a/Source/WebCore/testing/Internals.h b/Source/WebCore/testing/Internals.h >index fbc74ab7f8a34a734cc3760d6dde43f4bfd6c56e..af8a707544c5509f1d6a13d13c814cbe913a2380 100644 >--- a/Source/WebCore/testing/Internals.h >+++ b/Source/WebCore/testing/Internals.h >@@ -540,6 +540,7 @@ public: > void endSimulatedHDCPError(HTMLMediaElement&); > > bool elementShouldBufferData(HTMLMediaElement&); >+ String elementBufferingPolicy(HTMLMediaElement&); > #endif > > bool isSelectPopupVisible(HTMLSelectElement&); >diff --git a/Source/WebCore/testing/Internals.idl b/Source/WebCore/testing/Internals.idl >index d883c045d36ff6c331ee81bfce637329f5aa3aa0..9298e09d185e4a76a162761c6dc9769320253705 100644 >--- a/Source/WebCore/testing/Internals.idl >+++ b/Source/WebCore/testing/Internals.idl >@@ -528,6 +528,7 @@ enum CompositingPolicy { > [Conditional=VIDEO] void endSimulatedHDCPError(HTMLMediaElement media); > > [Conditional=VIDEO] boolean elementShouldBufferData(HTMLMediaElement media); >+ [Conditional=VIDEO] DOMString elementBufferingPolicy(HTMLMediaElement media); > > [Conditional=LEGACY_ENCRYPTED_MEDIA] void initializeMockCDM(); > [Conditional=ENCRYPTED_MEDIA] MockCDMFactory registerMockCDM(); >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index 72f9b10527505ac2f60fa25b17aa2e6d64d59ed8..c9babbbd520f79fbd3745445dbe9015278f27ef5 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,16 @@ >+2019-04-16 Eric Carlson <eric.carlson@apple.com> >+ >+ Define media buffering policy >+ https://bugs.webkit.org/show_bug.cgi?id=196979 >+ <rdar://problem/28383861> >+ >+ Reviewed by Jer Noble. >+ >+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: >+ * TestWebKitAPI/Tests/WebKitCocoa/MediaBufferingPolicy.mm: Added. >+ (waitUntilBufferingPolicyIsEqualTo): >+ (TEST): >+ > 2019-04-30 Tim Horton <timothy_horton@apple.com> > > Fix the WebKitTestRunner build >diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >index ead63ce29aca75a8fa91fbc63ea99c303a2ada7d..578b61a1216153d8fa6b1ce6f73787c528618f60 100644 >--- a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >+++ b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >@@ -32,6 +32,7 @@ > 0799C3491EBA2D7B003B7532 /* UserMediaDisabled.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07EDEFAC1EB9400C00D43292 /* UserMediaDisabled.mm */; }; > 0799C34B1EBA3301003B7532 /* disableGetUserMedia.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 0799C34A1EBA32F4003B7532 /* disableGetUserMedia.html */; }; > 07C046CA1E4262A8007201E7 /* CARingBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07C046C91E42573E007201E7 /* CARingBuffer.cpp */; }; >+ 07CC7DFE2266330900E39181 /* MediaBufferingPolicy.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07CC7DFD2266330800E39181 /* MediaBufferingPolicy.mm */; }; > 07CD32F62065B5430064A4BE /* AVFoundationPreference.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07CD32F52065B5420064A4BE /* AVFoundationPreference.mm */; }; > 07CE1CF31F06A7E000BF89F5 /* GetUserMediaNavigation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07CE1CF21F06A7E000BF89F5 /* GetUserMediaNavigation.mm */; }; > 07E1F6A21FFC44FA0096C7EC /* getDisplayMedia.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 07E1F6A11FFC44F90096C7EC /* getDisplayMedia.html */; }; >@@ -1349,6 +1350,7 @@ > 076E507E1F45031E006E9F5A /* Logging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Logging.cpp; sourceTree = "<group>"; }; > 0799C34A1EBA32F4003B7532 /* disableGetUserMedia.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = disableGetUserMedia.html; sourceTree = "<group>"; }; > 07C046C91E42573E007201E7 /* CARingBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CARingBuffer.cpp; sourceTree = "<group>"; }; >+ 07CC7DFD2266330800E39181 /* MediaBufferingPolicy.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MediaBufferingPolicy.mm; sourceTree = "<group>"; }; > 07CD32F52065B5420064A4BE /* AVFoundationPreference.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AVFoundationPreference.mm; sourceTree = "<group>"; }; > 07CD32F72065B72A0064A4BE /* video.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = video.html; sourceTree = "<group>"; }; > 07CE1CF21F06A7E000BF89F5 /* GetUserMediaNavigation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GetUserMediaNavigation.mm; sourceTree = "<group>"; }; >@@ -2623,6 +2625,7 @@ > 46C519D81D355A7300DAA51A /* LocalStorageNullEntries.mm */, > 8C10AF96206467770018FD90 /* LocalStoragePersistence.mm */, > 7A6A2C6F1DCCF87B00C0D085 /* LocalStorageQuirkTest.mm */, >+ 07CC7DFD2266330800E39181 /* MediaBufferingPolicy.mm */, > 5165FE03201EE617009F7EC3 /* MessagePortProviders.mm */, > 51CD1C6A1B38CE3600142CA5 /* ModalAlerts.mm */, > 1ABC3DED1899BE6D004F0626 /* Navigation.mm */, >@@ -4236,6 +4239,7 @@ > 7A6A2C701DCCFA8C00C0D085 /* LocalStorageQuirkTest.mm in Sources */, > 076E507F1F4513D6006E9F5A /* Logging.cpp in Sources */, > CE1866491F72E8F100A0CAB6 /* MarkedText.cpp in Sources */, >+ 07CC7DFE2266330900E39181 /* MediaBufferingPolicy.mm in Sources */, > CDA315981ED53651009F60D3 /* MediaPlaybackSleepAssertion.mm in Sources */, > CDC9442E1EF1FC080059C3C4 /* MediaStreamTrackDetached.mm in Sources */, > 7CCE7EB21A411A5100447C4C /* MemoryCacheAddImageToCacheIOS.mm in Sources */, >diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/MediaBufferingPolicy.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/MediaBufferingPolicy.mm >new file mode 100644 >index 0000000000000000000000000000000000000000..6c2d7b6f4e00ecf052d105938138d7c06be1259a >--- /dev/null >+++ b/Tools/TestWebKitAPI/Tests/WebKitCocoa/MediaBufferingPolicy.mm >@@ -0,0 +1,100 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+ >+#if WK_HAVE_C_SPI >+ >+#import "PlatformUtilities.h" >+#import "TestWKWebView.h" >+ >+#import <WebKit/WKWebViewConfigurationPrivate.h> >+#import <WebKit/WKWebViewPrivate.h> >+ >+static void waitUntilBufferingPolicyIsEqualTo(WKWebView* webView, const char* expected) >+{ >+ NSString* observed; >+ int tries = 0; >+ do { >+ observed = [webView stringByEvaluatingJavaScript:@"window.internals.elementBufferingPolicy(document.querySelector('video'))"]; >+ if ([observed isEqualToString:@(expected)]) >+ break; >+ >+ TestWebKitAPI::Util::sleep(0.1); >+ } while (++tries <= 100); >+ >+ EXPECT_WK_STREQ(expected, observed); >+} >+ >+TEST(WebKit, MediaBufferingPolicy) >+{ >+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]); >+ auto context = adoptWK(TestWebKitAPI::Util::createContextForInjectedBundleTest("InternalsInjectedBundleTest")); >+ configuration.get().processPool = (WKProcessPool *)context.get(); >+ configuration.get()._mediaDataLoadsAutomatically = YES; >+ configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone; >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]); >+ >+ __block bool isPlaying = false; >+ [webView performAfterReceivingMessage:@"playing" action:^() { isPlaying = true; }]; >+ >+ [webView synchronouslyLoadTestPageNamed:@"video-with-audio"]; >+ TestWebKitAPI::Util::run(&isPlaying); >+ >+ waitUntilBufferingPolicyIsEqualTo(webView.get(), "Default"); >+ >+ [webView stringByEvaluatingJavaScript:@"document.querySelector('video').pause()"]; >+ >+ // Suspending the process also forces a memory warning, which should purge whatever possible ASAP. >+ [webView _processWillSuspendImminentlyForTesting]; >+ waitUntilBufferingPolicyIsEqualTo(webView.get(), "PurgeResources"); >+ >+ // And should switch back to default when buffering is allowed. >+ [webView _processDidResumeForTesting]; >+ waitUntilBufferingPolicyIsEqualTo(webView.get(), "Default"); >+ >+ // All resources should be marked as purgeable when the document is hidden. >+#if PLATFORM(MAC) >+ [webView.get().window setIsVisible:NO]; >+#else >+ webView.get().window.hidden = YES; >+#endif >+ waitUntilBufferingPolicyIsEqualTo(webView.get(), "MakeResourcesPurgeable"); >+ >+#if PLATFORM(MAC) >+ [webView.get().window setIsVisible:YES]; >+#else >+ webView.get().window.hidden = NO; >+#endif >+ >+ // Policy should go back to default when playback starts. >+ isPlaying = false; >+ [webView stringByEvaluatingJavaScript:@"go()"]; >+ TestWebKitAPI::Util::run(&isPlaying); >+ >+ waitUntilBufferingPolicyIsEqualTo(webView.get(), "Default"); >+} >+ >+#endif // WK_HAVE_C_SPI
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 196979
:
367676
|
367683
|
367696
|
367701
|
367726
|
367727
|
367729
|
367750
|
368688
|
368694
|
368995
|
369045