Compare commits

..

No commits in common. "14831f4b59b1ead7abf02a88c0ce9145fc82da3f" and "50f262e1a947dd57e2f0ee10d93c395a0c2efe77" have entirely different histories.

10 changed files with 39 additions and 704 deletions

View File

@ -5,7 +5,7 @@
defined(_POWER) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
defined(__sparc__) || defined(__sparc) || defined(__s390__) || \
- defined(__SH4__) || defined(__alpha__) || \
+ defined(__SH4__) || defined(__alpha__) || defined(__loongarch64) || defined(__sw_64__) || \
+ defined(__SH4__) || defined(__alpha__) || defined(__loongarch64) || \
defined(_MIPS_ARCH_MIPS32R2) || \
defined(__AARCH64EL__) || defined(__aarch64__) || defined(__AARCH64EB__) || \
defined(__riscv) || \

View File

@ -1,511 +0,0 @@
From 37bc7427407685a224044ddc3df4b81c41d6fd38 Mon Sep 17 00:00:00 2001
From: Philippe Normand <philn@igalia.com>
Date: Mon, 28 Aug 2023 01:34:28 -0700
Subject: [PATCH] [GStreamer] Prevent a crash when fetching data on stopped
MediaRecorder https://bugs.webkit.org/show_bug.cgi?id=260649
rdar://problem/114370120
Reviewed by Xabier Rodriguez-Calvar.
The backend (GStreamer transcoder) is now clearly separated from the MediaRecorderPrivate, so that
fetchData() can create a weak pointer to be used from the main thread. If the backend was destroyed
in-flight no unsafe memory access is performed.
Test: http/wpt/mediarecorder/MediaRecorder-start-stop-crash.html
Canonical link: https://commits.webkit.org/267345@main
---
.../graphics/gstreamer/GRefPtrGStreamer.cpp | 52 +++++++
.../graphics/gstreamer/GRefPtrGStreamer.h | 15 ++
.../MediaRecorderPrivateGStreamer.cpp | 140 ++++++++++++------
.../MediaRecorderPrivateGStreamer.h | 57 +++++--
4 files changed, 206 insertions(+), 62 deletions(-)
diff --git a/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.cpp
index cc0afa79..822f5aaa 100644
--- a/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.cpp
+++ b/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.cpp
@@ -34,6 +34,10 @@
#undef GST_USE_UNSTABLE_API
#endif
+#if USE(GSTREAMER_TRANSCODER)
+#include <gst/transcoder/gsttranscoder.h>
+#endif
+
namespace WTF {
template<> GRefPtr<GstMiniObject> adoptGRef(GstMiniObject* ptr)
@@ -754,6 +758,54 @@ template<> void derefGPtr<GstRTPHeaderExtension>(GstRTPHeaderExtension* ptr)
#endif // USE(GSTREAMER_WEBRTC)
+#if USE(GSTREAMER_TRANSCODER)
+
+template<>
+GRefPtr<GstTranscoder> adoptGRef(GstTranscoder* ptr)
+{
+ return GRefPtr<GstTranscoder>(ptr, GRefPtrAdopt);
+}
+
+template<>
+GstTranscoder* refGPtr<GstTranscoder>(GstTranscoder* ptr)
+{
+ if (ptr)
+ gst_object_ref(GST_OBJECT_CAST(ptr));
+
+ return ptr;
+}
+
+template<>
+void derefGPtr<GstTranscoder>(GstTranscoder* ptr)
+{
+ if (ptr)
+ gst_object_unref(ptr);
+}
+
+template<>
+GRefPtr<GstTranscoderSignalAdapter> adoptGRef(GstTranscoderSignalAdapter* ptr)
+{
+ return GRefPtr<GstTranscoderSignalAdapter>(ptr, GRefPtrAdopt);
+}
+
+template<>
+GstTranscoderSignalAdapter* refGPtr<GstTranscoderSignalAdapter>(GstTranscoderSignalAdapter* ptr)
+{
+ if (ptr)
+ g_object_ref(G_OBJECT(ptr));
+
+ return ptr;
+}
+
+template<>
+void derefGPtr<GstTranscoderSignalAdapter>(GstTranscoderSignalAdapter* ptr)
+{
+ if (ptr)
+ g_object_unref(ptr);
+}
+
+#endif // USE(GSTREAMER_TRANSCODER)
+
} // namespace WTF
#endif // USE(GSTREAMER)
diff --git a/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.h b/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.h
index 57c93254..5ddbeec1 100644
--- a/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.h
+++ b/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.h
@@ -45,6 +45,11 @@ typedef struct _GstWebRTCRTPTransceiver GstWebRTCRTPTransceiver;
typedef struct _GstRTPHeaderExtension GstRTPHeaderExtension;
#endif
+#if USE(GSTREAMER_TRANSCODER)
+typedef struct _GstTranscoder GstTranscoder;
+typedef struct _GstTranscoderSignalAdapter GstTranscoderSignalAdapter;
+#endif
+
namespace WTF {
template<> GRefPtr<GstPlugin> adoptGRef(GstPlugin* ptr);
@@ -197,6 +202,16 @@ template<> void derefGPtr<GstRTPHeaderExtension>(GstRTPHeaderExtension*);
#endif
+#if USE(GSTREAMER_TRANSCODER)
+template<> GRefPtr<GstTranscoder> adoptGRef(GstTranscoder*);
+template<> GstTranscoder* refGPtr<GstTranscoder>(GstTranscoder*);
+template<> void derefGPtr<GstTranscoder>(GstTranscoder*);
+
+template<> GRefPtr<GstTranscoderSignalAdapter> adoptGRef(GstTranscoderSignalAdapter*);
+template<> GstTranscoderSignalAdapter* refGPtr<GstTranscoderSignalAdapter>(GstTranscoderSignalAdapter*);
+template<> void derefGPtr<GstTranscoderSignalAdapter>(GstTranscoderSignalAdapter*);
+#endif // USE(GSTREAMER_TRANSCODER)
+
} // namespace WTF
#endif // USE(GSTREAMER)
diff --git a/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateGStreamer.cpp b/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateGStreamer.cpp
index 835e357b..968eee75 100644
--- a/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateGStreamer.cpp
+++ b/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateGStreamer.cpp
@@ -30,6 +30,7 @@
#include "MediaRecorderPrivateOptions.h"
#include "MediaStreamPrivate.h"
#include <gst/app/gstappsink.h>
+#include <gst/transcoder/gsttranscoder.h>
#include <wtf/Scope.h>
namespace WebCore {
@@ -46,21 +47,73 @@ std::unique_ptr<MediaRecorderPrivateGStreamer> MediaRecorderPrivateGStreamer::cr
GST_DEBUG_CATEGORY_INIT(webkit_media_recorder_debug, "webkitmediarecorder", 0, "WebKit MediaStream recorder");
});
- auto recorder = makeUnique<MediaRecorderPrivateGStreamer>(stream, options);
+ auto recorder = MediaRecorderPrivateBackend::create(stream, options);
if (!recorder->preparePipeline())
return nullptr;
- return recorder;
+ return makeUnique<MediaRecorderPrivateGStreamer>(recorder.releaseNonNull());
}
-MediaRecorderPrivateGStreamer::MediaRecorderPrivateGStreamer(MediaStreamPrivate& stream, const MediaRecorderPrivateOptions& options)
+MediaRecorderPrivateGStreamer::MediaRecorderPrivateGStreamer(Ref<MediaRecorderPrivateBackend>&& recorder)
+ : m_recorder(WTFMove(recorder))
+{
+ m_recorder->setSelectTracksCallback([this](auto selectedTracks) {
+ if (selectedTracks.audioTrack) {
+ setAudioSource(&selectedTracks.audioTrack->source());
+ checkTrackState(*selectedTracks.audioTrack);
+ }
+ if (selectedTracks.videoTrack) {
+ setVideoSource(&selectedTracks.videoTrack->source());
+ checkTrackState(*selectedTracks.videoTrack);
+ }
+ });
+}
+
+void MediaRecorderPrivateGStreamer::startRecording(StartRecordingCallback&& callback)
+{
+ m_recorder->startRecording(WTFMove(callback));
+}
+
+void MediaRecorderPrivateGStreamer::stopRecording(CompletionHandler<void()>&& completionHandler)
+{
+ m_recorder->stopRecording(WTFMove(completionHandler));
+}
+
+void MediaRecorderPrivateGStreamer::fetchData(FetchDataCallback&& completionHandler)
+{
+ m_recorder->fetchData(WTFMove(completionHandler));
+}
+
+void MediaRecorderPrivateGStreamer::pauseRecording(CompletionHandler<void()>&& completionHandler)
+{
+ m_recorder->pauseRecording(WTFMove(completionHandler));
+}
+
+void MediaRecorderPrivateGStreamer::resumeRecording(CompletionHandler<void()>&& completionHandler)
+{
+ m_recorder->resumeRecording(WTFMove(completionHandler));
+}
+
+const String& MediaRecorderPrivateGStreamer::mimeType() const
+{
+ return m_recorder->mimeType();
+}
+
+bool MediaRecorderPrivateGStreamer::isTypeSupported(const ContentType& contentType)
+{
+ auto& scanner = GStreamerRegistryScanner::singleton();
+ return scanner.isContentTypeSupported(GStreamerRegistryScanner::Configuration::Encoding, contentType, { }) > MediaPlayerEnums::SupportsType::IsNotSupported;
+}
+
+MediaRecorderPrivateBackend::MediaRecorderPrivateBackend(MediaStreamPrivate& stream, const MediaRecorderPrivateOptions& options)
: m_stream(stream)
, m_options(options)
{
}
-MediaRecorderPrivateGStreamer::~MediaRecorderPrivateGStreamer()
+MediaRecorderPrivateBackend::~MediaRecorderPrivateBackend()
{
+ m_selectTracksCallback.reset();
if (m_src)
webkitMediaStreamSrcSignalEndOfStream(WEBKIT_MEDIA_STREAM_SRC(m_src.get()));
if (m_transcoder) {
@@ -69,7 +122,7 @@ MediaRecorderPrivateGStreamer::~MediaRecorderPrivateGStreamer()
}
}
-void MediaRecorderPrivateGStreamer::startRecording(StartRecordingCallback&& callback)
+void MediaRecorderPrivateBackend::startRecording(MediaRecorderPrivate::StartRecordingCallback&& callback)
{
if (!m_pipeline)
preparePipeline();
@@ -78,7 +131,7 @@ void MediaRecorderPrivateGStreamer::startRecording(StartRecordingCallback&& call
gst_transcoder_run_async(m_transcoder.get());
}
-void MediaRecorderPrivateGStreamer::stopRecording(CompletionHandler<void()>&& completionHandler)
+void MediaRecorderPrivateBackend::stopRecording(CompletionHandler<void()>&& completionHandler)
{
GST_DEBUG_OBJECT(m_transcoder.get(), "Stop requested, pushing EOS event");
@@ -99,24 +152,31 @@ void MediaRecorderPrivateGStreamer::stopRecording(CompletionHandler<void()>&& co
bool isEOS = false;
while (!isEOS) {
LockHolder lock(m_eosLock);
- m_eosCondition.waitFor(m_eosLock, 200_ms, [weakThis = WeakPtr { this }]() -> bool {
- if (!weakThis)
- return true;
- return weakThis->m_eos;
+ m_eosCondition.waitFor(m_eosLock, 200_ms, [weakThis = ThreadSafeWeakPtr { *this }]() -> bool {
+ if (auto strongThis = weakThis.get())
+ return strongThis->m_eos;
+ return true;
});
isEOS = m_eos;
}
}
-void MediaRecorderPrivateGStreamer::fetchData(FetchDataCallback&& completionHandler)
+void MediaRecorderPrivateBackend::fetchData(MediaRecorderPrivate::FetchDataCallback&& completionHandler)
{
- Locker locker { m_dataLock };
- GST_DEBUG_OBJECT(m_transcoder.get(), "Transfering %zu encoded bytes", m_data.size());
- auto buffer = m_data.take();
- completionHandler(WTFMove(buffer), mimeType(), m_position);
+ callOnMainThread([this, weakThis = ThreadSafeWeakPtr { *this }, completionHandler = WTFMove(completionHandler)]() mutable {
+ auto strongThis = weakThis.get();
+ if (!strongThis) {
+ completionHandler(nullptr, mimeType(), 0);
+ return;
+ }
+ Locker locker { m_dataLock };
+ GST_DEBUG_OBJECT(m_transcoder.get(), "Transfering %zu encoded bytes", m_data.size());
+ auto buffer = m_data.take();
+ completionHandler(WTFMove(buffer), mimeType(), m_position);
+ });
}
-void MediaRecorderPrivateGStreamer::pauseRecording(CompletionHandler<void()>&& completionHandler)
+void MediaRecorderPrivateBackend::pauseRecording(CompletionHandler<void()>&& completionHandler)
{
GST_INFO_OBJECT(m_transcoder.get(), "Pausing");
if (m_pipeline)
@@ -130,7 +190,7 @@ void MediaRecorderPrivateGStreamer::pauseRecording(CompletionHandler<void()>&& c
completionHandler();
}
-void MediaRecorderPrivateGStreamer::resumeRecording(CompletionHandler<void()>&& completionHandler)
+void MediaRecorderPrivateBackend::resumeRecording(CompletionHandler<void()>&& completionHandler)
{
GST_INFO_OBJECT(m_transcoder.get(), "Resuming");
auto selectedTracks = MediaRecorderPrivate::selectTracks(stream());
@@ -143,7 +203,7 @@ void MediaRecorderPrivateGStreamer::resumeRecording(CompletionHandler<void()>&&
completionHandler();
}
-const String& MediaRecorderPrivateGStreamer::mimeType() const
+const String& MediaRecorderPrivateBackend::mimeType() const
{
static NeverDestroyed<const String> MP4AUDIOMIMETYPE(MAKE_STATIC_STRING_IMPL("audio/mp4"));
static NeverDestroyed<const String> MP4VIDEOMIMETYPE(MAKE_STATIC_STRING_IMPL("video/mp4"));
@@ -152,13 +212,7 @@ const String& MediaRecorderPrivateGStreamer::mimeType() const
return selectedTracks.videoTrack ? MP4VIDEOMIMETYPE : MP4AUDIOMIMETYPE;
}
-bool MediaRecorderPrivateGStreamer::isTypeSupported(const ContentType& contentType)
-{
- auto& scanner = GStreamerRegistryScanner::singleton();
- return scanner.isContentTypeSupported(GStreamerRegistryScanner::Configuration::Encoding, contentType, { }) > MediaPlayerEnums::SupportsType::IsNotSupported;
-}
-
-GRefPtr<GstEncodingContainerProfile> MediaRecorderPrivateGStreamer::containerProfile()
+GRefPtr<GstEncodingContainerProfile> MediaRecorderPrivateBackend::containerProfile()
{
auto selectedTracks = MediaRecorderPrivate::selectTracks(m_stream);
auto mimeType = this->mimeType();
@@ -239,38 +293,36 @@ GRefPtr<GstEncodingContainerProfile> MediaRecorderPrivateGStreamer::containerPro
return profile;
}
-void MediaRecorderPrivateGStreamer::setSource(GstElement* element)
+void MediaRecorderPrivateBackend::setSource(GstElement* element)
{
auto selectedTracks = MediaRecorderPrivate::selectTracks(stream());
bool onlyTrack = (selectedTracks.audioTrack && !selectedTracks.videoTrack) || (selectedTracks.videoTrack && !selectedTracks.audioTrack);
auto* src = WEBKIT_MEDIA_STREAM_SRC(element);
- if (selectedTracks.audioTrack) {
+ if (selectedTracks.audioTrack)
webkitMediaStreamSrcAddTrack(src, selectedTracks.audioTrack, onlyTrack);
- setAudioSource(&selectedTracks.audioTrack->source());
- checkTrackState(*selectedTracks.audioTrack);
- }
- if (selectedTracks.videoTrack) {
+ if (selectedTracks.videoTrack)
webkitMediaStreamSrcAddTrack(src, selectedTracks.videoTrack, onlyTrack);
- setVideoSource(&selectedTracks.videoTrack->source());
- checkTrackState(*selectedTracks.videoTrack);
+ if (m_selectTracksCallback) {
+ auto& callback = *m_selectTracksCallback;
+ callback(selectedTracks);
}
m_src = element;
}
-void MediaRecorderPrivateGStreamer::setSink(GstElement* element)
+void MediaRecorderPrivateBackend::setSink(GstElement* element)
{
static GstAppSinkCallbacks callbacks = {
nullptr,
[](GstAppSink* sink, gpointer userData) -> GstFlowReturn {
auto sample = adoptGRef(gst_app_sink_pull_preroll(sink));
if (sample)
- static_cast<MediaRecorderPrivateGStreamer*>(userData)->processSample(WTFMove(sample));
+ static_cast<MediaRecorderPrivateBackend*>(userData)->processSample(WTFMove(sample));
return gst_app_sink_is_eos(sink) ? GST_FLOW_EOS : GST_FLOW_OK;
},
[](GstAppSink* sink, gpointer userData) -> GstFlowReturn {
auto sample = adoptGRef(gst_app_sink_pull_sample(sink));
if (sample)
- static_cast<MediaRecorderPrivateGStreamer*>(userData)->processSample(WTFMove(sample));
+ static_cast<MediaRecorderPrivateBackend*>(userData)->processSample(WTFMove(sample));
return gst_app_sink_is_eos(sink) ? GST_FLOW_EOS : GST_FLOW_OK;
},
// new_event
@@ -282,7 +334,7 @@ void MediaRecorderPrivateGStreamer::setSink(GstElement* element)
m_sink = element;
}
-void MediaRecorderPrivateGStreamer::configureVideoEncoder(GstElement* element)
+void MediaRecorderPrivateBackend::configureVideoEncoder(GstElement* element)
{
auto format = adoptGRef(gst_encoding_profile_get_format(GST_ENCODING_PROFILE(m_videoEncodingProfile.get())));
g_object_set(element, "format", format.get(), nullptr);
@@ -299,7 +351,7 @@ void MediaRecorderPrivateGStreamer::configureVideoEncoder(GstElement* element)
g_object_set(element, "bitrate", bitrate / 1024, nullptr);
}
-bool MediaRecorderPrivateGStreamer::preparePipeline()
+bool MediaRecorderPrivateBackend::preparePipeline()
{
auto profile = containerProfile();
if (!profile)
@@ -309,11 +361,11 @@ bool MediaRecorderPrivateGStreamer::preparePipeline()
gst_transcoder_set_avoid_reencoding(m_transcoder.get(), true);
m_pipeline = gst_transcoder_get_pipeline(m_transcoder.get());
- g_signal_connect_swapped(m_pipeline.get(), "source-setup", G_CALLBACK(+[](MediaRecorderPrivateGStreamer* recorder, GstElement* sourceElement) {
+ g_signal_connect_swapped(m_pipeline.get(), "source-setup", G_CALLBACK(+[](MediaRecorderPrivateBackend* recorder, GstElement* sourceElement) {
recorder->setSource(sourceElement);
}), this);
- g_signal_connect_swapped(m_pipeline.get(), "element-setup", G_CALLBACK(+[](MediaRecorderPrivateGStreamer* recorder, GstElement* element) {
+ g_signal_connect_swapped(m_pipeline.get(), "element-setup", G_CALLBACK(+[](MediaRecorderPrivateBackend* recorder, GstElement* element) {
if (WEBKIT_IS_WEBRTC_VIDEO_ENCODER(element)) {
recorder->configureVideoEncoder(element);
return;
@@ -330,18 +382,18 @@ bool MediaRecorderPrivateGStreamer::preparePipeline()
GST_WARNING("%s details: %" GST_PTR_FORMAT, error->message, details);
}), nullptr);
- g_signal_connect_swapped(m_signalAdapter.get(), "done", G_CALLBACK(+[](MediaRecorderPrivateGStreamer* recorder) {
+ g_signal_connect_swapped(m_signalAdapter.get(), "done", G_CALLBACK(+[](MediaRecorderPrivateBackend* recorder) {
recorder->notifyEOS();
}), this);
- g_signal_connect_swapped(m_signalAdapter.get(), "position-updated", G_CALLBACK(+[](MediaRecorderPrivateGStreamer* recorder, GstClockTime position) {
+ g_signal_connect_swapped(m_signalAdapter.get(), "position-updated", G_CALLBACK(+[](MediaRecorderPrivateBackend* recorder, GstClockTime position) {
recorder->notifyPosition(position);
}), this);
return true;
}
-void MediaRecorderPrivateGStreamer::processSample(GRefPtr<GstSample>&& sample)
+void MediaRecorderPrivateBackend::processSample(GRefPtr<GstSample>&& sample)
{
auto* sampleBuffer = gst_sample_get_buffer(sample.get());
GstMappedBuffer buffer(sampleBuffer, GST_MAP_READ);
@@ -351,7 +403,7 @@ void MediaRecorderPrivateGStreamer::processSample(GRefPtr<GstSample>&& sample)
m_data.append(buffer.data(), buffer.size());
}
-void MediaRecorderPrivateGStreamer::notifyEOS()
+void MediaRecorderPrivateBackend::notifyEOS()
{
GST_DEBUG("EOS received");
LockHolder lock(m_eosLock);
diff --git a/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateGStreamer.h b/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateGStreamer.h
index b15c7be4..d8379055 100644
--- a/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateGStreamer.h
+++ b/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateGStreamer.h
@@ -24,7 +24,6 @@
#include "GRefPtrGStreamer.h"
#include "MediaRecorderPrivate.h"
#include "SharedBuffer.h"
-#include <gst/transcoder/gsttranscoder.h>
#include <wtf/CompletionHandler.h>
#include <wtf/Condition.h>
#include <wtf/Forward.h>
@@ -37,29 +36,31 @@ class ContentType;
class MediaStreamTrackPrivate;
struct MediaRecorderPrivateOptions;
-class MediaRecorderPrivateGStreamer final : public MediaRecorderPrivate, public CanMakeWeakPtr<MediaRecorderPrivateGStreamer> {
+class MediaRecorderPrivateBackend : public ThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr<MediaRecorderPrivateBackend, WTF::DestructionThread::Main> {
WTF_MAKE_FAST_ALLOCATED;
public:
- static std::unique_ptr<MediaRecorderPrivateGStreamer> create(MediaStreamPrivate&, const MediaRecorderPrivateOptions&);
- explicit MediaRecorderPrivateGStreamer(MediaStreamPrivate&, const MediaRecorderPrivateOptions&);
- ~MediaRecorderPrivateGStreamer();
+ using SelectTracksCallback = Function<void(MediaRecorderPrivate::AudioVideoSelectedTracks)>;
+ static RefPtr<MediaRecorderPrivateBackend> create(MediaStreamPrivate& stream, const MediaRecorderPrivateOptions& options)
+ {
+ return adoptRef(*new MediaRecorderPrivateBackend(stream, options));
+ }
- static bool isTypeSupported(const ContentType&);
+ ~MediaRecorderPrivateBackend();
-protected:
bool preparePipeline();
-private:
- void videoFrameAvailable(VideoFrame&, VideoFrameTimeMetadata) final { };
- void audioSamplesAvailable(const WTF::MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) final { };
+ void fetchData(MediaRecorderPrivate::FetchDataCallback&&);
+ void startRecording(MediaRecorderPrivate::StartRecordingCallback&&);
+ void stopRecording(CompletionHandler<void()>&&);
+ void pauseRecording(CompletionHandler<void()>&&);
+ void resumeRecording(CompletionHandler<void()>&&);
+ const String& mimeType() const;
- void fetchData(FetchDataCallback&&) final;
- void startRecording(StartRecordingCallback&&) final;
- void stopRecording(CompletionHandler<void()>&&) final;
- void pauseRecording(CompletionHandler<void()>&&) final;
- void resumeRecording(CompletionHandler<void()>&&) final;
- const String& mimeType() const final;
+ void setSelectTracksCallback(SelectTracksCallback&& callback) { m_selectTracksCallback = WTFMove(callback); }
+
+private:
+ MediaRecorderPrivateBackend(MediaStreamPrivate&, const MediaRecorderPrivateOptions&);
void setSource(GstElement*);
void setSink(GstElement*);
@@ -88,6 +89,30 @@ private:
MediaStreamPrivate& m_stream;
const MediaRecorderPrivateOptions& m_options;
+ std::optional<SelectTracksCallback> m_selectTracksCallback;
+};
+
+class MediaRecorderPrivateGStreamer final : public MediaRecorderPrivate {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ static std::unique_ptr<MediaRecorderPrivateGStreamer> create(MediaStreamPrivate&, const MediaRecorderPrivateOptions&);
+ explicit MediaRecorderPrivateGStreamer(Ref<MediaRecorderPrivateBackend>&&);
+ ~MediaRecorderPrivateGStreamer() = default;
+
+ static bool isTypeSupported(const ContentType&);
+
+private:
+ void videoFrameAvailable(VideoFrame&, VideoFrameTimeMetadata) final { };
+ void audioSamplesAvailable(const WTF::MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) final { };
+
+ void fetchData(FetchDataCallback&&) final;
+ void startRecording(StartRecordingCallback&&) final;
+ void stopRecording(CompletionHandler<void()>&&) final;
+ void pauseRecording(CompletionHandler<void()>&&) final;
+ void resumeRecording(CompletionHandler<void()>&&) final;
+ const String& mimeType() const final;
+
+ Ref<MediaRecorderPrivateBackend> m_recorder;
};
} // namespace WebCore
--
2.33.0

View File

@ -1,41 +0,0 @@
From 2fe5ae29a5f6434ef456afe9673a4f400ec63848 Mon Sep 17 00:00:00 2001
From: Jean-Yves Avenard <jya@apple.com>
Date: Fri, 14 Jun 2024 16:08:19 -0700
Subject: [PATCH] Cherry-pick 272448.1085@safari-7618.3.10-branch
(ff52ff7cb64e). https://bugs.webkit.org/show_bug.cgi?id=275431
HeapBufferOverflow in computeSampleUsingLinearInterpolation
https://bugs.webkit.org/show_bug.cgi?id=275431
rdar://125617812
Reviewed by Youenn Fablet.
Add boundary check.
This is a copy of blink code for that same function.
https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/modules/webaudio/audio_buffer_source_handler.cc;l=336-341
* Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp:
(WebCore::AudioBufferSourceNode::renderFromBuffer):
Canonical link: https://commits.webkit.org/274313.347@webkitglib/2.44
---
.../webaudio/AudioBufferSourceNode.cpp | 6 +++++
1 file changed, 6 insertions(+)
diff --git a/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp b/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp
index 298bd48cdff5..740b793e0ec5 100644
--- a/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp
+++ b/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp
@@ -350,6 +350,12 @@ bool AudioBufferSourceNode::renderFromBuffer(AudioBus* bus, unsigned destination
if (readIndex2 >= maxFrame)
readIndex2 = m_isLooping ? minFrame : readIndex;
+ // Final sanity check on buffer access.
+ // FIXME: as an optimization, try to get rid of this inner-loop check and
+ // put assertions and guards before the loop.
+ if (readIndex >= bufferLength || readIndex2 >= bufferLength)
+ break;
+
// Linear interpolation.
for (unsigned i = 0; i < numberOfChannels; ++i) {
float* destination = destinationChannels[i];

View File

@ -1,41 +0,0 @@
From e83e4c7460972898dc06a5f5ab36eed7c6b101b5 Mon Sep 17 00:00:00 2001
From: Jer Noble <jer.noble@apple.com>
Date: Tue, 11 Jun 2024 11:54:06 -0700
Subject: [PATCH] Cherry-pick 272448.1080@safari-7618.3.10-branch
(64c9479d6f29). https://bugs.webkit.org/show_bug.cgi?id=275273
Add check in AudioBufferSourceNode::renderFromBuffer() when detune is set to large negative value
https://bugs.webkit.org/show_bug.cgi?id=275273
rdar://125617842
Reviewed by Eric Carlson.
* Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp:
(WebCore::AudioBufferSourceNode::renderFromBuffer):
Canonical link: https://commits.webkit.org/274313.345@webkitglib/2.44
---
.../webaudio/AudioBufferSourceNode.cpp | 7 +++++
1 file changed, 7 insertions(+)
diff --git a/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp b/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp
index f86bffb9b507..298bd48cdff5 100644
--- a/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp
+++ b/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp
@@ -328,9 +328,16 @@ bool AudioBufferSourceNode::renderFromBuffer(AudioBus* bus, unsigned destination
virtualReadIndex = readIndex;
} else if (!pitchRate) {
unsigned readIndex = static_cast<unsigned>(virtualReadIndex);
+ int deltaFrames = static_cast<int>(virtualDeltaFrames);
+ maxFrame = static_cast<unsigned>(virtualMaxFrame);
+
+ if (readIndex >= maxFrame)
+ readIndex -= deltaFrames;
for (unsigned i = 0; i < numberOfChannels; ++i)
std::fill_n(destinationChannels[i] + writeIndex, framesToProcess, sourceChannels[i][readIndex]);
+
+ virtualReadIndex = readIndex;
} else if (reverse) {
unsigned maxFrame = static_cast<unsigned>(virtualMaxFrame);
unsigned minFrame = static_cast<unsigned>(floorf(virtualMinFrame));

View File

@ -1,42 +0,0 @@
From 9d7ec80f78039e6646fcfc455ab4c05aa393f34c Mon Sep 17 00:00:00 2001
From: Kimmo Kinnunen <kkinnunen@apple.com>
Date: Tue, 14 May 2024 22:37:29 -0700
Subject: [PATCH] Cherry-pick ANGLE.
https://bugs.webkit.org/show_bug.cgi?id=274165
https://bugs.webkit.org/show_bug.cgi?id=274165
rdar://127764804
Reviewed by Dan Glastonbury.
Cherry-pick ANGLE upstream commit 1bb1ee061fe0bce322fb93b447a72e72c993a1f2:
GL: Sync unpack state for glCompressedTexSubImage3D
Unpack state is supposed to be ignored for compressed tex image calls
but some drivers use it anyways and read incorrect data.
Texture3DTestES3.PixelUnpackStateTexSubImage covers this case.
Bug: chromium:337766133
Change-Id: Ic11a056113b1850bd5b4d6840527164a12849a22
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5498735
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Canonical link: https://commits.webkit.org/274313.341@webkitglib/2.44
---
Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/TextureGL.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/TextureGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/TextureGL.cpp
index c659aacb9e48..f96eefe53f11 100644
--- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/TextureGL.cpp
+++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/TextureGL.cpp
@@ -664,6 +664,7 @@ angle::Result TextureGL::setCompressedSubImage(const gl::Context *context,
nativegl::GetCompressedSubTexImageFormat(functions, features, format);
stateManager->bindTexture(getType(), mTextureID);
+ ANGLE_TRY(stateManager->setPixelUnpackState(context, unpack));
if (nativegl::UseTexImage2D(getType()))
{
ASSERT(area.z == 0 && area.depth == 1);

View File

@ -14,23 +14,24 @@
Name: webkit2gtk3
Version: 2.38.2
Release: 11
Release: 6
Summary: GTK web content engine library
License: LGPLv2
URL: https://www.webkitgtk.org/
Source0: https://webkitgtk.org/releases/webkitgtk-%{version}.tar.xz
Source1: https://webkitgtk.org/releases/webkitgtk-%{version}.tar.xz.asc
Patch1000: webkitgtk-add-loongarch-and-sw.patch
%ifarch loongarch64
Patch0001: 0001-webkitgtk-add-loongarch.patch
%endif
%ifarch sw_64
Patch0002: webkitgtk-2.32.1-sw.patch
%endif
Patch6000: backport-CVE-2023-28204.patch
Patch6001: backport-CVE-2023-32373.patch
Patch6002: backport-CVE-2023-32409.patch
Patch6003: backport-Fix-build-with-Ruby-3.2.patch
Patch6004: backport-CVE-2023-39928.patch
Patch6005: backport-CVE-2024-4558.patch
Patch6006: backport-CVE-2024-40779.patch
Patch6007: backport-CVE-2024-40780.patch
#Dependency
BuildRequires: bison
@ -289,22 +290,7 @@ popd
%endif
%changelog
* Fri May 09 2025 lingsheng <lingsheng1@h-partners.com> - 2.38.2-11
- Adapt repo name webkitgtk
* Thu Aug 29 2024 lingsheng <lingsheng1@h-partners.com> - 2.38.2-10
- Modfiy loongarch64 and sw_64 support use all arch
* Mon Aug 26 2024 lingsheng <lingsheng1@h-partners.com> - 2.38.2-9
- fix CVE-2024-4558 CVE-2024-40779 CVE-2024-40780
* Wed Oct 11 2023 zhouwenpei <zhouwenpei1@h-partners.com> - 2.38.2-8
- fix check_install error
* Sun Oct 08 2023 zhouwenpei <zhouwenpei1@h-partners.com> - 2.38.2-7
- fix CVE-2023-39928
* Thu Aug 10 2023 xiasenlin <xiasenlin1@huawei.com> - 2.38.2-6
* Thurs Aug 10 2023 xiasenlin <xiasenlin1@huawei.com> - 2.38.2-6
- split webkit2gtk3 from webkit2gtk3
* Mon May 29 2023 zhangpan <zhangpan103@h-partners.com> - 2.38.2-4

View File

@ -14,23 +14,24 @@
Name: webkit2gtk4.1
Version: 2.38.2
Release: 11
Release: 6
Summary: GTK web content engine library
License: LGPLv2
URL: https://www.webkitgtk.org/
Source0: https://webkitgtk.org/releases/webkitgtk-%{version}.tar.xz
Source1: https://webkitgtk.org/releases/webkitgtk-%{version}.tar.xz.asc
Patch1000: webkitgtk-add-loongarch-and-sw.patch
%ifarch loongarch64
Patch0001: 0001-webkitgtk-add-loongarch.patch
%endif
%ifarch sw_64
Patch0002: webkitgtk-2.32.1-sw.patch
%endif
Patch6000: backport-CVE-2023-28204.patch
Patch6001: backport-CVE-2023-32373.patch
Patch6002: backport-CVE-2023-32409.patch
Patch6003: backport-Fix-build-with-Ruby-3.2.patch
Patch6004: backport-CVE-2023-39928.patch
Patch6005: backport-CVE-2024-4558.patch
Patch6006: backport-CVE-2024-40779.patch
Patch6007: backport-CVE-2024-40780.patch
#Dependency
BuildRequires: bison
@ -98,7 +99,7 @@ BuildRequires: pkgconfig(wpe-1.0)
BuildRequires: pkgconfig(wpebackend-fdo-1.0)
BuildRequires: pkgconfig(xt)
Requires: javascriptcoregtk4.1%{?_isa} = %{version}-%{release}
Requires: javascriptcoregtk4.0%{?_isa} = %{version}-%{release}
Requires: bubblewrap
Requires: xdg-dbus-proxy
Recommends: geoclue2
@ -258,22 +259,7 @@ popd
%endif
%changelog
* Fri May 09 2025 lingsheng <lingsheng1@h-partners.com> - 2.38.2-11
- Adapt repo name webkitgtk
* Thu Aug 29 2024 lingsheng <lingsheng1@h-partners.com> - 2.38.2-10
- Modfiy loongarch64 and sw_64 support use all arch
* Mon Aug 26 2024 lingsheng <lingsheng1@h-partners.com> - 2.38.2-9
- fix CVE-2024-4558 CVE-2024-40779 CVE-2024-40780
* Wed Oct 11 2023 zhouwenpei <zhouwenpei1@h-partners.com> - 2.38.2-8
- fix check_install error
* Sun Oct 08 2023 zhouwenpei <zhouwenpei1@h-partners.com> - 2.38.2-7
- fix CVE-2023-39928
* Thu Aug 10 2023 xiasenlin <xiasenlin1@huawei.com> - 2.38.2-6
* Thurs Aug 10 2023 xiasenlin <xiasenlin1@huawei.com> - 2.38.2-6
- split webkit2gtk4.1 from webkit2gtk3
* Tue Aug 08 2023 zhouwenpei <zhouwenpei1@h-partners.com> - 2.38.2-5

View File

@ -14,23 +14,24 @@
Name: webkit2gtk5.0
Version: 2.38.2
Release: 11
Release: 6
Summary: GTK web content engine library
License: LGPLv2
URL: https://www.webkitgtk.org/
Source0: https://webkitgtk.org/releases/webkitgtk-%{version}.tar.xz
Source1: https://webkitgtk.org/releases/webkitgtk-%{version}.tar.xz.asc
Patch1000: webkitgtk-add-loongarch-and-sw.patch
%ifarch loongarch64
Patch0001: 0001-webkitgtk-add-loongarch.patch
%endif
%ifarch sw_64
Patch0002: webkitgtk-2.32.1-sw.patch
%endif
Patch6000: backport-CVE-2023-28204.patch
Patch6001: backport-CVE-2023-32373.patch
Patch6002: backport-CVE-2023-32409.patch
Patch6003: backport-Fix-build-with-Ruby-3.2.patch
Patch6004: backport-CVE-2023-39928.patch
Patch6005: backport-CVE-2024-4558.patch
Patch6006: backport-CVE-2024-40779.patch
Patch6007: backport-CVE-2024-40780.patch
#Dependency
BuildRequires: bison
@ -98,7 +99,7 @@ BuildRequires: pkgconfig(wpe-1.0)
BuildRequires: pkgconfig(wpebackend-fdo-1.0)
BuildRequires: pkgconfig(xt)
Requires: javascriptcoregtk5.0%{?_isa} = %{version}-%{release}
Requires: javascriptcoregtk4.0%{?_isa} = %{version}-%{release}
Requires: bubblewrap
Requires: xdg-dbus-proxy
Recommends: geoclue2
@ -258,22 +259,7 @@ popd
%endif
%changelog
* Fri May 09 2025 lingsheng <lingsheng1@h-partners.com> - 2.38.2-11
- Adapt repo name webkitgtk
* Thu Aug 29 2024 lingsheng <lingsheng1@h-partners.com> - 2.38.2-10
- Modfiy loongarch64 and sw_64 support use all arch
* Mon Aug 26 2024 lingsheng <lingsheng1@h-partners.com> - 2.38.2-9
- fix CVE-2024-4558 CVE-2024-40779 CVE-2024-40780
* Wed Oct 11 2023 zhouwenpei <zhouwenpei1@h-partners.com> - 2.38.2-8
- fix check_install error
* Sun Oct 08 2023 zhouwenpei <zhouwenpei1@h-partners.com> - 2.38.2-7
- fix CVE-2023-39928
* Thu Aug 10 2023 xiasenlin <xiasenlin1@huawei.com> - 2.38.2-6
* Thurs Aug 10 2023 xiasenlin <xiasenlin1@huawei.com> - 2.38.2-6
- split webkit2gtk5.0 from webkit2gtk3
* Tue Aug 08 2023 zhouwenpei <zhouwenpei1@h-partners.com> - 2.38.2-5

12
webkitgtk-2.32.1-sw.patch Executable file
View File

@ -0,0 +1,12 @@
diff -Naur webkitgtk-2.32.1.org/Source/WTF/wtf/dtoa/utils.h webkitgtk-2.32.1.sw/Source/WTF/wtf/dtoa/utils.h
--- webkitgtk-2.32.1.org/Source/WTF/wtf/dtoa/utils.h 2022-06-06 15:32:28.840000000 +0000
+++ webkitgtk-2.32.1.sw/Source/WTF/wtf/dtoa/utils.h 2022-06-06 15:33:01.600000000 +0000
@@ -86,7 +86,7 @@
defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \
defined(_POWER) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
defined(__sparc__) || defined(__sparc) || defined(__s390__) || \
- defined(__SH4__) || defined(__alpha__) || \
+ defined(__SH4__) || defined(__alpha__) || defined(__sw_64__) || \
defined(_MIPS_ARCH_MIPS32R2) || \
defined(__AARCH64EL__) || defined(__aarch64__) || defined(__AARCH64EB__) || \
defined(__riscv) || \