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

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: comments addressed. Added TODO for unsigned->signed change 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| (where a value of zero indicates Platform to use
47 // whatever it sees fit). If |options.bitsPerSecond()| is specified, it
48 // overrides any specific bitrate, and the UA is free to allocate as desired:
49 // here a 90%/10% video/audio is used. In all cases where a value is explicited
50 // or calculated, values are clamped in sane ranges.
51 // This method throws NotSupportedError.
52 void AllocateVideoAndAudioBitrates(ExceptionState& exceptionState, ExecutionCont ext* context, const MediaRecorderOptions& options, MediaStream* stream, int32_t* audioBitsPerSecond, int32_t* videoBitsPerSecond)
53 {
54 // Throw if any value would overflow an int32_t.
55 // TODO(mcasas): This section would no be needed if the bit rates are signed , see https://github.com/w3c/mediacapture-record/issues/48.
56 const uint32_t kInt32MaxValueAsULong = std::numeric_limits<int32_t>::max();
57 if (options.bitsPerSecond() >= kInt32MaxValueAsULong) {
58 exceptionState.throwDOMException(NotSupportedError, "Overall bit rate to o large " + String::number(options.bitsPerSecond()) + "bps)");
59 return;
60 }
61 if (options.bitsPerSecond() == 0) {
62 if (options.videoBitsPerSecond() >= kInt32MaxValueAsULong) {
63 exceptionState.throwDOMException(NotSupportedError, "Video bit rate too large " + String::number(options.videoBitsPerSecond()) + "bps)");
64 return;
65 }
66 if (options.audioBitsPerSecond() >= kInt32MaxValueAsULong) {
67 exceptionState.throwDOMException(NotSupportedError, "Audio bit rate too large " + String::number(options.audioBitsPerSecond()) + "bps)");
68 return;
69 }
70 }
71
72 int32_t videoBps = options.videoBitsPerSecond();
73 int32_t audioBps = options.audioBitsPerSecond();
74 bool useVideo = stream->getVideoTracks().size() > 0;
75 bool useAudio = stream->getAudioTracks().size() > 0;
76
77 if (useAudio) {
78 // |options.bitsPerSecond()| overrides the specific audio and video bit rates.
79 if (options.bitsPerSecond()) {
80 if (useVideo)
81 audioBps = options.bitsPerSecond() / 10;
82 else
83 audioBps = options.bitsPerSecond();
84 }
85 // Limit audio bitrate values if set explicitly or calculated.
86 if (audioBps) {
87 if (audioBps > kLargestAutoAllocatedOpusBitRate) {
88 context->addConsoleMessage(ConsoleMessage::create(JSMessageSourc e, WarningMessageLevel, "Clamping calculated audio bitrate (" + String::number(a udioBps) + "bps) to the maximum (" + String::number(kLargestAutoAllocatedOpusBit Rate) + "bps)"));
89 audioBps = kLargestAutoAllocatedOpusBitRate;
90 }
91
92 if (audioBps < kSmallestPossibleOpusBitRate) {
93 context->addConsoleMessage(ConsoleMessage::create(JSMessageSourc e, WarningMessageLevel, "Clamping calculated audio bitrate (" + String::number(a udioBps) + "bps) to the minimum (" + String::number(kSmallestPossibleOpusBitRate ) + "bps)"));
94 audioBps = kSmallestPossibleOpusBitRate;
95 }
96 }
97 } else {
98 audioBps = 0;
99 }
100 if (useVideo) {
101 // Allocate the remaining overall |options.bitsPerSecond()|, if any, to video.
102 if (options.bitsPerSecond())
103 videoBps = options.bitsPerSecond() - audioBps;
104 // Clamp the video bit rate if the user has set explicitly the video bit rate or has used the overall bitrate.
105 if ((options.videoBitsPerSecond() > 0 || options.bitsPerSecond() > 0) && (videoBps < kSmallestPossibleVpxBitRate)) {
106 context->addConsoleMessage(ConsoleMessage::create(JSMessageSource, W arningMessageLevel, "Clamping calculated video bitrate (" + String::number(video Bps) + "bps) to the minimum (" + String::number(kSmallestPossibleVpxBitRate) + " bps)"));
107 videoBps = kSmallestPossibleVpxBitRate;
108 }
109 } else {
110 videoBps = 0;
111 }
112
113 *videoBitsPerSecond = videoBps;
114 *audioBitsPerSecond = audioBps;
115 return;
116 }
117
37 } // namespace 118 } // namespace
38 119
39 MediaRecorder* MediaRecorder::create(ExecutionContext* context, MediaStream* str eam, ExceptionState& exceptionState) 120 MediaRecorder* MediaRecorder::create(ExecutionContext* context, MediaStream* str eam, ExceptionState& exceptionState)
40 { 121 {
41 MediaRecorder* recorder = new MediaRecorder(context, stream, MediaRecorderOp tions(), exceptionState); 122 MediaRecorder* recorder = new MediaRecorder(context, stream, MediaRecorderOp tions(), exceptionState);
42 recorder->suspendIfNeeded(); 123 recorder->suspendIfNeeded();
43 124
44 return recorder; 125 return recorder;
45 } 126 }
46 127
(...skipping 13 matching lines...) Expand all
60 , m_stopped(true) 141 , m_stopped(true)
61 , m_ignoreMutedMedia(true) 142 , m_ignoreMutedMedia(true)
62 , m_state(State::Inactive) 143 , m_state(State::Inactive)
63 , m_dispatchScheduledEventRunner(AsyncMethodRunner<MediaRecorder>::create(th is, &MediaRecorder::dispatchScheduledEvent)) 144 , m_dispatchScheduledEventRunner(AsyncMethodRunner<MediaRecorder>::create(th is, &MediaRecorder::dispatchScheduledEvent))
64 { 145 {
65 ASSERT(m_stream->getTracks().size()); 146 ASSERT(m_stream->getTracks().size());
66 147
67 m_recorderHandler = adoptPtr(Platform::current()->createMediaRecorderHandler ()); 148 m_recorderHandler = adoptPtr(Platform::current()->createMediaRecorderHandler ());
68 ASSERT(m_recorderHandler); 149 ASSERT(m_recorderHandler);
69 150
70 // We deviate from the spec by not returning |UnsupportedOption|, see https: //github.com/w3c/mediacapture-record/issues/18
71 if (!m_recorderHandler) { 151 if (!m_recorderHandler) {
72 exceptionState.throwDOMException(NotSupportedError, "No MediaRecorder ha ndler can be created."); 152 exceptionState.throwDOMException(NotSupportedError, "No MediaRecorder ha ndler can be created.");
73 return; 153 return;
74 } 154 }
75 ContentType contentType(m_mimeType); 155
76 if (!m_recorderHandler->initialize(this, stream->descriptor(), contentType.t ype(), contentType.parameter("codecs"))) { 156 int32_t audioBitsPerSecond = 0;
77 exceptionState.throwDOMException(NotSupportedError, "Failed to initializ e native MediaRecorder, the type provided " + m_mimeType + "is unsupported." ); 157 int32_t videoBitsPerSecond = 0;
158 AllocateVideoAndAudioBitrates(exceptionState, context, options, stream, &aud ioBitsPerSecond, &videoBitsPerSecond);
159
160 const ContentType contentType(m_mimeType);
161 if (!m_recorderHandler->initialize(this, stream->descriptor(), contentType.t ype(), contentType.parameter("codecs"), audioBitsPerSecond, videoBitsPerSecond)) {
162 exceptionState.throwDOMException(NotSupportedError, "Failed to initializ e native MediaRecorder the type provided (" + m_mimeType + ") is not supported." );
78 return; 163 return;
79 } 164 }
80 m_stopped = false; 165 m_stopped = false;
81 } 166 }
82 167
83 String MediaRecorder::state() const 168 String MediaRecorder::state() const
84 { 169 {
85 return stateToString(m_state); 170 return stateToString(m_state);
86 } 171 }
87 172
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 DEFINE_TRACE(MediaRecorder) 353 DEFINE_TRACE(MediaRecorder)
269 { 354 {
270 visitor->trace(m_stream); 355 visitor->trace(m_stream);
271 visitor->trace(m_dispatchScheduledEventRunner); 356 visitor->trace(m_dispatchScheduledEventRunner);
272 visitor->trace(m_scheduledEvents); 357 visitor->trace(m_scheduledEvents);
273 RefCountedGarbageCollectedEventTargetWithInlineData<MediaRecorder>::trace(vi sitor); 358 RefCountedGarbageCollectedEventTargetWithInlineData<MediaRecorder>::trace(vi sitor);
274 ActiveDOMObject::trace(visitor); 359 ActiveDOMObject::trace(visitor);
275 } 360 }
276 361
277 } // namespace blink 362 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698