Diff
Modified: trunk/LayoutTests/ChangeLog (287612 => 287613)
--- trunk/LayoutTests/ChangeLog 2022-01-05 10:46:30 UTC (rev 287612)
+++ trunk/LayoutTests/ChangeLog 2022-01-05 11:26:48 UTC (rev 287613)
@@ -1,5 +1,15 @@
2022-01-05 Youenn Fablet <you...@apple.com>
+ MediaRecorder should support the bitsPerSecond option
+ https://bugs.webkit.org/show_bug.cgi?id=234784
+
+ Reviewed by Darin Adler.
+
+ * http/wpt/mediarecorder/MediaRecorder-bitrate-expected.txt: Added.
+ * http/wpt/mediarecorder/MediaRecorder-bitrate.html: Added.
+
+2022-01-05 Youenn Fablet <you...@apple.com>
+
Fetch using FormData with file doesn't go through Service Worker
https://bugs.webkit.org/show_bug.cgi?id=187461
<rdar://problem/41975544>
Added: trunk/LayoutTests/http/wpt/mediarecorder/MediaRecorder-bitrate-expected.txt (0 => 287613)
--- trunk/LayoutTests/http/wpt/mediarecorder/MediaRecorder-bitrate-expected.txt (rev 0)
+++ trunk/LayoutTests/http/wpt/mediarecorder/MediaRecorder-bitrate-expected.txt 2022-01-05 11:26:48 UTC (rev 287613)
@@ -0,0 +1,5 @@
+
+PASS audio bitrate
+PASS video bitrate
+PASS audio video bitrate
+
Added: trunk/LayoutTests/http/wpt/mediarecorder/MediaRecorder-bitrate.html (0 => 287613)
--- trunk/LayoutTests/http/wpt/mediarecorder/MediaRecorder-bitrate.html (rev 0)
+++ trunk/LayoutTests/http/wpt/mediarecorder/MediaRecorder-bitrate.html 2022-01-05 11:26:48 UTC (rev 287613)
@@ -0,0 +1,57 @@
+<!doctype html>
+<html>
+<head>
+ <title>MediaRecorder bitrate</title>
+ <script src=""
+ <script src=""
+</head>
+<body>
+<script>
+promise_test(async (t) => {
+ const stream = await navigator.mediaDevices.getUserMedia({ audio : true });
+
+ let recorder = new MediaRecorder(stream, { bitsPerSecond : 1000000 });
+ assert_equals(recorder.audioBitsPerSecond, 100000, "test 1");
+
+ recorder = new MediaRecorder(stream, { bitsPerSecond : 10000 });
+ assert_equals(recorder.audioBitsPerSecond, 8000, "test 2");
+
+ recorder = new MediaRecorder(stream, { bitsPerSecond : 1000 });
+ assert_equals(recorder.audioBitsPerSecond, 8000, "test 3");
+}, "audio bitrate");
+
+promise_test(async (t) => {
+ const stream = await navigator.mediaDevices.getUserMedia({ video : true });
+
+ let recorder = new MediaRecorder(stream, { bitsPerSecond : 1000000 });
+ assert_equals(recorder.videoBitsPerSecond, 900000, "test 1");
+
+ recorder = new MediaRecorder(stream, { bitsPerSecond : 100000 });
+ assert_equals(recorder.videoBitsPerSecond, 90000, "test 2");
+
+ recorder = new MediaRecorder(stream, { bitsPerSecond : 10000 });
+ assert_equals(recorder.videoBitsPerSecond, 80000, "test 3");
+}, "video bitrate");
+
+promise_test(async (t) => {
+ const stream = await navigator.mediaDevices.getUserMedia({ audio : true, video : true });
+
+ let recorder = new MediaRecorder(stream, { bitsPerSecond : 1000000 });
+ assert_equals(recorder.audioBitsPerSecond, 100000, "test 1");
+ assert_equals(recorder.videoBitsPerSecond, 900000, "test 2");
+
+ recorder = new MediaRecorder(stream, { bitsPerSecond : 200000 });
+ assert_equals(recorder.audioBitsPerSecond, 20000, "test 3");
+ assert_equals(recorder.videoBitsPerSecond, 180000, "test 4");
+
+ recorder = new MediaRecorder(stream, { bitsPerSecond : 88000 });
+ assert_equals(recorder.audioBitsPerSecond, 8800, "test 5");
+ assert_equals(recorder.videoBitsPerSecond, 80000, "test 6");
+
+ recorder = new MediaRecorder(stream, { bitsPerSecond : 50000 });
+ assert_equals(recorder.audioBitsPerSecond, 8000, "test 7");
+ assert_equals(recorder.videoBitsPerSecond, 80000, "test 8");
+}, "audio video bitrate");
+</script>
+</body>
+</html>
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (287612 => 287613)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2022-01-05 10:46:30 UTC (rev 287612)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2022-01-05 11:26:48 UTC (rev 287613)
@@ -1,5 +1,14 @@
2022-01-05 Youenn Fablet <you...@apple.com>
+ MediaRecorder should support the bitsPerSecond option
+ https://bugs.webkit.org/show_bug.cgi?id=234784
+
+ Reviewed by Darin Adler.
+
+ * web-platform-tests/mediacapture-record/MediaRecorder-bitrate.https-expected.txt:
+
+2022-01-05 Youenn Fablet <you...@apple.com>
+
Fetch using FormData with file doesn't go through Service Worker
https://bugs.webkit.org/show_bug.cgi?id=187461
<rdar://problem/41975544>
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/mediacapture-record/MediaRecorder-bitrate.https-expected.txt (287612 => 287613)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/mediacapture-record/MediaRecorder-bitrate.https-expected.txt 2022-01-05 10:46:30 UTC (rev 287612)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/mediacapture-record/MediaRecorder-bitrate.https-expected.txt 2022-01-05 11:26:48 UTC (rev 287613)
@@ -1,11 +1,11 @@
PASS Passing no bitrate config results in defaults
-FAIL Passing bitsPerSecond:0 results in targets close to 0 assert_approx_equals: expected 0 +/- 100000 but got 10192000
+PASS Passing bitsPerSecond:0 results in targets close to 0
PASS Passing only audioBitsPerSecond:0 results in 0 for audio, default for video
PASS Passing only videoBitsPerSecond:0 results in 0 for video, default for audio
-FAIL Passing bitsPerSecond:0 overrides audio/video-specific values assert_approx_equals: expected 0 +/- 100000 but got 1100000
-FAIL Passing bitsPerSecond overrides audio/video zero values assert_not_equals: got disallowed value 0
-FAIL Passing bitsPerSecond sets audio/video bitrate values assert_approx_equals: expected 2000000 +/- 100000 but got 10192000
+PASS Passing bitsPerSecond:0 overrides audio/video-specific values
+PASS Passing bitsPerSecond overrides audio/video zero values
+PASS Passing bitsPerSecond sets audio/video bitrate values
PASS Passing only audioBitsPerSecond results in default for video
PASS Passing only videoBitsPerSecond results in default for audio
PASS Passing videoBitsPerSecond for audio-only stream still results in something for video
@@ -15,6 +15,6 @@
PASS Selected default track bitrates are not changed by start()
PASS Passed-in track bitrates are not changed by start()
PASS Passing bitsPerSecond for audio/video stream does not change track bitrates in start()
-FAIL Passing bitsPerSecond for audio stream sets video track bitrate to 0 in start() assert_approx_equals: expected 500000 +/- 100000 but got 192000
-FAIL Passing bitsPerSecond for video stream sets audio track bitrate to 0 in start() assert_equals: expected 0 but got 192000
+PASS Passing bitsPerSecond for audio stream sets video track bitrate to 0 in start()
+PASS Passing bitsPerSecond for video stream sets audio track bitrate to 0 in start()
Modified: trunk/Source/WebCore/ChangeLog (287612 => 287613)
--- trunk/Source/WebCore/ChangeLog 2022-01-05 10:46:30 UTC (rev 287612)
+++ trunk/Source/WebCore/ChangeLog 2022-01-05 11:26:48 UTC (rev 287613)
@@ -1,5 +1,26 @@
2022-01-05 Youenn Fablet <you...@apple.com>
+ MediaRecorder should support the bitsPerSecond option
+ https://bugs.webkit.org/show_bug.cgi?id=234784
+
+ Reviewed by Darin Adler.
+
+ In case bitsPerSecond is set, we now compute audioBitsPerSecond and videoBitsPerSecond value according to it.
+ We set audioBitsPerSecond to a tenth of bitsPerSecond and set videoBitsPerSecond to the remaining available bandwidth.
+ We then use minimum values of 8kbps for audio and 80kbps for video.
+ As per spec, we compute these values at creation, start and stop times.
+ We introduce dedicated class members for audio and video bitrates, similarly to the spec defining corresponding slots.
+
+ Test: http/wpt/mediarecorder/MediaRecorder-bitrate.html
+
+ * Modules/mediarecorder/MediaRecorder.cpp:
+ * Modules/mediarecorder/MediaRecorder.h:
+ * platform/mediarecorder/MediaRecorderPrivate.cpp:
+ * platform/mediarecorder/MediaRecorderPrivate.h:
+ * platform/mediarecorder/MediaRecorderPrivateAVFImpl.cpp:
+
+2022-01-05 Youenn Fablet <you...@apple.com>
+
Fetch using FormData with file doesn't go through Service Worker
https://bugs.webkit.org/show_bug.cgi?id=187461
<rdar://problem/41975544>
Modified: trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.cpp (287612 => 287613)
--- trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.cpp 2022-01-05 10:46:30 UTC (rev 287612)
+++ trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.cpp 2022-01-05 11:26:48 UTC (rev 287613)
@@ -103,7 +103,7 @@
, m_stream(WTFMove(stream))
, m_timeSliceTimer([this] { requestData(); })
{
- MediaRecorderPrivate::updateOptions(m_options);
+ computeInitialBitRates();
m_tracks = WTF::map(m_stream->getTracks(), [] (auto&& track) -> Ref<MediaStreamTrackPrivate> {
return track->privateTrack();
@@ -154,8 +154,14 @@
if (state() != RecordingState::Inactive)
return Exception { InvalidStateError, "The MediaRecorder's state must be inactive in order to start recording"_s };
+ updateBitRates();
+
+ Options options;
+ options.audioBitsPerSecond = m_audioBitsPerSecond;
+ options.videoBitsPerSecond = m_videoBitsPerSecond;
+
ASSERT(!m_private);
- auto result = createMediaRecorderPrivate(*document(), m_stream->privateStream(), m_options);
+ auto result = createMediaRecorderPrivate(*document(), m_stream->privateStream(), options);
if (result.hasException())
return result.releaseException();
@@ -207,6 +213,8 @@
if (state() == RecordingState::Inactive)
return;
+ updateBitRates();
+
stopRecordingInternal();
fetchData([this](auto&& buffer, auto& mimeType, auto timeCode) {
if (!m_isActive)
@@ -393,6 +401,13 @@
return m_state != RecordingState::Inactive;
}
+void MediaRecorder::computeBitRates(const MediaStreamPrivate* stream)
+{
+ auto bitRates = MediaRecorderPrivate::computeBitRates(m_options, stream);
+ m_audioBitsPerSecond = bitRates.audio;
+ m_videoBitsPerSecond = bitRates.video;
+}
+
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)
Modified: trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.h (287612 => 287613)
--- trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.h 2022-01-05 10:46:30 UTC (rev 287612)
+++ trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.h 2022-01-05 11:26:48 UTC (rev 287613)
@@ -75,8 +75,8 @@
ExceptionOr<void> pauseRecording();
ExceptionOr<void> resumeRecording();
- unsigned videoBitsPerSecond() const { return m_options.videoBitsPerSecond.value_or(0); }
- unsigned audioBitsPerSecond() const { return m_options.audioBitsPerSecond.value_or(0); }
+ unsigned videoBitsPerSecond() const { return m_videoBitsPerSecond; }
+ unsigned audioBitsPerSecond() const { return m_audioBitsPerSecond; }
MediaStream& stream() { return m_stream.get(); }
@@ -99,7 +99,7 @@
const char* activeDOMObjectName() const final;
bool virtualHasPendingActivity() const final;
- void stopRecordingInternal(CompletionHandler<void()>&& = [] { });
+ void stopRecordingInternal(CompletionHandler<void()>&& = [] { });
void dispatchError(Exception&&);
enum class TakePrivateRecorder { No, Yes };
@@ -118,6 +118,10 @@
void trackEnabledChanged(MediaStreamTrackPrivate&) final;
void trackSettingsChanged(MediaStreamTrackPrivate&) final { };
+ void computeInitialBitRates() { computeBitRates(nullptr); }
+ void updateBitRates() { computeBitRates(&m_stream->privateStream()); }
+ void computeBitRates(const MediaStreamPrivate*);
+
static CreatorFunction m_customCreator;
Options m_options;
@@ -131,6 +135,9 @@
bool m_isActive { true };
bool m_isFetchingData { false };
Deque<FetchDataCallback> m_pendingFetchDataTasks;
+
+ unsigned m_audioBitsPerSecond { 0 };
+ unsigned m_videoBitsPerSecond { 0 };
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.cpp (287612 => 287613)
--- trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.cpp 2022-01-05 10:46:30 UTC (rev 287612)
+++ trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.cpp 2022-01-05 11:26:48 UTC (rev 287613)
@@ -32,6 +32,8 @@
namespace WebCore {
+constexpr unsigned SmallAudioBitRate = 8000;
+constexpr unsigned SmallVideoBitRate = 80000;
constexpr unsigned LargeAudioBitRate = 192000;
constexpr unsigned LargeVideoBitRate = 10000000;
@@ -100,13 +102,26 @@
resumeRecording(WTFMove(completionHandler));
}
-void MediaRecorderPrivate::updateOptions(MediaRecorderPrivateOptions& options)
+MediaRecorderPrivate::BitRates MediaRecorderPrivate::computeBitRates(const MediaRecorderPrivateOptions& options, const MediaStreamPrivate* stream)
{
- // FIXME: Add support for options.bitsPerSecond.
- if (!options.audioBitsPerSecond)
- options.audioBitsPerSecond = LargeAudioBitRate;
- if (!options.videoBitsPerSecond)
- options.videoBitsPerSecond = LargeVideoBitRate;
+ if (options.bitsPerSecond) {
+ bool hasAudio = stream ? stream->hasAudio() : true;
+ bool hasVideo = stream ? stream->hasVideo() : true;
+ auto totalBitsPerSecond = *options.bitsPerSecond;
+
+ if (hasAudio && hasVideo) {
+ auto audioBitsPerSecond = std::min(LargeAudioBitRate, std::max(SmallAudioBitRate, totalBitsPerSecond / 10));
+ auto remainingBitsPerSecond = totalBitsPerSecond > audioBitsPerSecond ? (totalBitsPerSecond - audioBitsPerSecond) : 0;
+ return { audioBitsPerSecond, std::max(remainingBitsPerSecond, SmallVideoBitRate) };
+ }
+
+ if (hasAudio)
+ return { std::max(SmallAudioBitRate, totalBitsPerSecond), 0 };
+
+ return { 0, std::max(SmallVideoBitRate, totalBitsPerSecond) };
+ }
+
+ return { options.audioBitsPerSecond.value_or(LargeAudioBitRate), options.videoBitsPerSecond.value_or(LargeVideoBitRate) };
}
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.h (287612 => 287613)
--- trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.h 2022-01-05 10:46:30 UTC (rev 287612)
+++ trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.h 2022-01-05 11:26:48 UTC (rev 287613)
@@ -73,7 +73,11 @@
void trackMutedChanged(MediaStreamTrackPrivate& track) { checkTrackState(track); }
void trackEnabledChanged(MediaStreamTrackPrivate& track) { checkTrackState(track); }
- static void updateOptions(MediaRecorderPrivateOptions&);
+ struct BitRates {
+ unsigned audio;
+ unsigned video;
+ };
+ static BitRates computeBitRates(const MediaRecorderPrivateOptions&, const MediaStreamPrivate* = nullptr);
protected:
void setAudioSource(RefPtr<RealtimeMediaSource>&&);
Modified: trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateAVFImpl.cpp (287612 => 287613)
--- trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateAVFImpl.cpp 2022-01-05 10:46:30 UTC (rev 287612)
+++ trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateAVFImpl.cpp 2022-01-05 11:26:48 UTC (rev 287613)
@@ -79,7 +79,6 @@
void MediaRecorderPrivateAVFImpl::startRecording(StartRecordingCallback&& callback)
{
// FIMXE: In case of of audio recording, we should wait for the audio compression to start to give back the exact bit rate.
- // FIXME: Add support to options.bitsPerSecond as well.
callback(String(m_writer->mimeType()), m_writer->audioBitRate(), m_writer->videoBitRate());
}