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
|
||||
Version: 2.38.2
|
||||
Release: 6
|
||||
Release: 7
|
||||
Summary: GTK web content engine library
|
||||
License: LGPLv2
|
||||
URL: https://www.webkitgtk.org/
|
||||
@ -32,6 +32,7 @@ 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
|
||||
|
||||
#Dependency
|
||||
BuildRequires: bison
|
||||
@ -290,7 +291,10 @@ popd
|
||||
%endif
|
||||
|
||||
%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
|
||||
|
||||
* Mon May 29 2023 zhangpan <zhangpan103@h-partners.com> - 2.38.2-4
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
|
||||
Name: webkit2gtk4.1
|
||||
Version: 2.38.2
|
||||
Release: 6
|
||||
Release: 7
|
||||
Summary: GTK web content engine library
|
||||
License: LGPLv2
|
||||
URL: https://www.webkitgtk.org/
|
||||
@ -32,6 +32,7 @@ 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
|
||||
|
||||
#Dependency
|
||||
BuildRequires: bison
|
||||
@ -259,7 +260,10 @@ popd
|
||||
%endif
|
||||
|
||||
%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
|
||||
|
||||
* Tue Aug 08 2023 zhouwenpei <zhouwenpei1@h-partners.com> - 2.38.2-5
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
|
||||
Name: webkit2gtk5.0
|
||||
Version: 2.38.2
|
||||
Release: 6
|
||||
Release: 7
|
||||
Summary: GTK web content engine library
|
||||
License: LGPLv2
|
||||
URL: https://www.webkitgtk.org/
|
||||
@ -32,6 +32,7 @@ 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
|
||||
|
||||
#Dependency
|
||||
BuildRequires: bison
|
||||
@ -259,7 +260,10 @@ popd
|
||||
%endif
|
||||
|
||||
%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
|
||||
|
||||
* Tue Aug 08 2023 zhouwenpei <zhouwenpei1@h-partners.com> - 2.38.2-5
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user