Skip to content

Commit 7278d48

Browse files
committed
[GStreamer][WPE] Add dummy telemetry support
https://bugs.webkit.org/show_bug.cgi?id=288584 Reviewed by Philippe Normand. Some platforms downstream require having telemetry. We would like to add a stub upstream to help future downstream revisions and ensure we are not breaking downstream with upstream changes. Let's clarify that this is only for WPE, this telemetry implementation is dummy and won't ever be implemented for real upstream. * Source/WebCore/platform/GStreamer.cmake: * Source/WebCore/platform/graphics/egl/GLContext.cpp: (WebCore::GLContext::GLContext): (WebCore::GLContext::~GLContext): (WebCore::GLContext::eglDisplay const): (WebCore::GLContext::eglConfig const): (WebCore::GLContext::eglSurface const): (WebCore::GLContext::eglContext const): (WebCore::GLContext::windowWidth const): (WebCore::GLContext::windowHeight const): * Source/WebCore/platform/graphics/egl/GLContext.h: * Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp: (WebCore::MediaPlayerPrivateGStreamer::tearDown): (WebCore::MediaPlayerPrivateGStreamer::play): (WebCore::MediaPlayerPrivateGStreamer::pause): (WebCore::MediaPlayerPrivateGStreamer::seekToTarget): (WebCore::MediaPlayerPrivateGStreamer::handleMessage): (WebCore::MediaPlayerPrivateGStreamer::finishSeek): (WebCore::MediaPlayerPrivateGStreamer::didEnd): (WebCore::MediaPlayerPrivateGStreamer::createGSTPlayBin): (WebCore::MediaPlayerPrivateGStreamer::pausedTimerFired): (WebCore::MediaPlayerPrivateGStreamer::getDrm const): * Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h: * Source/WebCore/platform/graphics/gstreamer/telemetry/MediaTelemetry.cpp: Added. (WebCore::MediaTelemetryReport::singleton): (WebCore::MediaTelemetryReport::~MediaTelemetryReport): (WebCore::MediaTelemetryReport::reportPlaybackState): (WebCore::MediaTelemetryReport::reportDrmInfo): (WebCore::MediaTelemetryReport::reportWaylandInfo): * Source/WebCore/platform/graphics/gstreamer/telemetry/MediaTelemetry.h: Added. (WebCore::MediaTelemetryReport::MediaTelemetryReport): * Source/WebCore/platform/graphics/gstreamer/telemetry/MediaTelemetryReportPrivateMembers.h: Added. * Source/cmake/GStreamerChecks.cmake: * Source/cmake/GStreamerDefinitions.cmake: * Source/cmake/GStreamerDependencies.cmake: Canonical link: https://commits.webkit.org/293410@main
1 parent 599a188 commit 7278d48

10 files changed

Lines changed: 414 additions & 3 deletions

Source/WebCore/platform/GStreamer.cmake

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ if (ENABLE_VIDEO OR ENABLE_WEB_AUDIO)
44
"${WEBCORE_DIR}/platform/graphics/gstreamer"
55
"${WEBCORE_DIR}/platform/graphics/gstreamer/mse"
66
"${WEBCORE_DIR}/platform/graphics/gstreamer/eme"
7+
"${WEBCORE_DIR}/platform/graphics/gstreamer/telemetry"
78
"${WEBCORE_DIR}/platform/gstreamer"
89
"${WEBCORE_DIR}/platform/mediarecorder/gstreamer"
910
)
@@ -128,6 +129,16 @@ if (ENABLE_VIDEO OR ENABLE_WEB_AUDIO)
128129
platform/mediastream/libwebrtc/gstreamer/LibWebRTCProviderGStreamer.h
129130
)
130131

132+
if (ENABLE_MEDIA_TELEMETRY)
133+
list(APPEND WebCore_SOURCES
134+
platform/graphics/gstreamer/telemetry/MediaTelemetry.cpp
135+
)
136+
list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS
137+
platform/graphics/gstreamer/telemetry/MediaTelemetry.h
138+
platform/graphics/gstreamer/telemetry/MediaTelemetryReportPrivateMembers.h
139+
)
140+
endif ()
141+
131142
if (USE_GSTREAMER_FULL)
132143
list(APPEND WebCore_SYSTEM_INCLUDE_DIRECTORIES
133144
${GSTREAMER_FULL_INCLUDE_DIRS}

Source/WebCore/platform/graphics/egl/GLContextEGL.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#endif
4747

4848
#include <wtf/Vector.h>
49+
#include <wtf/text/StringToIntegerConversion.h>
4950

5051
namespace WebCore {
5152

@@ -381,6 +382,13 @@ GLContextEGL::GLContextEGL(PlatformDisplay& display, EGLContext context, EGLSurf
381382
}
382383
RELEASE_ASSERT(!m_eglCreateImageKHR == !m_eglDestroyImageKHR);
383384
}
385+
386+
#if ENABLE(MEDIA_TELEMETRY)
387+
if (m_type == WindowSurface) {
388+
MediaTelemetryReport::singleton().reportWaylandInfo(*this, MediaTelemetryReport::WaylandAction::InitGfx,
389+
MediaTelemetryReport::WaylandGraphicsState::GfxInitialized, MediaTelemetryReport::WaylandInputsState::InputsInitialized);
390+
}
391+
#endif
384392
}
385393

