Diff
Modified: trunk/Source/WTF/ChangeLog (245038 => 245039)
--- trunk/Source/WTF/ChangeLog 2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WTF/ChangeLog 2019-05-07 22:00:32 UTC (rev 245039)
@@ -1,3 +1,13 @@
+2019-05-07 Eric Carlson <eric.carl...@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-05-07 Robin Morisset <rmoris...@apple.com>
WTF::BitVector should have an isEmpty() method
Modified: trunk/Source/WTF/wtf/Platform.h (245038 => 245039)
--- trunk/Source/WTF/wtf/Platform.h 2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WTF/wtf/Platform.h 2019-05-07 22:00:32 UTC (rev 245039)
@@ -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
+
Modified: trunk/Source/WebCore/ChangeLog (245038 => 245039)
--- trunk/Source/WebCore/ChangeLog 2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/ChangeLog 2019-05-07 22:00:32 UTC (rev 245039)
@@ -1,3 +1,55 @@
+2019-05-07 Eric Carlson <eric.carl...@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-05-07 Alex Christensen <achristen...@webkit.org>
Add SPI to set a list of hosts to which to send custom header fields cross-origin
Modified: trunk/Source/WebCore/PAL/ChangeLog (245038 => 245039)
--- trunk/Source/WebCore/PAL/ChangeLog 2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/PAL/ChangeLog 2019-05-07 22:00:32 UTC (rev 245039)
@@ -1,3 +1,13 @@
+2019-05-07 Eric Carlson <eric.carl...@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-05-04 Alex Christensen <achristen...@webkit.org>
Revert r244953 and r244954 because they broke internal builds.
Modified: trunk/Source/WebCore/PAL/pal/spi/mac/AVFoundationSPI.h (245038 => 245039)
--- trunk/Source/WebCore/PAL/pal/spi/mac/AVFoundationSPI.h 2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/PAL/pal/spi/mac/AVFoundationSPI.h 2019-05-07 22:00:32 UTC (rev 245039)
@@ -324,3 +324,16 @@
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
Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (245038 => 245039)
--- trunk/Source/WebCore/html/HTMLMediaElement.cpp 2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp 2019-05-07 22:00:32 UTC (rev 245039)
@@ -449,7 +449,6 @@
, 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 @@
case ReasonForSuspension::PageCache:
stopWithoutDestroyingMediaPlayer();
m_asyncEventQueue.suspend();
- setShouldBufferData(false);
+ setBufferingPolicy(BufferingPolicy::MakeResourcesPurgeable);
m_mediaSession->addBehaviorRestriction(MediaElementSession::RequirePageConsentToResumeMedia);
break;
case ReasonForSuspension::PageWillBeSuspended:
@@ -5798,8 +5797,6 @@
m_asyncEventQueue.resume();
- setShouldBufferData(true);
-
if (!m_mediaSession->pageAllowsPlaybackAfterResuming())
document().addMediaCanStartListener(*this);
else
@@ -5806,6 +5803,7 @@
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 @@
#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 @@
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 @@
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 @@
m_mediaSession->inActiveDocumentChanged();
}
+HTMLMediaElementEnums::BufferingPolicy HTMLMediaElement::bufferingPolicy() const
+{
+ return m_bufferingPolicy;
}
+}
+
#endif
Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (245038 => 245039)
--- trunk/Source/WebCore/html/HTMLMediaElement.h 2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h 2019-05-07 22:00:32 UTC (rev 245039)
@@ -268,13 +268,14 @@
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 @@
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 @@
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;
Modified: trunk/Source/WebCore/html/MediaElementSession.cpp (245038 => 245039)
--- trunk/Source/WebCore/html/MediaElementSession.cpp 2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/html/MediaElementSession.cpp 2019-05-07 22:00:32 UTC (rev 245039)
@@ -216,7 +216,7 @@
if (m_clientDataBufferingTimer.isActive())
m_clientDataBufferingTimer.stop();
- m_element.setShouldBufferData(dataBufferingPermitted());
+ m_element.setBufferingPolicy(preferredBufferingPolicy());
}
void MediaElementSession::addBehaviorRestriction(BehaviorRestrictions restrictions)
@@ -356,29 +356,29 @@
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
Modified: trunk/Source/WebCore/html/MediaElementSession.h (245038 => 245039)
--- trunk/Source/WebCore/html/MediaElementSession.h 2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/html/MediaElementSession.h 2019-05-07 22:00:32 UTC (rev 245039)
@@ -73,7 +73,7 @@
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 @@
void suspendBuffering() override;
void resumeBuffering() override;
bool bufferingSuspended() const;
+ void updateBufferingPolicy() { scheduleClientDataBufferingCheck(); }
// Restrictions to modify default behaviors.
enum BehaviorRestrictionFlags : unsigned {
Modified: trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp (245038 => 245039)
--- trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp 2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp 2019-05-07 22:00:32 UTC (rev 245039)
@@ -563,9 +563,9 @@
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 @@
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
Modified: trunk/Source/WebCore/platform/graphics/MediaPlayer.h (245038 => 245039)
--- trunk/Source/WebCore/platform/graphics/MediaPlayer.h 2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayer.h 2019-05-07 22:00:32 UTC (rev 245039)
@@ -312,8 +312,10 @@
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.
// This is different from the asynchronous MediaKeyError.
Modified: trunk/Source/WebCore/platform/graphics/MediaPlayerEnums.h (245038 => 245039)
--- trunk/Source/WebCore/platform/graphics/MediaPlayerEnums.h 2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayerEnums.h 2019-05-07 22:00:32 UTC (rev 245039)
@@ -43,6 +43,13 @@
VideoFullscreenModePictureInPicture = 1 << 1,
};
typedef uint32_t VideoFullscreenMode;
+
+ enum class BufferingPolicy {
+ Default,
+ LimitReadAhead,
+ MakeResourcesPurgeable,
+ PurgeResources,
+ };
};
WTF::String convertEnumerationToString(MediaPlayerEnums::ReadyState);
@@ -49,6 +56,7 @@
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 @@
}
};
+template <>
+struct LogArgument<WebCore::MediaPlayerEnums::BufferingPolicy> {
+ static WTF::String toString(const WebCore::MediaPlayerEnums::BufferingPolicy policy)
+ {
+ return convertEnumerationToString(policy);
+ }
+};
+
}; // namespace WTF
Modified: trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h (245038 => 245039)
--- trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h 2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h 2019-05-07 22:00:32 UTC (rev 245039)
@@ -68,7 +68,7 @@
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; }
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h (245038 => 245039)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h 2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h 2019-05-07 22:00:32 UTC (rev 245039)
@@ -121,7 +121,7 @@
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 @@
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;
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm (245038 => 245039)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm 2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm 2019-05-07 22:00:32 UTC (rev 245039)
@@ -348,7 +348,6 @@
, m_cachedBufferEmpty(false)
, m_cachedBufferFull(false)
, m_cachedHasEnabledAudio(false)
- , m_shouldBufferData(true)
, m_cachedIsReadyForDisplay(false)
, m_haveBeenAskedToCreateLayer(false)
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
@@ -379,7 +378,7 @@
void MediaPlayerPrivateAVFoundationObjC::cancelLoad()
{
- INFO_LOG(LOGIDENTIFIER);
+ ALWAYS_LOG(LOGIDENTIFIER);
tearDownVideoRendering();
[[NSNotificationCenter defaultCenter] removeObserver:m_objcObserver.get()];
@@ -543,7 +542,7 @@
updateVideoLayerGravity();
[m_videoLayer setContentsScale:player()->client().mediaPlayerContentsScale()];
IntSize defaultSize = snappedIntRect(player()->client().mediaPlayerContentBoxRect()).size();
- INFO_LOG(LOGIDENTIFIER);
+ ALWAYS_LOG(LOGIDENTIFIER);
m_videoFullscreenLayerManager->setVideoLayer(m_videoLayer.get(), defaultSize);
@@ -558,7 +557,7 @@
if (!m_videoLayer)
return;
- INFO_LOG(LOGIDENTIFIER);
+ ALWAYS_LOG(LOGIDENTIFIER);
[m_videoLayer removeObserver:m_objcObserver.get() forKeyPath:@"readyForDisplay"];
[m_videoLayer setPlayer:nil];
@@ -698,7 +697,7 @@
if (m_avAsset)
return;
- INFO_LOG(LOGIDENTIFIER);
+ ALWAYS_LOG(LOGIDENTIFIER);
setDelayCallbacks(true);
@@ -835,7 +834,7 @@
if (m_avPlayer)
return;
- INFO_LOG(LOGIDENTIFIER);
+ ALWAYS_LOG(LOGIDENTIFIER);
setDelayCallbacks(true);
@@ -884,7 +883,7 @@
if (m_avPlayerItem)
return;
- INFO_LOG(LOGIDENTIFIER);
+ ALWAYS_LOG(LOGIDENTIFIER);
setDelayCallbacks(true);
@@ -1112,10 +1111,11 @@
void MediaPlayerPrivateAVFoundationObjC::platformPlay()
{
- INFO_LOG(LOGIDENTIFIER);
if (!metaDataAvailable())
return;
+ ALWAYS_LOG(LOGIDENTIFIER);
+
m_requestedPlaying = true;
setPlayerRate(m_requestedRate);
}
@@ -1122,10 +1122,11 @@
void MediaPlayerPrivateAVFoundationObjC::platformPause()
{
- INFO_LOG(LOGIDENTIFIER);
if (!metaDataAvailable())
return;
+ ALWAYS_LOG(LOGIDENTIFIER);
+
m_requestedPlaying = false;
setPlayerRate(0);
}
@@ -1215,6 +1216,8 @@
if (!m_avPlayer)
return;
+ ALWAYS_LOG(LOGIDENTIFIER, volume);
+
[m_avPlayer.get() setVolume:volume];
#endif
}
@@ -1224,7 +1227,7 @@
if (m_muted == muted)
return;
- INFO_LOG(LOGIDENTIFIER, muted);
+ ALWAYS_LOG(LOGIDENTIFIER, muted);
m_muted = muted;
@@ -1241,7 +1244,7 @@
if (!metaDataAvailable())
return;
- INFO_LOG(LOGIDENTIFIER, closedCaptionsVisible);
+ ALWAYS_LOG(LOGIDENTIFIER, closedCaptionsVisible);
}
void MediaPlayerPrivateAVFoundationObjC::setRateDouble(double rate)
@@ -2859,19 +2862,45 @@
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:
+ setAVPlayerItem(m_avPlayerItem.get());
+ break;
+ case MediaPlayer::BufferingPolicy::LimitReadAhead:
+ case MediaPlayer::BufferingPolicy::MakeResourcesPurgeable:
+ setAVPlayerItem(nil);
+ break;
+ case MediaPlayer::BufferingPolicy::PurgeResources:
+ setAVPlayerItem(nil);
+ setAVPlayerItem(m_avPlayerItem.get());
+ break;
+ }
+
updateStates();
}
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h (245038 => 245039)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h 2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h 2019-05-07 22:00:32 UTC (rev 245039)
@@ -154,7 +154,6 @@
void enqueueVideoSample(MediaStreamTrackPrivate&, MediaSample&);
void enqueueCorrectedVideoSample(MediaSample&);
- void flushAndRemoveVideoSampleBuffers();
void requestNotificationWhenReadyForVideoData();
void paint(GraphicsContext&, const FloatRect&) override;
@@ -174,7 +173,7 @@
bool ended() const override { return m_ended; }
- void setShouldBufferData(bool) override;
+ void setBufferingPolicy(MediaPlayer::BufferingPolicy) override;
MediaPlayer::ReadyState currentReadyState();
void updateReadyState();
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm (245038 => 245039)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm 2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm 2019-05-07 22:00:32 UTC (rev 245039)
@@ -457,11 +457,6 @@
[m_sampleBufferDisplayLayer flush];
}
-void MediaPlayerPrivateMediaStreamAVFObjC::flushAndRemoveVideoSampleBuffers()
-{
- [m_sampleBufferDisplayLayer flushAndRemoveImage];
-}
-
void MediaPlayerPrivateMediaStreamAVFObjC::ensureLayers()
{
if (m_sampleBufferDisplayLayer)
@@ -1149,10 +1144,10 @@
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)
Modified: trunk/Source/WebCore/testing/Internals.cpp (245038 => 245039)
--- trunk/Source/WebCore/testing/Internals.cpp 2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/testing/Internals.cpp 2019-05-07 22:00:32 UTC (rev 245039)
@@ -3501,9 +3501,25 @@
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)
Modified: trunk/Source/WebCore/testing/Internals.h (245038 => 245039)
--- trunk/Source/WebCore/testing/Internals.h 2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/testing/Internals.h 2019-05-07 22:00:32 UTC (rev 245039)
@@ -540,6 +540,7 @@
void endSimulatedHDCPError(HTMLMediaElement&);
bool elementShouldBufferData(HTMLMediaElement&);
+ String elementBufferingPolicy(HTMLMediaElement&);
#endif
bool isSelectPopupVisible(HTMLSelectElement&);
Modified: trunk/Source/WebCore/testing/Internals.idl (245038 => 245039)
--- trunk/Source/WebCore/testing/Internals.idl 2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Source/WebCore/testing/Internals.idl 2019-05-07 22:00:32 UTC (rev 245039)
@@ -528,6 +528,7 @@
[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();
Modified: trunk/Tools/ChangeLog (245038 => 245039)
--- trunk/Tools/ChangeLog 2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Tools/ChangeLog 2019-05-07 22:00:32 UTC (rev 245039)
@@ -1,3 +1,16 @@
+2019-05-07 Eric Carlson <eric.carl...@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-05-07 Alex Christensen <achristen...@webkit.org>
Add SPI to set a list of hosts to which to send custom header fields cross-origin
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (245038 => 245039)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2019-05-07 21:51:43 UTC (rev 245038)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2019-05-07 22:00:32 UTC (rev 245039)
@@ -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 */,
Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/MediaBufferingPolicy.mm (0 => 245039)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/MediaBufferingPolicy.mm (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/MediaBufferingPolicy.mm 2019-05-07 22:00:32 UTC (rev 245039)
@@ -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