From 1e2d1a15b2ae0cefacc859f8807bb7c4e4446dcc Mon Sep 17 00:00:00 2001 From: Michael Nutt Date: Wed, 17 Jul 2024 17:17:08 +0900 Subject: [PATCH] gstreamer feature builds but does not yet work --- Source/WTF/wtf/PlatformQt.cmake | 6 ++++++ .../graphics/gstreamer/GStreamerCommon.cpp | 2 ++ .../graphics/gstreamer/ImageGStreamer.h | 8 ++++++++ .../graphics/gstreamer/ImageGStreamerQt.cpp | 8 +++++--- .../gstreamer/MediaPlayerPrivateGStreamer.cpp | 19 +++++++++++++++++-- .../gstreamer/MediaPlayerPrivateGStreamer.h | 4 ++-- .../gstreamer/VideoFrameGStreamer.cpp | 15 +++++++++++++++ 7 files changed, 55 insertions(+), 7 deletions(-) diff --git a/Source/WTF/wtf/PlatformQt.cmake b/Source/WTF/wtf/PlatformQt.cmake index 961785363bb3c..7b36060246da9 100644 --- a/Source/WTF/wtf/PlatformQt.cmake +++ b/Source/WTF/wtf/PlatformQt.cmake @@ -109,6 +109,12 @@ if (USE_GLIB) glib/Sandbox.h glib/WTFGType.h ) + + if (USE_GSTREAMER) + list(APPEND WTF_PUBLIC_HEADERS + glib/GThreadSafeWeakPtr.h + ) + endif () endif () if (WIN32) diff --git a/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp b/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp index 993a98ccfd102..e9e50fc7af14e 100644 --- a/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp @@ -276,7 +276,9 @@ bool ensureGStreamerInitialized() { // WARNING: Please note this function can be called from any thread, for instance when creating // a WebCodec element from a JS Worker. +#if !PLATFORM(QT) RELEASE_ASSERT(isInWebProcess()); +#endif static std::once_flag onceFlag; static bool isGStreamerInitialized; std::call_once(onceFlag, [] { diff --git a/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h b/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h index 388e34ad4b8d3..d092f4aded711 100644 --- a/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h +++ b/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h @@ -40,14 +40,22 @@ class ImageGStreamer : public RefCounted { } ~ImageGStreamer(); +#if PLATFORM(QT) + operator bool() const { return !m_image.isNull(); } +#else operator bool() const { return !!m_image; } +#endif PlatformImagePtr image() const { return m_image; } void setCropRect(FloatRect rect) { m_cropRect = rect; } FloatRect rect() { +#if PLATFORM(QT) + ASSERT(!m_image.isNull()); +#else ASSERT(m_image); +#endif if (!m_cropRect.isEmpty()) return FloatRect(m_cropRect); return FloatRect(0, 0, m_size.width(), m_size.height()); diff --git a/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerQt.cpp b/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerQt.cpp index 90f4d129831af..beae68bcd6584 100644 --- a/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerQt.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerQt.cpp @@ -23,6 +23,7 @@ #if ENABLE(VIDEO) && USE(GSTREAMER) #include "GStreamerCommon.h" +#include "BitmapImage.h" #include #include @@ -96,7 +97,11 @@ ImageGStreamer::ImageGStreamer(GRefPtr&& sample) } else surface = QImage(bufferData, width, height, stride, imageFormat); +#if PLATFORM(QT) + m_image = QImage(surface); +#else m_image = BitmapImage::create(WTFMove(surface)); +#endif if (GstVideoCropMeta* cropMeta = gst_buffer_get_video_crop_meta(buffer)) setCropRect(FloatRect(cropMeta->x, cropMeta->y, cropMeta->width, cropMeta->height)); @@ -104,9 +109,6 @@ ImageGStreamer::ImageGStreamer(GRefPtr&& sample) ImageGStreamer::~ImageGStreamer() { - if (m_image) - m_image = nullptr; - // We keep the buffer memory mapped until the image is destroyed because the internal // QImage was created using the buffer data directly. if (m_frameMapped) diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp index 42905d8621501..f7952858d0122 100644 --- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp @@ -120,6 +120,10 @@ #include "TextureMapperPlatformLayerProxyGL.h" #endif // USE(TEXTURE_MAPPER) +#if PLATFORM(QT) +#include "TextureMapperFlags.h" +#endif + #if USE(TEXTURE_MAPPER_DMABUF) #include "DMABufFormat.h" #include "DMABufObject.h" @@ -1992,6 +1996,7 @@ void MediaPlayerPrivateGStreamer::handleMessage(GstMessage* message) GstState newState; gst_message_parse_state_changed(message, ¤tState, &newState, nullptr); +#if USE(GSTREAMER_GL) if (isHolePunchRenderingEnabled() && currentState <= GST_STATE_READY && newState >= GST_STATE_READY) { // If we didn't create a video sink, store a reference to the created one. if (!m_videoSink) { @@ -2010,6 +2015,7 @@ void MediaPlayerPrivateGStreamer::handleMessage(GstMessage* message) } } } +#endif auto& quirksManager = GStreamerQuirksManager::singleton(); if (quirksManager.isEnabled() && currentState <= GST_STATE_READY && newState >= GST_STATE_READY) { @@ -4081,13 +4087,13 @@ bool MediaPlayerPrivateGStreamer::setVideoSourceOrientation(ImageOrientation ori return false; m_videoSourceOrientation = orientation; -#if USE(TEXTURE_MAPPER) && !PLATFORM(QT) +#if USE(TEXTURE_MAPPER) updateTextureMapperFlags(); #endif return true; } -#if USE(TEXTURE_MAPPER) && !PLATFORM(QT) +#if USE(TEXTURE_MAPPER) void MediaPlayerPrivateGStreamer::updateTextureMapperFlags() { switch (m_videoSourceOrientation.orientation()) { @@ -4173,6 +4179,12 @@ GstElement* MediaPlayerPrivateGStreamer::createVideoSinkGL() } #endif // USE(GSTREAMER_GL) +#if PLATFORM(QT) +bool MediaPlayerPrivateGStreamer::isHolePunchRenderingEnabled() const +{ + return false; +} +#else class GStreamerHolePunchClient : public TextureMapperPlatformLayerBuffer::HolePunchClient { public: GStreamerHolePunchClient(GRefPtr&& videoSink, RefPtr&& quirksManagerForTesting) @@ -4249,6 +4261,7 @@ void MediaPlayerPrivateGStreamer::pushNextHolePunchBuffer() proxyOperation(*m_platformLayerProxy); #endif } +#endif // !PLATFORM(QT) bool MediaPlayerPrivateGStreamer::shouldIgnoreIntrinsicSize() { @@ -4297,12 +4310,14 @@ GstElement* MediaPlayerPrivateGStreamer::createVideoSink() return m_videoSink.get(); } +#if USE(GSTREAMER_GL) if (isHolePunchRenderingEnabled()) { m_videoSink = createHolePunchVideoSink(); // Do not check the m_videoSink value. The nullptr case will trigger auto-plugging in playbin. pushNextHolePunchBuffer(); return m_videoSink.get(); } +#endif #if USE(TEXTURE_MAPPER_DMABUF) if (!m_videoSink && m_canRenderingBeAccelerated) diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h index 2e1015ecf0f40..8e04f81a31d81 100644 --- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h +++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h @@ -342,7 +342,7 @@ class MediaPlayerPrivateGStreamer void loadingFailed(MediaPlayer::NetworkState, MediaPlayer::ReadyState = MediaPlayer::ReadyState::HaveNothing, bool forceNotifications = false); void loadStateChanged(); -#if USE(TEXTURE_MAPPER) && !PLATFORM(QT) +#if USE(TEXTURE_MAPPER) void updateTextureMapperFlags(); #endif @@ -389,7 +389,7 @@ class MediaPlayerPrivateGStreamer GRefPtr m_source { nullptr }; bool m_areVolumeAndMuteInitialized { false }; -#if USE(TEXTURE_MAPPER) && !PLATFORM(QT) +#if USE(TEXTURE_MAPPER) OptionSet m_textureMapperFlags; #endif diff --git a/Source/WebCore/platform/graphics/gstreamer/VideoFrameGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/VideoFrameGStreamer.cpp index 8a621d9afa30d..f0a61499af790 100644 --- a/Source/WebCore/platform/graphics/gstreamer/VideoFrameGStreamer.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/VideoFrameGStreamer.cpp @@ -25,7 +25,9 @@ #if ENABLE(VIDEO) && USE(GSTREAMER) #include "BitmapImage.h" +#if USE(GSTREAMER_GL) #include "GLContext.h" +#endif #include "GStreamerCommon.h" #include "GraphicsContext.h" #include "ImageGStreamer.h" @@ -149,6 +151,19 @@ RefPtr VideoFrame::fromNativeImage(NativeImage& image) default: return nullptr; } +#elif PLATFORM(QT) + QImage platformImage = image.platformImage(); + auto width = platformImage.width(); + auto height = platformImage.height(); + strides[0] = platformImage.bytesPerLine(); + auto size = platformImage.sizeInBytes(); + + auto format = G_BYTE_ORDER == G_LITTLE_ENDIAN ? GST_VIDEO_FORMAT_BGRA : GST_VIDEO_FORMAT_ARGB; + QImage* imagePtr = new QImage(platformImage); + auto buffer = adoptGRef(gst_buffer_new_wrapped_full(GST_MEMORY_FLAG_READONLY, (void *)platformImage.constBits(), size, 0, size, imagePtr, [](gpointer userData) { + QImage* imagePtr = static_cast(userData); + delete imagePtr; + })); #endif gst_buffer_add_video_meta_full(buffer.get(), GST_VIDEO_FRAME_FLAG_NONE, format, width, height, 1, offsets, strides);