386394
GLContextEGL::~GLContextEGL()
@@ -401,6 +409,13 @@ GLContextEGL::~GLContextEGL()
401409
#if USE(WPE_RENDERER)
402410
destroyWPETarget();
403411
#endif
412+
413+
#if ENABLE(MEDIA_TELEMETRY)
414+
if (m_type == WindowSurface) {
415+
MediaTelemetryReport::singleton().reportWaylandInfo(*this, MediaTelemetryReport::WaylandAction::DeinitGfx,
416+
MediaTelemetryReport::WaylandGraphicsState::GfxNotInitialized, MediaTelemetryReport::WaylandInputsState::InputsInitialized);
417+
}
418+
#endif
404419
}
405420

406421
EGLImage GLContextEGL::createImage(EGLenum target, EGLClientBuffer clientBuffer, const Vector<EGLAttrib>& attribList) const
@@ -543,6 +558,46 @@ GCGLContext GLContextEGL::platformContext()
543558
return m_context;
544559
}
545560

561+
#if ENABLE(MEDIA_TELEMETRY)
562+
EGLDisplay GLContextEGL::eglDisplay() const
563+
{
564+
return m_display.eglDisplay();
565+
}
566+
567+
EGLConfig GLContextEGL::eglConfig() const
568+
{
569+
EGLConfig config = nullptr;
570+
571+
if (!getEGLConfig(m_display.eglDisplay(), &config, WindowSurface)) {
572+
WTFLogAlways("Cannot obtain EGL window context configuration: %s\n", lastErrorString());
573+
config = nullptr;
574+
ASSERT_NOT_REACHED();
575+
}
576+
577+
return config;
578+
}
579+
580+
EGLSurface GLContextEGL::eglSurface() const
581+
{
582+
return m_surface;
583+
}
584+
585+
EGLContext GLContextEGL::eglContext() const
586+
{
587+
return m_context;
588+
}
589+
590+
unsigned GLContextEGL::windowWidth() const
591+
{
592+
return parseInteger<unsigned>(StringView::fromLatin1(std::getenv("WPE_INIT_VIEW_WIDTH"))).value_or(1920);
593+
}
594+
595+
unsigned GLContextEGL::windowHeight() const
596+
{
597+
return parseInteger<unsigned>(StringView::fromLatin1(std::getenv("WPE_INIT_VIEW_HEIGHT"))).value_or(1080);
598+
}
599+
#endif
600+
546601
} // namespace WebCore
547602

548603
#endif // USE(EGL)

Source/WebCore/platform/graphics/egl/GLContextEGL.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
struct wl_egl_window;
3333
#endif
3434

35+
#if ENABLE(MEDIA_TELEMETRY)
36+
#include "MediaTelemetry.h"
37+
#endif
38+
3539
#if USE(WPE_RENDERER)
3640
struct wpe_renderer_backend_egl_offscreen_target;
3741
#endif
@@ -63,7 +67,11 @@ typedef EGLBoolean (*PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay, EGLImageKHR);
6367

