Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(291)

Side by Side Diff: third_party/WebKit/Source/modules/mediarecorder/MediaRecorder.cpp

Issue 1610473002: MediaRecorder: wire the bitRate settings in Blink and content (2nd go) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "modules/mediarecorder/MediaRecorder.h" 5 #include "modules/mediarecorder/MediaRecorder.h"
6 6
7 #include "bindings/core/v8/Dictionary.h" 7 #include "bindings/core/v8/Dictionary.h"
8 #include "core/events/Event.h" 8 #include "core/events/Event.h"
9 #include "core/fileapi/Blob.h" 9 #include "core/fileapi/Blob.h"
10 #include "core/inspector/ConsoleMessage.h"
10 #include "modules/EventTargetModules.h" 11 #include "modules/EventTargetModules.h"
11 #include "modules/mediarecorder/BlobEvent.h" 12 #include "modules/mediarecorder/BlobEvent.h"
12 #include "platform/ContentType.h" 13 #include "platform/ContentType.h"
13 #include "platform/NotImplemented.h" 14 #include "platform/NotImplemented.h"
14 #include "platform/blob/BlobData.h" 15 #include "platform/blob/BlobData.h"
15 #include "public/platform/Platform.h" 16 #include "public/platform/Platform.h"
16 #include "public/platform/WebMediaStream.h" 17 #include "public/platform/WebMediaStream.h"
17 18
18 namespace blink { 19 namespace blink {
19 20
20 namespace { 21 namespace {
21 22
23 // Boundaries of Opus bitrate from https://www.opus-codec.org/.
24 const int kSmallestPossibleOpusBitRate = 6000;
25 const int kLargestAutoAllocatedOpusBitRate = 128000;
26
27 // Smallest Vpx bitrate that can be requested.
28 const int kSmallestPossibleVpxBitRate = 100000;
29
22 String stateToString(MediaRecorder::State state) 30 String stateToString(MediaRecorder::State state)
23 { 31 {
24 switch (state) { 32 switch (state) {
25 case MediaRecorder::State::Inactive: 33 case MediaRecorder::State::Inactive:
26 return "inactive"; 34 return "inactive";
27 case MediaRecorder::State::Recording: 35 case MediaRecorder::State::Recording:
28 return "recording"; 36 return "recording";
29 case MediaRecorder::State::Paused: 37 case MediaRecorder::State::Paused:
30 return "paused"; 38 return "paused";
31 } 39 }
32 40
33 ASSERT_NOT_REACHED(); 41 ASSERT_NOT_REACHED();
34 return String(); 42 return String();
35 } 43 }
36 44
45 // Allocates the requested bit rates from |bitrateOptions| into the respective
46 // |{audio,video}BitsPerSecond|, calculating and clamping if needed.
Peter Beverloo 2016/01/20 18:35:35 nit: A comment here explaining *why* certain ratio
mcasas 2016/01/20 21:13:22 Commented.
47 bool AllocateVideoAndAudioBitrates(ExecutionContext* context, const MediaRecorde rOptions& options, bool useAudio, bool useVideo, int32_t* audioBitsPerSecond, in t32_t* videoBitsPerSecond)
48 {
49 // Check that |options| don't overflow an int32_t.
50 const unsigned long kInt32MaxValueAsULong = std::numeric_limits<int32_t>::ma x();
51 if (options.bitsPerSecond() >= kInt32MaxValueAsULong || (options.bitsPerSeco nd() == 0 && (options.videoBitsPerSecond() >= kInt32MaxValueAsULong || options.a udioBitsPerSecond() >= kInt32MaxValueAsULong))) {
52 const String message = "bitrates too large (audio: " + String::number(op tions.audioBitsPerSecond()) + "bps, video: " + String::number(options.videoBitsP erSecond()) + "bps, overall: " + String::number(options.bitsPerSecond()) + "bps) ";
53 context->addConsoleMessage(ConsoleMessage::create(JSMessageSource, Error MessageLevel, message));
54 return false;
55 }
56
Peter Beverloo 2016/01/20 18:35:35 [Comment applies to lines 49-55.] I think this is
mcasas 2016/01/20 21:13:22 I'd love to but Gecko had it as ulong beforehand,
Peter Beverloo 2016/01/21 11:04:36 It is unfortunate that we can't rely on the standa
mcasas 2016/01/21 18:42:46 I filed https://github.com/w3c/mediacapture-record
57 *videoBitsPerSecond = options.videoBitsPerSecond();
58 *audioBitsPerSecond = options.audioBitsPerSecond();
Peter Beverloo 2016/01/20 18:35:35 nit: There's a lot of stars in the code. Might be
mcasas 2016/01/20 21:13:22 Done.
59
60 // |options.bitsPerSecond()| overrides the specific audio and video bit
61 // rates, and we are free to allocate as desired.
62 if (useAudio) {
63 if (options.bitsPerSecond()) {
64 if (useVideo)
65 *audioBitsPerSecond = options.bitsPerSecond() / 10;
66 else
67 *audioBitsPerSecond = options.bitsPerSecond();
68 }
69 // Limit audio bitrate values if they are too large or too small.
70 if (*audioBitsPerSecond) {
71 if (*audioBitsPerSecond > kLargestAutoAllocatedOpusBitRate) {
72 const String message = "clamping calculated audio bitrate (" + S tring::number(*audioBitsPerSecond) + "bps) to the maximum (" + String::number(kL argestAutoAllocatedOpusBitRate) + "bps)";
Peter Beverloo 2016/01/20 18:35:35 nit: s/clamping/Clamping/. These are sentences.
mcasas 2016/01/20 21:13:22 Done.
73 context->addConsoleMessage(ConsoleMessage::create(JSMessageSourc e, WarningMessageLevel, message));
74 *audioBitsPerSecond = kLargestAutoAllocatedOpusBitRate;
75 }
76
77 if (*audioBitsPerSecond < kSmallestPossibleOpusBitRate) {
78 const String message = "clamping calculated audio bitrate (" + S tring::number(*audioBitsPerSecond) + "bps) to the minimum (" + String::number(kS mallestPossibleOpusBitRate) + "bps)";
79 context->addConsoleMessage(ConsoleMessage::create(JSMessageSourc e, WarningMessageLevel, message));
80 *audioBitsPerSecond = kSmallestPossibleOpusBitRate;
81 }
82 }
83 } else {
84 *audioBitsPerSecond = 0;
85 }
86 // If there is video bit rate allocated it should be larger than a minimum.
87 if (useVideo) {
88 if (options.bitsPerSecond())
89 *videoBitsPerSecond = options.bitsPerSecond() - *audioBitsPerSecond;
90 // Clamp the video bit rate if there is any configured (explicitly or
Peter Beverloo 2016/01/20 18:35:35 nit: it's a bit odd to break this comment given th
mcasas 2016/01/20 21:13:22 Yup, sorry, came from Cr side 80-char limit. Done.
91 // implicitly via |options.bitsPerSecond()|).
92 if ((*videoBitsPerSecond || options.bitsPerSecond()) && (*videoBitsPerSe cond < kSmallestPossibleVpxBitRate)) {
Peter Beverloo 2016/01/20 18:35:35 In which situation is the "(*videoBitsPerSecond ||
mcasas 2016/01/20 21:13:22 It's a peculiar case indeed, as miu@ detailed: - t
93 const String message = "clamping calculated video bitrate (" + Strin g::number(*videoBitsPerSecond) + "bps) to the minimum (" + String::number(kSmall estPossibleVpxBitRate) + "bps)";
94 context->addConsoleMessage(ConsoleMessage::create(JSMessageSource, W arningMessageLevel, message));
95 *videoBitsPerSecond = kSmallestPossibleVpxBitRate;
96 }
97 } else {
98 *videoBitsPerSecond = 0;
99 }
100 return true;
101 }
102
37 } // namespace 103 } // namespace
38 104
39 MediaRecorder* MediaRecorder::create(ExecutionContext* context, MediaStream* str eam, ExceptionState& exceptionState) 105 MediaRecorder* MediaRecorder::create(ExecutionContext* context, MediaStream* str eam, ExceptionState& exceptionState)
40 { 106 {
41 MediaRecorder* recorder = new MediaRecorder(context, stream, MediaRecorderOp tions(), exceptionState); 107 MediaRecorder* recorder = new MediaRecorder(context, stream, MediaRecorderOp tions(), exceptionState);
42 recorder->suspendIfNeeded(); 108 recorder->suspendIfNeeded();
43 109
44 return recorder; 110 return recorder;
45 } 111 }
46 112
(...skipping 13 matching lines...) Expand all
60 , m_stopped(true) 126 , m_stopped(true)
61 , m_ignoreMutedMedia(true) 127 , m_ignoreMutedMedia(true)
62 , m_state(State::Inactive) 128 , m_state(State::Inactive)
63 , m_dispatchScheduledEventRunner(AsyncMethodRunner<MediaRecorder>::create(th is, &MediaRecorder::dispatchScheduledEvent)) 129 , m_dispatchScheduledEventRunner(AsyncMethodRunner<MediaRecorder>::create(th is, &MediaRecorder::dispatchScheduledEvent))
64 { 130 {
65 ASSERT(m_stream->getTracks().size()); 131 ASSERT(m_stream->getTracks().size());
66 132
67 m_recorderHandler = adoptPtr(Platform::current()->createMediaRecorderHandler ()); 133 m_recorderHandler = adoptPtr(Platform::current()->createMediaRecorderHandler ());
68 ASSERT(m_recorderHandler); 134 ASSERT(m_recorderHandler);
69 135
70 // We deviate from the spec by not returning |UnsupportedOption|, see https: //github.com/w3c/mediacapture-record/issues/18
71 if (!m_recorderHandler) { 136 if (!m_recorderHandler) {
72 exceptionState.throwDOMException(NotSupportedError, "No MediaRecorder ha ndler can be created."); 137 exceptionState.throwDOMException(NotSupportedError, "No MediaRecorder ha ndler can be created.");
73 return; 138 return;
74 } 139 }
75 ContentType contentType(m_mimeType); 140
76 if (!m_recorderHandler->initialize(this, stream->descriptor(), contentType.t ype(), contentType.parameter("codecs"))) { 141 const ContentType contentType(m_mimeType);
77 exceptionState.throwDOMException(NotSupportedError, "Failed to initializ e native MediaRecorder, the type provided " + m_mimeType + "is unsupported." ); 142 const bool useVideo = stream->getVideoTracks().size() > 0;
143 const bool useAudio = stream->getAudioTracks().size() > 0;
144 int32_t audioBitsPerSecond = 0;
145 int32_t videoBitsPerSecond = 0;
146 // If bit rate calculation fails, throw an exception but allow continuing wi th defaults.
Peter Beverloo 2016/01/20 18:35:35 This could do with a few more blank lines for read
mcasas 2016/01/20 21:13:22 cleaned up.
147 if (!AllocateVideoAndAudioBitrates(context, options, useAudio, useVideo, &au dioBitsPerSecond, &videoBitsPerSecond)) {
148 const String message = "target bitrates too large (audio: " + String::nu mber(options.audioBitsPerSecond()) + "bps, video: " + String::number(options.vid eoBitsPerSecond()) + "bps, overall: " + String::number(options.bitsPerSecond()) + "bps)";
149 exceptionState.throwDOMException(NotSupportedError, message);
150 }
151
152 if (!m_recorderHandler->initialize(this, stream->descriptor(), contentType.t ype(), contentType.parameter("codecs"), audioBitsPerSecond, videoBitsPerSecond)) {
153 exceptionState.throwDOMException(NotSupportedError, "Failed to initializ e native MediaRecorder, the bitrates supplied, or the type provided (" + m_mimeT ype + ") are unsupported.");
78 return; 154 return;
79 } 155 }
80 m_stopped = false; 156 m_stopped = false;
81 } 157 }
82 158
83 String MediaRecorder::state() const 159 String MediaRecorder::state() const
84 { 160 {
85 return stateToString(m_state); 161 return stateToString(m_state);
86 } 162 }
87 163
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 DEFINE_TRACE(MediaRecorder) 344 DEFINE_TRACE(MediaRecorder)
269 { 345 {
270 visitor->trace(m_stream); 346 visitor->trace(m_stream);
271 visitor->trace(m_dispatchScheduledEventRunner); 347 visitor->trace(m_dispatchScheduledEventRunner);
272 visitor->trace(m_scheduledEvents); 348 visitor->trace(m_scheduledEvents);
273 RefCountedGarbageCollectedEventTargetWithInlineData<MediaRecorder>::trace(vi sitor); 349 RefCountedGarbageCollectedEventTargetWithInlineData<MediaRecorder>::trace(vi sitor);
274 ActiveDOMObject::trace(visitor); 350 ActiveDOMObject::trace(visitor);
275 } 351 }
276 352
277 } // namespace blink 353 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698