diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp index 6d767dd2e400..55c76d37ecdc 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 000000000000..eb6599bfccff --- /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 000000000000..a8dc585649b5 --- /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 ec3bf127110b..79028db0c2aa 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 7a6ad90311e5..675a78784a62 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);