6468
namespace WebCore {
6569

66-
class GLContextEGL final : public GLContext {
70+
class GLContextEGL final : public GLContext
71+
#if ENABLE(MEDIA_TELEMETRY)
72+
, public MediaTelemetryWaylandInfoGetter
73+
#endif
74+
{
6775
WTF_MAKE_NONCOPYABLE(GLContextEGL);
6876
public:
6977
static std::unique_ptr<GLContextEGL> createContext(GLNativeWindowType, PlatformDisplay&);
@@ -126,6 +134,15 @@ class GLContextEGL final : public GLContext {
126134

127135
static bool getEGLConfig(EGLDisplay, EGLConfig*, EGLSurfaceType);
128136

137+
#if ENABLE(MEDIA_TELEMETRY)
138+
EGLDisplay eglDisplay() const final;
139+
EGLConfig eglConfig() const final;
140+
EGLSurface eglSurface() const final;
141+
EGLContext eglContext() const final;
142+
unsigned windowWidth() const final;
143+
unsigned windowHeight() const final;
144+
#endif
145+
129146
EGLContext m_context { nullptr };
130147
EGLSurface m_surface { nullptr };
131148
EGLConfig m_config { nullptr };

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

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,10 @@ MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer()
228228
if (m_gstreamerHolePunchHost)
229229
m_gstreamerHolePunchHost->playerPrivateWillBeDestroyed();
230230

231+
#if ENABLE(MEDIA_TELEMETRY)
232+
MediaTelemetryReport::singleton().reportPlaybackState(MediaTelemetryReport::AVPipelineState::Stop);
233+
#endif
234+
231235
m_sinkTaskQueue.startAborting();
232236

233237
for (auto& track : m_audioTracks.values())
@@ -291,6 +295,10 @@ MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer()
291295

292296
m_player = nullptr;
293297
m_notifier->invalidate();
298+
299+
#if ENABLE(MEDIA_TELEMETRY)
300+
MediaTelemetryReport::singleton().reportPlaybackState(MediaTelemetryReport::AVPipelineState::Destroy);
301+
#endif
294302
}
295303

296304
bool MediaPlayerPrivateGStreamer::isAvailable()
@@ -451,6 +459,10 @@ void MediaPlayerPrivateGStreamer::play()
451459
m_preload = MediaPlayer::Preload::Auto;
452460
updateDownloadBufferingFlag();
453461
GST_INFO_OBJECT(pipeline(), "Play");
462+
463+
#if ENABLE(MEDIA_TELEMETRY)
464+
MediaTelemetryReport::singleton().reportPlaybackState(MediaTelemetryReport::AVPipelineState::Play);
465+
#endif
454466
} else
455467
loadingFailed(MediaPlayer::NetworkState::Empty);
456468
}
@@ -467,9 +479,12 @@ void MediaPlayerPrivateGStreamer::pause()
467479
return;
468480

469481
auto result = changePipelineState(GST_STATE_PAUSED);
470-
if (result == ChangePipelineStateResult::Ok)
482+
if (result == ChangePipelineStateResult::Ok) {
471483
GST_INFO_OBJECT(pipeline(), "Pause");
472-
else if (result == ChangePipelineStateResult::Failed)
484+
#if ENABLE(MEDIA_TELEMETRY)
485+
MediaTelemetryReport::singleton().reportPlaybackState(MediaTelemetryReport::AVPipelineState::Pause);
486+
#endif
487+
} else if (result == ChangePipelineStateResult::Failed)
473488
loadingFailed(MediaPlayer::NetworkState::Empty);
474489
}
475490

@@ -577,6 +592,10 @@ void MediaPlayerPrivateGStreamer::seek(const MediaTime& mediaTime)
577592
MediaTime time = std::min(mediaTime, durationMediaTime());
578593
GST_INFO_OBJECT(pipeline(), "[Seek] seeking to %s", toString(time).utf8().data());
579594

595+
#if ENABLE(MEDIA_TELEMETRY)
596+
MediaTelemetryReport::singleton().reportPlaybackState(MediaTelemetryReport::AVPipelineState::SeekStart, makeString(toString(playbackPosition()), "->"_s, toString(time)));
597+
#endif
598+
580599
if (m_isSeeking) {
581600
m_timeOfOverlappingSeek = time;
582601
if (m_isSeekPending) {
@@ -1879,6 +1898,11 @@ void MediaPlayerPrivateGStreamer::handleMessage(GstMessage* message)
18791898

18801899
m_errorMessage = String::fromLatin1(err->message);
18811900

1901+
#if ENABLE(MEDIA_TELEMETRY)
1902+
MediaTelemetryReport::singleton().reportPlaybackState(MediaTelemetryReport::AVPipelineState::PlaybackError,
1903+
m_errorMessage);
1904+
#endif
1905+
18821906
error = MediaPlayer::NetworkState::Empty;
18831907
if (g_error_matches(err.get(), GST_STREAM_ERROR, GST_STREAM_ERROR_CODEC_NOT_FOUND)
18841908
|| g_error_matches(err.get(), GST_STREAM_ERROR, GST_STREAM_ERROR_DECRYPT)
@@ -2517,6 +2541,12 @@ void MediaPlayerPrivateGStreamer::purgeOldDownloadFiles(const String& downloadFi
25172541
void MediaPlayerPrivateGStreamer::finishSeek()
25182542
{
25192543
GST_DEBUG_OBJECT(pipeline(), "[Seek] seeked to %s", toString(m_seekTime).utf8().data());
2544+
2545+
#if ENABLE(MEDIA_TELEMETRY)
2546+
MediaTelemetryReport::singleton().reportPlaybackState(MediaTelemetryReport::AVPipelineState::SeekDone,
2547+
toString(m_seekTime));
2548+
#endif
2549+
25202550
m_isSeeking = false;
25212551
invalidateCachedPosition();
25222552
if (m_timeOfOverlappingSeek != m_seekTime && m_timeOfOverlappingSeek.isValid()) {
@@ -2881,6 +2911,10 @@ void MediaPlayerPrivateGStreamer::didEnd()
28812911
#endif
28822912
}
28832913
timeChanged();
2914+
2915+
#if ENABLE(MEDIA_TELEMETRY)
2916+
MediaTelemetryReport::singleton().reportPlaybackState(MediaTelemetryReport::AVPipelineState::EndOfStream);
2917+
#endif
28842918
}
28852919

28862920
void MediaPlayerPrivateGStreamer::getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& types)
@@ -3100,6 +3134,11 @@ void MediaPlayerPrivateGStreamer::createGSTPlayBin(const URL& url)
31003134
g_object_set(m_pipeline.get(), "audio-filter", scale, nullptr);
31013135
}
31023136

3137+
#if ENABLE(MEDIA_TELEMETRY)
3138+
MediaTelemetryReport::singleton().reportDrmInfo(getDrm());
3139+
MediaTelemetryReport::singleton().reportPlaybackState(MediaTelemetryReport::AVPipelineState::Create);
3140+
#endif
3141+
31033142
if (!m_player->isVideoPlayer())
31043143
return;
31053144

@@ -3200,6 +3239,10 @@ void MediaPlayerPrivateGStreamer::pausedTimerFired()
32003239
{
32013240
GST_DEBUG_OBJECT(pipeline(), "In PAUSED for too long. Releasing pipeline resources.");
32023241
changePipelineState(GST_STATE_NULL);
3242+
3243+
#if ENABLE(MEDIA_TELEMETRY)
3244+
MediaTelemetryReport::singleton().reportPlaybackState(MediaTelemetryReport::AVPipelineState::Destroy);
3245+
#endif
32033246
}
32043247

32053248
void MediaPlayerPrivateGStreamer::acceleratedRenderingStateChanged()
@@ -4638,6 +4681,37 @@ void MediaPlayerPrivateGStreamer::checkPlayingConsistency()
46384681
}
46394682
}
46404683

