Diff
Modified: trunk/LayoutTests/ChangeLog (286304 => 286305)
--- trunk/LayoutTests/ChangeLog 2021-11-30 18:10:35 UTC (rev 286304)
+++ trunk/LayoutTests/ChangeLog 2021-11-30 18:15:46 UTC (rev 286305)
@@ -1,5 +1,15 @@
2021-11-30 Youenn Fablet <[email protected]>
+ Add support for rvfc to MediaPlayerPrivateMediaSourceAVFObjC
+ https://bugs.webkit.org/show_bug.cgi?id=233186
+
+ Reviewed by Eric Carlson.
+
+ * http/tests/media/media-source/mediasource-rvfc-expected.txt: Added.
+ * http/tests/media/media-source/mediasource-rvfc.html: Added.
+
+2021-11-30 Youenn Fablet <[email protected]>
+
Move TransformStreamAPIEnabled flag to Settings
https://bugs.webkit.org/show_bug.cgi?id=233524
Added: trunk/LayoutTests/http/tests/media/media-source/mediasource-rvfc-expected.txt (0 => 286305)
--- trunk/LayoutTests/http/tests/media/media-source/mediasource-rvfc-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/media/media-source/mediasource-rvfc-expected.txt 2021-11-30 18:15:46 UTC (rev 286305)
@@ -0,0 +1,3 @@
+
+PASS Test media source with requestVideoFrameCallback.
+
Added: trunk/LayoutTests/http/tests/media/media-source/mediasource-rvfc.html (0 => 286305)
--- trunk/LayoutTests/http/tests/media/media-source/mediasource-rvfc.html (rev 0)
+++ trunk/LayoutTests/http/tests/media/media-source/mediasource-rvfc.html 2021-11-30 18:15:46 UTC (rev 286305)
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Simple MediaSource playback & seek test case.</title>
+ <script src=""
+ <script src=""
+ <script src=""
+ </head>
+ <body>
+ <div id="log"></div>
+ <script>
+
+ mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+ {
+ if (window.internals && !internals.settings.mediaSourceInlinePaintingEnabled) {
+ test.done();
+ return;
+ }
+ mediaElement.play();
+ // Append all the segments
+ test.expectEvent(sourceBuffer, 'updateend', 'sourceBuffer');
+ test.expectEvent(mediaElement, 'playing', 'Playing triggered');
+ sourceBuffer.appendBuffer(mediaData);
+ mediaElement.requestVideoFrameCallback((now, metadata) => {
+ mediaElement.requestVideoFrameCallback((now, metadata) => {
+ assert_greater_than(metadata.presentedFrames, 0);
+ assert_equals(metadata.width, 320);
+ assert_equals(metadata.height, 240);
+ test.done();
+ });
+ });
+ }, 'Test media source with requestVideoFrameCallback.');
+ </script>
+ </body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (286304 => 286305)
--- trunk/Source/WebCore/ChangeLog 2021-11-30 18:10:35 UTC (rev 286304)
+++ trunk/Source/WebCore/ChangeLog 2021-11-30 18:15:46 UTC (rev 286305)
@@ -1,3 +1,23 @@
+2021-11-30 Youenn Fablet <[email protected]>
+
+ Add support for rvfc to MediaPlayerPrivateMediaSourceAVFObjC
+ https://bugs.webkit.org/show_bug.cgi?id=233186
+
+ Reviewed by Eric Carlson.
+
+ Implement rvfc support using canvas painting code path infrastructure.
+ We check 60 times per second whether a new frame is being displayed.
+ If so, we update the metadata.
+ We only enable the test if mediaSourceInlinePaintingEnabled is true since canvas painting does not work otherwise.
+
+ Test: http/tests/media/media-source/mediasource-rvfc.html
+
+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
+ * testing/InternalSettings.cpp:
+ * testing/InternalSettings.h:
+ * testing/InternalSettings.idl:
+
2021-11-30 Antti Koivisto <[email protected]>
[:has() pseudo-class] Cache :has() failures for subtrees
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h (286304 => 286305)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h 2021-11-30 18:10:35 UTC (rev 286304)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h 2021-11-30 18:15:46 UTC (rev 286305)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,6 +29,7 @@
#include "MediaPlayerPrivate.h"
#include "SourceBufferPrivateClient.h"
+#include <CoreMedia/CMTime.h>
#include <wtf/Deque.h>
#include <wtf/Function.h>
#include <wtf/HashMap.h>
@@ -275,6 +276,11 @@
bool pauseAtHostTime(const MonotonicTime&) final;
#endif
+ void startVideoFrameMetadataGathering() final;
+ void stopVideoFrameMetadataGathering() final;
+ std::optional<VideoFrameMetadata> videoFrameMetadata() final { return std::exchange(m_videoFrameMetadata, { }); }
+ void checkNewVideoFrameMetadata(CMTime);
+
friend class MediaSourcePrivateAVFObjC;
struct PendingSeek {
@@ -345,6 +351,11 @@
const void* m_logIdentifier;
std::unique_ptr<VideoLayerManagerObjC> m_videoLayerManager;
Ref<EffectiveRateChangedListener> m_effectiveRateChangedListener;
+ uint64_t m_sampleCount { 0 };
+ RetainPtr<id> m_videoFrameMetadataGatheringObserver;
+ bool m_isGatheringVideoFrameMetadata { false };
+ std::optional<VideoFrameMetadata> m_videoFrameMetadata;
+ uint64_t m_lastConvertedSampleCount { 0 };
};
String convertEnumerationToString(MediaPlayerPrivateMediaSourceAVFObjC::SeekState);
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm (286304 => 286305)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm 2021-11-30 18:10:35 UTC (rev 286304)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm 2021-11-30 18:15:46 UTC (rev 286305)
@@ -187,6 +187,8 @@
[m_synchronizer removeTimeObserver:m_timeChangedObserver.get()];
if (m_durationObserver)
[m_synchronizer removeTimeObserver:m_durationObserver.get()];
+ if (m_videoFrameMetadataGatheringObserver)
+ [m_synchronizer removeTimeObserver:m_videoFrameMetadataGatheringObserver.get()];
flushPendingSizeChanges();
destroyLayer();
@@ -680,7 +682,13 @@
bool MediaPlayerPrivateMediaSourceAVFObjC::updateLastImage()
{
- if (!updateLastPixelBuffer())
+ if (m_isGatheringVideoFrameMetadata) {
+ if (!m_lastPixelBuffer)
+ return false;
+ if (m_sampleCount == m_lastConvertedSampleCount)
+ return false;
+ m_lastConvertedSampleCount = m_sampleCount;
+ } else if (!updateLastPixelBuffer())
return false;
ASSERT(m_lastPixelBuffer);
@@ -723,10 +731,8 @@
acceleratedRenderingStateChanged();
}
- if (updateLastPixelBuffer()) {
- if (!m_lastPixelBuffer)
- return nullptr;
- }
+ if (!m_isGatheringVideoFrameMetadata)
+ updateLastPixelBuffer();
return m_lastPixelBuffer;
}
@@ -1389,6 +1395,49 @@
#endif
}
+void MediaPlayerPrivateMediaSourceAVFObjC::startVideoFrameMetadataGathering()
+{
+ ASSERT(!m_videoFrameMetadataGatheringObserver || m_synchronizer);
+ m_isGatheringVideoFrameMetadata = true;
+
+ // FIXME: We should use a CADisplayLink to get updates on rendering, for now we emulate with addPeriodicTimeObserverForInterval.
+ m_videoFrameMetadataGatheringObserver = [m_synchronizer addPeriodicTimeObserverForInterval:PAL::CMTimeMake(1, 60) queue:dispatch_get_main_queue() usingBlock:[weakThis = WeakPtr { *this }](CMTime currentTime) {
+ ensureOnMainThread([weakThis, currentTime] {
+ if (weakThis)
+ weakThis->checkNewVideoFrameMetadata(currentTime);
+ });
+ }];
+}
+
+void MediaPlayerPrivateMediaSourceAVFObjC::checkNewVideoFrameMetadata(CMTime currentTime)
+{
+ if (!m_player)
+ return;
+
+ if (!updateLastPixelBuffer())
+ return;
+
+ VideoFrameMetadata metadata;
+ metadata.width = m_naturalSize.width();
+ metadata.height = m_naturalSize.height();
+ metadata.presentedFrames = ++m_sampleCount;
+ metadata.presentationTime = PAL::CMTimeGetSeconds(currentTime);
+
+ m_videoFrameMetadata = metadata;
+ m_player->onNewVideoFrameMetadata(WTFMove(metadata), m_lastPixelBuffer.get());
+}
+
+void MediaPlayerPrivateMediaSourceAVFObjC::stopVideoFrameMetadataGathering()
+{
+ m_isGatheringVideoFrameMetadata = false;
+ m_videoFrameMetadata = { };
+
+ ASSERT(m_videoFrameMetadataGatheringObserver);
+ if (m_videoFrameMetadataGatheringObserver)
+ [m_synchronizer removeTimeObserver:m_videoFrameMetadataGatheringObserver.get()];
+ m_videoFrameMetadataGatheringObserver = nil;
+}
+
WTFLogChannel& MediaPlayerPrivateMediaSourceAVFObjC::logChannel() const
{
return LogMediaSource;
Modified: trunk/Source/WebCore/testing/InternalSettings.cpp (286304 => 286305)
--- trunk/Source/WebCore/testing/InternalSettings.cpp 2021-11-30 18:10:35 UTC (rev 286304)
+++ trunk/Source/WebCore/testing/InternalSettings.cpp 2021-11-30 18:15:46 UTC (rev 286305)
@@ -438,6 +438,15 @@
#endif
}
+bool InternalSettings::mediaSourceInlinePaintingEnabled() const
+{
+#if ENABLE(MEDIA_SOURCE) && HAVE(AVSAMPLEBUFFERVIDEOOUTPUT)
+ return RuntimeEnabledFeatures::sharedFeatures().mediaSourceInlinePaintingEnabled();
+#else
+ return false;
+#endif
+}
+
ExceptionOr<void> InternalSettings::setCustomPasteboardDataEnabled(bool enabled)
{
if (!m_page)
Modified: trunk/Source/WebCore/testing/InternalSettings.h (286304 => 286305)
--- trunk/Source/WebCore/testing/InternalSettings.h 2021-11-30 18:10:35 UTC (rev 286304)
+++ trunk/Source/WebCore/testing/InternalSettings.h 2021-11-30 18:15:46 UTC (rev 286305)
@@ -94,6 +94,7 @@
ExceptionOr<void> setCustomPasteboardDataEnabled(bool);
bool vp9DecoderEnabled() const;
+ bool mediaSourceInlinePaintingEnabled() const;
// DeprecatedGlobalSettings.
ExceptionOr<void> setShouldManageAudioSessionCategory(bool);
Modified: trunk/Source/WebCore/testing/InternalSettings.idl (286304 => 286305)
--- trunk/Source/WebCore/testing/InternalSettings.idl 2021-11-30 18:10:35 UTC (rev 286304)
+++ trunk/Source/WebCore/testing/InternalSettings.idl 2021-11-30 18:15:46 UTC (rev 286305)
@@ -69,6 +69,7 @@
undefined setCustomPasteboardDataEnabled(boolean enabled);
readonly attribute boolean vp9DecoderEnabled;
+ readonly attribute boolean mediaSourceInlinePaintingEnabled;
// DeprecatedGlobalSettings.
undefined setShouldManageAudioSessionCategory(boolean should);