fix CVE-2023-39928
This commit is contained in:
parent
50f262e1a9
commit
2f061d211a
511
backport-CVE-2023-39928.patch
Normal file
511
backport-CVE-2023-39928.patch
Normal file
@ -0,0 +1,511 @@
|
|||||||
|
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
|
||||||
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
Name: webkit2gtk3
|
Name: webkit2gtk3
|
||||||
Version: 2.38.2
|
Version: 2.38.2
|
||||||
Release: 6
|
Release: 7
|
||||||
Summary: GTK web content engine library
|
Summary: GTK web content engine library
|
||||||
License: LGPLv2
|
License: LGPLv2
|
||||||
URL: https://www.webkitgtk.org/
|
URL: https://www.webkitgtk.org/
|
||||||
@ -32,6 +32,7 @@ Patch6000: backport-CVE-2023-28204.patch
|
|||||||
Patch6001: backport-CVE-2023-32373.patch
|
Patch6001: backport-CVE-2023-32373.patch
|
||||||
Patch6002: backport-CVE-2023-32409.patch
|
Patch6002: backport-CVE-2023-32409.patch
|
||||||
Patch6003: backport-Fix-build-with-Ruby-3.2.patch
|
Patch6003: backport-Fix-build-with-Ruby-3.2.patch
|
||||||
|
Patch6004: backport-CVE-2023-39928.patch
|
||||||
|
|
||||||
#Dependency
|
#Dependency
|
||||||
BuildRequires: bison
|
BuildRequires: bison
|
||||||
@ -290,7 +291,10 @@ popd
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Thurs Aug 10 2023 xiasenlin <xiasenlin1@huawei.com> - 2.38.2-6
|
* 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
|
||||||
- split webkit2gtk3 from webkit2gtk3
|
- split webkit2gtk3 from webkit2gtk3
|
||||||
|
|
||||||
* Mon May 29 2023 zhangpan <zhangpan103@h-partners.com> - 2.38.2-4
|
* Mon May 29 2023 zhangpan <zhangpan103@h-partners.com> - 2.38.2-4
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
Name: webkit2gtk4.1
|
Name: webkit2gtk4.1
|
||||||
Version: 2.38.2
|
Version: 2.38.2
|
||||||
Release: 6
|
Release: 7
|
||||||
Summary: GTK web content engine library
|
Summary: GTK web content engine library
|
||||||
License: LGPLv2
|
License: LGPLv2
|
||||||
URL: https://www.webkitgtk.org/
|
URL: https://www.webkitgtk.org/
|
||||||
@ -32,6 +32,7 @@ Patch6000: backport-CVE-2023-28204.patch
|
|||||||
Patch6001: backport-CVE-2023-32373.patch
|
Patch6001: backport-CVE-2023-32373.patch
|
||||||
Patch6002: backport-CVE-2023-32409.patch
|
Patch6002: backport-CVE-2023-32409.patch
|
||||||
Patch6003: backport-Fix-build-with-Ruby-3.2.patch
|
Patch6003: backport-Fix-build-with-Ruby-3.2.patch
|
||||||
|
Patch6004: backport-CVE-2023-39928.patch
|
||||||
|
|
||||||
#Dependency
|
#Dependency
|
||||||
BuildRequires: bison
|
BuildRequires: bison
|
||||||
@ -259,7 +260,10 @@ popd
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Thurs Aug 10 2023 xiasenlin <xiasenlin1@huawei.com> - 2.38.2-6
|
* 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
|
||||||
- split webkit2gtk4.1 from webkit2gtk3
|
- split webkit2gtk4.1 from webkit2gtk3
|
||||||
|
|
||||||
* Tue Aug 08 2023 zhouwenpei <zhouwenpei1@h-partners.com> - 2.38.2-5
|
* Tue Aug 08 2023 zhouwenpei <zhouwenpei1@h-partners.com> - 2.38.2-5
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
Name: webkit2gtk5.0
|
Name: webkit2gtk5.0
|
||||||
Version: 2.38.2
|
Version: 2.38.2
|
||||||
Release: 6
|
Release: 7
|
||||||
Summary: GTK web content engine library
|
Summary: GTK web content engine library
|
||||||
License: LGPLv2
|
License: LGPLv2
|
||||||
URL: https://www.webkitgtk.org/
|
URL: https://www.webkitgtk.org/
|
||||||
@ -32,6 +32,7 @@ Patch6000: backport-CVE-2023-28204.patch
|
|||||||
Patch6001: backport-CVE-2023-32373.patch
|
Patch6001: backport-CVE-2023-32373.patch
|
||||||
Patch6002: backport-CVE-2023-32409.patch
|
Patch6002: backport-CVE-2023-32409.patch
|
||||||
Patch6003: backport-Fix-build-with-Ruby-3.2.patch
|
Patch6003: backport-Fix-build-with-Ruby-3.2.patch
|
||||||
|
Patch6004: backport-CVE-2023-39928.patch
|
||||||
|
|
||||||
#Dependency
|
#Dependency
|
||||||
BuildRequires: bison
|
BuildRequires: bison
|
||||||
@ -259,7 +260,10 @@ popd
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Thurs Aug 10 2023 xiasenlin <xiasenlin1@huawei.com> - 2.38.2-6
|
* 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
|
||||||
- split webkit2gtk5.0 from webkit2gtk3
|
- split webkit2gtk5.0 from webkit2gtk3
|
||||||
|
|
||||||
* Tue Aug 08 2023 zhouwenpei <zhouwenpei1@h-partners.com> - 2.38.2-5
|
* Tue Aug 08 2023 zhouwenpei <zhouwenpei1@h-partners.com> - 2.38.2-5
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user