OLD | NEW |
---|---|
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 "content/renderer/media_recorder/media_recorder_handler.h" | 5 #include "content/renderer/media_recorder/media_recorder_handler.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/macros.h" | 12 #include "base/macros.h" |
13 #include "base/strings/string_tokenizer.h" | 13 #include "base/strings/string_tokenizer.h" |
14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
15 #include "base/sys_info.h" | |
15 #include "content/child/scoped_web_callbacks.h" | 16 #include "content/child/scoped_web_callbacks.h" |
16 #include "content/renderer/media/media_stream_audio_track.h" | 17 #include "content/renderer/media/media_stream_audio_track.h" |
17 #include "content/renderer/media/media_stream_track.h" | 18 #include "content/renderer/media/media_stream_track.h" |
18 #include "content/renderer/media/webrtc_uma_histograms.h" | 19 #include "content/renderer/media/webrtc_uma_histograms.h" |
19 #include "content/renderer/media_recorder/audio_track_recorder.h" | 20 #include "content/renderer/media_recorder/audio_track_recorder.h" |
20 #include "media/base/audio_bus.h" | 21 #include "media/base/audio_bus.h" |
21 #include "media/base/audio_parameters.h" | 22 #include "media/base/audio_parameters.h" |
22 #include "media/base/bind_to_current_loop.h" | 23 #include "media/base/bind_to_current_loop.h" |
23 #include "media/base/mime_util.h" | 24 #include "media/base/mime_util.h" |
24 #include "media/base/video_frame.h" | 25 #include "media/base/video_frame.h" |
(...skipping 23 matching lines...) Expand all Loading... | |
48 case VideoTrackRecorder::CodecId::H264: | 49 case VideoTrackRecorder::CodecId::H264: |
49 return media::kCodecH264; | 50 return media::kCodecH264; |
50 #endif | 51 #endif |
51 case VideoTrackRecorder::CodecId::LAST: | 52 case VideoTrackRecorder::CodecId::LAST: |
52 return media::kUnknownVideoCodec; | 53 return media::kUnknownVideoCodec; |
53 } | 54 } |
54 NOTREACHED() << "Unsupported codec"; | 55 NOTREACHED() << "Unsupported codec"; |
55 return media::kUnknownVideoCodec; | 56 return media::kUnknownVideoCodec; |
56 } | 57 } |
57 | 58 |
59 // Extracts the first recognised CodecId of |codecs| or CodecId::LAST if none | |
60 // of them is known. | |
61 VideoTrackRecorder::CodecId StringToCodecId(const blink::WebString& codecs) { | |
62 const std::string& codecs_str = ToLowerASCII(codecs.Utf8()); | |
63 | |
64 if (codecs_str.find("vp8") != std::string::npos) | |
65 return VideoTrackRecorder::CodecId::VP8; | |
66 else if (codecs_str.find("vp9") != std::string::npos) | |
67 return VideoTrackRecorder::CodecId::VP9; | |
68 #if BUILDFLAG(RTC_USE_H264) | |
69 else if (codecs_str.find("h264") != std::string::npos || | |
70 codecs_str.find("avc1") != std::string::npos) | |
71 return VideoTrackRecorder::CodecId::H264; | |
72 #endif | |
73 return VideoTrackRecorder::CodecId::LAST; | |
74 } | |
75 | |
58 void OnEncodingInfoError( | 76 void OnEncodingInfoError( |
59 std::unique_ptr<WebMediaCapabilitiesQueryCallbacks> callbacks) { | 77 std::unique_ptr<WebMediaCapabilitiesQueryCallbacks> callbacks) { |
60 callbacks->OnError(); | 78 callbacks->OnError(); |
61 } | 79 } |
62 | 80 |
63 } // anonymous namespace | 81 } // anonymous namespace |
64 | 82 |
65 MediaRecorderHandler::MediaRecorderHandler() | 83 MediaRecorderHandler::MediaRecorderHandler() |
66 : video_bits_per_second_(0), | 84 : video_bits_per_second_(0), |
67 audio_bits_per_second_(0), | 85 audio_bits_per_second_(0), |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
130 // Save histogram data so we can see how much MediaStream Recorder is used. | 148 // Save histogram data so we can see how much MediaStream Recorder is used. |
131 // The histogram counts the number of calls to the JS API. | 149 // The histogram counts the number of calls to the JS API. |
132 UpdateWebRTCMethodCount(WEBKIT_MEDIA_STREAM_RECORDER); | 150 UpdateWebRTCMethodCount(WEBKIT_MEDIA_STREAM_RECORDER); |
133 | 151 |
134 if (!CanSupportMimeType(type, codecs)) { | 152 if (!CanSupportMimeType(type, codecs)) { |
135 DLOG(ERROR) << "Unsupported " << type.Utf8() << ";codecs=" << codecs.Utf8(); | 153 DLOG(ERROR) << "Unsupported " << type.Utf8() << ";codecs=" << codecs.Utf8(); |
136 return false; | 154 return false; |
137 } | 155 } |
138 | 156 |
139 // Once established that we support the codec(s), hunt then individually. | 157 // Once established that we support the codec(s), hunt then individually. |
140 const std::string& codecs_str = ToLowerASCII(codecs.Utf8()); | 158 const VideoTrackRecorder::CodecId codec_id = StringToCodecId(codecs); |
141 if (codecs_str.find("vp8") != std::string::npos) | 159 codec_id_ = (codec_id != VideoTrackRecorder::CodecId::LAST) |
142 codec_id_ = VideoTrackRecorder::CodecId::VP8; | 160 ? codec_id |
143 else if (codecs_str.find("vp9") != std::string::npos) | 161 : VideoTrackRecorder::GetPreferredCodecId(); |
144 codec_id_ = VideoTrackRecorder::CodecId::VP9; | |
145 #if BUILDFLAG(RTC_USE_H264) | |
146 else if (codecs_str.find("h264") != std::string::npos) | |
147 codec_id_ = VideoTrackRecorder::CodecId::H264; | |
148 else if (codecs_str.find("avc1") != std::string::npos) | |
149 codec_id_ = VideoTrackRecorder::CodecId::H264; | |
150 #endif | |
151 else | |
152 codec_id_ = VideoTrackRecorder::GetPreferredCodecId(); | |
153 | 162 |
154 DVLOG_IF(1, codecs_str.empty()) << "Falling back to preferred codec id " | 163 DVLOG_IF(1, codec_id == VideoTrackRecorder::CodecId::LAST) |
155 << static_cast<int>(codec_id_); | 164 << "Falling back to preferred codec id " << static_cast<int>(codec_id_); |
156 | 165 |
157 media_stream_ = media_stream; | 166 media_stream_ = media_stream; |
158 DCHECK(client); | 167 DCHECK(client); |
159 client_ = client; | 168 client_ = client; |
160 | 169 |
161 audio_bits_per_second_ = audio_bits_per_second; | 170 audio_bits_per_second_ = audio_bits_per_second; |
162 video_bits_per_second_ = video_bits_per_second; | 171 video_bits_per_second_ = video_bits_per_second; |
163 return true; | 172 return true; |
164 } | 173 } |
165 | 174 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
295 blink::WebString mime_type; | 304 blink::WebString mime_type; |
296 blink::WebString codec; | 305 blink::WebString codec; |
297 if (configuration.video_configuration) { | 306 if (configuration.video_configuration) { |
298 mime_type = configuration.video_configuration->mime_type; | 307 mime_type = configuration.video_configuration->mime_type; |
299 codec = configuration.video_configuration->codec; | 308 codec = configuration.video_configuration->codec; |
300 } else { | 309 } else { |
301 mime_type = configuration.audio_configuration->mime_type; | 310 mime_type = configuration.audio_configuration->mime_type; |
302 codec = configuration.audio_configuration->codec; | 311 codec = configuration.audio_configuration->codec; |
303 } | 312 } |
304 | 313 |
305 // See RFC 2231. https://tools.ietf.org/html/rfc2231 | |
306 info->supported = CanSupportMimeType(mime_type, codec); | 314 info->supported = CanSupportMimeType(mime_type, codec); |
307 DVLOG(1) << "type: " << mime_type.Ascii() << ", codec:" << codec.Ascii() | 315 |
308 << " is" << (info->supported ? " supported" : " NOT supported"); | 316 if (configuration.video_configuration && info->supported) { |
317 const bool is_likely_accelerated = | |
318 VideoTrackRecorder::CanUseAcceleratedEncoder( | |
319 StringToCodecId(codec), configuration.video_configuration->width, | |
320 configuration.video_configuration->height); | |
321 | |
322 // Encoding smoothness depends on a number of parameters, namely: frame | |
323 // rate, resolution, hardware support availability, platform and | |
324 // IsLowEndDevice(); to simplify calculations we compare the amount of | |
325 // pixels per second (i.e. |resolution| times |framerate|). Software based | |
326 // encoding on Desktop can run fine up and until HD resolution at 30fps, | |
327 // whereas if IsLowEndDevice() we set the cut at VGA (note that either pixel | |
328 // volumes would make use of hardware acceleration if available). | |
329 const float kNumPixelsPerSecondSmoothnessThreshold = | |
330 base::SysInfo::IsLowEndDevice() ? 640 * 480 * 30.0 : 1280 * 720 * 30.0; | |
emircan
2017/05/01 17:12:29
Can we define this as constant at the top of this
mcasas
2017/05/01 20:18:44
Done.
| |
331 const float pixels_per_second = | |
332 configuration.video_configuration->width * | |
333 configuration.video_configuration->height * | |
334 configuration.video_configuration->framerate; | |
335 info->smooth = is_likely_accelerated || | |
336 pixels_per_second <= kNumPixelsPerSecondSmoothnessThreshold; | |
337 | |
338 // TODO(mcasas): revisit what |power_efficient| means | |
339 // https://crbug.com/709181. | |
340 info->power_efficient = info->smooth; | |
341 } | |
342 DVLOG(1) << "type: " << mime_type.Ascii() << ", params:" << codec.Ascii() | |
343 << " is" << (info->supported ? " supported" : " NOT supported") | |
344 << " and" << (info->smooth ? " smooth" : " NOT smooth"); | |
309 | 345 |
310 scoped_callbacks.PassCallbacks()->OnSuccess(std::move(info)); | 346 scoped_callbacks.PassCallbacks()->OnSuccess(std::move(info)); |
311 } | 347 } |
312 | 348 |
313 void MediaRecorderHandler::OnEncodedVideo( | 349 void MediaRecorderHandler::OnEncodedVideo( |
314 const media::WebmMuxer::VideoParameters& params, | 350 const media::WebmMuxer::VideoParameters& params, |
315 std::unique_ptr<std::string> encoded_data, | 351 std::unique_ptr<std::string> encoded_data, |
316 std::unique_ptr<std::string> encoded_alpha, | 352 std::unique_ptr<std::string> encoded_alpha, |
317 TimeTicks timestamp, | 353 TimeTicks timestamp, |
318 bool is_key_frame) { | 354 bool is_key_frame) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
418 recorder->OnData(audio_bus, timestamp); | 454 recorder->OnData(audio_bus, timestamp); |
419 } | 455 } |
420 | 456 |
421 void MediaRecorderHandler::SetAudioFormatForTesting( | 457 void MediaRecorderHandler::SetAudioFormatForTesting( |
422 const media::AudioParameters& params) { | 458 const media::AudioParameters& params) { |
423 for (const auto& recorder : audio_recorders_) | 459 for (const auto& recorder : audio_recorders_) |
424 recorder->OnSetFormat(params); | 460 recorder->OnSetFormat(params); |
425 } | 461 } |
426 | 462 |
427 } // namespace content | 463 } // namespace content |
OLD | NEW |