Skip to content

Commit 21ed252

Browse files
committed
Quirks: Add plumbing for hole-punch testing
1 parent 0e80f1b commit 21ed252

12 files changed

Lines changed: 132 additions & 11 deletions

File tree

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
2+
(GraphicsLayer
3+
(anchor 0.00 0.00)
4+
(bounds 1288.00 807.00)
5+
(children 1
6+
(GraphicsLayer
7+
(bounds 1288.00 807.00)
8+
(contentsOpaque 1)
9+
(children 1
10+
(GraphicsLayer
11+
(position 8.00 8.00)
12+
(bounds 1280.00 720.00)
13+
)
14+
)
15+
)
16+
)
17+
)
18+
RUN(internals.enableGStreamerHolePunching(video))
19+
RUN(video.src = findMediaFile('video', '../../../media/content/test'))
20+
RUN(video.play())
21+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<script src="../../../media/media-file.js"></script>
5+
<script src="../../../media/video-test.js"></script>
6+
<script>
7+
function dumpLayers()
8+
{
9+
if (window.testRunner) {
10+
document.getElementById('outText').textContent = window.internals.layerTreeAsText(document);
11+
testRunner.notifyDone();
12+
}
13+
}
14+
window.addEventListener('load', async event => {
15+
findMediaElement();
16+
run("internals.enableGStreamerHolePunching(video)");
17+
run("video.src = findMediaFile('video', '../../../media/content/test')");
18+
run("video.play()");
19+
setTimeout(dumpLayers, 500);
20+
});
21+
</script>
22+
</head>
23+
<body>
24+
<video></video>
25+
<pre id="outText"></pre>
26+
</body>
27+
</html>

Source/WebCore/html/HTMLVideoElement.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,11 @@ class HTMLVideoElement final : public HTMLMediaElement, public Supplementable<HT
119119
unsigned requestVideoFrameCallback(Ref<VideoFrameRequestCallback>&&);
120120
void cancelVideoFrameCallback(unsigned);
121121

122+
#if USE(GSTREAMER)
123+
void enableGStreamerHolePunching() { m_enableGStreamerHolePunching = true; }
124+
bool isGStreamerHolePunchingEnabled() const final { return m_enableGStreamerHolePunching; }
125+
#endif
126+
122127
private:
123128
HTMLVideoElement(const QualifiedName&, Document&, bool createdByParser);
124129

@@ -175,6 +180,10 @@ class HTMLVideoElement final : public HTMLMediaElement, public Supplementable<HT
175180
Vector<UniqueRef<VideoFrameRequest>> m_videoFrameRequests;
176181
Vector<UniqueRef<VideoFrameRequest>> m_servicedVideoFrameRequests;
177182
unsigned m_nextVideoFrameRequestIndex { 0 };
183+
184+
#if USE(GSTREAMER)
185+
bool m_enableGStreamerHolePunching { false };
186+
#endif
178187
};
179188

180189
} // namespace WebCore

Source/WebCore/platform/graphics/MediaPlayer.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1625,6 +1625,11 @@ void MediaPlayer::simulateAudioInterruption()
16251625

16261626
m_private->simulateAudioInterruption();
16271627
}
1628+
1629+
bool MediaPlayer::isGStreamerHolePunchingEnabled()
1630+
{
1631+
return client().isGStreamerHolePunchingEnabled();
1632+
}
16281633
#endif
16291634

16301635
void MediaPlayer::beginSimulatedHDCPError()

