From 6a5ec7db440601b440c06487b5b7e6a50a217869 Mon Sep 17 00:00:00 2001 From: Marcin Mielczarczyk Date: Thu, 9 Jan 2025 16:20:00 +0100 Subject: [PATCH 1/2] Integrate RDK Telemetry --- Source/CMakeLists.txt | 5 + Source/ThirdParty/telemetry/CMakeLists.txt | 44 ++++++ .../telemetry/cmake/FindOdhErrTelemetry.cmake | 45 ++++++ .../telemetry/cmake/FindOdhOttTelemetry.cmake | 45 ++++++ .../telemetry/include/DummyTelemetryReport.h | 23 +++ .../ThirdParty/telemetry/include/ITelemetry.h | 100 +++++++++++++ .../telemetry/include/RdkTelemetryReport.h | 24 ++++ .../telemetry/include/TelemetryReport.h | 20 +++ .../telemetry/src/DummyTelemetryReport.cpp | 53 +++++++ .../telemetry/src/RdkTelemetryReport.cpp | 131 ++++++++++++++++++ Source/WebCore/CMakeLists.txt | 3 + .../platform/graphics/egl/GLContextEGL.cpp | 55 ++++++++ .../platform/graphics/egl/GLContextEGL.h | 11 +- .../gstreamer/MediaPlayerPrivateGStreamer.cpp | 53 ++++++- .../gstreamer/MediaPlayerPrivateGStreamer.h | 3 + Source/cmake/OptionsWPE.cmake | 3 +- 16 files changed, 614 insertions(+), 4 deletions(-) create mode 100644 Source/ThirdParty/telemetry/CMakeLists.txt create mode 100644 Source/ThirdParty/telemetry/cmake/FindOdhErrTelemetry.cmake create mode 100644 Source/ThirdParty/telemetry/cmake/FindOdhOttTelemetry.cmake create mode 100644 Source/ThirdParty/telemetry/include/DummyTelemetryReport.h create mode 100644 Source/ThirdParty/telemetry/include/ITelemetry.h create mode 100644 Source/ThirdParty/telemetry/include/RdkTelemetryReport.h create mode 100644 Source/ThirdParty/telemetry/include/TelemetryReport.h create mode 100644 Source/ThirdParty/telemetry/src/DummyTelemetryReport.cpp create mode 100644 Source/ThirdParty/telemetry/src/RdkTelemetryReport.cpp diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index c9729ba415d2d..df6f795cca1c3 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -13,6 +13,11 @@ endif () add_subdirectory(JavaScriptCore) +add_subdirectory(ThirdParty/telemetry) +if (USE_RDK_TELEMETRY) + add_definitions(-DRDK_TELEMETRY) +endif () + if (ENABLE_WEBGL OR USE_ANGLE_EGL) add_subdirectory(ThirdParty/ANGLE) endif () diff --git a/Source/ThirdParty/telemetry/CMakeLists.txt b/Source/ThirdParty/telemetry/CMakeLists.txt new file mode 100644 index 0000000000000..00526fd8637e1 --- /dev/null +++ b/Source/ThirdParty/telemetry/CMakeLists.txt @@ -0,0 +1,44 @@ +set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +set(TELEMETRY_DIR "${THIRDPARTY_DIR}/telemetry") + +set(TELEMETRY_INCLUDE_DIRECTORIES + "${TELEMETRY_DIR}/include" + "${CMAKE_BINARY_DIR}" +) + +include_directories("${TELEMETRY_INCLUDE_DIRECTORIES}") + +if (USE_RDK_TELEMETRY) + find_package(OdhErrTelemetry) + if (NOT OdhErrTelemetry_FOUND) + message(FATAL_ERROR "OdhErrTelemetry is needed for USE_RDK_TELEMETRY") + endif () + + find_package(OdhOttTelemetry) + if (NOT OdhOttTelemetry_FOUND) + message(FATAL_ERROR "OdhOttTelemetry is needed for USE_RDK_TELEMETRY") + endif () + + include_directories( + ${OdhErrTelemetry_INCLUDE_DIR} + ${OdhOttTelemetry_INCLUDE_DIR} + ) + + set(TELEMETRY_LIBRARIES + ${OdhErrTelemetry_LIBRARIES} + ${OdhOttTelemetry_LIBRARIES} + ) + + set(TELEMETRY_SOURCES + ${TELEMETRY_DIR}/src/RdkTelemetryReport.cpp + ) + + add_definitions(-DRDK_TELEMETRY) +else () + set(TELEMETRY_SOURCES + ${TELEMETRY_DIR}/src/DummyTelemetryReport.cpp + ) +endif () + +add_library(telemetry STATIC ${TELEMETRY_SOURCES}) +target_link_libraries(telemetry PRIVATE ${TELEMETRY_LIBRARIES}) diff --git a/Source/ThirdParty/telemetry/cmake/FindOdhErrTelemetry.cmake b/Source/ThirdParty/telemetry/cmake/FindOdhErrTelemetry.cmake new file mode 100644 index 0000000000000..4c5654dd8f155 --- /dev/null +++ b/Source/ThirdParty/telemetry/cmake/FindOdhErrTelemetry.cmake @@ -0,0 +1,45 @@ +#============================================================================ +# Copyright (c) 2023 Liberty Global +#============================================================================ + +# - Try to find ODH telemetry +# +# Once done this will define +# OdhErrTelemetry_FOUND - System has the component +# OdhErrTelemetry_INCLUDE_DIRS - Component include directories +# OdhErrTelemetry_LIBRARIES - Libraries needed to use the component + +find_package(PkgConfig QUIET) + +find_path(OdhErrTelemetry_INCLUDE_DIR + NAMES odherr.h + HINTS ${TARGET_SYS_ROOT}/usr/include/rdk/libodherr + ) + +find_library(OdhErrTelemetry_LIBRARY + NAMES odherr + HINTS ${TARGET_SYS_ROOT}/usr/lib + ) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OdhErrTelemetry + FOUND_VAR OdhErrTelemetry_FOUND + REQUIRED_VARS OdhErrTelemetry_LIBRARY OdhErrTelemetry_INCLUDE_DIR +) + +if (OdhErrTelemetry_LIBRARY AND NOT TARGET OdhErrTelemetry::OdhErrTelemetry) + add_library(OdhErrTelemetry::OdhErrTelemetry UNKNOWN IMPORTED GLOBAL) + set_target_properties(OdhErrTelemetry::OdhErrTelemetry PROPERTIES + IMPORTED_LOCATION "${OdhErrTelemetry_LIBRARY}" + INTERFACE_COMPILE_OPTIONS "${OdhErrTelemetry_COMPILE_OPTIONS}" + INTERFACE_INCLUDE_DIRECTORIES "${OdhErrTelemetry_INCLUDE_DIR}" + ) +endif () + +mark_as_advanced(OdhErrTelemetry_INCLUDE_DIR OdhErrTelemetry_LIBRARY) + +if (OdhErrTelemetry_FOUND) + set(OdhErrTelemetry_INCLUDE_DIRS ${OdhErrTelemetry_INCLUDE_DIR}) + set(OdhErrTelemetry_LIBRARIES ${OdhErrTelemetry_LIBRARY}) + set(OdhErrTelemetry_PKG_EXTRA_LIBS "-lodherr") +endif () diff --git a/Source/ThirdParty/telemetry/cmake/FindOdhOttTelemetry.cmake b/Source/ThirdParty/telemetry/cmake/FindOdhOttTelemetry.cmake new file mode 100644 index 0000000000000..f9bcfcc200d1c --- /dev/null +++ b/Source/ThirdParty/telemetry/cmake/FindOdhOttTelemetry.cmake @@ -0,0 +1,45 @@ +#============================================================================ +# Copyright (c) 2023 Liberty Global +#============================================================================ + +# - Try to find ODH telemetry +# +# Once done this will define +# OdhOttTelemetry_FOUND - System has the component +# OdhOttTelemetry_INCLUDE_DIRS - Component include directories +# OdhOttTelemetry_LIBRARIES - Libraries needed to use the component + +find_package(PkgConfig QUIET) + +find_path(OdhOttTelemetry_INCLUDE_DIR + NAMES odhott_wl.h + HINTS ${TARGET_SYS_ROOT}/usr/include/odhott + ) + +find_library(OdhOttTelemetry_LIBRARY + NAMES odhott + HINTS ${TARGET_SYS_ROOT}/usr/lib + ) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OdhOttTelemetry + FOUND_VAR OdhOttTelemetry_FOUND + REQUIRED_VARS OdhOttTelemetry_LIBRARY OdhOttTelemetry_INCLUDE_DIR +) + +if (OdhOttTelemetry_LIBRARY AND NOT TARGET OdhOttTelemetry::OdhOttTelemetry) + add_library(OdhOttTelemetry::OdhOttTelemetry UNKNOWN IMPORTED GLOBAL) + set_target_properties(OdhOttTelemetry::OdhOttTelemetry PROPERTIES + IMPORTED_LOCATION "${OdhOttTelemetry_LIBRARY}" + INTERFACE_COMPILE_OPTIONS "${OdhOttTelemetry_COMPILE_OPTIONS}" + INTERFACE_INCLUDE_DIRECTORIES "${OdhOttTelemetry_INCLUDE_DIR}" + ) +endif () + +mark_as_advanced(OdhOttTelemetry_INCLUDE_DIR OdhOttTelemetry_LIBRARY) + +if (OdhOttTelemetry_FOUND) + set(OdhOttTelemetry_INCLUDE_DIRS ${OdhOttTelemetry_INCLUDE_DIR}) + set(OdhOttTelemetry_LIBRARIES ${OdhOttTelemetry_LIBRARY}) + set(OdhOttTelemetry_PKG_EXTRA_LIBS "-lodhott") +endif () diff --git a/Source/ThirdParty/telemetry/include/DummyTelemetryReport.h b/Source/ThirdParty/telemetry/include/DummyTelemetryReport.h new file mode 100644 index 0000000000000..fcc5b3b85c9fb --- /dev/null +++ b/Source/ThirdParty/telemetry/include/DummyTelemetryReport.h @@ -0,0 +1,23 @@ +#pragma once + +#include "ITelemetry.h" + +namespace Telemetry { + +class DummyTelemetryReport: public IReport { + +public: + void reportPlaybackState( + AVPipelineState state, + const std::string &additionalInfo = "", + MediaType mediaType = MediaType::NONE) override; + void reportDrmInfo( + DrmType drmType, + const std::string &additionalInfo = "") override; + void reportWaylandInfo( + const IWaylandInfoGetter &getter, + WaylandAction action, + WaylandGraphicsState gfxState, + WaylandInputsState inputsState) override; +}; +} diff --git a/Source/ThirdParty/telemetry/include/ITelemetry.h b/Source/ThirdParty/telemetry/include/ITelemetry.h new file mode 100644 index 0000000000000..8698bc95a1a20 --- /dev/null +++ b/Source/ThirdParty/telemetry/include/ITelemetry.h @@ -0,0 +1,100 @@ +#pragma once + +#include + +namespace Telemetry { + +/* +* Helper function to get some telemetry data from Wayland. +*/ +class IWaylandInfoGetter { +public: + /* + * Don't include: + * #include + * #include + * since there are import order issues. + * Defining needed types as void*, like WebKit does. + */ + typedef void *EGLConfig; + typedef void *EGLContext; + typedef void *EGLDisplay; + typedef void *EGLSurface; + + virtual EGLDisplay getEGLDisplay() const = 0; + virtual EGLConfig getEGLConfig() const = 0; + virtual EGLSurface getEGLSurface() const = 0; + virtual EGLContext getEGLContext() const = 0; + virtual unsigned int getWindowWidth() const = 0; + virtual unsigned int getWindowHeight() const = 0; +}; + +class IReport +{ +public: + enum class AVPipelineState { + CREATE, + PLAY, + PAUSE, + STOP, + DESTROY, + FIRST_FRAME_DECODED, + END_OF_STREAM, + DECRYPT_ERROR, + PLAYBACK_ERROR, + DRM_ERROR, + ERROR, + SEEK_START, + SEEK_DONE, + VIDEO_RESOLUTION_CHANGED, + UNKNOWN + }; + + enum class MediaType { + AUDIO, + VIDEO, + NONE + }; + + enum class DrmType { + PLAYREADY, + WIDEVINE, + NONE, + UNKNOWN + }; + + enum class WaylandAction + { + INIT_GFX, + DEINIT_GFX, + INIT_INPUTS, + DEINIT_INPUTS + }; + + enum class WaylandGraphicsState + { + GFX_NOT_INITIALIZED, + GFX_INITIALIZED + }; + + enum class WaylandInputsState + { + INPUTS_NOT_INITIALIZED, + INPUTS_INITIALIZED + }; + + virtual ~IReport() = default; + virtual void reportPlaybackState( + AVPipelineState state, + const std::string &additionalInfo, + MediaType mediaType) = 0; + virtual void reportDrmInfo( + DrmType drmType, + const std::string &additionalInfo) = 0; + virtual void reportWaylandInfo( + const IWaylandInfoGetter &getter, + WaylandAction action, + WaylandGraphicsState gfxState, + WaylandInputsState inputsState) = 0; +}; +} diff --git a/Source/ThirdParty/telemetry/include/RdkTelemetryReport.h b/Source/ThirdParty/telemetry/include/RdkTelemetryReport.h new file mode 100644 index 0000000000000..f81716079167b --- /dev/null +++ b/Source/ThirdParty/telemetry/include/RdkTelemetryReport.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include "ITelemetry.h" + +namespace Telemetry { + +class RdkTelemetryReport: public IReport { + +public: + void reportPlaybackState( + AVPipelineState state, + const std::string &additionalInfo = "", + MediaType mediaType = MediaType::NONE) override; + void reportDrmInfo( + DrmType drmType, + const std::string &additionalInfo = "") override; + void reportWaylandInfo( + const IWaylandInfoGetter &getter, + WaylandAction action, + WaylandGraphicsState gfxState, + WaylandInputsState inputsState) override; +}; +} diff --git a/Source/ThirdParty/telemetry/include/TelemetryReport.h b/Source/ThirdParty/telemetry/include/TelemetryReport.h new file mode 100644 index 0000000000000..85830661486dc --- /dev/null +++ b/Source/ThirdParty/telemetry/include/TelemetryReport.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include + +#if defined(RDK_TELEMETRY) + #include "RdkTelemetryReport.h" + using TelemetryImpl = Telemetry::RdkTelemetryReport; +#else + #include "DummyTelemetryReport.h" + using TelemetryImpl = Telemetry::DummyTelemetryReport; +#endif + +namespace Telemetry +{ + void init(const std::string &name = "WebKitBrowser"); + void deinit(); + void reportErrorV(const char* file, int line, const char* function, const char* format, va_list args); + void reportError(const char* file, int line, const char* function, const char* format, ...); +} diff --git a/Source/ThirdParty/telemetry/src/DummyTelemetryReport.cpp b/Source/ThirdParty/telemetry/src/DummyTelemetryReport.cpp new file mode 100644 index 0000000000000..62aee783ab5f3 --- /dev/null +++ b/Source/ThirdParty/telemetry/src/DummyTelemetryReport.cpp @@ -0,0 +1,53 @@ +#include "TelemetryReport.h" + +namespace Telemetry { + +void init(const std::string &name) { + (void)name; +} + +void deinit() { +} + +void reportErrorV(const char* file, int line, const char* function, const char* format, va_list args) { + (void)file; + (void)line; + (void)function; + (void)format; + (void)args; +} + +void reportError(const char* file, int line, const char* function, const char* format, ...) { + (void)file; + (void)line; + (void)function; + (void)format; +} + +void DummyTelemetryReport::reportPlaybackState( + AVPipelineState state, + const std::string &additionalInfo, + MediaType mediaType) { + (void)state; + (void)additionalInfo; + (void)mediaType; +} + +void DummyTelemetryReport::reportDrmInfo( + DrmType drmType, + const std::string &additionalInfo) { + (void)drmType; + (void)additionalInfo; +} + +void DummyTelemetryReport::reportWaylandInfo( + const IWaylandInfoGetter &getter, + WaylandAction action, + WaylandGraphicsState gfxState, + WaylandInputsState inputsState) { + (void)getter; + (void)action; + (void)gfxState; + (void)inputsState; +} +} diff --git a/Source/ThirdParty/telemetry/src/RdkTelemetryReport.cpp b/Source/ThirdParty/telemetry/src/RdkTelemetryReport.cpp new file mode 100644 index 0000000000000..2976f7db26338 --- /dev/null +++ b/Source/ThirdParty/telemetry/src/RdkTelemetryReport.cpp @@ -0,0 +1,131 @@ +#include +#include +#include + +#include "TelemetryReport.h" +#include "av_pipeline.h" +#include "odhott_wl.h" +#include "odherr_ctx.h" + +namespace AVP = OttReports::AvPipeline; + +namespace Telemetry { + +static AVP::AvPipeline avPipelineReport{OttReports::Owner::type::Wpe}; + +void init(const std::string &name) { + odh_error_report_init(name.c_str()); +} + +void deinit() { + odh_error_report_deinit(ODH_ERROR_REPORT_DEINIT_MODE_DEFERRED); +} + +void reportErrorV(const char* file, int line, const char* function, const char* format, va_list args) +{ + int length = vsnprintf(NULL, 0, format, args); + if (length < 0) return; + + char *msg = (char*)malloc(length + 1); + if (!msg) return; + + vsnprintf(msg, length + 1, format, args); + + char* backtrace = odh_error_report_sprintf("%s:%d %s", file, line, function); + char* ctx = odh_ctx_create_json("wpe", "ss", + "function", function, + "file", file); + odh_error_report_send_v3(ODH_ERROR_REPORT_SENSITIVITY_NONSENSITIVE, + ODH_ERROR_REPORT_LEVEL_ERROR, + "WPE0050", + nullptr, + msg, + ctx, + backtrace, + "browser"); + free(ctx); + free(backtrace); + free(msg); +} + +void reportError(const char* file, int line, const char* function, const char* format, ...) +{ + va_list args; + va_start(args, format); + reportErrorV(file, line, function, format, args); + va_end(args); +} + +static std::map pipelineStateMap { + {IReport::AVPipelineState::CREATE, AVP::State::type::Create}, + {IReport::AVPipelineState::PLAY, AVP::State::type::Play}, + {IReport::AVPipelineState::PAUSE, AVP::State::type::Pause}, + {IReport::AVPipelineState::STOP, AVP::State::type::Stop}, + {IReport::AVPipelineState::DESTROY, AVP::State::type::Destroy}, + {IReport::AVPipelineState::FIRST_FRAME_DECODED, AVP::State::type::FirstFrameDecoded}, + {IReport::AVPipelineState::END_OF_STREAM, AVP::State::type::EndOfStream}, + {IReport::AVPipelineState::DECRYPT_ERROR, AVP::State::type::DecryptError}, + {IReport::AVPipelineState::PLAYBACK_ERROR, AVP::State::type::PlaybackError}, + {IReport::AVPipelineState::DRM_ERROR, AVP::State::type::DrmError}, + {IReport::AVPipelineState::ERROR, AVP::State::type::Error}, + {IReport::AVPipelineState::SEEK_START, AVP::State::type::SeekStart}, + {IReport::AVPipelineState::SEEK_DONE, AVP::State::type::SeekDone}, + {IReport::AVPipelineState::VIDEO_RESOLUTION_CHANGED, AVP::State::type::VideoResolutionChanged}, + {IReport::AVPipelineState::UNKNOWN, AVP::State::type::Unknown} +}; + +static std::map drmTypeMap { + {IReport::DrmType::PLAYREADY, AVP::Drm::type::Playready}, + {IReport::DrmType::WIDEVINE, AVP::Drm::type::Widevine}, + {IReport::DrmType::NONE, AVP::Drm::type::None}, + {IReport::DrmType::UNKNOWN, AVP::Drm::type::Unknown}, +}; + +static std::map waylandActionMap { + {IReport::WaylandAction::INIT_GFX , odh_report_wayland_action_t::ODH_REPORT_WAYLAND_ACTION_INIT_GFX}, + {IReport::WaylandAction::DEINIT_GFX, odh_report_wayland_action_t::ODH_REPORT_WAYLAND_ACTION_DEINIT_GFX}, + {IReport::WaylandAction::INIT_INPUTS, odh_report_wayland_action_t::ODH_REPORT_WAYLAND_ACTION_INIT_INPUTS}, + {IReport::WaylandAction::DEINIT_INPUTS, odh_report_wayland_action_t::ODH_REPORT_WAYLAND_ACTION_DEINIT_INPUTS} +}; + +static std::map waylandGraphicsStateMap { + {IReport::WaylandGraphicsState::GFX_NOT_INITIALIZED, false}, + {IReport::WaylandGraphicsState::GFX_INITIALIZED, true} +}; + +static std::map waylandInputsStateMap { + {IReport::WaylandInputsState::INPUTS_NOT_INITIALIZED, false}, + {IReport::WaylandInputsState::INPUTS_INITIALIZED, true} +}; + +void RdkTelemetryReport::reportPlaybackState( + IReport::AVPipelineState state, + const std::string &additionalInfo, + MediaType mediaType) { + avPipelineReport.setSource(AVP::Source::type::Unknown); + avPipelineReport.setAdditionalInfo(additionalInfo.empty() ? "" : additionalInfo); + avPipelineReport.send(pipelineStateMap[state]); +} + +void RdkTelemetryReport::reportDrmInfo( + IReport::DrmType drmType, + const std::string &additionalInfo) { + avPipelineReport.setDrm(drmTypeMap[drmType]); + avPipelineReport.setSource(AVP::Source::type::Unknown); + avPipelineReport.setAdditionalInfo(additionalInfo.empty() ? "" : additionalInfo); + avPipelineReport.send(AVP::State::type::Unknown); +} + +void RdkTelemetryReport::reportWaylandInfo( + const IWaylandInfoGetter &getter, + IReport::WaylandAction action, + IReport::WaylandGraphicsState gfxState, + IReport::WaylandInputsState inputsState) { + odh_ott_wayland_report( + reinterpret_cast(getter), + ODH_REPORT_WAYLAND_OWNER_WPE, + waylandActionMap[action], + waylandGraphicsStateMap[gfxState], + waylandInputsStateMap[inputsState]); +} +} diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt index 078ee00a25c89..ff735bc1130be 100644 --- a/Source/WebCore/CMakeLists.txt +++ b/Source/WebCore/CMakeLists.txt @@ -2059,6 +2059,9 @@ if (USE_LIBWEBRTC) ) endif () +list(APPEND WebCore_PRIVATE_INCLUDE_DIRECTORIES "${THIRDPARTY_DIR}/telemetry/include") +list(APPEND WebCore_LIBRARIES "telemetry") + if (HAVE_OS_DARK_MODE_SUPPORT) set(FEATURE_DEFINES_WITH_SPACE_SEPARATOR "${FEATURE_DEFINES_WITH_SPACE_SEPARATOR} HAVE_OS_DARK_MODE_SUPPORT") endif () diff --git a/Source/WebCore/platform/graphics/egl/GLContextEGL.cpp b/Source/WebCore/platform/graphics/egl/GLContextEGL.cpp index 6ef9788c6fbe1..1475298f0098f 100644 --- a/Source/WebCore/platform/graphics/egl/GLContextEGL.cpp +++ b/Source/WebCore/platform/graphics/egl/GLContextEGL.cpp @@ -381,6 +381,11 @@ GLContextEGL::GLContextEGL(PlatformDisplay& display, EGLContext context, EGLSurf } RELEASE_ASSERT(!m_eglCreateImageKHR == !m_eglDestroyImageKHR); } + + if(m_type == WindowSurface) { + m_telemetry.reportWaylandInfo(*this, Telemetry::IReport::WaylandAction::INIT_GFX, + Telemetry::IReport::WaylandGraphicsState::GFX_INITIALIZED, Telemetry::IReport::WaylandInputsState::INPUTS_INITIALIZED); + } } GLContextEGL::~GLContextEGL() @@ -401,6 +406,11 @@ GLContextEGL::~GLContextEGL() #if USE(WPE_RENDERER) destroyWPETarget(); #endif + + if(m_type == WindowSurface) { + m_telemetry.reportWaylandInfo(*this, Telemetry::IReport::WaylandAction::DEINIT_GFX, + Telemetry::IReport::WaylandGraphicsState::GFX_NOT_INITIALIZED, Telemetry::IReport::WaylandInputsState::INPUTS_INITIALIZED); + } } EGLImage GLContextEGL::createImage(EGLenum target, EGLClientBuffer clientBuffer, const Vector& attribList) const @@ -543,6 +553,51 @@ GCGLContext GLContextEGL::platformContext() return m_context; } +EGLDisplay GLContextEGL::getEGLDisplay() const +{ + return m_display.eglDisplay(); +} + +EGLConfig GLContextEGL::getEGLConfig() const +{ + EGLConfig config = nullptr; + if (!getEGLConfig(m_display.eglDisplay(), &config, WindowSurface)) { + WTFLogAlways("Cannot obtain EGL window context configuration: %s\n", lastErrorString()); + config = nullptr; + } + return config; +} + +EGLSurface GLContextEGL::getEGLSurface() const +{ + return m_surface; +} + +EGLContext GLContextEGL::getEGLContext() const +{ + return m_context; +} + +unsigned int GLContextEGL::getWindowWidth() const +{ + const unsigned int WIDTH = 1920; + unsigned int ret_val = WIDTH; + char *tmp; + if ( (tmp = std::getenv("WPE_INIT_VIEW_WIDTH")) ) + ret_val = atoi(tmp); + return ret_val; +} + +unsigned int GLContextEGL::getWindowHeight() const +{ + const unsigned int HEIGHT = 1080; + unsigned int ret_val = HEIGHT; + char *tmp; + if ( (tmp = std::getenv("WPE_INIT_VIEW_HEIGHT")) ) + ret_val = atoi(tmp); + return ret_val; +} + } // namespace WebCore #endif // USE(EGL) diff --git a/Source/WebCore/platform/graphics/egl/GLContextEGL.h b/Source/WebCore/platform/graphics/egl/GLContextEGL.h index c48531a83c89f..646963ee3ae75 100644 --- a/Source/WebCore/platform/graphics/egl/GLContextEGL.h +++ b/Source/WebCore/platform/graphics/egl/GLContextEGL.h @@ -36,6 +36,8 @@ struct wl_egl_window; struct wpe_renderer_backend_egl_offscreen_target; #endif +#include + typedef intptr_t EGLAttrib; typedef unsigned EGLBoolean; typedef void *EGLClientBuffer; @@ -63,7 +65,7 @@ typedef EGLBoolean (*PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay, EGLImageKHR); namespace WebCore { -class GLContextEGL final : public GLContext { +class GLContextEGL final : public GLContext, public Telemetry::IWaylandInfoGetter { WTF_MAKE_NONCOPYABLE(GLContextEGL); public: static std::unique_ptr createContext(GLNativeWindowType, PlatformDisplay&); @@ -134,6 +136,7 @@ class GLContextEGL final : public GLContext { PFNEGLDESTROYIMAGEPROC m_eglDestroyImage { nullptr }; PFNEGLCREATEIMAGEKHRPROC m_eglCreateImageKHR { nullptr }; PFNEGLDESTROYIMAGEKHRPROC m_eglDestroyImageKHR { nullptr }; + TelemetryImpl m_telemetry; #if PLATFORM(X11) XUniquePixmap m_pixmap; #endif @@ -144,6 +147,12 @@ class GLContextEGL final : public GLContext { #if USE(WPE_RENDERER) struct wpe_renderer_backend_egl_offscreen_target* m_wpeTarget { nullptr }; #endif + EGLDisplay getEGLDisplay() const override; + EGLConfig getEGLConfig() const override; + EGLSurface getEGLSurface() const override; + EGLContext getEGLContext() const override; + unsigned int getWindowWidth() const override; + unsigned int getWindowHeight() const override; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp index db4c5624873a8..6d767dd2e400e 100644 --- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp @@ -224,6 +224,7 @@ MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer() { GST_DEBUG_OBJECT(pipeline(), "Disposing player"); m_isPlayerShuttingDown.store(true); + m_telemetry.reportPlaybackState(Telemetry::IReport::AVPipelineState::STOP); if (m_gstreamerHolePunchHost) m_gstreamerHolePunchHost->playerPrivateWillBeDestroyed(); @@ -291,6 +292,7 @@ MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer() m_player = nullptr; m_notifier->invalidate(); + m_telemetry.reportPlaybackState(Telemetry::IReport::AVPipelineState::DESTROY); } bool MediaPlayerPrivateGStreamer::isAvailable() @@ -450,6 +452,7 @@ void MediaPlayerPrivateGStreamer::play() m_preload = MediaPlayer::Preload::Auto; updateDownloadBufferingFlag(); GST_INFO_OBJECT(pipeline(), "Play"); + m_telemetry.reportPlaybackState(Telemetry::IReport::AVPipelineState::PLAY); } else loadingFailed(MediaPlayer::NetworkState::Empty); } @@ -466,9 +469,10 @@ void MediaPlayerPrivateGStreamer::pause() return; auto result = changePipelineState(GST_STATE_PAUSED); - if (result == ChangePipelineStateResult::Ok) + if (result == ChangePipelineStateResult::Ok) { GST_INFO_OBJECT(pipeline(), "Pause"); - else if (result == ChangePipelineStateResult::Failed) + m_telemetry.reportPlaybackState(Telemetry::IReport::AVPipelineState::PAUSE); + } else if (result == ChangePipelineStateResult::Failed) loadingFailed(MediaPlayer::NetworkState::Empty); } @@ -574,6 +578,8 @@ void MediaPlayerPrivateGStreamer::seek(const MediaTime& mediaTime) MediaTime time = std::min(mediaTime, durationMediaTime()); GST_INFO_OBJECT(pipeline(), "[Seek] seeking to %s", toString(time).utf8().data()); + m_telemetry.reportPlaybackState(Telemetry::IReport::AVPipelineState::SEEK_START, + "seek_from:" + std::to_string(playbackPosition().toDouble()) + ", seek_to:" + std::to_string(time.toDouble())); if (m_isSeeking) { m_timeOfOverlappingSeek = time; @@ -1876,6 +1882,7 @@ void MediaPlayerPrivateGStreamer::handleMessage(GstMessage* message) break; m_errorMessage = String::fromLatin1(err->message); + m_telemetry.reportPlaybackState(Telemetry::IReport::AVPipelineState::PLAYBACK_ERROR, std::string(err->message)); error = MediaPlayer::NetworkState::Empty; if (g_error_matches(err.get(), GST_STREAM_ERROR, GST_STREAM_ERROR_CODEC_NOT_FOUND) @@ -2514,6 +2521,7 @@ void MediaPlayerPrivateGStreamer::purgeOldDownloadFiles(const String& downloadFi void MediaPlayerPrivateGStreamer::finishSeek() { GST_DEBUG_OBJECT(pipeline(), "[Seek] seeked to %s", toString(m_seekTime).utf8().data()); + m_telemetry.reportPlaybackState(Telemetry::IReport::AVPipelineState::SEEK_DONE, "seek_to:" + std::to_string(m_seekTime.toDouble())); m_isSeeking = false; invalidateCachedPosition(); if (m_timeOfOverlappingSeek != m_seekTime && m_timeOfOverlappingSeek.isValid()) { @@ -2873,6 +2881,7 @@ void MediaPlayerPrivateGStreamer::didEnd() #endif } timeChanged(); + m_telemetry.reportPlaybackState(Telemetry::IReport::AVPipelineState::END_OF_STREAM); } void MediaPlayerPrivateGStreamer::getSupportedTypes(HashSet& types) @@ -3103,6 +3112,9 @@ void MediaPlayerPrivateGStreamer::createGSTPlayBin(const URL& url) g_signal_connect(videoSinkPad.get(), "notify::caps", G_CALLBACK(+[](GstPad* videoSinkPad, GParamSpec*, MediaPlayerPrivateGStreamer* player) { player->videoSinkCapsChanged(videoSinkPad); }), this); + + m_telemetry.reportDrmInfo(getDrm()); + m_telemetry.reportPlaybackState(Telemetry::IReport::AVPipelineState::CREATE); } void MediaPlayerPrivateGStreamer::configureVideoDecoder(GstElement* decoder) @@ -3192,6 +3204,7 @@ void MediaPlayerPrivateGStreamer::pausedTimerFired() { GST_DEBUG_OBJECT(pipeline(), "In PAUSED for too long. Releasing pipeline resources."); changePipelineState(GST_STATE_NULL); + m_telemetry.reportPlaybackState(Telemetry::IReport::AVPipelineState::DESTROY); } void MediaPlayerPrivateGStreamer::acceleratedRenderingStateChanged() @@ -4630,6 +4643,42 @@ void MediaPlayerPrivateGStreamer::checkPlayingConsistency() } } +Telemetry::IReport::DrmType MediaPlayerPrivateGStreamer::getDrm() const +{ + if (m_pipeline.get()) { + GRefPtr drmCdmInstanceContext = adoptGRef(gst_element_get_context(GST_ELEMENT(m_pipeline.get()), "drm-cdm-instance")); + if (!drmCdmInstanceContext) { + return {Telemetry::IReport::DrmType::NONE}; + } + + const GstStructure* drmCdmInstanceStructure = gst_context_get_structure(drmCdmInstanceContext.get()); + if (!drmCdmInstanceStructure) { + return {Telemetry::IReport::DrmType::NONE}; + } + + const GValue* drmCdmInstanceVal = gst_structure_get_value(drmCdmInstanceStructure, "cdm-instance"); + if (!drmCdmInstanceVal) { + return {Telemetry::IReport::DrmType::NONE}; + } + + const CDMInstance* drmCdmInstance = (const CDMInstance*)g_value_get_pointer(drmCdmInstanceVal); + if (!drmCdmInstance) { + return {Telemetry::IReport::DrmType::NONE}; + } + + const std::string keySystem = drmCdmInstance->keySystem().utf8().data(); + if (keySystem.find("playready") != string::npos) { + return {Telemetry::IReport::DrmType::PLAYREADY}; + } else if (keySystem.find("widevine") != string::npos) { + return {Telemetry::IReport::DrmType::WIDEVINE}; + } + else { + return {Telemetry::IReport::DrmType::UNKNOWN}; + } + } + return {Telemetry::IReport::DrmType::NONE}; +} + } #endif // USE(GSTREAMER) diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h index b6c48889e2d2c..aa418b66488be 100644 --- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h +++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h @@ -48,6 +48,7 @@ #include #include #include +#include typedef struct _GstMpegtsSection GstMpegtsSection; @@ -581,6 +582,7 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface InitData parseInitDataFromProtectionMessage(GstMessage*); bool waitForCDMAttachment(); #endif + Telemetry::IReport::DrmType getDrm() const; void configureMediaStreamAudioTracks(); void invalidateCachedPositionOnNextIteration() const; @@ -604,6 +606,7 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface Lock m_drawLock; RunLoop::Timer m_drawTimer WTF_GUARDED_BY_LOCK(m_drawLock); RunLoop::Timer m_pausedTimerHandler; + TelemetryImpl m_telemetry; #if USE(TEXTURE_MAPPER_GL) #if USE(NICOSIA) RefPtr m_nicosiaLayer; diff --git a/Source/cmake/OptionsWPE.cmake b/Source/cmake/OptionsWPE.cmake index 8c4a5f1ae1cfd..c11dfec555740 100644 --- a/Source/cmake/OptionsWPE.cmake +++ b/Source/cmake/OptionsWPE.cmake @@ -97,6 +97,7 @@ WEBKIT_OPTION_DEFINE(USE_JPEGXL "Whether to enable support for JPEG-XL images." WEBKIT_OPTION_DEFINE(USE_LCMS "Whether to enable support for image color management using libcms2." PUBLIC ON) WEBKIT_OPTION_DEFINE(USE_LIBBACKTRACE "Whether to enable usage of libbacktrace." PUBLIC OFF) WEBKIT_OPTION_DEFINE(USE_OPENJPEG "Whether to enable support for JPEG2000 images." PUBLIC ON) +WEBKIT_OPTION_DEFINE(USE_RDK_TELEMETRY "Whether to enable support for ODH telemetry." PUBLIC OFF) WEBKIT_OPTION_DEFINE(USE_SOUP2 "Whether to enable usage of Soup 2 instead of Soup 3." PUBLIC OFF) WEBKIT_OPTION_DEFINE(USE_WOFF2 "Whether to enable support for WOFF2 Web Fonts." PUBLIC ON) @@ -440,4 +441,4 @@ if (USE_LIBBACKTRACE) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}${CMAKE_COMPILER_SIZE_OPT_FLAGS} -funwind-tables") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}${CMAKE_COMPILER_SIZE_OPT_FLAGS} -funwind-tables") -endif () \ No newline at end of file +endif () From cff168db27dd202e50d4dfe9cb30710bd4d1865d Mon Sep 17 00:00:00 2001 From: Marcin Mielczarczyk Date: Tue, 28 Jan 2025 23:48:59 +0100 Subject: [PATCH 2/2] Draft proposal of RDK Telemetry quirk for gstreamer --- .../gstreamer/MediaPlayerPrivateGStreamer.cpp | 53 +++++++++++++---- .../gstreamer/GStreamerQuirkRdkTelemetry.cpp | 57 +++++++++++++++++++ .../gstreamer/GStreamerQuirkRdkTelemetry.h | 41 +++++++++++++ .../platform/gstreamer/GStreamerQuirks.cpp | 7 ++- .../platform/gstreamer/GStreamerQuirks.h | 4 ++ 5 files changed, 149 insertions(+), 13 deletions(-) create mode 100644 Source/WebCore/platform/gstreamer/GStreamerQuirkRdkTelemetry.cpp create mode 100644 Source/WebCore/platform/gstreamer/GStreamerQuirkRdkTelemetry.h diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp index 6d767dd2e400e..55c76d37ecdc5 100644 --- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp @@ -224,7 +224,10 @@ MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer() { GST_DEBUG_OBJECT(pipeline(), "Disposing player"); m_isPlayerShuttingDown.store(true); - m_telemetry.reportPlaybackState(Telemetry::IReport::AVPipelineState::STOP); + + auto& quirksManager = GStreamerQuirksManager::singleton(); + if (quirksManager.isEnabled()) + quirksManager.reportPlaybackState(Telemetry::IReport::AVPipelineState::STOP); if (m_gstreamerHolePunchHost) m_gstreamerHolePunchHost->playerPrivateWillBeDestroyed(); @@ -292,7 +295,9 @@ MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer() m_player = nullptr; m_notifier->invalidate(); - m_telemetry.reportPlaybackState(Telemetry::IReport::AVPipelineState::DESTROY); + + if (quirksManager.isEnabled()) + quirksManager.reportPlaybackState(Telemetry::IReport::AVPipelineState::DESTROY); } bool MediaPlayerPrivateGStreamer::isAvailable() @@ -452,7 +457,10 @@ void MediaPlayerPrivateGStreamer::play() m_preload = MediaPlayer::Preload::Auto; updateDownloadBufferingFlag(); GST_INFO_OBJECT(pipeline(), "Play"); - m_telemetry.reportPlaybackState(Telemetry::IReport::AVPipelineState::PLAY); + + auto& quirksManager = GStreamerQuirksManager::singleton(); + if (quirksManager.isEnabled()) + quirksManager.reportPlaybackState(Telemetry::IReport::AVPipelineState::PLAY); } else loadingFailed(MediaPlayer::NetworkState::Empty); } @@ -471,7 +479,9 @@ void MediaPlayerPrivateGStreamer::pause() auto result = changePipelineState(GST_STATE_PAUSED); if (result == ChangePipelineStateResult::Ok) { GST_INFO_OBJECT(pipeline(), "Pause"); - m_telemetry.reportPlaybackState(Telemetry::IReport::AVPipelineState::PAUSE); + auto& quirksManager = GStreamerQuirksManager::singleton(); + if (quirksManager.isEnabled()) + quirksManager.reportPlaybackState(Telemetry::IReport::AVPipelineState::PAUSE); } else if (result == ChangePipelineStateResult::Failed) loadingFailed(MediaPlayer::NetworkState::Empty); } @@ -578,8 +588,11 @@ void MediaPlayerPrivateGStreamer::seek(const MediaTime& mediaTime) MediaTime time = std::min(mediaTime, durationMediaTime()); GST_INFO_OBJECT(pipeline(), "[Seek] seeking to %s", toString(time).utf8().data()); - m_telemetry.reportPlaybackState(Telemetry::IReport::AVPipelineState::SEEK_START, - "seek_from:" + std::to_string(playbackPosition().toDouble()) + ", seek_to:" + std::to_string(time.toDouble())); + + auto& quirksManager = GStreamerQuirksManager::singleton(); + if (quirksManager.isEnabled()) + quirksManager.reportPlaybackState(Telemetry::IReport::AVPipelineState::SEEK_START, + "seek_from:" + std::to_string(playbackPosition().toDouble()) + ", seek_to:" + std::to_string(time.toDouble())); if (m_isSeeking) { m_timeOfOverlappingSeek = time; @@ -1882,7 +1895,10 @@ void MediaPlayerPrivateGStreamer::handleMessage(GstMessage* message) break; m_errorMessage = String::fromLatin1(err->message); - m_telemetry.reportPlaybackState(Telemetry::IReport::AVPipelineState::PLAYBACK_ERROR, std::string(err->message)); + + auto& quirksManager = GStreamerQuirksManager::singleton(); + if (quirksManager.isEnabled()) + quirksManager.reportPlaybackState(Telemetry::IReport::AVPipelineState::PLAYBACK_ERROR, std::string(err->message)); error = MediaPlayer::NetworkState::Empty; if (g_error_matches(err.get(), GST_STREAM_ERROR, GST_STREAM_ERROR_CODEC_NOT_FOUND) @@ -2521,7 +2537,11 @@ void MediaPlayerPrivateGStreamer::purgeOldDownloadFiles(const String& downloadFi void MediaPlayerPrivateGStreamer::finishSeek() { GST_DEBUG_OBJECT(pipeline(), "[Seek] seeked to %s", toString(m_seekTime).utf8().data()); - m_telemetry.reportPlaybackState(Telemetry::IReport::AVPipelineState::SEEK_DONE, "seek_to:" + std::to_string(m_seekTime.toDouble())); + + auto& quirksManager = GStreamerQuirksManager::singleton(); + if (quirksManager.isEnabled()) + quirksManager.reportPlaybackState(Telemetry::IReport::AVPipelineState::SEEK_DONE, "seek_to:" + std::to_string(m_seekTime.toDouble())); + m_isSeeking = false; invalidateCachedPosition(); if (m_timeOfOverlappingSeek != m_seekTime && m_timeOfOverlappingSeek.isValid()) { @@ -2881,7 +2901,10 @@ void MediaPlayerPrivateGStreamer::didEnd() #endif } timeChanged(); - m_telemetry.reportPlaybackState(Telemetry::IReport::AVPipelineState::END_OF_STREAM); + + auto& quirksManager = GStreamerQuirksManager::singleton(); + if (quirksManager.isEnabled()) + quirksManager.reportPlaybackState(Telemetry::IReport::AVPipelineState::END_OF_STREAM); } void MediaPlayerPrivateGStreamer::getSupportedTypes(HashSet& types) @@ -3113,8 +3136,11 @@ void MediaPlayerPrivateGStreamer::createGSTPlayBin(const URL& url) player->videoSinkCapsChanged(videoSinkPad); }), this); - m_telemetry.reportDrmInfo(getDrm()); - m_telemetry.reportPlaybackState(Telemetry::IReport::AVPipelineState::CREATE); + auto& quirksManager = GStreamerQuirksManager::singleton(); + if (quirksManager.isEnabled()) { + quirksManager.reportDrmInfo(getDrm()); + quirksManager.reportPlaybackState(Telemetry::IReport::AVPipelineState::CREATE); + } } void MediaPlayerPrivateGStreamer::configureVideoDecoder(GstElement* decoder) @@ -3204,7 +3230,10 @@ void MediaPlayerPrivateGStreamer::pausedTimerFired() { GST_DEBUG_OBJECT(pipeline(), "In PAUSED for too long. Releasing pipeline resources."); changePipelineState(GST_STATE_NULL); - m_telemetry.reportPlaybackState(Telemetry::IReport::AVPipelineState::DESTROY); + + auto& quirksManager = GStreamerQuirksManager::singleton(); + if (quirksManager.isEnabled()) + quirksManager.reportPlaybackState(Telemetry::IReport::AVPipelineState::DESTROY); } void MediaPlayerPrivateGStreamer::acceleratedRenderingStateChanged() diff --git a/Source/WebCore/platform/gstreamer/GStreamerQuirkRdkTelemetry.cpp b/Source/WebCore/platform/gstreamer/GStreamerQuirkRdkTelemetry.cpp new file mode 100644 index 0000000000000..eb6599bfccffa --- /dev/null +++ b/Source/WebCore/platform/gstreamer/GStreamerQuirkRdkTelemetry.cpp @@ -0,0 +1,57 @@ +/* + * Copyright 2024 RDK Management + * + * 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" +#include "GStreamerQuirkRdkTelemetry.h" + +#if USE(GSTREAMER) + +#include "GStreamerCommon.h" + +namespace WebCore { + +GST_DEBUG_CATEGORY_STATIC(webkit_rdktelemetry_quirks_debug); +#define GST_CAT_DEFAULT webkit_rdktelemetry_quirks_debug + +GStreamerQuirkRdkTelemetry::GStreamerQuirkRdkTelemetry() +{ + GST_DEBUG_CATEGORY_INIT(webkit_rdktelemetry_quirks_debug, "webkitquirksrdktelemetry", 0, "WebKit RDK Telemetry Quirks"); +} + +void GStreamerQuirkRdkTelemetry::reportPlaybackState(AVPipelineState state, const std::string &additionalInfo, MediaType mediaType) +{ + //TBD +} + +void GStreamerQuirkRdkTelemetry::reportDrmInfo(DrmType drmType, const std::string &additionalInfo) +{ + //TBD +} + +#undef GST_CAT_DEFAULT + +} // namespace WebCore + +#endif // USE(GSTREAMER) diff --git a/Source/WebCore/platform/gstreamer/GStreamerQuirkRdkTelemetry.h b/Source/WebCore/platform/gstreamer/GStreamerQuirkRdkTelemetry.h new file mode 100644 index 0000000000000..a8dc585649b5d --- /dev/null +++ b/Source/WebCore/platform/gstreamer/GStreamerQuirkRdkTelemetry.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 Igalia S.L + * Copyright (C) 2024 Metrological Group B.V. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * aint with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#if USE(GSTREAMER) + +#include "GStreamerQuirks.h" +#include "ITelemetry.h" + +namespace WebCore { + +class GStreamerQuirkRdkTelemetry final : public GStreamerQuirk { +public: + GStreamerQuirkRdkTelemetry(); + const ASCIILiteral identifier() const final { return "RdkTelemetry"_s; } + + void reportPlaybackState(AVPipelineState state, const std::string &additionalInfo, MediaType mediaType) final; + void reportDrmInfo(DrmType drmType, const std::string &additionalInfo) final; +}; + +} // namespace WebCore + +#endif // USE(GSTREAMER) diff --git a/Source/WebCore/platform/gstreamer/GStreamerQuirks.cpp b/Source/WebCore/platform/gstreamer/GStreamerQuirks.cpp index ec3bf127110b3..79028db0c2aae 100644 --- a/Source/WebCore/platform/gstreamer/GStreamerQuirks.cpp +++ b/Source/WebCore/platform/gstreamer/GStreamerQuirks.cpp @@ -85,6 +85,9 @@ GStreamerQuirksManager::GStreamerQuirksManager(bool isForTesting, bool loadQuirk #if PLATFORM(RPI) && CPU(ARM) && !CPU(ARM64) quirksListBuilder.append("openmax,"); #endif +#if USE(RDK_TELEMETRY) + quirksListBuilder.append("rdktelemetry"); +#endif #if PLATFORM(REALTEK) quirksListBuilder.append("realtek,"); #endif @@ -96,7 +99,7 @@ GStreamerQuirksManager::GStreamerQuirksManager(bool isForTesting, bool loadQuirk GST_DEBUG("Attempting to parse requested quirks: %s", quirks.ascii().data()); if (!quirks.isEmpty()) { if (WTF::equalLettersIgnoringASCIICase(quirks, "help"_s)) { - WTFLogAlways("Supported quirks for WEBKIT_GST_QUIRKS are: amlogic, broadcom, bcmnexus, openmax, realtek, westeros"); + WTFLogAlways("Supported quirks for WEBKIT_GST_QUIRKS are: amlogic, broadcom, bcmnexus, openmax, rdktelemetry, realtek, westeros"); return; } @@ -110,6 +113,8 @@ GStreamerQuirksManager::GStreamerQuirksManager(bool isForTesting, bool loadQuirk quirk = WTF::makeUnique(); else if (WTF::equalLettersIgnoringASCIICase(identifier, "openmax"_s)) quirk = WTF::makeUnique(); + else if (WTF::equalLettersIgnoringASCIICase(identifier, "rdktelemetry"_s)) + quirk = WTF::makeUnique(); else if (WTF::equalLettersIgnoringASCIICase(identifier, "realtek"_s)) quirk = WTF::makeUnique(); else if (WTF::equalLettersIgnoringASCIICase(identifier, "rialto"_s)) diff --git a/Source/WebCore/platform/gstreamer/GStreamerQuirks.h b/Source/WebCore/platform/gstreamer/GStreamerQuirks.h index 7a6ad90311e53..675a78784a62f 100644 --- a/Source/WebCore/platform/gstreamer/GStreamerQuirks.h +++ b/Source/WebCore/platform/gstreamer/GStreamerQuirks.h @@ -147,6 +147,10 @@ class GStreamerQuirksManager : public RefCounted { void setupBufferingPercentageCorrection(MediaPlayerPrivateGStreamer*, GstState currentState, GstState newState, GRefPtr&&) const; void processWebAudioSilentBuffer(GstBuffer*) const; + + void reportPlaybackState(AVPipelineState state, const std::string &additionalInfo = "", MediaType mediaType = MediaType::NONE); + void reportDrmInfo(DrmType drmType, const std::string &additionalInfo = ""); + private: GStreamerQuirksManager(bool, bool);