Unreviewed, rolling out r254564.
This caused internal test crashes.
Reverted changeset:
"Introduce an abstract SampleBufferDisplayLayer"
https://bugs.webkit.org/show_bug.cgi?id=206066
https://trac.webkit.org/changeset/254564
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@254779 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index bc6ba4d..c71ff6c 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,5 +1,17 @@
2020-01-17 Matt Lewis <jlewis3@apple.com>
+ Unreviewed, rolling out r254564.
+
+ This caused internal test crashes.
+
+ Reverted changeset:
+
+ "Introduce an abstract SampleBufferDisplayLayer"
+ https://bugs.webkit.org/show_bug.cgi?id=206066
+ https://trac.webkit.org/changeset/254564
+
+2020-01-17 Matt Lewis <jlewis3@apple.com>
+
Unreviewed, rolling out r254688.
This caused internal test crashes.
diff --git a/Source/WebCore/SourcesCocoa.txt b/Source/WebCore/SourcesCocoa.txt
index 8906f57..e6f817a 100644
--- a/Source/WebCore/SourcesCocoa.txt
+++ b/Source/WebCore/SourcesCocoa.txt
@@ -253,7 +253,6 @@
platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm @no-unify
platform/graphics/avfoundation/objc/InbandTextTrackPrivateAVFObjC.mm @no-unify
platform/graphics/avfoundation/objc/InbandTextTrackPrivateLegacyAVFObjC.mm @no-unify
-platform/graphics/avfoundation/objc/LocalSampleBufferDisplayLayer.mm @no-unify
platform/graphics/avfoundation/objc/MediaPlaybackTargetPickerMac.mm @no-unify
platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm @no-unify
platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm @no-unify
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
index aa182ff..6507b9a 100644
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -1067,7 +1067,6 @@
413C2C341BC29A8F0075204C /* JSDOMConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 413C2C331BC29A7B0075204C /* JSDOMConstructor.h */; };
413CCD4A20DE034F0065A21A /* MockMediaDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 413CCD4820DE013C0065A21A /* MockMediaDevice.h */; settings = {ATTRIBUTES = (Private, ); }; };
413E00791DB0E4F2002341D2 /* MemoryRelease.h in Headers */ = {isa = PBXBuildFile; fileRef = 413E00781DB0E4DE002341D2 /* MemoryRelease.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 414598C223C8D177002B9CC8 /* LocalSampleBufferDisplayLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 414598C123C8AD79002B9CC8 /* LocalSampleBufferDisplayLayer.mm */; };
414B82051D6DF0E50077EBE3 /* StructuredClone.h in Headers */ = {isa = PBXBuildFile; fileRef = 414B82031D6DF0D90077EBE3 /* StructuredClone.h */; };
414DEDE71F9FE91E0047C40D /* EmptyFrameLoaderClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 414DEDE51F9FE9150047C40D /* EmptyFrameLoaderClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
415071581685067300C3C7B3 /* SelectorFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 415071561685067300C3C7B3 /* SelectorFilter.h */; };
@@ -1154,8 +1153,6 @@
41F062140F5F192600A07EAC /* InspectorDatabaseResource.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F062120F5F192600A07EAC /* InspectorDatabaseResource.h */; };
41F1D21F0EF35C2A00DA8753 /* ScriptCachedFrameData.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F1D21D0EF35C2A00DA8753 /* ScriptCachedFrameData.h */; settings = {ATTRIBUTES = (Private, ); }; };
41FABD2D1F4DFE4A006A6C97 /* DOMCacheEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 41FABD2B1F4DFE42006A6C97 /* DOMCacheEngine.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 41FCD6B923CE015500C62567 /* SampleBufferDisplayLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 414598BE23C8AAB8002B9CC8 /* SampleBufferDisplayLayer.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 41FCD6BB23CE027700C62567 /* LocalSampleBufferDisplayLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 414598C023C8AD78002B9CC8 /* LocalSampleBufferDisplayLayer.h */; settings = {ATTRIBUTES = (Private, ); }; };
427DA71D13735DFA007C57FB /* JSServiceWorkerInternals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 427DA71B13735DFA007C57FB /* JSServiceWorkerInternals.cpp */; };
427DA71E13735DFA007C57FB /* JSServiceWorkerInternals.h in Headers */ = {isa = PBXBuildFile; fileRef = 427DA71C13735DFA007C57FB /* JSServiceWorkerInternals.h */; };
43107BE218CC19DE00CC18E8 /* SelectorPseudoTypeMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 43107BE118CC19DE00CC18E8 /* SelectorPseudoTypeMap.h */; };
@@ -7350,9 +7347,6 @@
413E00781DB0E4DE002341D2 /* MemoryRelease.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryRelease.h; sourceTree = "<group>"; };
413E007B1DB0E707002341D2 /* MemoryReleaseCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MemoryReleaseCocoa.mm; sourceTree = "<group>"; };
413FC4CD1FD1DD8C00541C4B /* ServiceWorkerClientQueryOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerClientQueryOptions.h; sourceTree = "<group>"; };
- 414598BE23C8AAB8002B9CC8 /* SampleBufferDisplayLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SampleBufferDisplayLayer.h; sourceTree = "<group>"; };
- 414598C023C8AD78002B9CC8 /* LocalSampleBufferDisplayLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocalSampleBufferDisplayLayer.h; sourceTree = "<group>"; };
- 414598C123C8AD79002B9CC8 /* LocalSampleBufferDisplayLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LocalSampleBufferDisplayLayer.mm; sourceTree = "<group>"; };
4147E2B21C88337F00A7E715 /* FetchBodyOwner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FetchBodyOwner.h; sourceTree = "<group>"; };
4147E2B31C89912600A7E715 /* FetchBodyOwner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FetchBodyOwner.cpp; sourceTree = "<group>"; };
4147E2B41C89912600A7E715 /* FetchLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FetchLoader.cpp; sourceTree = "<group>"; };
@@ -16332,7 +16326,6 @@
076F0D0A12B8192700C26AA4 /* MediaPlayerPrivateAVFoundation.h */,
CDBEAEAB19D92B6C00BEBA88 /* MediaSelectionGroupAVFObjC.h */,
CDBEAEAA19D92B6C00BEBA88 /* MediaSelectionGroupAVFObjC.mm */,
- 414598BE23C8AAB8002B9CC8 /* SampleBufferDisplayLayer.h */,
CD336F6317FA0A4D00DDDCD0 /* VideoTrackPrivateAVF.h */,
0709D7901AE5557E004E42F8 /* WebMediaSessionManagerMac.cpp */,
0709D7911AE5557E004E42F8 /* WebMediaSessionManagerMac.h */,
@@ -26757,8 +26750,6 @@
07AA6B6A166D019500D45671 /* InbandTextTrackPrivateAVFObjC.mm */,
07367DDD172CA67F00D861B9 /* InbandTextTrackPrivateLegacyAVFObjC.h */,
07367DDE172CA67F00D861B9 /* InbandTextTrackPrivateLegacyAVFObjC.mm */,
- 414598C023C8AD78002B9CC8 /* LocalSampleBufferDisplayLayer.h */,
- 414598C123C8AD79002B9CC8 /* LocalSampleBufferDisplayLayer.mm */,
078E43DB1ABB6F6F001C2FA6 /* MediaPlaybackTargetPickerMac.h */,
078E43DC1ABB6F6F001C2FA6 /* MediaPlaybackTargetPickerMac.mm */,
DF9AFD7013FC31D80015FEB7 /* MediaPlayerPrivateAVFoundationObjC.h */,
@@ -31408,7 +31399,6 @@
7633A72613D8B33A008501B6 /* LocaleToScriptMapping.h in Headers */,
A516E8B7136E04DB0076C3C0 /* LocalizedDateCache.h in Headers */,
935207BE09BD410A00F2038D /* LocalizedStrings.h in Headers */,
- 41FCD6BB23CE027700C62567 /* LocalSampleBufferDisplayLayer.h in Headers */,
BCE1C41B0D982980003B02F2 /* Location.h in Headers */,
6B4D412D23983F88002494C2 /* LoggedInStatus.h in Headers */,
A8239E0109B3CF8A00B60641 /* Logging.h in Headers */,
@@ -32193,7 +32183,6 @@
293EAE1F1356B2FE0067ACF9 /* RuntimeApplicationChecks.h in Headers */,
7C52229E1E1DAE47002CB8F7 /* RuntimeEnabledFeatures.h in Headers */,
CE7A6C28208537E200FA2B46 /* SameSiteInfo.h in Headers */,
- 41FCD6B923CE015500C62567 /* SampleBufferDisplayLayer.h in Headers */,
CDD7089718359F6F002B3DC6 /* SampleMap.h in Headers */,
49E911CB0EF86D47009D0CAF /* ScaleTransformOperation.h in Headers */,
5DFE8F570D16477C0076E937 /* ScheduledAction.h in Headers */,
@@ -33663,7 +33652,6 @@
41D28D0D2139E05800F4206F /* LibWebRTCStatsCollector.cpp in Sources */,
4186BD3E213EE3400001826F /* LibWebRTCUtils.cpp in Sources */,
9759E93E14EF1CF80026A2DD /* LoadableTextTrack.cpp in Sources */,
- 414598C223C8D177002B9CC8 /* LocalSampleBufferDisplayLayer.mm in Sources */,
FABE72FE1059C21100D999DD /* MathMLNames.cpp in Sources */,
2D9BF7051DBFBB24007A7D99 /* MediaEncryptedEvent.cpp in Sources */,
2D9BF7471DBFDC49007A7D99 /* MediaKeyMessageEvent.cpp in Sources */,
diff --git a/Source/WebCore/platform/graphics/avfoundation/SampleBufferDisplayLayer.h b/Source/WebCore/platform/graphics/avfoundation/SampleBufferDisplayLayer.h
deleted file mode 100644
index 4ff57d7..0000000
--- a/Source/WebCore/platform/graphics/avfoundation/SampleBufferDisplayLayer.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2020 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. ``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
- * 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.
- */
-
-#pragma once
-
-#include "PlatformLayer.h"
-#include <wtf/WeakPtr.h>
-
-namespace WTF {
-class MediaTime;
-}
-
-namespace WebCore {
-class IntSize;
-class MediaSample;
-
-class SampleBufferDisplayLayer {
-public:
- class Client : public CanMakeWeakPtr<Client> {
- public:
- virtual ~Client() = default;
- virtual void sampleBufferDisplayLayerStatusDidChange(SampleBufferDisplayLayer&) = 0;
- virtual void sampleBufferDisplayLayerBoundsDidChange(SampleBufferDisplayLayer&) = 0;
- virtual WTF::MediaTime streamTime() const = 0;
- };
-
- explicit SampleBufferDisplayLayer(Client&);
- virtual ~SampleBufferDisplayLayer() = default;
-
- virtual bool didFail() const = 0;
-
- virtual void updateDisplayMode(bool hideDisplayLayer, bool hideRootLayer) = 0;
-
- virtual CGRect bounds() const = 0;
- virtual void updateAffineTransform(CGAffineTransform) = 0;
- virtual void updateBoundsAndPosition(CGRect, CGPoint) = 0;
-
- virtual void flush() = 0;
- virtual void flushAndRemoveImage() = 0;
-
- virtual void enqueueSample(MediaSample&) = 0;
- virtual void clearEnqueuedSamples() = 0;
-
- virtual PlatformLayer* rootLayer() = 0;
-
-protected:
- WeakPtr<Client> m_client;
-};
-
-inline SampleBufferDisplayLayer::SampleBufferDisplayLayer(Client& client)
- : m_client(makeWeakPtr(client))
-{
-}
-
-}
diff --git a/Source/WebCore/platform/graphics/avfoundation/objc/LocalSampleBufferDisplayLayer.h b/Source/WebCore/platform/graphics/avfoundation/objc/LocalSampleBufferDisplayLayer.h
deleted file mode 100644
index 29cdea4..0000000
--- a/Source/WebCore/platform/graphics/avfoundation/objc/LocalSampleBufferDisplayLayer.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2020 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. ``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
- * 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.
- */
-
-#pragma once
-
-#if ENABLE(MEDIA_STREAM) && USE(AVFOUNDATION)
-
-#include "SampleBufferDisplayLayer.h"
-#include <wtf/Deque.h>
-#include <wtf/Forward.h>
-#include <wtf/RetainPtr.h>
-
-OBJC_CLASS AVSampleBufferDisplayLayer;
-OBJC_CLASS WebAVSampleBufferStatusChangeListener;
-
-namespace WebCore {
-
-class WEBCORE_EXPORT LocalSampleBufferDisplayLayer final : public SampleBufferDisplayLayer, public CanMakeWeakPtr<LocalSampleBufferDisplayLayer> {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- static std::unique_ptr<SampleBufferDisplayLayer> create(Client&, bool hideRootLayer, IntSize);
-
- LocalSampleBufferDisplayLayer(RetainPtr<AVSampleBufferDisplayLayer>&&, Client&, bool hideRootLayer, IntSize);
- ~LocalSampleBufferDisplayLayer();
-
- // API used by WebAVSampleBufferStatusChangeListener
- void layerStatusDidChange();
- void layerErrorDidChange();
- void rootLayerBoundsDidChange();
-
- PlatformLayer* displayLayer();
-
- PlatformLayer* rootLayer() final;
-
-private:
- bool didFail() const final;
-
- void updateDisplayMode(bool hideDisplayLayer, bool hideRootLayer) final;
-
- CGRect bounds() const final;
- void updateAffineTransform(CGAffineTransform) final;
- void updateBoundsAndPosition(CGRect, CGPoint) final;
-
- void flush() final;
- void flushAndRemoveImage() final;
-
- void enqueueSample(MediaSample&) final;
- void clearEnqueuedSamples() final;
-
- void ensureLayers();
-
- void removeOldSamplesFromPendingQueue();
- void addSampleToPendingQueue(MediaSample&);
- void requestNotificationWhenReadyForVideoData();
-
-private:
- RetainPtr<WebAVSampleBufferStatusChangeListener> m_statusChangeListener;
- RetainPtr<AVSampleBufferDisplayLayer> m_sampleBufferDisplayLayer;
- RetainPtr<PlatformLayer> m_rootLayer;
-
- using PendingSampleQueue = Deque<Ref<MediaSample>>;
- PendingSampleQueue m_pendingVideoSampleQueue;
-};
-
-}
-
-#endif // ENABLE(MEDIA_STREAM) && USE(AVFOUNDATION)
diff --git a/Source/WebCore/platform/graphics/avfoundation/objc/LocalSampleBufferDisplayLayer.mm b/Source/WebCore/platform/graphics/avfoundation/objc/LocalSampleBufferDisplayLayer.mm
deleted file mode 100644
index f0c9cc7..0000000
--- a/Source/WebCore/platform/graphics/avfoundation/objc/LocalSampleBufferDisplayLayer.mm
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * Copyright (C) 2020 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. ``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
- * 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.
- */
-
-#import "config.h"
-#import "LocalSampleBufferDisplayLayer.h"
-
-#if ENABLE(MEDIA_STREAM) && USE(AVFOUNDATION)
-
-#import "Color.h"
-#import "IntSize.h"
-#import "MediaSample.h"
-
-#import <AVFoundation/AVSampleBufferDisplayLayer.h>
-#import <QuartzCore/CALayer.h>
-#import <QuartzCore/CATransaction.h>
-
-#import <wtf/MainThread.h>
-
-#import <pal/cocoa/AVFoundationSoftLink.h>
-
-using namespace WebCore;
-
-@interface WebAVSampleBufferStatusChangeListener : NSObject {
- LocalSampleBufferDisplayLayer* _parent;
-}
-
-- (id)initWithParent:(LocalSampleBufferDisplayLayer*)callback;
-- (void)invalidate;
-- (void)beginObservingLayers;
-- (void)stopObservingLayers;
-@end
-
-@implementation WebAVSampleBufferStatusChangeListener
-
-- (id)initWithParent:(LocalSampleBufferDisplayLayer*)parent
-{
- if (!(self = [super init]))
- return nil;
-
- _parent = parent;
-
- return self;
-}
-
-- (void)dealloc
-{
- [self invalidate];
- [super dealloc];
-}
-
-- (void)invalidate
-{
- [self stopObservingLayers];
- _parent = nullptr;
-}
-
-- (void)beginObservingLayers
-{
- ASSERT(_parent);
- ASSERT(_parent->displayLayer());
- ASSERT(_parent->rootLayer());
-
- [_parent->displayLayer() addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
- [_parent->displayLayer() addObserver:self forKeyPath:@"error" options:NSKeyValueObservingOptionNew context:nil];
- [_parent->rootLayer() addObserver:self forKeyPath:@"bounds" options:NSKeyValueObservingOptionNew context:nil];
-}
-
-- (void)stopObservingLayers
-{
- if (!_parent)
- return;
-
- if (_parent->displayLayer()) {
- [_parent->displayLayer() removeObserver:self forKeyPath:@"status"];
- [_parent->displayLayer() removeObserver:self forKeyPath:@"error"];
- }
- if (_parent->rootLayer())
- [_parent->rootLayer() removeObserver:self forKeyPath:@"bounds"];
-}
-
-- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
-{
- UNUSED_PARAM(context);
- UNUSED_PARAM(keyPath);
- ASSERT(_parent);
-
- if (!_parent)
- return;
-
- if ([object isKindOfClass:PAL::getAVSampleBufferDisplayLayerClass()]) {
- ASSERT(object == _parent->displayLayer());
-
- if ([keyPath isEqualToString:@"status"]) {
- callOnMainThread([protectedSelf = RetainPtr<WebAVSampleBufferStatusChangeListener>(self)] {
- if (!protectedSelf->_parent)
- return;
-
- protectedSelf->_parent->layerStatusDidChange();
- });
- return;
- }
-
- if ([keyPath isEqualToString:@"error"]) {
- callOnMainThread([protectedSelf = RetainPtr<WebAVSampleBufferStatusChangeListener>(self)] {
- if (!protectedSelf->_parent)
- return;
-
- protectedSelf->_parent->layerErrorDidChange();
- });
- return;
- }
- }
-
- if ([[change valueForKey:NSKeyValueChangeNotificationIsPriorKey] boolValue])
- return;
-
- if ((CALayer *)object == _parent->rootLayer()) {
- if ([keyPath isEqualToString:@"bounds"]) {
- if (!_parent)
- return;
-
- if (isMainThread()) {
- _parent->rootLayerBoundsDidChange();
- return;
- }
-
- callOnMainThread([protectedSelf = RetainPtr<WebAVSampleBufferStatusChangeListener>(self)] {
- if (!protectedSelf->_parent)
- return;
-
- protectedSelf->_parent->rootLayerBoundsDidChange();
- });
- }
- }
-
-}
-@end
-
-namespace WebCore {
-
-static void runWithoutAnimations(const WTF::Function<void()>& function)
-{
- [CATransaction begin];
- [CATransaction setAnimationDuration:0];
- [CATransaction setDisableActions:YES];
- function();
- [CATransaction commit];
-}
-
-std::unique_ptr<SampleBufferDisplayLayer> LocalSampleBufferDisplayLayer::create(Client& client, bool hideRootLayer, IntSize size)
-{
- auto sampleBufferDisplayLayer = adoptNS([PAL::allocAVSampleBufferDisplayLayerInstance() init]);
- if (!sampleBufferDisplayLayer)
- return nullptr;
-
- return makeUnique<LocalSampleBufferDisplayLayer>(WTFMove(sampleBufferDisplayLayer), client, hideRootLayer, size);
-}
-
-LocalSampleBufferDisplayLayer::LocalSampleBufferDisplayLayer(RetainPtr<AVSampleBufferDisplayLayer>&& sampleBufferDisplayLayer, Client& client, bool hideRootLayer, IntSize size)
- : SampleBufferDisplayLayer(client)
- , m_statusChangeListener(adoptNS([[WebAVSampleBufferStatusChangeListener alloc] initWithParent:this]))
- , m_sampleBufferDisplayLayer(WTFMove(sampleBufferDisplayLayer))
-{
- m_sampleBufferDisplayLayer.get().backgroundColor = cachedCGColor(Color::black);
- m_sampleBufferDisplayLayer.get().anchorPoint = { .5, .5 };
- m_sampleBufferDisplayLayer.get().needsDisplayOnBoundsChange = YES;
- m_sampleBufferDisplayLayer.get().videoGravity = AVLayerVideoGravityResizeAspectFill;
-
- m_rootLayer = adoptNS([[CALayer alloc] init]);
- m_rootLayer.get().hidden = hideRootLayer;
-
- m_rootLayer.get().backgroundColor = cachedCGColor(Color::black);
- m_rootLayer.get().needsDisplayOnBoundsChange = YES;
-
- m_rootLayer.get().bounds = CGRectMake(0, 0, size.width(), size.height());
-
- [m_statusChangeListener beginObservingLayers];
-
- [m_rootLayer addSublayer:m_sampleBufferDisplayLayer.get()];
-
-#ifndef NDEBUG
- [m_sampleBufferDisplayLayer setName:@"LocalSampleBufferDisplayLayer AVSampleBufferDisplayLayer"];
- [m_rootLayer setName:@"LocalSampleBufferDisplayLayer AVSampleBufferDisplayLayer parent"];
-#endif
-}
-
-LocalSampleBufferDisplayLayer::~LocalSampleBufferDisplayLayer()
-{
- [m_statusChangeListener stopObservingLayers];
-
- m_pendingVideoSampleQueue.clear();
-
- [m_sampleBufferDisplayLayer stopRequestingMediaData];
- [m_sampleBufferDisplayLayer flush];
- m_sampleBufferDisplayLayer = nullptr;
-
- m_rootLayer = nullptr;
-}
-
-void LocalSampleBufferDisplayLayer::layerStatusDidChange()
-{
- ASSERT(isMainThread());
- if (m_sampleBufferDisplayLayer.get().status != AVQueuedSampleBufferRenderingStatusRendering)
- return;
- if (!m_client)
- return;
- m_client->sampleBufferDisplayLayerStatusDidChange(*this);
-}
-
-void LocalSampleBufferDisplayLayer::layerErrorDidChange()
-{
- ASSERT(isMainThread());
- // FIXME: Log error.
-}
-
-void LocalSampleBufferDisplayLayer::rootLayerBoundsDidChange()
-{
- ASSERT(isMainThread());
- if (!m_client)
- return;
- m_client->sampleBufferDisplayLayerBoundsDidChange(*this);
-}
-
-PlatformLayer* LocalSampleBufferDisplayLayer::displayLayer()
-{
- return m_sampleBufferDisplayLayer.get();
-}
-
-PlatformLayer* LocalSampleBufferDisplayLayer::rootLayer()
-{
- return m_rootLayer.get();
-}
-
-bool LocalSampleBufferDisplayLayer::didFail() const
-{
- return [m_sampleBufferDisplayLayer status] == AVQueuedSampleBufferRenderingStatusFailed;
-}
-
-void LocalSampleBufferDisplayLayer::updateDisplayMode(bool hideDisplayLayer, bool hideRootLayer)
-{
- if (m_rootLayer.get().hidden == hideRootLayer && m_sampleBufferDisplayLayer.get().hidden == hideDisplayLayer)
- return;
-
- runWithoutAnimations([&] {
- m_sampleBufferDisplayLayer.get().hidden = hideDisplayLayer;
- m_rootLayer.get().hidden = hideRootLayer;
- });
-}
-
-CGRect LocalSampleBufferDisplayLayer::bounds() const
-{
- return m_rootLayer.get().bounds;
-}
-
-void LocalSampleBufferDisplayLayer::updateAffineTransform(CGAffineTransform transform)
-{
- runWithoutAnimations([&] {
- m_sampleBufferDisplayLayer.get().affineTransform = transform;
- });
-}
-
-void LocalSampleBufferDisplayLayer::updateBoundsAndPosition(CGRect videoBounds, CGPoint position)
-{
- runWithoutAnimations([&] {
- m_sampleBufferDisplayLayer.get().bounds = videoBounds;
- m_sampleBufferDisplayLayer.get().position = position;
- });
-}
-
-void LocalSampleBufferDisplayLayer::flush()
-{
- [m_sampleBufferDisplayLayer flush];
-}
-
-void LocalSampleBufferDisplayLayer::flushAndRemoveImage()
-{
- [m_sampleBufferDisplayLayer flushAndRemoveImage];
-}
-
-void LocalSampleBufferDisplayLayer::enqueueSample(MediaSample& sample)
-{
- if (![m_sampleBufferDisplayLayer isReadyForMoreMediaData]) {
- addSampleToPendingQueue(sample);
- requestNotificationWhenReadyForVideoData();
- return;
- }
-
- [m_sampleBufferDisplayLayer enqueueSampleBuffer:sample.platformSample().sample.cmSampleBuffer];
-}
-
-void LocalSampleBufferDisplayLayer::removeOldSamplesFromPendingQueue()
-{
- if (m_pendingVideoSampleQueue.isEmpty() || !m_client)
- return;
-
- auto decodeTime = m_pendingVideoSampleQueue.first()->decodeTime();
- if (!decodeTime.isValid() || decodeTime < MediaTime::zeroTime()) {
- while (m_pendingVideoSampleQueue.size() > 5)
- m_pendingVideoSampleQueue.removeFirst();
-
- return;
- }
-
- MediaTime now = m_client->streamTime();
- while (!m_pendingVideoSampleQueue.isEmpty()) {
- if (m_pendingVideoSampleQueue.first()->decodeTime() > now)
- break;
- m_pendingVideoSampleQueue.removeFirst();
- }
-}
-
-void LocalSampleBufferDisplayLayer::addSampleToPendingQueue(MediaSample& sample)
-{
- removeOldSamplesFromPendingQueue();
- m_pendingVideoSampleQueue.append(sample);
-}
-
-void LocalSampleBufferDisplayLayer::clearEnqueuedSamples()
-{
- m_pendingVideoSampleQueue.clear();
-}
-
-void LocalSampleBufferDisplayLayer::requestNotificationWhenReadyForVideoData()
-{
- auto weakThis = makeWeakPtr(*this);
- [m_sampleBufferDisplayLayer requestMediaDataWhenReadyOnQueue:dispatch_get_main_queue() usingBlock:^{
- if (!weakThis)
- return;
-
- [m_sampleBufferDisplayLayer stopRequestingMediaData];
-
- while (!m_pendingVideoSampleQueue.isEmpty()) {
- if (![m_sampleBufferDisplayLayer isReadyForMoreMediaData]) {
- requestNotificationWhenReadyForVideoData();
- return;
- }
-
- auto sample = m_pendingVideoSampleQueue.takeFirst();
- enqueueSample(sample.get());
- }
- }];
-}
-
-}
-
-#endif
diff --git a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h b/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h
index d9af27a..0340a8d 100644
--- a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h
+++ b/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h
@@ -30,10 +30,10 @@
#include "MediaPlayerPrivate.h"
#include "MediaSample.h"
#include "MediaStreamPrivate.h"
-#include "SampleBufferDisplayLayer.h"
#include <wtf/Deque.h>
#include <wtf/Forward.h>
#include <wtf/LoggerHelper.h>
+#include <wtf/WeakPtr.h>
OBJC_CLASS AVSampleBufferDisplayLayer;
OBJC_CLASS WebAVSampleBufferStatusChangeListener;
@@ -51,7 +51,7 @@
class VideoFullscreenLayerManagerObjC;
class VideoTrackPrivateMediaStream;
-class MediaPlayerPrivateMediaStreamAVFObjC final : public MediaPlayerPrivateInterface, private MediaStreamPrivate::Observer, private MediaStreamTrackPrivate::Observer, public SampleBufferDisplayLayer::Client
+class MediaPlayerPrivateMediaStreamAVFObjC final : public CanMakeWeakPtr<MediaPlayerPrivateMediaStreamAVFObjC>, public MediaPlayerPrivateInterface, private MediaStreamPrivate::Observer, private MediaStreamTrackPrivate::Observer
#if !RELEASE_LOG_DISABLED
, private LoggerHelper
#endif
@@ -75,6 +75,13 @@
void ensureLayers();
void destroyLayers();
+ void layerStatusDidChange(AVSampleBufferDisplayLayer*);
+ void layerErrorDidChange(AVSampleBufferDisplayLayer*);
+ void backgroundLayerBoundsChanged();
+
+ PlatformLayer* displayLayer();
+ PlatformLayer* backgroundLayer();
+
#if !RELEASE_LOG_DISABLED
const Logger& logger() const final { return m_logger.get(); }
const char* logClassName() const override { return "MediaPlayerPrivateMediaStreamAVFObjC"; }
@@ -130,6 +137,10 @@
void flushRenderers();
+ using PendingSampleQueue = Deque<Ref<MediaSample>>;
+ void addSampleToPendingQueue(PendingSampleQueue&, MediaSample&);
+ void removeOldSamplesFromPendingQueue(PendingSampleQueue&);
+
MediaTime calculateTimelineOffset(const MediaSample&, double);
void enqueueVideoSample(MediaStreamTrackPrivate&, MediaSample&);
@@ -201,7 +212,7 @@
void setVideoFullscreenLayer(PlatformLayer*, WTF::Function<void()>&& completionHandler) override;
void setVideoFullscreenFrame(FloatRect) override;
- MediaTime streamTime() const final;
+ MediaTime streamTime() const;
AudioSourceProvider* audioSourceProvider() final;
@@ -209,11 +220,14 @@
void applicationDidBecomeActive() final;
- bool hideRootLayer() const { return (!m_activeVideoTrack || m_waitingForFirstImage) && m_displayMode != PaintItBlack; }
+ bool hideBackgroundLayer() const { return (!m_activeVideoTrack || m_waitingForFirstImage) && m_displayMode != PaintItBlack; }
MediaPlayer* m_player { nullptr };
RefPtr<MediaStreamPrivate> m_mediaStreamPrivate;
RefPtr<MediaStreamTrackPrivate> m_activeVideoTrack;
+ RetainPtr<WebAVSampleBufferStatusChangeListener> m_statusChangeListener;
+ RetainPtr<AVSampleBufferDisplayLayer> m_sampleBufferDisplayLayer;
+ RetainPtr<PlatformLayer> m_backgroundLayer;
std::unique_ptr<PAL::Clock> m_clock;
MediaTime m_pausedTime;
@@ -230,6 +244,7 @@
HashMap<String, RefPtr<AudioTrackPrivateMediaStream>> m_audioTrackMap;
HashMap<String, RefPtr<VideoTrackPrivateMediaStream>> m_videoTrackMap;
+ PendingSampleQueue m_pendingVideoSampleQueue;
MediaPlayer::NetworkState m_networkState { MediaPlayer::NetworkState::Empty };
MediaPlayer::ReadyState m_readyState { MediaPlayer::ReadyState::HaveNothing };
@@ -239,13 +254,8 @@
PlaybackState m_playbackState { PlaybackState::None };
MediaSample::VideoRotation m_videoRotation { MediaSample::VideoRotation::None };
CGAffineTransform m_videoTransform;
- std::unique_ptr<SampleBufferDisplayLayer> m_sampleBufferDisplayLayer;
std::unique_ptr<VideoFullscreenLayerManagerObjC> m_videoFullscreenLayerManager;
- // SampleBufferDisplayLayer::Client
- void sampleBufferDisplayLayerStatusDidChange(SampleBufferDisplayLayer&) final;
- void sampleBufferDisplayLayerBoundsDidChange(SampleBufferDisplayLayer&) final;
-
#if !RELEASE_LOG_DISABLED
Ref<const Logger> m_logger;
const void* m_logIdentifier;
diff --git a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm b/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm
index df9e205..5fcf9ab 100644
--- a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm
+++ b/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015-2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,16 +31,20 @@
#import "AudioTrackPrivateMediaStream.h"
#import "GraphicsContextCG.h"
#import "Logging.h"
-#import "LocalSampleBufferDisplayLayer.h"
#import "MediaStreamPrivate.h"
#import "PixelBufferConformerCV.h"
#import "VideoFullscreenLayerManagerObjC.h"
#import "VideoTrackPrivateMediaStream.h"
+#import <AVFoundation/AVSampleBufferDisplayLayer.h>
#import <CoreGraphics/CGAffineTransform.h>
+#import <QuartzCore/CALayer.h>
+#import <QuartzCore/CATransaction.h>
#import <objc_runtime.h>
#import <pal/avfoundation/MediaTimeAVFoundation.h>
#import <pal/spi/mac/AVFoundationSPI.h>
#import <pal/system/Clock.h>
+#import <wtf/Deque.h>
+#import <wtf/Function.h>
#import <wtf/MainThread.h>
#import <wtf/NeverDestroyed.h>
@@ -48,6 +52,127 @@
#import <pal/cf/CoreMediaSoftLink.h>
#import <pal/cocoa/AVFoundationSoftLink.h>
+using namespace WebCore;
+
+@interface WebAVSampleBufferStatusChangeListener : NSObject {
+ MediaPlayerPrivateMediaStreamAVFObjC* _parent;
+}
+
+- (id)initWithParent:(MediaPlayerPrivateMediaStreamAVFObjC*)callback;
+- (void)invalidate;
+- (void)beginObservingLayers;
+- (void)stopObservingLayers;
+@end
+
+@implementation WebAVSampleBufferStatusChangeListener
+
+- (id)initWithParent:(MediaPlayerPrivateMediaStreamAVFObjC*)parent
+{
+ if (!(self = [super init]))
+ return nil;
+
+ _parent = parent;
+
+ return self;
+}
+
+- (void)dealloc
+{
+ [self invalidate];
+ [super dealloc];
+}
+
+- (void)invalidate
+{
+ [self stopObservingLayers];
+ _parent = nullptr;
+}
+
+- (void)beginObservingLayers
+{
+ ASSERT(_parent);
+ ASSERT(_parent->displayLayer());
+ ASSERT(_parent->backgroundLayer());
+
+ [_parent->displayLayer() addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
+ [_parent->displayLayer() addObserver:self forKeyPath:@"error" options:NSKeyValueObservingOptionNew context:nil];
+ [_parent->backgroundLayer() addObserver:self forKeyPath:@"bounds" options:NSKeyValueObservingOptionNew context:nil];
+}
+
+- (void)stopObservingLayers
+{
+ if (!_parent)
+ return;
+
+ if (_parent->displayLayer()) {
+ [_parent->displayLayer() removeObserver:self forKeyPath:@"status"];
+ [_parent->displayLayer() removeObserver:self forKeyPath:@"error"];
+ }
+ if (_parent->backgroundLayer())
+ [_parent->backgroundLayer() removeObserver:self forKeyPath:@"bounds"];
+}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
+{
+ UNUSED_PARAM(context);
+ UNUSED_PARAM(keyPath);
+ ASSERT(_parent);
+
+ if (!_parent)
+ return;
+
+ if ([object isKindOfClass:PAL::getAVSampleBufferDisplayLayerClass()]) {
+ RetainPtr<AVSampleBufferDisplayLayer> layer = (AVSampleBufferDisplayLayer *)object;
+ ASSERT(layer.get() == _parent->displayLayer());
+
+ if ([keyPath isEqualToString:@"status"]) {
+ RetainPtr<NSNumber> status = [change valueForKey:NSKeyValueChangeNewKey];
+ callOnMainThread([protectedSelf = RetainPtr<WebAVSampleBufferStatusChangeListener>(self), layer = WTFMove(layer), status = WTFMove(status)] {
+ if (!protectedSelf->_parent)
+ return;
+
+ protectedSelf->_parent->layerStatusDidChange(layer.get());
+ });
+ return;
+ }
+
+ if ([keyPath isEqualToString:@"error"]) {
+ RetainPtr<NSNumber> status = [change valueForKey:NSKeyValueChangeNewKey];
+ callOnMainThread([protectedSelf = RetainPtr<WebAVSampleBufferStatusChangeListener>(self), layer = WTFMove(layer), status = WTFMove(status)] {
+ if (!protectedSelf->_parent)
+ return;
+
+ protectedSelf->_parent->layerErrorDidChange(layer.get());
+ });
+ return;
+ }
+ }
+
+ if ([[change valueForKey:NSKeyValueChangeNotificationIsPriorKey] boolValue])
+ return;
+
+ if ((CALayer *)object == _parent->backgroundLayer()) {
+ if ([keyPath isEqualToString:@"bounds"]) {
+ if (!_parent)
+ return;
+
+ if (isMainThread()) {
+ _parent->backgroundLayerBoundsChanged();
+ return;
+ }
+
+ callOnMainThread([protectedSelf = RetainPtr<WebAVSampleBufferStatusChangeListener>(self)] {
+ if (!protectedSelf->_parent)
+ return;
+
+ protectedSelf->_parent->backgroundLayerBoundsChanged();
+ });
+ }
+ }
+
+}
+@end
+
namespace WebCore {
using namespace PAL;
@@ -58,6 +183,7 @@
MediaPlayerPrivateMediaStreamAVFObjC::MediaPlayerPrivateMediaStreamAVFObjC(MediaPlayer* player)
: m_player(player)
+ , m_statusChangeListener(adoptNS([[WebAVSampleBufferStatusChangeListener alloc] initWithParent:this]))
, m_clock(PAL::Clock::create())
, m_videoFullscreenLayerManager(makeUnique<VideoFullscreenLayerManagerObjC>())
#if !RELEASE_LOG_DISABLED
@@ -72,6 +198,8 @@
{
INFO_LOG(LOGIDENTIFIER);
+ [m_statusChangeListener invalidate];
+
for (const auto& track : m_audioTrackMap.values())
track->pause();
@@ -141,6 +269,33 @@
#pragma mark -
#pragma mark AVSampleBuffer Methods
+void MediaPlayerPrivateMediaStreamAVFObjC::removeOldSamplesFromPendingQueue(PendingSampleQueue& queue)
+{
+ if (queue.isEmpty())
+ return;
+
+ auto decodeTime = queue.first()->decodeTime();
+ if (!decodeTime.isValid() || decodeTime < MediaTime::zeroTime()) {
+ while (queue.size() > 5)
+ queue.removeFirst();
+
+ return;
+ }
+
+ MediaTime now = streamTime();
+ while (!queue.isEmpty()) {
+ if (queue.first()->decodeTime() > now)
+ break;
+ queue.removeFirst();
+ }
+}
+
+void MediaPlayerPrivateMediaStreamAVFObjC::addSampleToPendingQueue(PendingSampleQueue& queue, MediaSample& sample)
+{
+ removeOldSamplesFromPendingQueue(queue);
+ queue.append(sample);
+}
+
MediaTime MediaPlayerPrivateMediaStreamAVFObjC::calculateTimelineOffset(const MediaSample& sample, double latency)
{
MediaTime sampleTime = sample.outputPresentationTime();
@@ -175,19 +330,37 @@
return m_videoTransform;
}
+static void runWithoutAnimations(const WTF::Function<void()>& function)
+{
+ [CATransaction begin];
+ [CATransaction setAnimationDuration:0];
+ [CATransaction setDisableActions:YES];
+ function();
+ [CATransaction commit];
+}
+
void MediaPlayerPrivateMediaStreamAVFObjC::enqueueCorrectedVideoSample(MediaSample& sample)
{
if (m_sampleBufferDisplayLayer) {
- if (m_sampleBufferDisplayLayer->didFail())
+ if ([m_sampleBufferDisplayLayer status] == AVQueuedSampleBufferRenderingStatusFailed)
return;
if (sample.videoRotation() != m_videoRotation || sample.videoMirrored() != m_videoMirrored) {
m_videoRotation = sample.videoRotation();
m_videoMirrored = sample.videoMirrored();
- m_sampleBufferDisplayLayer->updateAffineTransform(videoTransformationMatrix(sample, true));
- updateDisplayLayer();
+ runWithoutAnimations([this, &sample] {
+ m_sampleBufferDisplayLayer.get().affineTransform = videoTransformationMatrix(sample, true);
+ updateDisplayLayer();
+ });
}
- m_sampleBufferDisplayLayer->enqueueSample(sample);
+
+ if (![m_sampleBufferDisplayLayer isReadyForMoreMediaData]) {
+ addSampleToPendingQueue(m_pendingVideoSampleQueue, sample);
+ requestNotificationWhenReadyForVideoData();
+ return;
+ }
+
+ [m_sampleBufferDisplayLayer enqueueSampleBuffer:sample.platformSample().sample.cmSampleBuffer];
}
if (!m_hasEverEnqueuedVideoFrame) {
@@ -242,26 +415,61 @@
}
}
+void MediaPlayerPrivateMediaStreamAVFObjC::requestNotificationWhenReadyForVideoData()
+{
+ auto weakThis = makeWeakPtr(*this);
+ [m_sampleBufferDisplayLayer requestMediaDataWhenReadyOnQueue:dispatch_get_main_queue() usingBlock:^ {
+ if (!weakThis)
+ return;
+
+ [m_sampleBufferDisplayLayer stopRequestingMediaData];
+
+ if (!m_activeVideoTrack) {
+ m_pendingVideoSampleQueue.clear();
+ return;
+ }
+
+ while (!m_pendingVideoSampleQueue.isEmpty()) {
+ if (![m_sampleBufferDisplayLayer isReadyForMoreMediaData]) {
+ requestNotificationWhenReadyForVideoData();
+ return;
+ }
+
+ auto sample = m_pendingVideoSampleQueue.takeFirst();
+ enqueueVideoSample(*m_activeVideoTrack.get(), sample.get());
+ }
+ }];
+}
+
AudioSourceProvider* MediaPlayerPrivateMediaStreamAVFObjC::audioSourceProvider()
{
// FIXME: This should return a mix of all audio tracks - https://bugs.webkit.org/show_bug.cgi?id=160305
return nullptr;
}
-void MediaPlayerPrivateMediaStreamAVFObjC::sampleBufferDisplayLayerStatusDidChange(SampleBufferDisplayLayer& layer)
+void MediaPlayerPrivateMediaStreamAVFObjC::layerErrorDidChange(AVSampleBufferDisplayLayer* layer)
{
- ASSERT(&layer == m_sampleBufferDisplayLayer.get());
UNUSED_PARAM(layer);
- if (!m_activeVideoTrack)
+ ERROR_LOG(LOGIDENTIFIER, "error = ", [[layer.error localizedDescription] UTF8String]);
+}
+
+void MediaPlayerPrivateMediaStreamAVFObjC::layerStatusDidChange(AVSampleBufferDisplayLayer* layer)
+{
+ ALWAYS_LOG(LOGIDENTIFIER, "status = ", (int)layer.status);
+
+ if (layer.status != AVQueuedSampleBufferRenderingStatusRendering)
+ return;
+ if (!m_sampleBufferDisplayLayer || !m_activeVideoTrack || layer != m_sampleBufferDisplayLayer)
return;
- if (auto track = m_videoTrackMap.get(m_activeVideoTrack->id()))
+ auto track = m_videoTrackMap.get(m_activeVideoTrack->id());
+ if (track)
track->setTimelineOffset(MediaTime::invalidTime());
}
void MediaPlayerPrivateMediaStreamAVFObjC::applicationDidBecomeActive()
{
- if (m_sampleBufferDisplayLayer && m_sampleBufferDisplayLayer->didFail()) {
+ if (m_sampleBufferDisplayLayer && [m_sampleBufferDisplayLayer status] == AVQueuedSampleBufferRenderingStatusFailed) {
flushRenderers();
if (m_imagePainter.mediaSample)
enqueueCorrectedVideoSample(*m_imagePainter.mediaSample);
@@ -272,7 +480,7 @@
void MediaPlayerPrivateMediaStreamAVFObjC::flushRenderers()
{
if (m_sampleBufferDisplayLayer)
- m_sampleBufferDisplayLayer->flush();
+ [m_sampleBufferDisplayLayer flush];
}
void MediaPlayerPrivateMediaStreamAVFObjC::ensureLayers()
@@ -283,24 +491,51 @@
if (!m_mediaStreamPrivate || !m_mediaStreamPrivate->activeVideoTrack() || !m_mediaStreamPrivate->activeVideoTrack()->enabled())
return;
- auto size = snappedIntRect(m_player->playerContentBoxRect()).size();
- m_sampleBufferDisplayLayer = LocalSampleBufferDisplayLayer::create(*this, hideRootLayer(), size);
-
+ m_sampleBufferDisplayLayer = adoptNS([PAL::allocAVSampleBufferDisplayLayerInstance() init]);
if (!m_sampleBufferDisplayLayer) {
- ERROR_LOG(LOGIDENTIFIER, "Creating the SampleBufferDisplayLayer failed.");
+ ERROR_LOG(LOGIDENTIFIER, "+[AVSampleBufferDisplayLayer alloc] failed.");
return;
}
+ m_sampleBufferDisplayLayer.get().backgroundColor = cachedCGColor(Color::black);
+ m_sampleBufferDisplayLayer.get().anchorPoint = { .5, .5 };
+ m_sampleBufferDisplayLayer.get().needsDisplayOnBoundsChange = YES;
+ m_sampleBufferDisplayLayer.get().videoGravity = AVLayerVideoGravityResizeAspectFill;
+
+ m_backgroundLayer = adoptNS([[CALayer alloc] init]);
+ m_backgroundLayer.get().hidden = hideBackgroundLayer();
+
+ m_backgroundLayer.get().backgroundColor = cachedCGColor(Color::black);
+ m_backgroundLayer.get().needsDisplayOnBoundsChange = YES;
+
+ auto size = snappedIntRect(m_player->playerContentBoxRect()).size();
+ m_backgroundLayer.get().bounds = CGRectMake(0, 0, size.width(), size.height());
+
+ [m_statusChangeListener beginObservingLayers];
+
+ [m_backgroundLayer addSublayer:m_sampleBufferDisplayLayer.get()];
+
+#ifndef NDEBUG
+ [m_sampleBufferDisplayLayer setName:@"MediaPlayerPrivateMediaStreamAVFObjC AVSampleBufferDisplayLayer"];
+ [m_backgroundLayer setName:@"MediaPlayerPrivateMediaStreamAVFObjC AVSampleBufferDisplayLayer parent"];
+#endif
+
updateRenderingMode();
updateDisplayLayer();
- m_videoFullscreenLayerManager->setVideoLayer(m_sampleBufferDisplayLayer->rootLayer(), size);
+ m_videoFullscreenLayerManager->setVideoLayer(m_backgroundLayer.get(), size);
}
void MediaPlayerPrivateMediaStreamAVFObjC::destroyLayers()
{
- if (m_sampleBufferDisplayLayer)
+ [m_statusChangeListener stopObservingLayers];
+ if (m_sampleBufferDisplayLayer) {
+ m_pendingVideoSampleQueue.clear();
+ [m_sampleBufferDisplayLayer stopRequestingMediaData];
+ [m_sampleBufferDisplayLayer flush];
m_sampleBufferDisplayLayer = nullptr;
+ }
+ m_backgroundLayer = nullptr;
updateRenderingMode();
@@ -367,12 +602,22 @@
PlatformLayer* MediaPlayerPrivateMediaStreamAVFObjC::platformLayer() const
{
- if (!m_sampleBufferDisplayLayer || !m_sampleBufferDisplayLayer->rootLayer() || m_displayMode == None)
+ if (!m_backgroundLayer || m_displayMode == None)
return nullptr;
return m_videoFullscreenLayerManager->videoInlineLayer();
}
+PlatformLayer* MediaPlayerPrivateMediaStreamAVFObjC::displayLayer()
+{
+ return m_sampleBufferDisplayLayer.get();
+}
+
+PlatformLayer* MediaPlayerPrivateMediaStreamAVFObjC::backgroundLayer()
+{
+ return m_backgroundLayer.get();
+}
+
MediaPlayerPrivateMediaStreamAVFObjC::DisplayMode MediaPlayerPrivateMediaStreamAVFObjC::currentDisplayMode() const
{
if (m_intrinsicSize.isEmpty() || !metaDataAvailable() || !m_sampleBufferDisplayLayer)
@@ -408,8 +653,18 @@
INFO_LOG(LOGIDENTIFIER, "updated to ", static_cast<int>(displayMode));
m_displayMode = displayMode;
- if (m_sampleBufferDisplayLayer)
- m_sampleBufferDisplayLayer->updateDisplayMode(m_displayMode < PausedImage, hideRootLayer());
+ auto hidden = m_displayMode < PausedImage;
+ if (m_sampleBufferDisplayLayer && m_sampleBufferDisplayLayer.get().hidden != hidden) {
+ runWithoutAnimations([this, hidden] {
+ m_sampleBufferDisplayLayer.get().hidden = hidden;
+ });
+ }
+ hidden = hideBackgroundLayer();
+ if (m_backgroundLayer && m_backgroundLayer.get().hidden != hidden) {
+ runWithoutAnimations([this, hidden] {
+ m_backgroundLayer.get().hidden = hidden;
+ });
+ }
return true;
}
@@ -768,11 +1023,8 @@
m_waitingForFirstImage = true;
}
ensureLayers();
- if (m_sampleBufferDisplayLayer) {
- if (!m_activeVideoTrack)
- m_sampleBufferDisplayLayer->clearEnqueuedSamples();
- m_sampleBufferDisplayLayer->updateDisplayMode(hideVideoLayer || m_displayMode < PausedImage, hideRootLayer());
- }
+ m_sampleBufferDisplayLayer.get().hidden = hideVideoLayer || m_displayMode < PausedImage;
+ m_backgroundLayer.get().hidden = hideBackgroundLayer();
m_pendingSelectedTrackCheck = false;
updateDisplayMode();
@@ -921,8 +1173,8 @@
void MediaPlayerPrivateMediaStreamAVFObjC::setBufferingPolicy(MediaPlayer::BufferingPolicy policy)
{
- if (policy != MediaPlayer::BufferingPolicy::Default && m_sampleBufferDisplayLayer)
- m_sampleBufferDisplayLayer->flushAndRemoveImage();
+ if (policy != MediaPlayer::BufferingPolicy::Default)
+ [m_sampleBufferDisplayLayer flushAndRemoveImage];
}
void MediaPlayerPrivateMediaStreamAVFObjC::scheduleDeferredTask(Function<void ()>&& function)
@@ -945,20 +1197,23 @@
void MediaPlayerPrivateMediaStreamAVFObjC::updateDisplayLayer()
{
- if (!m_sampleBufferDisplayLayer)
+ if (!m_backgroundLayer || !m_sampleBufferDisplayLayer)
return;
- auto bounds = m_sampleBufferDisplayLayer->bounds();
- auto videoBounds = bounds;
+ auto backgroundBounds = m_backgroundLayer.get().bounds;
+ auto videoBounds = backgroundBounds;
if (m_videoRotation == MediaSample::VideoRotation::Right || m_videoRotation == MediaSample::VideoRotation::Left)
std::swap(videoBounds.size.width, videoBounds.size.height);
- m_sampleBufferDisplayLayer->updateBoundsAndPosition(videoBounds, { bounds.size.width / 2, bounds.size.height / 2});
+ m_sampleBufferDisplayLayer.get().bounds = videoBounds;
+ m_sampleBufferDisplayLayer.get().position = { backgroundBounds.size.width / 2, backgroundBounds.size.height / 2};
}
-void MediaPlayerPrivateMediaStreamAVFObjC::sampleBufferDisplayLayerBoundsDidChange(SampleBufferDisplayLayer&)
+void MediaPlayerPrivateMediaStreamAVFObjC::backgroundLayerBoundsChanged()
{
- updateDisplayLayer();
+ runWithoutAnimations([this] {
+ updateDisplayLayer();
+ });
}
#if !RELEASE_LOG_DISABLED