Source/WebCore/platform/graphics/MediaPlayer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,8 @@ class MediaPlayerClient {
295295

296296
virtual bool mediaPlayerShouldDisableHDR() const { return false; }
297297

298+
virtual bool isGStreamerHolePunchingEnabled() const { return false; }
299+
298300
#if !RELEASE_LOG_DISABLED
299301
virtual const void* mediaPlayerLogIdentifier() { return nullptr; }
300302
virtual const Logger& mediaPlayerLogger() = 0;
@@ -620,6 +622,7 @@ class WEBCORE_EXPORT MediaPlayer : public MediaPlayerEnums, public ThreadSafeRef
620622

621623
#if USE(GSTREAMER)
622624
void simulateAudioInterruption();
625+
bool isGStreamerHolePunchingEnabled();
623626
#endif
624627

625628
void beginSimulatedHDCPError();

Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,11 @@ MediaPlayerPrivateGStreamer::MediaPlayerPrivateGStreamer(MediaPlayer* player)
189189
#endif
190190
m_isPlayerShuttingDown.store(false);
191191

192+
if (player->isGStreamerHolePunchingEnabled()) {
193+
m_quirksManagerForTesting = GStreamerQuirksManager::createForTesting();
194+
m_quirksManagerForTesting->setHolePunchEnabledForTesting(true);
195+
}
196+
192197
#if USE(TEXTURE_MAPPER_GL) && USE(NICOSIA)
193198
m_nicosiaLayer = Nicosia::ContentLayer::create(Nicosia::ContentLayerTextureMapperImpl::createFactory(*this,
194199
[&]() -> Ref<TextureMapperPlatformLayerProxy> {
@@ -4015,14 +4020,19 @@ GstElement* MediaPlayerPrivateGStreamer::createVideoSinkGL()
40154020
}
40164021
#endif // USE(GSTREAMER_GL)
40174022

4018-
static void setRectangleToVideoSink(GstElement* videoSink, const IntRect& rect)
4023+
static void setRectangleToVideoSink(GStreamerQuirksManager* quirksManagerForTesting, GstElement* videoSink, const IntRect& rect)
40194024
{
40204025
// Here goes the platform-dependant code to set to the videoSink the size
40214026
// and position of the video rendering window.
40224027

40234028
if (!videoSink)
40244029
return;
40254030

4031+
if (quirksManagerForTesting) {
4032+
quirksManagerForTesting->setHolePunchVideoRectangle(videoSink, rect);
4033+
return;
4034+
}
4035+
40264036
auto& quirksManager = GStreamerQuirksManager::singleton();
40274037
quirksManager.setHolePunchVideoRectangle(videoSink, rect);
40284038
}
@@ -4037,6 +4047,8 @@ class GStreamerHolePunchClient : public TextureMapperPlatformLayerBuffer::HolePu
40374047

40384048
bool MediaPlayerPrivateGStreamer::isHolePunchRenderingEnabled() const
40394049
{
4050+
if (m_quirksManagerForTesting)
4051+
return m_quirksManagerForTesting->supportsVideoHolePunchRendering();
40404052
auto& quirksManager = GStreamerQuirksManager::singleton();
40414053
return quirksManager.supportsVideoHolePunchRendering();
40424054
}
@@ -4046,8 +4058,11 @@ GstElement* MediaPlayerPrivateGStreamer::createHolePunchVideoSink()
40464058
if (!isHolePunchRenderingEnabled())
40474059
return nullptr;
40484060

4049-
auto& quirksManager = GStreamerQuirksManager::singleton();
4050-
auto sink = quirksManager.createHolePunchVideoSink(m_isLegacyPlaybin, m_player);
4061+
GstElement* sink = nullptr;
4062+
if (m_quirksManagerForTesting)
4063+
sink = m_quirksManagerForTesting->createHolePunchVideoSink(m_isLegacyPlaybin, m_player);
4064+
else
4065+
sink = GStreamerQuirksManager::singleton().createHolePunchVideoSink(m_isLegacyPlaybin, m_player);
40514066

40524067
// Configure sink before it allocates resources.
40534068
if (sink)
@@ -4085,7 +4100,7 @@ void MediaPlayerPrivateGStreamer::setVideoRectangle(const IntRect& rect)
40854100
Locker locker { m_holePunchLock };
40864101

40874102
if (m_visible && !m_suspended)
4088-
setRectangleToVideoSink(m_videoSink.get(), rect);
4103+
setRectangleToVideoSink(m_quirksManagerForTesting.get(), m_videoSink.get(), rect);
40894104
}
40904105

40914106
bool MediaPlayerPrivateGStreamer::shouldIgnoreIntrinsicSize()
@@ -4463,7 +4478,7 @@ void MediaPlayerPrivateGStreamer::setPageIsVisible(bool visible)
44634478
m_visible = visible;
44644479

44654480
if (!m_visible)
4466-
setRectangleToVideoSink(m_videoSink.get(), IntRect());
4481+
setRectangleToVideoSink(m_quirksManagerForTesting.get(), m_videoSink.get(), IntRect());
44674482
}
44684483
}
44694484

@@ -4475,7 +4490,7 @@ void MediaPlayerPrivateGStreamer::setPageIsSuspended(bool suspended)
44754490
m_suspended = suspended;
44764491

44774492
if (m_suspended)
4478-
setRectangleToVideoSink(m_videoSink.get(), IntRect());
4493+
setRectangleToVideoSink(m_quirksManagerForTesting.get(), m_videoSink.get(), IntRect());
44794494
}
44804495
}
44814496

Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "AbortableTaskQueue.h"
3030
#include "GStreamerCommon.h"
3131
#include "GStreamerEMEUtilities.h"
32+
#include "GStreamerQuirks.h"
3233
#include "ImageOrientation.h"
3334
#include "Logging.h"
3435
#include "MainThreadNotifier.h"
@@ -673,6 +674,8 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface
673674
// Specific to MediaStream playback.
674675
MediaTime m_startTime;
675676
MediaTime m_pausedTime;
677+
678+
RefPtr<GStreamerQuirksManager> m_quirksManagerForTesting;
676679
};
677680

678681
}

Source/WebCore/platform/gstreamer/GStreamerQuirks.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,28 @@ GST_DEBUG_CATEGORY_STATIC(webkit_quirks_debug);
4343