4684+
#if ENABLE(MEDIA_TELEMETRY)
4685+
MediaTelemetryReport::DrmType MediaPlayerPrivateGStreamer::getDrm() const
4686+
{
4687+
if (!m_pipeline)
4688+
return MediaTelemetryReport::DrmType::None;
4689+
4690+
GRefPtr<GstContext> drmCdmInstanceContext = adoptGRef(gst_element_get_context(GST_ELEMENT(m_pipeline.get()), "drm-cdm-instance"));
4691+
if (!drmCdmInstanceContext)
4692+
return MediaTelemetryReport::DrmType::None;
4693+
4694+
const GstStructure* drmCdmInstanceStructure = gst_context_get_structure(drmCdmInstanceContext.get());
4695+
if (!drmCdmInstanceStructure)
4696+
return MediaTelemetryReport::DrmType::None;
4697+
4698+
const GValue* drmCdmInstanceVal = gst_structure_get_value(drmCdmInstanceStructure, "cdm-instance");
4699+
if (!drmCdmInstanceVal)
4700+
return MediaTelemetryReport::DrmType::None;
4701+
4702+
const CDMInstance* drmCdmInstance = static_cast<const CDMInstance*>(g_value_get_pointer(drmCdmInstanceVal));
4703+
if (!drmCdmInstance)
4704+
return MediaTelemetryReport::DrmType::None;
4705+
4706+
String keySystem = drmCdmInstance->keySystem();
4707+
if (GStreamerEMEUtilities::isPlayReadyKeySystem(keySystem))
4708+
return MediaTelemetryReport::DrmType::PlayReady;
4709+
if (GStreamerEMEUtilities::isWidevineKeySystem(keySystem))
4710+
return MediaTelemetryReport::DrmType::Widevine;
4711+
return MediaTelemetryReport::DrmType::Unknown;
4712+
}
4713+
#endif
4714+
46414715
}
46424716

46434717
#endif // USE(GSTREAMER)

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ typedef struct _GstMpegtsSection GstMpegtsSection;
7575
#include "CDMProxy.h"
7676
#endif
7777

78+
#if ENABLE(MEDIA_TELEMETRY)
79+
#include "MediaTelemetry.h"
80+
#endif
81+
7882
typedef struct _GstStreamVolume GstStreamVolume;
7983
typedef struct _GstVideoInfo GstVideoInfo;
8084

@@ -585,6 +589,10 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface
585589
bool waitForCDMAttachment();
586590
#endif
587591

592+
#if ENABLE(MEDIA_TELEMETRY)
593+
MediaTelemetryReport::DrmType getDrm() const;
594+
#endif
595+
588596
void configureMediaStreamAudioTracks();
589597
void invalidateCachedPositionOnNextIteration() const;
590598

0 commit comments

Comments
 (0)