Diff
Modified: trunk/LayoutTests/ChangeLog (265327 => 265328)
--- trunk/LayoutTests/ChangeLog 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/LayoutTests/ChangeLog 2020-08-06 15:25:39 UTC (rev 265328)
@@ -1,3 +1,15 @@
+2020-08-06 Youenn Fablet <you...@apple.com>
+
+ Add support for MediaRecorder bitrate options
+ https://bugs.webkit.org/show_bug.cgi?id=214973
+
+ Reviewed by Eric Carlson.
+
+ * http/wpt/mediarecorder/MediaRecorder-audio-bitrate-expected.txt: Added.
+ * http/wpt/mediarecorder/MediaRecorder-audio-bitrate.html: Added.
+ * http/wpt/mediarecorder/MediaRecorder-video-bitrate-expected.txt: Added.
+ * http/wpt/mediarecorder/MediaRecorder-video-bitrate.html: Added.
+
2020-08-06 Simon Fraser <simon.fra...@apple.com>
Scrolling tree nodes sometimes don't match layer z-order
Added: trunk/LayoutTests/http/wpt/mediarecorder/MediaRecorder-audio-bitrate-expected.txt (0 => 265328)
--- trunk/LayoutTests/http/wpt/mediarecorder/MediaRecorder-audio-bitrate-expected.txt (rev 0)
+++ trunk/LayoutTests/http/wpt/mediarecorder/MediaRecorder-audio-bitrate-expected.txt 2020-08-06 15:25:39 UTC (rev 265328)
@@ -0,0 +1,3 @@
+
+PASS Various audio bitrates
+
Added: trunk/LayoutTests/http/wpt/mediarecorder/MediaRecorder-audio-bitrate.html (0 => 265328)
--- trunk/LayoutTests/http/wpt/mediarecorder/MediaRecorder-audio-bitrate.html (rev 0)
+++ trunk/LayoutTests/http/wpt/mediarecorder/MediaRecorder-audio-bitrate.html 2020-08-06 15:25:39 UTC (rev 265328)
@@ -0,0 +1,40 @@
+<!doctype html>
+<html>
+<head>
+ <title>MediaRecorder audio bitrate</title>
+ <script src=""
+ <script src=""
+</head>
+<body>
+<script>
+ async function record(stream, bitRate)
+ {
+ const recorder = new MediaRecorder(stream, { audioBitsPerSecond : bitRate });
+ const promise = new Promise((resolve, reject) => {
+ recorder._ondataavailable_ = (e) => resolve(e.data);
+ setTimeout(reject, 5000);
+ });
+ recorder.start();
+ setTimeout(() => recorder.stop(), 2500);
+ return promise;
+ }
+
+ promise_test(async (t) => {
+ const stream = await navigator.mediaDevices.getUserMedia({ audio : true });
+ const bitRates = [128000, 192000, 256000];
+ let promises = [];
+ bitRates.forEach(bitRate => {
+ promises.push(record(stream, bitRate));
+ });
+
+ let blobs = [0, 0, 0];
+ promises.forEach(async (promise, index) => {
+ blobs[index] = await promise;
+ });
+ await Promise.all(promises);
+ assert_not_equals(blobs[0].size, 0);
+ assert_greater_than(blobs[2].size, blobs[0].size);
+ }, "Various audio bitrates");
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/http/wpt/mediarecorder/MediaRecorder-video-bitrate-expected.txt (0 => 265328)
--- trunk/LayoutTests/http/wpt/mediarecorder/MediaRecorder-video-bitrate-expected.txt (rev 0)
+++ trunk/LayoutTests/http/wpt/mediarecorder/MediaRecorder-video-bitrate-expected.txt 2020-08-06 15:25:39 UTC (rev 265328)
@@ -0,0 +1,3 @@
+
+PASS Various video bitrates
+
Added: trunk/LayoutTests/http/wpt/mediarecorder/MediaRecorder-video-bitrate.html (0 => 265328)
--- trunk/LayoutTests/http/wpt/mediarecorder/MediaRecorder-video-bitrate.html (rev 0)
+++ trunk/LayoutTests/http/wpt/mediarecorder/MediaRecorder-video-bitrate.html 2020-08-06 15:25:39 UTC (rev 265328)
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+<head>
+ <title>MediaRecorder video bitrate</title>
+ <script src=""
+ <script src=""
+</head>
+<body>
+<script>
+ async function record(bitRate)
+ {
+ const stream = await navigator.mediaDevices.getUserMedia({ video : { width : 1024 } });
+ const recorder = new MediaRecorder(stream, { videoBitsPerSecond : bitRate });
+ const promise = new Promise((resolve, reject) => {
+ let count = 0;
+ let blobs = [];
+ recorder._ondataavailable_ = (e) => resolve(e.data);
+ setTimeout(() => reject("datavailable event timed out"), 15000);
+ });
+ recorder.start();
+ setTimeout(() => recorder.stop(), 1000);
+ return promise;
+ }
+
+ promise_test(async (t) => {
+ let blobs = [0, 0];
+ blobs[0] = await record(50000);
+ blobs[1] = await record(5000000);
+
+ // We are taking the second blob since it might be more accurate than the first one.
+ assert_greater_than(blobs[0].size, 0, "blob0");
+ assert_greater_than(blobs[1].size, blobs[0].size, "blob2");
+ }, "Various video bitrates");
+</script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (265327 => 265328)
--- trunk/Source/WebCore/ChangeLog 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebCore/ChangeLog 2020-08-06 15:25:39 UTC (rev 265328)
@@ -1,3 +1,51 @@
+2020-08-06 Youenn Fablet <you...@apple.com>
+
+ Add support for MediaRecorder bitrate options
+ https://bugs.webkit.org/show_bug.cgi?id=214973
+
+ Reviewed by Eric Carlson.
+
+ Pipe options to MediaRecorderPrivate constructor.
+ For the actual implementation, pass it down to VideoSampleBufferCompressor and AudioSampleBufferCompressor.
+ For AudioSampleBufferCompressor, we do not handle well some bit rates, so for now, we limit to specific values.
+
+ Tests: http/wpt/mediarecorder/MediaRecorder-audio-bitrate.html
+ http/wpt/mediarecorder/MediaRecorder-video-bitrate.html
+
+ * Modules/mediarecorder/MediaRecorder.cpp:
+ (WebCore::MediaRecorder::create):
+ (WebCore::MediaRecorder::createMediaRecorderPrivate):
+ (WebCore::MediaRecorder::MediaRecorder):
+ (WebCore::MediaRecorder::startRecording):
+ * Modules/mediarecorder/MediaRecorder.h:
+ * Modules/mediarecorder/MediaRecorderProvider.cpp:
+ (WebCore::MediaRecorderProvider::createMediaRecorderPrivate):
+ * Modules/mediarecorder/MediaRecorderProvider.h:
+ * WebCore.xcodeproj/project.pbxproj:
+ * loader/EmptyClients.cpp:
+ * platform/mediarecorder/MediaRecorderPrivate.h:
+ * platform/mediarecorder/MediaRecorderPrivateAVFImpl.cpp:
+ (WebCore::MediaRecorderPrivateAVFImpl::create):
+ * platform/mediarecorder/MediaRecorderPrivateAVFImpl.h:
+ * platform/mediarecorder/cocoa/AudioSampleBufferCompressor.h:
+ * platform/mediarecorder/cocoa/AudioSampleBufferCompressor.mm:
+ (WebCore::AudioSampleBufferCompressor::setBitsPerSecond):
+ (WebCore::AudioSampleBufferCompressor::outputBitRate const):
+ (WebCore::AudioSampleBufferCompressor::initAudioConverterForSourceFormatDescription):
+ Do not exit when not able to set bitrate as we still want to set m_maxOutputPacketSize.
+ In case of error in setting up the converter, clean it up so that we do not use a partially set up converter.
+ * platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.h:
+ * platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.mm:
+ (WebCore::MediaRecorderPrivateWriter::create):
+ (WebCore::MediaRecorderPrivateWriter::setOptions):
+ * platform/mediarecorder/cocoa/VideoSampleBufferCompressor.h:
+ * platform/mediarecorder/cocoa/VideoSampleBufferCompressor.mm:
+ (WebCore::VideoSampleBufferCompressor::setBitsPerSecond):
+ (WebCore::setCompressionSessionProperty):
+ (WebCore::VideoSampleBufferCompressor::initCompressionSession):
+ * testing/Internals.cpp:
+ (WebCore::createRecorderMockSource):
+
2020-08-06 Simon Fraser <simon.fra...@apple.com>
Scrolling tree nodes sometimes don't match layer z-order
Modified: trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.cpp (265327 => 265328)
--- trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.cpp 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.cpp 2020-08-06 15:25:39 UTC (rev 265328)
@@ -48,9 +48,10 @@
ExceptionOr<Ref<MediaRecorder>> MediaRecorder::create(Document& document, Ref<MediaStream>&& stream, Options&& options)
{
- auto privateInstance = MediaRecorder::createMediaRecorderPrivate(document, stream->privateStream());
- if (!privateInstance)
- return Exception { NotSupportedError, "The MediaRecorder is unsupported on this platform"_s };
+ auto result = MediaRecorder::createMediaRecorderPrivate(document, stream->privateStream(), options);
+ if (result.hasException())
+ return result.releaseException();
+
auto recorder = adoptRef(*new MediaRecorder(document, WTFMove(stream), WTFMove(options)));
recorder->suspendIfNeeded();
return recorder;
@@ -61,27 +62,27 @@
m_customCreator = creator;
}
-std::unique_ptr<MediaRecorderPrivate> MediaRecorder::createMediaRecorderPrivate(Document& document, MediaStreamPrivate& stream)
+ExceptionOr<std::unique_ptr<MediaRecorderPrivate>> MediaRecorder::createMediaRecorderPrivate(Document& document, MediaStreamPrivate& stream, const Options& options)
{
if (m_customCreator)
- return m_customCreator(stream);
+ return m_customCreator(stream, options);
#if PLATFORM(COCOA)
auto* page = document.page();
if (!page)
- return nullptr;
+ return Exception { InvalidStateError };
- return page->mediaRecorderProvider().createMediaRecorderPrivate(stream);
+ return page->mediaRecorderProvider().createMediaRecorderPrivate(stream, options);
#else
UNUSED_PARAM(document);
UNUSED_PARAM(stream);
- return nullptr;
+ return Exception { NotSupportedError, "The MediaRecorder is unsupported on this platform"_s };
#endif
}
-MediaRecorder::MediaRecorder(Document& document, Ref<MediaStream>&& stream, Options&& option)
+MediaRecorder::MediaRecorder(Document& document, Ref<MediaStream>&& stream, Options&& options)
: ActiveDOMObject(document)
- , m_options(WTFMove(option))
+ , m_options(WTFMove(options))
, m_stream(WTFMove(stream))
, m_timeSliceTimer([this] { requestData(); })
{
@@ -135,11 +136,13 @@
return Exception { InvalidStateError, "The MediaRecorder's state must be inactive in order to start recording"_s };
ASSERT(!m_private);
- m_private = createMediaRecorderPrivate(*document(), m_stream->privateStream());
+ auto result = createMediaRecorderPrivate(*document(), m_stream->privateStream(), m_options);
- if (!m_private)
- return Exception { NotSupportedError, "The MediaRecorder is unsupported on this platform"_s };
+ ASSERT(!result.hasException());
+ if (result.hasException())
+ return result.releaseException();
+ m_private = result.releaseReturnValue();
m_private->startRecording([this, pendingActivity = makePendingActivity(*this)](auto&& exception) mutable {
if (!m_isActive)
return;
Modified: trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.h (265327 => 265328)
--- trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.h 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.h 2020-08-06 15:25:39 UTC (rev 265328)
@@ -28,6 +28,8 @@
#include "ActiveDOMObject.h"
#include "EventTarget.h"
+#include "ExceptionOr.h"
+#include "MediaRecorderPrivateOptions.h"
#include "MediaStream.h"
#include "MediaStreamTrackPrivate.h"
#include "Timer.h"
@@ -49,18 +51,12 @@
public:
enum class RecordingState { Inactive, Recording, Paused };
- struct Options {
- String mimeType;
- unsigned audioBitsPerSecond;
- unsigned videoBitsPerSecond;
- unsigned bitsPerSecond;
- };
-
~MediaRecorder();
+ using Options = MediaRecorderPrivateOptions;
static ExceptionOr<Ref<MediaRecorder>> create(Document&, Ref<MediaStream>&&, Options&& = { });
- using CreatorFunction = std::unique_ptr<MediaRecorderPrivate>(*)(MediaStreamPrivate&);
+ using CreatorFunction = ExceptionOr<std::unique_ptr<MediaRecorderPrivate>> (*)(MediaStreamPrivate&, const Options&);
WEBCORE_EXPORT static void setCustomPrivateRecorderCreator(CreatorFunction);
@@ -76,9 +72,9 @@
MediaStream& stream() { return m_stream.get(); }
private:
- MediaRecorder(Document&, Ref<MediaStream>&&, Options&& = { });
+ MediaRecorder(Document&, Ref<MediaStream>&&, Options&&);
- static std::unique_ptr<MediaRecorderPrivate> createMediaRecorderPrivate(Document&, MediaStreamPrivate&);
+ static ExceptionOr<std::unique_ptr<MediaRecorderPrivate>> createMediaRecorderPrivate(Document&, MediaStreamPrivate&, const Options&);
Document* document() const;
@@ -111,7 +107,7 @@
void trackEnabledChanged(MediaStreamTrackPrivate&) final { };
static CreatorFunction m_customCreator;
-
+
Options m_options;
Ref<MediaStream> m_stream;
std::unique_ptr<MediaRecorderPrivate> m_private;
Modified: trunk/Source/WebCore/Modules/mediarecorder/MediaRecorderProvider.cpp (265327 => 265328)
--- trunk/Source/WebCore/Modules/mediarecorder/MediaRecorderProvider.cpp 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebCore/Modules/mediarecorder/MediaRecorderProvider.cpp 2020-08-06 15:25:39 UTC (rev 265328)
@@ -32,12 +32,13 @@
namespace WebCore {
-std::unique_ptr<MediaRecorderPrivate> MediaRecorderProvider::createMediaRecorderPrivate(MediaStreamPrivate& stream)
+std::unique_ptr<MediaRecorderPrivate> MediaRecorderProvider::createMediaRecorderPrivate(MediaStreamPrivate& stream, const MediaRecorderPrivateOptions& options)
{
#if HAVE(AVASSETWRITERDELEGATE)
- return MediaRecorderPrivateAVFImpl::create(stream);
+ return MediaRecorderPrivateAVFImpl::create(stream, options);
#else
UNUSED_PARAM(stream);
+ UNUSED_PARAM(options);
return nullptr;
#endif
}
Modified: trunk/Source/WebCore/Modules/mediarecorder/MediaRecorderProvider.h (265327 => 265328)
--- trunk/Source/WebCore/Modules/mediarecorder/MediaRecorderProvider.h 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebCore/Modules/mediarecorder/MediaRecorderProvider.h 2020-08-06 15:25:39 UTC (rev 265328)
@@ -29,6 +29,7 @@
class MediaRecorderPrivate;
class MediaStreamPrivate;
+struct MediaRecorderPrivateOptions;
class WEBCORE_EXPORT MediaRecorderProvider {
WTF_MAKE_FAST_ALLOCATED;
@@ -37,7 +38,7 @@
virtual ~MediaRecorderProvider() = default;
#if ENABLE(MEDIA_STREAM) && PLATFORM(COCOA)
- virtual std::unique_ptr<MediaRecorderPrivate> createMediaRecorderPrivate(MediaStreamPrivate&);
+ virtual std::unique_ptr<MediaRecorderPrivate> createMediaRecorderPrivate(MediaStreamPrivate&, const MediaRecorderPrivateOptions&);
#endif
void setUseGPUProcess(bool value) { m_useGPUProcess = value; }
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (265327 => 265328)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2020-08-06 15:25:39 UTC (rev 265328)
@@ -1052,6 +1052,7 @@
413E00791DB0E4F2002341D2 /* MemoryRelease.h in Headers */ = {isa = PBXBuildFile; fileRef = 413E00781DB0E4DE002341D2 /* MemoryRelease.h */; settings = {ATTRIBUTES = (Private, ); }; };
414460A22412994500814BE7 /* MediaSessionIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 414460A02412994100814BE7 /* MediaSessionIdentifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
414598C223C8D177002B9CC8 /* LocalSampleBufferDisplayLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 414598C123C8AD79002B9CC8 /* LocalSampleBufferDisplayLayer.mm */; };
+ 414B7FAD24D81CC10033D442 /* MediaRecorderPrivateOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 414B7FAB24D81C8F0033D442 /* MediaRecorderPrivateOptions.h */; settings = {ATTRIBUTES = (Private, ); }; };
414B82051D6DF0E50077EBE3 /* StructuredClone.h in Headers */ = {isa = PBXBuildFile; fileRef = 414B82031D6DF0D90077EBE3 /* StructuredClone.h */; };
414DEDE71F9FE91E0047C40D /* EmptyFrameLoaderClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 414DEDE51F9FE9150047C40D /* EmptyFrameLoaderClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
415071581685067300C3C7B3 /* SelectorFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 415071561685067300C3C7B3 /* SelectorFilter.h */; };
@@ -7475,6 +7476,7 @@
414AD40021498D3100521676 /* RTCRtpDecodingParameters.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RTCRtpDecodingParameters.h; sourceTree = "<group>"; };
414AD40121498D3100521676 /* RTCRtpDecodingParameters.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = RTCRtpDecodingParameters.idl; sourceTree = "<group>"; };
414AD40221498D3200521676 /* RTCRtpCodingParameters.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = RTCRtpCodingParameters.idl; sourceTree = "<group>"; };
+ 414B7FAB24D81C8F0033D442 /* MediaRecorderPrivateOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaRecorderPrivateOptions.h; sourceTree = "<group>"; };
414B82021D6DF0D90077EBE3 /* StructuredClone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructuredClone.cpp; sourceTree = "<group>"; };
414B82031D6DF0D90077EBE3 /* StructuredClone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructuredClone.h; sourceTree = "<group>"; };
414DEDE51F9FE9150047C40D /* EmptyFrameLoaderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EmptyFrameLoaderClient.h; sourceTree = "<group>"; };
@@ -19554,6 +19556,7 @@
4D73F944218BC5FA003A3ED6 /* MediaRecorderPrivateAVFImpl.h */,
4D9F6B652182532B0092A9C5 /* MediaRecorderPrivateMock.cpp */,
4D9F6B642182532B0092A9C5 /* MediaRecorderPrivateMock.h */,
+ 414B7FAB24D81C8F0033D442 /* MediaRecorderPrivateOptions.h */,
);
path = mediarecorder;
sourceTree = "<group>";
@@ -32568,6 +32571,7 @@
4DB7130D216ECB4D0096A4DD /* MediaRecorderErrorEvent.h in Headers */,
4D3B5016217E58B700665DB1 /* MediaRecorderPrivate.h in Headers */,
4D73F946218BC5FA003A3ED6 /* MediaRecorderPrivateAVFImpl.h in Headers */,
+ 414B7FAD24D81CC10033D442 /* MediaRecorderPrivateOptions.h in Headers */,
4D73F94E218C4A87003A3ED6 /* MediaRecorderPrivateWriterCocoa.h in Headers */,
4176E89623C3537B003E83FE /* MediaRecorderProvider.h in Headers */,
C90843D01B18E47D00B68564 /* MediaRemoteControls.h in Headers */,
Modified: trunk/Source/WebCore/loader/EmptyClients.cpp (265327 => 265328)
--- trunk/Source/WebCore/loader/EmptyClients.cpp 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebCore/loader/EmptyClients.cpp 2020-08-06 15:25:39 UTC (rev 265328)
@@ -588,7 +588,7 @@
EmptyMediaRecorderProvider() = default;
private:
#if ENABLE(MEDIA_STREAM) && PLATFORM(COCOA)
- std::unique_ptr<MediaRecorderPrivate> createMediaRecorderPrivate(MediaStreamPrivate&) final { return nullptr; }
+ std::unique_ptr<MediaRecorderPrivate> createMediaRecorderPrivate(MediaStreamPrivate&, const MediaRecorderPrivateOptions&) final { return nullptr; }
#endif
};
Modified: trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.h (265327 => 265328)
--- trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.h 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.h 2020-08-06 15:25:39 UTC (rev 265328)
@@ -27,6 +27,7 @@
#include <wtf/CompletionHandler.h>
#include <wtf/Forward.h>
#include "Exception.h"
+#include "MediaRecorderPrivateOptions.h"
#include "RealtimeMediaSource.h"
#if ENABLE(MEDIA_STREAM)
Modified: trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateAVFImpl.cpp (265327 => 265328)
--- trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateAVFImpl.cpp 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateAVFImpl.cpp 2020-08-06 15:25:39 UTC (rev 265328)
@@ -37,7 +37,7 @@
namespace WebCore {
-std::unique_ptr<MediaRecorderPrivateAVFImpl> MediaRecorderPrivateAVFImpl::create(MediaStreamPrivate& stream)
+std::unique_ptr<MediaRecorderPrivateAVFImpl> MediaRecorderPrivateAVFImpl::create(MediaStreamPrivate& stream, const MediaRecorderPrivateOptions& options)
{
// FIXME: we will need to implement support for multiple audio/video tracks
// Currently we only choose the first track as the recorded track.
@@ -45,11 +45,11 @@
auto selectedTracks = MediaRecorderPrivate::selectTracks(stream);
- auto writer = MediaRecorderPrivateWriter::create(!!selectedTracks.audioTrack, !!selectedTracks.videoTrack);
+ auto writer = MediaRecorderPrivateWriter::create(!!selectedTracks.audioTrack, !!selectedTracks.videoTrack, options);
if (!writer)
return nullptr;
- auto recorder = makeUnique<MediaRecorderPrivateAVFImpl>(writer.releaseNonNull());
+ auto recorder = std::unique_ptr<MediaRecorderPrivateAVFImpl>(new MediaRecorderPrivateAVFImpl(writer.releaseNonNull()));
if (selectedTracks.audioTrack)
recorder->setAudioSource(&selectedTracks.audioTrack->source());
if (selectedTracks.videoTrack)
Modified: trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateAVFImpl.h (265327 => 265328)
--- trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateAVFImpl.h 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateAVFImpl.h 2020-08-06 15:25:39 UTC (rev 265328)
@@ -37,12 +37,12 @@
: public MediaRecorderPrivate {
WTF_MAKE_FAST_ALLOCATED;
public:
- static std::unique_ptr<MediaRecorderPrivateAVFImpl> create(MediaStreamPrivate&);
+ static std::unique_ptr<MediaRecorderPrivateAVFImpl> create(MediaStreamPrivate&, const MediaRecorderPrivateOptions&);
+ ~MediaRecorderPrivateAVFImpl();
+private:
explicit MediaRecorderPrivateAVFImpl(Ref<MediaRecorderPrivateWriter>&&);
- ~MediaRecorderPrivateAVFImpl();
-private:
// MediaRecorderPrivate
void videoSampleAvailable(MediaSample&) final;
void fetchData(FetchDataCallback&&) final;
Added: trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateOptions.h (0 => 265328)
--- trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateOptions.h (rev 0)
+++ trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateOptions.h 2020-08-06 15:25:39 UTC (rev 265328)
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/Forward.h>
+
+#if ENABLE(MEDIA_STREAM)
+
+namespace WebCore {
+
+struct MediaRecorderPrivateOptions {
+ String mimeType;
+ Optional<unsigned> audioBitsPerSecond;
+ Optional<unsigned> videoBitsPerSecond;
+ Optional<unsigned> bitsPerSecond;
+
+ template<class Encoder> void encode(Encoder&) const;
+ template<class Decoder> static Optional<MediaRecorderPrivateOptions> decode(Decoder&);
+};
+
+template<class Encoder>
+inline void MediaRecorderPrivateOptions::encode(Encoder& encoder) const
+{
+ encoder << mimeType;
+ encoder << audioBitsPerSecond;
+ encoder << videoBitsPerSecond;
+ encoder << bitsPerSecond;
+}
+
+template<class Decoder>
+inline Optional<MediaRecorderPrivateOptions> MediaRecorderPrivateOptions::decode(Decoder& decoder)
+{
+ String mimeType;
+ if (!decoder.decode(mimeType))
+ return WTF::nullopt;
+
+ Optional<Optional<unsigned>> audioBitsPerSecond;
+ decoder >> audioBitsPerSecond;
+ if (!audioBitsPerSecond)
+ return WTF::nullopt;
+
+ Optional<Optional<unsigned>> videoBitsPerSecond;
+ decoder >> videoBitsPerSecond;
+ if (!videoBitsPerSecond)
+ return WTF::nullopt;
+
+ Optional<Optional<unsigned>> bitsPerSecond;
+ decoder >> bitsPerSecond;
+ if (!bitsPerSecond)
+ return WTF::nullopt;
+
+ return MediaRecorderPrivateOptions { WTFMove(mimeType), *audioBitsPerSecond, *videoBitsPerSecond, *bitsPerSecond };
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
Modified: trunk/Source/WebCore/platform/mediarecorder/cocoa/AudioSampleBufferCompressor.h (265327 => 265328)
--- trunk/Source/WebCore/platform/mediarecorder/cocoa/AudioSampleBufferCompressor.h 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebCore/platform/mediarecorder/cocoa/AudioSampleBufferCompressor.h 2020-08-06 15:25:39 UTC (rev 265328)
@@ -39,6 +39,7 @@
static std::unique_ptr<AudioSampleBufferCompressor> create(CMBufferQueueTriggerCallback, void* callbackObject);
~AudioSampleBufferCompressor();
+ void setBitsPerSecond(unsigned);
void finish();
void addSampleBuffer(CMSampleBufferRef);
CMSampleBufferRef getOutputSampleBuffer();
@@ -47,6 +48,7 @@
private:
AudioSampleBufferCompressor();
bool initialize(CMBufferQueueTriggerCallback, void* callbackObject);
+ UInt32 outputBitRate(const AudioStreamBasicDescription&) const;
static OSStatus audioConverterComplexInputDataProc(AudioConverterRef, UInt32*, AudioBufferList*, AudioStreamPacketDescription**, void*);
@@ -85,6 +87,7 @@
size_t m_sampleBlockBufferSize { 0 };
size_t m_currentOffsetInSampleBlockBuffer { 0 };
AudioFormatID m_outputCodecType { kAudioFormatMPEG4AAC };
+ Optional<unsigned> m_outputBitRate;
};
}
Modified: trunk/Source/WebCore/platform/mediarecorder/cocoa/AudioSampleBufferCompressor.mm (265327 => 265328)
--- trunk/Source/WebCore/platform/mediarecorder/cocoa/AudioSampleBufferCompressor.mm 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebCore/platform/mediarecorder/cocoa/AudioSampleBufferCompressor.mm 2020-08-06 15:25:39 UTC (rev 265328)
@@ -32,6 +32,8 @@
#include <AudioToolbox/AudioConverter.h>
#include <AudioToolbox/AudioFormat.h>
#include <Foundation/Foundation.h>
+#include <algorithm>
+#include <wtf/Scope.h>
#import <pal/cf/AudioToolboxSoftLink.h>
@@ -95,6 +97,34 @@
});
}
+void AudioSampleBufferCompressor::setBitsPerSecond(unsigned bitRate)
+{
+ // FIXME: we have some issues when setting up some bit rates, only allow some that work for the moment.
+ if (bitRate < 128000) {
+ RELEASE_LOG_INFO(WebRTC, "AudioSampleBufferCompressor::outputBitRate clamped to 128000.");
+ bitRate = 128000;
+ } else if (bitRate > 256000) {
+ RELEASE_LOG_INFO(WebRTC, "AudioSampleBufferCompressor::outputBitRate clamped to 256000.");
+ bitRate = 256000;
+ } else if (bitRate != 128000 && bitRate != 192000 && bitRate != 256000) {
+ RELEASE_LOG_INFO(WebRTC, "AudioSampleBufferCompressor::outputBitRate did not set output bit rate as value is not supported.");
+ return;
+ }
+ m_outputBitRate = bitRate;
+}
+
+UInt32 AudioSampleBufferCompressor::outputBitRate(const AudioStreamBasicDescription& destinationFormat) const
+{
+ if (m_outputBitRate)
+ return *m_outputBitRate;
+
+ if (destinationFormat.mSampleRate >= 44100)
+ return 192000;
+ if (destinationFormat.mSampleRate < 22000)
+ return 32000;
+ return 64000;
+}
+
bool AudioSampleBufferCompressor::initAudioConverterForSourceFormatDescription(CMFormatDescriptionRef formatDescription, AudioFormatID outputFormatID)
{
const auto *audioFormatListItem = CMAudioFormatDescriptionGetRichestDecodableFormat(formatDescription);
@@ -118,6 +148,11 @@
}
m_converter = converter;
+ auto cleanupInCaseOfError = makeScopeExit([&] {
+ AudioConverterDispose(m_converter);
+ m_converter = nullptr;
+ });
+
size_t cookieSize = 0;
const void *cookie = CMAudioFormatDescriptionGetMagicCookie(formatDescription, &cookieSize);
if (cookieSize) {
@@ -145,18 +180,10 @@
}
if (m_destinationFormat.mFormatID == kAudioFormatMPEG4AAC) {
- // FIXME: Set outputBitRate according MediaRecorderOptions.audioBitsPerSecond.
- UInt32 outputBitRate = 64000;
- if (m_destinationFormat.mSampleRate >= 44100)
- outputBitRate = 192000;
- else if (m_destinationFormat.mSampleRate < 22000)
- outputBitRate = 32000;
-
+ auto outputBitRate = this->outputBitRate(m_destinationFormat);
size = sizeof(outputBitRate);
- if (auto error = AudioConverterSetProperty(m_converter, kAudioConverterEncodeBitRate, size, &outputBitRate)) {
+ if (auto error = AudioConverterSetProperty(m_converter, kAudioConverterEncodeBitRate, size, &outputBitRate))
RELEASE_LOG_ERROR(MediaStream, "AudioSampleBufferCompressor setting kAudioConverterEncodeBitRate failed with %d", error);
- return false;
- }
}
if (!m_destinationFormat.mBytesPerPacket) {
@@ -169,6 +196,8 @@
}
}
+ cleanupInCaseOfError.release();
+
auto destinationBufferSize = computeBufferSizeForAudioFormat(m_destinationFormat, m_maxOutputPacketSize, LOW_WATER_TIME_IN_SECONDS);
if (m_destinationBuffer.size() < destinationBufferSize)
m_destinationBuffer.resize(destinationBufferSize);
@@ -428,8 +457,10 @@
m_currentOutputPresentationTimeStamp = CMSampleBufferGetOutputPresentationTimeStamp(buffer);
auto formatDescription = CMSampleBufferGetFormatDescription(buffer);
- if (!initAudioConverterForSourceFormatDescription(formatDescription, m_outputCodecType))
+ if (!initAudioConverterForSourceFormatDescription(formatDescription, m_outputCodecType)) {
+ // FIXME: Maybe we should error the media recorder if we are not able to get a correct converter.
return;
+ }
}
while (CMTIME_IS_INVALID(lowWaterTime) || CMTIME_COMPARE_INLINE(lowWaterTime, <, CMBufferQueueGetDuration(m_inputBufferQueue.get()))) {
Modified: trunk/Source/WebCore/platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.h (265327 => 265328)
--- trunk/Source/WebCore/platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.h 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebCore/platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.h 2020-08-06 15:25:39 UTC (rev 265328)
@@ -59,10 +59,11 @@
class MediaStreamTrackPrivate;
class PlatformAudioData;
class VideoSampleBufferCompressor;
+struct MediaRecorderPrivateOptions;
class WEBCORE_EXPORT MediaRecorderPrivateWriter : public ThreadSafeRefCounted<MediaRecorderPrivateWriter, WTF::DestructionThread::Main>, public CanMakeWeakPtr<MediaRecorderPrivateWriter, WeakPtrFactoryInitialization::Eager> {
public:
- static RefPtr<MediaRecorderPrivateWriter> create(bool hasAudio, bool hasVideo);
+ static RefPtr<MediaRecorderPrivateWriter> create(bool hasAudio, bool hasVideo, const MediaRecorderPrivateOptions&);
~MediaRecorderPrivateWriter();
void appendVideoSampleBuffer(CMSampleBufferRef);
@@ -78,6 +79,7 @@
void clear();
bool initialize();
+ void setOptions(const MediaRecorderPrivateOptions&);
static void compressedVideoOutputBufferCallback(void*, CMBufferQueueTriggerToken);
static void compressedAudioOutputBufferCallback(void*, CMBufferQueueTriggerToken);
Modified: trunk/Source/WebCore/platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.mm (265327 => 265328)
--- trunk/Source/WebCore/platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.mm 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebCore/platform/mediarecorder/cocoa/MediaRecorderPrivateWriterCocoa.mm 2020-08-06 15:25:39 UTC (rev 265328)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2018-2020 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,6 +31,7 @@
#include "AudioSampleBufferCompressor.h"
#include "AudioStreamDescription.h"
#include "Logging.h"
+#include "MediaRecorderPrivateOptions.h"
#include "MediaStreamTrackPrivate.h"
#include "VideoSampleBufferCompressor.h"
#include "WebAudioBufferList.h"
@@ -114,11 +115,12 @@
using namespace PAL;
-RefPtr<MediaRecorderPrivateWriter> MediaRecorderPrivateWriter::create(bool hasAudio, bool hasVideo)
+RefPtr<MediaRecorderPrivateWriter> MediaRecorderPrivateWriter::create(bool hasAudio, bool hasVideo, const MediaRecorderPrivateOptions& options)
{
auto writer = adoptRef(*new MediaRecorderPrivateWriter(hasAudio, hasVideo));
if (!writer->initialize())
return nullptr;
+ writer->setOptions(options);
return writer;
}
@@ -176,6 +178,14 @@
return true;
}
+void MediaRecorderPrivateWriter::setOptions(const MediaRecorderPrivateOptions& options)
+{
+ if (options.audioBitsPerSecond && m_audioCompressor)
+ m_audioCompressor->setBitsPerSecond(*options.audioBitsPerSecond);
+ if (options.videoBitsPerSecond && m_videoCompressor)
+ m_videoCompressor->setBitsPerSecond(*options.videoBitsPerSecond);
+}
+
void MediaRecorderPrivateWriter::processNewCompressedVideoSampleBuffers()
{
ASSERT(m_hasVideo);
Modified: trunk/Source/WebCore/platform/mediarecorder/cocoa/VideoSampleBufferCompressor.h (265327 => 265328)
--- trunk/Source/WebCore/platform/mediarecorder/cocoa/VideoSampleBufferCompressor.h 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebCore/platform/mediarecorder/cocoa/VideoSampleBufferCompressor.h 2020-08-06 15:25:39 UTC (rev 265328)
@@ -40,6 +40,7 @@
static std::unique_ptr<VideoSampleBufferCompressor> create(CMVideoCodecType, CMBufferQueueTriggerCallback, void* callbackObject);
~VideoSampleBufferCompressor();
+ void setBitsPerSecond(unsigned);
void finish();
void addSampleBuffer(CMSampleBufferRef);
CMSampleBufferRef getOutputSampleBuffer();
@@ -64,6 +65,7 @@
bool m_isEncoding { false };
float m_maxKeyFrameIntervalDuration { 2.0 };
unsigned m_expectedFrameRate { 30 };
+ Optional<unsigned> m_outputBitRate;
};
}
Modified: trunk/Source/WebCore/platform/mediarecorder/cocoa/VideoSampleBufferCompressor.mm (265327 => 265328)
--- trunk/Source/WebCore/platform/mediarecorder/cocoa/VideoSampleBufferCompressor.mm 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebCore/platform/mediarecorder/cocoa/VideoSampleBufferCompressor.mm 2020-08-06 15:25:39 UTC (rev 265328)
@@ -76,6 +76,11 @@
return true;
}
+void VideoSampleBufferCompressor::setBitsPerSecond(unsigned bitRate)
+{
+ m_outputBitRate = bitRate;
+}
+
void VideoSampleBufferCompressor::finish()
{
dispatch_sync(m_serialDispatchQueue, ^{
@@ -101,6 +106,15 @@
RELEASE_LOG_ERROR_IF(error, MediaStream, "VideoSampleBufferCompressor CMBufferQueueEnqueue failed with %d", error);
}
+static inline OSStatus setCompressionSessionProperty(VTCompressionSessionRef vtSession, CFStringRef key, uint32_t value)
+{
+ int64_t value64 = value;
+ CFNumberRef cfValue = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value64);
+ OSStatus status = VTSessionSetProperty(vtSession, key, cfValue);
+ CFRelease(cfValue);
+ return status;
+}
+
bool VideoSampleBufferCompressor::initCompressionSession(CMVideoFormatDescriptionRef formatDescription)
{
CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions(formatDescription);
@@ -120,12 +134,16 @@
error = VTSessionSetProperty(m_vtSession.get(), kVTCompressionPropertyKey_RealTime, kCFBooleanTrue);
RELEASE_LOG_ERROR_IF(error, MediaStream, "VideoSampleBufferCompressor VTSessionSetProperty kVTCompressionPropertyKey_RealTime failed with %d", error);
- error = VTSessionSetProperty(m_vtSession.get(), kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration, (__bridge CFTypeRef)@(m_maxKeyFrameIntervalDuration));
+ error = setCompressionSessionProperty(m_vtSession.get(), kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration, m_maxKeyFrameIntervalDuration);
RELEASE_LOG_ERROR_IF(error, MediaStream, "VideoSampleBufferCompressor VTSessionSetProperty kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration failed with %d", error);
- error = VTSessionSetProperty(m_vtSession.get(), kVTCompressionPropertyKey_ExpectedFrameRate, (__bridge CFTypeRef)@(m_expectedFrameRate));
+ error = setCompressionSessionProperty(m_vtSession.get(), kVTCompressionPropertyKey_ExpectedFrameRate, m_expectedFrameRate);
RELEASE_LOG_ERROR_IF(error, MediaStream, "VideoSampleBufferCompressor VTSessionSetProperty kVTCompressionPropertyKey_ExpectedFrameRate failed with %d", error);
- // FIXME: Set video compression rate.
+ if (m_outputBitRate) {
+ error = setCompressionSessionProperty(m_vtSession.get(), kVTCompressionPropertyKey_AverageBitRate, *m_outputBitRate);
+ RELEASE_LOG_ERROR_IF(error, MediaStream, "VideoSampleBufferCompressor VTSessionSetProperty kVTCompressionPropertyKey_AverageBitRate failed with %d", error);
+ }
+
error = VTCompressionSessionPrepareToEncodeFrames(m_vtSession.get());
RELEASE_LOG_ERROR_IF(error, MediaStream, "VideoSampleBufferCompressor VTCompressionSessionPrepareToEncodeFrames failed with %d", error);
Modified: trunk/Source/WebCore/testing/Internals.cpp (265327 => 265328)
--- trunk/Source/WebCore/testing/Internals.cpp 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebCore/testing/Internals.cpp 2020-08-06 15:25:39 UTC (rev 265328)
@@ -1691,9 +1691,9 @@
page->settings().setMediaCaptureRequiresSecureConnection(enabled);
}
-static std::unique_ptr<MediaRecorderPrivate> createRecorderMockSource(MediaStreamPrivate& stream)
+static ExceptionOr<std::unique_ptr<MediaRecorderPrivate>> createRecorderMockSource(MediaStreamPrivate& stream, const MediaRecorderPrivateOptions&)
{
- return std::unique_ptr<MediaRecorderPrivateMock>(new MediaRecorderPrivateMock(stream));
+ return std::unique_ptr<MediaRecorderPrivate>(new MediaRecorderPrivateMock(stream));
}
void Internals::setCustomPrivateRecorderCreator()
@@ -1700,9 +1700,8 @@
{
WebCore::MediaRecorder::setCustomPrivateRecorderCreator(createRecorderMockSource);
}
+#endif // ENABLE(MEDIA_STREAM)
-#endif
-
ExceptionOr<Ref<DOMRect>> Internals::absoluteCaretBounds()
{
Document* document = contextDocument();
Modified: trunk/Source/WebKit/ChangeLog (265327 => 265328)
--- trunk/Source/WebKit/ChangeLog 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebKit/ChangeLog 2020-08-06 15:25:39 UTC (rev 265328)
@@ -1,3 +1,27 @@
+2020-08-06 Youenn Fablet <you...@apple.com>
+
+ Add support for MediaRecorder bitrate options
+ https://bugs.webkit.org/show_bug.cgi?id=214973
+
+ Reviewed by Eric Carlson.
+
+ Serialize options when creating remote media recorder.
+
+ * GPUProcess/webrtc/RemoteMediaRecorder.cpp:
+ (WebKit::RemoteMediaRecorder::create):
+ * GPUProcess/webrtc/RemoteMediaRecorder.h:
+ * GPUProcess/webrtc/RemoteMediaRecorderManager.cpp:
+ (WebKit::RemoteMediaRecorderManager::createRecorder):
+ * GPUProcess/webrtc/RemoteMediaRecorderManager.h:
+ * GPUProcess/webrtc/RemoteMediaRecorderManager.messages.in:
+ * WebProcess/GPU/webrtc/MediaRecorderPrivate.cpp:
+ (WebKit::MediaRecorderPrivate::MediaRecorderPrivate):
+ (WebKit::MediaRecorderPrivate::startRecording):
+ * WebProcess/GPU/webrtc/MediaRecorderPrivate.h:
+ * WebProcess/GPU/webrtc/MediaRecorderProvider.cpp:
+ (WebKit::MediaRecorderProvider::createMediaRecorderPrivate):
+ * WebProcess/GPU/webrtc/MediaRecorderProvider.h:
+
2020-08-06 Adrian Perez de Castro <ape...@igalia.com>
[WPE][GTK] Wrong argument order for clone syscall seccomp filter on s390x
Modified: trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorder.cpp (265327 => 265328)
--- trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorder.cpp 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorder.cpp 2020-08-06 15:25:39 UTC (rev 265328)
@@ -38,9 +38,9 @@
namespace WebKit {
using namespace WebCore;
-std::unique_ptr<RemoteMediaRecorder> RemoteMediaRecorder::create(GPUConnectionToWebProcess& gpuConnectionToWebProcess, MediaRecorderIdentifier identifier, bool recordAudio, bool recordVideo)
+std::unique_ptr<RemoteMediaRecorder> RemoteMediaRecorder::create(GPUConnectionToWebProcess& gpuConnectionToWebProcess, MediaRecorderIdentifier identifier, bool recordAudio, bool recordVideo, const MediaRecorderPrivateOptions& options)
{
- auto writer = MediaRecorderPrivateWriter::create(recordAudio, recordVideo);
+ auto writer = MediaRecorderPrivateWriter::create(recordAudio, recordVideo, options);
if (!writer)
return nullptr;
return std::unique_ptr<RemoteMediaRecorder>(new RemoteMediaRecorder { gpuConnectionToWebProcess, identifier, writer.releaseNonNull(), recordAudio });
Modified: trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorder.h (265327 => 265328)
--- trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorder.h 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorder.h 2020-08-06 15:25:39 UTC (rev 265328)
@@ -44,6 +44,7 @@
class CARingBuffer;
class ImageTransferSessionVT;
class RemoteVideoSample;
+struct MediaRecorderPrivateOptions;
}
namespace WebKit {
@@ -54,7 +55,7 @@
class RemoteMediaRecorder : private IPC::MessageReceiver {
WTF_MAKE_FAST_ALLOCATED;
public:
- static std::unique_ptr<RemoteMediaRecorder> create(GPUConnectionToWebProcess&, MediaRecorderIdentifier, bool recordAudio, bool recordVideo);
+ static std::unique_ptr<RemoteMediaRecorder> create(GPUConnectionToWebProcess&, MediaRecorderIdentifier, bool recordAudio, bool recordVideo, const WebCore::MediaRecorderPrivateOptions&);
~RemoteMediaRecorder();
void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
Modified: trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorderManager.cpp (265327 => 265328)
--- trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorderManager.cpp 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorderManager.cpp 2020-08-06 15:25:39 UTC (rev 265328)
@@ -51,10 +51,10 @@
recorder->didReceiveMessage(connection, decoder);
}
-void RemoteMediaRecorderManager::createRecorder(MediaRecorderIdentifier identifier, bool recordAudio, bool recordVideo, CompletionHandler<void(Optional<ExceptionData>&&)>&& completionHandler)
+void RemoteMediaRecorderManager::createRecorder(MediaRecorderIdentifier identifier, bool recordAudio, bool recordVideo, const MediaRecorderPrivateOptions& options, CompletionHandler<void(Optional<ExceptionData>&&)>&& completionHandler)
{
ASSERT(!m_recorders.contains(identifier));
- auto recorder = RemoteMediaRecorder::create(m_gpuConnectionToWebProcess, identifier, recordAudio, recordVideo);
+ auto recorder = RemoteMediaRecorder::create(m_gpuConnectionToWebProcess, identifier, recordAudio, recordVideo, options);
if (!recorder)
return completionHandler(ExceptionData { NotSupportedError, "Unable to create a recorder with the provided stream"_s });
Modified: trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorderManager.h (265327 => 265328)
--- trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorderManager.h 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorderManager.h 2020-08-06 15:25:39 UTC (rev 265328)
@@ -41,6 +41,7 @@
namespace WebCore {
struct ExceptionData;
+struct MediaRecorderPrivateOptions;
}
namespace WebKit {
@@ -60,7 +61,7 @@
private:
// IPC::MessageReceiver
void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
- void createRecorder(MediaRecorderIdentifier, bool recordAudio, bool recordVideo, CompletionHandler<void(Optional<WebCore::ExceptionData>&&)>&&);
+ void createRecorder(MediaRecorderIdentifier, bool recordAudio, bool recordVideo, const WebCore::MediaRecorderPrivateOptions&, CompletionHandler<void(Optional<WebCore::ExceptionData>&&)>&&);
void releaseRecorder(MediaRecorderIdentifier);
GPUConnectionToWebProcess& m_gpuConnectionToWebProcess;
Modified: trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorderManager.messages.in (265327 => 265328)
--- trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorderManager.messages.in 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorderManager.messages.in 2020-08-06 15:25:39 UTC (rev 265328)
@@ -24,7 +24,7 @@
#if PLATFORM(COCOA) && ENABLE(GPU_PROCESS) && ENABLE(MEDIA_STREAM) && HAVE(AVASSETWRITERDELEGATE)
messages -> RemoteMediaRecorderManager NotRefCounted {
- CreateRecorder(WebKit::MediaRecorderIdentifier id, bool hasAudio, bool hasVideo) -> (Optional<WebCore::ExceptionData> creationError) Async
+ CreateRecorder(WebKit::MediaRecorderIdentifier id, bool hasAudio, bool hasVideo, struct WebCore::MediaRecorderPrivateOptions options) -> (Optional<WebCore::ExceptionData> creationError) Async
ReleaseRecorder(WebKit::MediaRecorderIdentifier id)
}
Modified: trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderPrivate.cpp (265327 => 265328)
--- trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderPrivate.cpp 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderPrivate.cpp 2020-08-06 15:25:39 UTC (rev 265328)
@@ -43,10 +43,11 @@
namespace WebKit {
using namespace WebCore;
-MediaRecorderPrivate::MediaRecorderPrivate(MediaStreamPrivate& stream)
+MediaRecorderPrivate::MediaRecorderPrivate(MediaStreamPrivate& stream, const MediaRecorderPrivateOptions& options)
: m_identifier(MediaRecorderIdentifier::generate())
, m_stream(makeRef(stream))
, m_connection(WebProcess::singleton().ensureGPUProcessConnection().connection())
+ , m_options(options)
{
}
@@ -59,7 +60,7 @@
if (selectedTracks.audioTrack)
m_ringBuffer = makeUnique<CARingBuffer>(makeUniqueRef<SharedRingBufferStorage>(this));
- m_connection->sendWithAsyncReply(Messages::RemoteMediaRecorderManager::CreateRecorder { m_identifier, !!selectedTracks.audioTrack, !!selectedTracks.videoTrack }, [this, weakThis = makeWeakPtr(this), audioTrack = makeRefPtr(selectedTracks.audioTrack), videoTrack = makeRefPtr(selectedTracks.videoTrack), errorCallback = WTFMove(errorCallback)](auto&& exception) mutable {
+ m_connection->sendWithAsyncReply(Messages::RemoteMediaRecorderManager::CreateRecorder { m_identifier, !!selectedTracks.audioTrack, !!selectedTracks.videoTrack, m_options }, [this, weakThis = makeWeakPtr(this), audioTrack = makeRefPtr(selectedTracks.audioTrack), videoTrack = makeRefPtr(selectedTracks.videoTrack), errorCallback = WTFMove(errorCallback)](auto&& exception) mutable {
if (!weakThis) {
errorCallback({ });
return;
Modified: trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderPrivate.h (265327 => 265328)
--- trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderPrivate.h 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderPrivate.h 2020-08-06 15:25:39 UTC (rev 265328)
@@ -50,7 +50,7 @@
, public CanMakeWeakPtr<MediaRecorderPrivate> {
WTF_MAKE_FAST_ALLOCATED;
public:
- explicit MediaRecorderPrivate(WebCore::MediaStreamPrivate&);
+ MediaRecorderPrivate(WebCore::MediaStreamPrivate&, const WebCore::MediaRecorderPrivateOptions&);
~MediaRecorderPrivate();
private:
@@ -71,6 +71,7 @@
std::unique_ptr<WebCore::CARingBuffer> m_ringBuffer;
WebCore::CAAudioStreamDescription m_description { };
int64_t m_numberOfFrames { 0 };
+ WebCore::MediaRecorderPrivateOptions m_options;
};
}
Modified: trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderProvider.cpp (265327 => 265328)
--- trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderProvider.cpp 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderProvider.cpp 2020-08-06 15:25:39 UTC (rev 265328)
@@ -34,13 +34,13 @@
namespace WebKit {
using namespace WebCore;
-std::unique_ptr<WebCore::MediaRecorderPrivate> MediaRecorderProvider::createMediaRecorderPrivate(MediaStreamPrivate& stream)
+std::unique_ptr<WebCore::MediaRecorderPrivate> MediaRecorderProvider::createMediaRecorderPrivate(MediaStreamPrivate& stream, const MediaRecorderPrivateOptions& options)
{
#if ENABLE(GPU_PROCESS) && HAVE(AVASSETWRITERDELEGATE)
if (m_useGPUProcess)
- return makeUnique<MediaRecorderPrivate>(stream);
+ return makeUnique<MediaRecorderPrivate>(stream, options);
#endif
- return WebCore::MediaRecorderProvider::createMediaRecorderPrivate(stream);
+ return WebCore::MediaRecorderProvider::createMediaRecorderPrivate(stream, options);
}
}
Modified: trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderProvider.h (265327 => 265328)
--- trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderProvider.h 2020-08-06 14:55:55 UTC (rev 265327)
+++ trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderProvider.h 2020-08-06 15:25:39 UTC (rev 265328)
@@ -35,7 +35,7 @@
private:
#if ENABLE(MEDIA_STREAM) && PLATFORM(COCOA)
- std::unique_ptr<WebCore::MediaRecorderPrivate> createMediaRecorderPrivate(WebCore::MediaStreamPrivate&) final;
+ std::unique_ptr<WebCore::MediaRecorderPrivate> createMediaRecorderPrivate(WebCore::MediaStreamPrivate&, const WebCore::MediaRecorderPrivateOptions&) final;
#endif
};