4444
GStreamerQuirksManager& GStreamerQuirksManager::singleton()
4545
{
46-
static NeverDestroyed<GStreamerQuirksManager> sharedInstance;
46+
static NeverDestroyed<GStreamerQuirksManager> sharedInstance(false, true);
4747
return sharedInstance;
4848
}
4949

50-
GStreamerQuirksManager::GStreamerQuirksManager()
50+
GStreamerQuirksManager::GStreamerQuirksManager(bool isForTesting, bool loadQuirksFromEnvironment)
51+
: m_isForTesting(isForTesting)
5152
{
52-
GST_DEBUG_CATEGORY_INIT(webkit_quirks_debug, "webkitquirks", 0, "WebKit Quirks");
53+
static std::once_flag debugRegisteredFlag;
54+
std::call_once(debugRegisteredFlag, [] {
55+
GST_DEBUG_CATEGORY_INIT(webkit_quirks_debug, "webkitquirks", 0, "WebKit Quirks");
56+
});
5357

5458
// For the time being keep this disabled on non-WPE platforms. GTK on desktop shouldn't require
5559
// quirks, for instance.
5660
#if !PLATFORM(WPE)
5761
return;
5862
#endif
5963

64+
GST_DEBUG("Quirk manager created%s", m_isForTesting ? " for testing." : ".");
65+
if (!loadQuirksFromEnvironment)
66+
return;
67+
6068
const char* quirksListFromEnvironment = g_getenv("WEBKIT_GST_QUIRKS");
6169
StringBuilder quirksListBuilder;
6270
if (quirksListFromEnvironment)
@@ -235,6 +243,14 @@ Vector<String> GStreamerQuirksManager::disallowedWebAudioDecoders() const
235243
return result;
236244
}
237245

246+
void GStreamerQuirksManager::setHolePunchEnabledForTesting(bool enabled)
247+
{
248+
if (enabled)
249+
m_holePunchQuirk = WTF::makeUnique<GStreamerHolePunchQuirkFake>();
250+
else
251+
m_holePunchQuirk = nullptr;
252+
}
253+
238254
#undef GST_CAT_DEFAULT
239255

240256
} // namespace WebCore

Source/WebCore/platform/gstreamer/GStreamerQuirks.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "GRefPtrGStreamer.h"
2626
#include "MediaPlayer.h"
2727
#include <wtf/Forward.h>
28+
#include <wtf/RefCounted.h>
2829
#include <wtf/Vector.h>
2930

3031
namespace WebCore {
@@ -70,13 +71,18 @@ class GStreamerHolePunchQuirk : public GStreamerQuirkBase {
7071
virtual bool setHolePunchVideoRectangle(GstElement*, const IntRect&) { return false; }
7172
};
7273

73-
class GStreamerQuirksManager {
74+
class GStreamerQuirksManager : public RefCounted<GStreamerQuirksManager> {
7475
friend NeverDestroyed<GStreamerQuirksManager>;
7576
WTF_MAKE_FAST_ALLOCATED;
7677

7778
public:
7879
static GStreamerQuirksManager& singleton();
7980

81+
static RefPtr<GStreamerQuirksManager> createForTesting()
82+
{
83+
return adoptRef(*new GStreamerQuirksManager(true, false));
84+
}
85+
8086
bool isEnabled() const;
8187

8288
GstElement* createWebAudioSink();
@@ -89,11 +95,14 @@ class GStreamerQuirksManager {
8995
GstElement* createHolePunchVideoSink(bool isLegacyPlaybin, const MediaPlayer*);
9096
void setHolePunchVideoRectangle(GstElement*, const IntRect&);
9197

98+
void setHolePunchEnabledForTesting(bool);
99+
92100
private:
93-
GStreamerQuirksManager();
101+
GStreamerQuirksManager(bool, bool);
94102

95103
Vector<std::unique_ptr<GStreamerQuirk>> m_quirks;
96104
std::unique_ptr<GStreamerHolePunchQuirk> m_holePunchQuirk;
105+
bool m_isForTesting { false };
97106
};
98107

99108
} // namespace WebCore

Source/WebCore/testing/Internals.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4116,6 +4116,15 @@ ExceptionOr<void> Internals::setOverridePreferredDynamicRangeMode(HTMLMediaEleme
41164116
return { };
41174117
}
41184118

4119+
void Internals::enableGStreamerHolePunching(HTMLVideoElement& element)
4120+
{
4121+
#if USE(GSTREAMER)
4122+
element.enableGStreamerHolePunching();
4123+
#else
4124+
UNUSED_PARAM(element);
4125+
#endif
4126+
}
4127+
41194128
#endif
41204129

41214130
bool Internals::isSelectPopupVisible(HTMLSelectElement& element)

0 commit comments

Comments
 (0)