Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/media_stream_video_capturer_source.h" | 5 #include "content/renderer/media/media_stream_video_capturer_source.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/callback_helpers.h" | 11 #include "base/callback_helpers.h" |
| 12 #include "base/debug/stack_trace.h" | 12 #include "base/debug/stack_trace.h" |
| 13 #include "base/location.h" | 13 #include "base/location.h" |
| 14 #include "base/macros.h" | 14 #include "base/macros.h" |
| 15 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
| 16 #include "content/common/media/media_stream_messages.h" | 16 #include "content/common/media/media_stream_messages.h" |
| 17 #include "content/public/common/media_stream_request.h" | 17 #include "content/public/common/media_stream_request.h" |
| 18 #include "content/renderer/media/media_stream_constraints_util.h" | 18 #include "content/renderer/media/media_stream_constraints_util.h" |
| 19 #include "content/renderer/media/video_capture_impl_manager.h" | 19 #include "content/renderer/media/video_capture_impl_manager.h" |
| 20 #include "content/renderer/render_thread_impl.h" | 20 #include "content/renderer/render_thread_impl.h" |
| 21 #include "media/base/bind_to_current_loop.h" | 21 #include "media/base/bind_to_current_loop.h" |
| 22 #include "media/base/limits.h" | 22 #include "media/base/limits.h" |
| 23 #include "media/base/video_frame.h" | 23 #include "media/base/video_frame.h" |
| 24 #include "media/capture/video_capturer_source.h" | 24 #include "media/capture/video_capturer_source.h" |
| 25 | 25 |
| 26 namespace content { | 26 namespace content { |
| 27 | 27 |
| 28 namespace { | 28 namespace { |
| 29 | 29 |
| 30 // Resolutions used if the source doesn't support capability enumeration. | |
| 31 struct { | |
| 32 int width; | |
| 33 int height; | |
| 34 } const kVideoResolutions[] = {{1920, 1080}, | |
| 35 {1280, 720}, | |
| 36 {960, 720}, | |
| 37 {640, 480}, | |
| 38 {640, 360}, | |
| 39 {320, 240}, | |
| 40 {320, 180}}; | |
| 41 | |
| 42 // Frame rates for sources with no support for capability enumeration. | |
| 43 const int kVideoFrameRates[] = {30, 60}; | |
| 44 | |
| 45 // Hard upper-bound frame rate for tab/desktop capture. | |
| 46 const double kMaxScreenCastFrameRate = 120.0; | |
| 47 | |
| 48 // Allows the user to Override default power line frequency. | 30 // Allows the user to Override default power line frequency. |
| 49 const char kPowerLineFrequency[] = "googPowerLineFrequency"; | 31 const char kPowerLineFrequency[] = "googPowerLineFrequency"; |
|
hbos_chromium
2017/06/30 15:04:12
Power line: remove this?
Guido Urdaneta
2017/07/03 18:43:16
Done.
| |
| 50 | 32 |
| 51 // Returns true if the value for width or height is reasonable. | |
| 52 bool DimensionValueIsValid(int x) { | |
| 53 return x > 0 && x <= media::limits::kMaxDimension; | |
| 54 } | |
| 55 | |
| 56 // Returns true if the value for frame rate is reasonable. | |
| 57 bool FrameRateValueIsValid(double frame_rate) { | |
| 58 return (frame_rate > (1.0 / 60.0)) && // Lower-bound: One frame per minute. | |
| 59 (frame_rate <= media::limits::kMaxFramesPerSecond); | |
| 60 } | |
| 61 | |
| 62 // Returns true if the aspect ratio of |a| and |b| are equivalent to two | |
| 63 // significant digits. | |
| 64 bool AreNearlyEquivalentInAspectRatio(const gfx::Size& a, const gfx::Size& b) { | |
| 65 DCHECK(!a.IsEmpty()); | |
| 66 DCHECK(!b.IsEmpty()); | |
| 67 const int aspect_ratio_a = (100 * a.width()) / a.height(); | |
| 68 const int aspect_ratio_b = (100 * b.width()) / b.height(); | |
| 69 return aspect_ratio_a == aspect_ratio_b; | |
| 70 } | |
| 71 | |
| 72 // Checks if |device_info|s type is a generated content, e.g. Tab or Desktop. | |
| 73 bool IsContentVideoCaptureDevice(const StreamDeviceInfo& device_info) { | |
| 74 return device_info.device.type == MEDIA_TAB_VIDEO_CAPTURE || | |
| 75 device_info.device.type == MEDIA_DESKTOP_VIDEO_CAPTURE; | |
| 76 } | |
| 77 | |
| 78 // Interprets the properties in |constraints| to override values in |params| and | |
| 79 // determine the resolution change policy. | |
| 80 void SetContentCaptureParamsFromConstraints( | |
| 81 const blink::WebMediaConstraints& constraints, | |
| 82 MediaStreamType type, | |
| 83 media::VideoCaptureParams* params) { | |
| 84 // The default resolution change policies for tab versus desktop capture are | |
| 85 // the way they are for legacy reasons. | |
| 86 if (type == MEDIA_TAB_VIDEO_CAPTURE) { | |
| 87 params->resolution_change_policy = | |
| 88 media::RESOLUTION_POLICY_FIXED_RESOLUTION; | |
| 89 } else if (type == MEDIA_DESKTOP_VIDEO_CAPTURE) { | |
| 90 params->resolution_change_policy = | |
| 91 media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT; | |
| 92 } else { | |
| 93 NOTREACHED(); | |
| 94 } | |
| 95 | |
| 96 // If the maximum frame resolution was provided in the constraints, use it if | |
| 97 // either: 1) none has been set yet; or 2) the maximum specificed is smaller | |
| 98 // than the current setting. | |
| 99 int width = 0; | |
| 100 int height = 0; | |
| 101 gfx::Size desired_max_frame_size; | |
| 102 if (GetConstraintMaxAsInteger( | |
| 103 constraints, &blink::WebMediaTrackConstraintSet::width, &width) && | |
| 104 GetConstraintMaxAsInteger( | |
| 105 constraints, &blink::WebMediaTrackConstraintSet::height, &height) && | |
| 106 DimensionValueIsValid(width) && DimensionValueIsValid(height)) { | |
| 107 desired_max_frame_size.SetSize(width, height); | |
| 108 if (params->requested_format.frame_size.IsEmpty() || | |
| 109 desired_max_frame_size.width() < | |
| 110 params->requested_format.frame_size.width() || | |
| 111 desired_max_frame_size.height() < | |
| 112 params->requested_format.frame_size.height()) { | |
| 113 params->requested_format.frame_size = desired_max_frame_size; | |
| 114 } | |
| 115 } | |
| 116 | |
| 117 // Set the default frame resolution if none was provided. | |
| 118 if (params->requested_format.frame_size.IsEmpty()) { | |
| 119 params->requested_format.frame_size.SetSize( | |
| 120 MediaStreamVideoSource::kDefaultWidth, | |
| 121 MediaStreamVideoSource::kDefaultHeight); | |
| 122 } | |
| 123 | |
| 124 // If the maximum frame rate was provided, use it if either: 1) none has been | |
| 125 // set yet; or 2) the maximum specificed is smaller than the current setting. | |
| 126 double frame_rate = 0.0; | |
| 127 if (GetConstraintMaxAsDouble(constraints, | |
| 128 &blink::WebMediaTrackConstraintSet::frame_rate, | |
| 129 &frame_rate) && | |
| 130 FrameRateValueIsValid(frame_rate)) { | |
| 131 if (params->requested_format.frame_rate <= 0.0f || | |
| 132 frame_rate < params->requested_format.frame_rate) { | |
| 133 params->requested_format.frame_rate = frame_rate; | |
| 134 } | |
| 135 } | |
| 136 | |
| 137 // Set the default frame rate if none was provided. | |
| 138 if (params->requested_format.frame_rate <= 0.0f) { | |
| 139 params->requested_format.frame_rate = | |
| 140 MediaStreamVideoSource::kDefaultFrameRate; | |
| 141 } | |
| 142 | |
| 143 // If the minimum frame resolution was provided, compare it to the maximum | |
| 144 // frame resolution to determine the intended resolution change policy. | |
| 145 if (!desired_max_frame_size.IsEmpty() && | |
| 146 GetConstraintMinAsInteger( | |
| 147 constraints, &blink::WebMediaTrackConstraintSet::width, &width) && | |
| 148 GetConstraintMinAsInteger( | |
| 149 constraints, &blink::WebMediaTrackConstraintSet::height, &height) && | |
| 150 width <= desired_max_frame_size.width() && | |
| 151 height <= desired_max_frame_size.height()) { | |
| 152 if (width == desired_max_frame_size.width() && | |
| 153 height == desired_max_frame_size.height()) { | |
| 154 // Constraints explicitly require a single frame resolution. | |
| 155 params->resolution_change_policy = | |
| 156 media::RESOLUTION_POLICY_FIXED_RESOLUTION; | |
| 157 } else if (DimensionValueIsValid(width) && | |
| 158 DimensionValueIsValid(height) && | |
| 159 AreNearlyEquivalentInAspectRatio(gfx::Size(width, height), | |
| 160 desired_max_frame_size)) { | |
| 161 // Constraints only mention a single aspect ratio. | |
| 162 params->resolution_change_policy = | |
| 163 media::RESOLUTION_POLICY_FIXED_ASPECT_RATIO; | |
| 164 } else { | |
| 165 // Constraints specify a minimum resolution that is smaller than the | |
| 166 // maximum resolution and has a different aspect ratio (possibly even | |
| 167 // 0x0). This indicates any frame resolution and aspect ratio is | |
| 168 // acceptable. | |
| 169 params->resolution_change_policy = | |
| 170 media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT; | |
| 171 } | |
| 172 } | |
| 173 | |
| 174 DVLOG(1) << __func__ << " " | |
| 175 << media::VideoCaptureFormat::ToString(params->requested_format) | |
| 176 << " with resolution change policy " | |
| 177 << params->resolution_change_policy; | |
| 178 } | |
| 179 | |
| 180 // Interprets the properties in |constraints| to override values in |params| and | |
| 181 // determine the power line frequency. | |
| 182 void SetPowerLineFrequencyParamFromConstraints( | |
| 183 const blink::WebMediaConstraints& constraints, | |
| 184 media::VideoCaptureParams* params) { | |
| 185 int freq; | |
| 186 params->power_line_frequency = media::PowerLineFrequency::FREQUENCY_DEFAULT; | |
| 187 if (!GetConstraintValueAsInteger( | |
| 188 constraints, | |
| 189 &blink::WebMediaTrackConstraintSet::goog_power_line_frequency, | |
| 190 &freq)) { | |
| 191 return; | |
| 192 } | |
| 193 if (freq == static_cast<int>(media::PowerLineFrequency::FREQUENCY_50HZ)) | |
| 194 params->power_line_frequency = media::PowerLineFrequency::FREQUENCY_50HZ; | |
| 195 else if (freq == static_cast<int>(media::PowerLineFrequency::FREQUENCY_60HZ)) | |
| 196 params->power_line_frequency = media::PowerLineFrequency::FREQUENCY_60HZ; | |
| 197 } | |
| 198 | |
| 199 // LegacyLocalVideoCapturerSource is a delegate used by | |
| 200 // MediaStreamVideoCapturerSource for local video capture. It uses the Render | |
| 201 // singleton VideoCaptureImplManager to start / stop and receive I420 frames | |
| 202 // from Chrome's video capture implementation. This is a main Render thread only | |
| 203 // object. | |
| 204 // TODO(guidou): Remove this class. http://crbug.com/706408 | |
| 205 class LegacyLocalVideoCapturerSource final : public media::VideoCapturerSource { | |
| 206 public: | |
| 207 explicit LegacyLocalVideoCapturerSource(const StreamDeviceInfo& device_info); | |
| 208 ~LegacyLocalVideoCapturerSource() override; | |
| 209 | |
| 210 // VideoCaptureDelegate Implementation. | |
| 211 void GetCurrentSupportedFormats( | |
| 212 int max_requested_width, | |
| 213 int max_requested_height, | |
| 214 double max_requested_frame_rate, | |
| 215 const VideoCaptureDeviceFormatsCB& callback) override; | |
| 216 media::VideoCaptureFormats GetPreferredFormats() override; | |
| 217 void StartCapture(const media::VideoCaptureParams& params, | |
| 218 const VideoCaptureDeliverFrameCB& new_frame_callback, | |
| 219 const RunningCallback& running_callback) override; | |
| 220 void RequestRefreshFrame() override; | |
| 221 void MaybeSuspend() override; | |
| 222 void Resume() override; | |
| 223 void StopCapture() override; | |
| 224 | |
| 225 private: | |
| 226 void OnStateUpdate(VideoCaptureState state); | |
| 227 void OnDeviceFormatsInUseReceived(const media::VideoCaptureFormats& formats); | |
| 228 void OnDeviceSupportedFormatsEnumerated( | |
| 229 const media::VideoCaptureFormats& formats); | |
| 230 | |
| 231 // |session_id_| identifies the capture device used for this capture session. | |
| 232 const media::VideoCaptureSessionId session_id_; | |
| 233 | |
| 234 VideoCaptureImplManager* const manager_; | |
| 235 | |
| 236 const base::Closure release_device_cb_; | |
| 237 | |
| 238 // Indicates if we are capturing generated content, e.g. Tab or Desktop. | |
| 239 const bool is_content_capture_; | |
| 240 | |
| 241 // These two are valid between StartCapture() and StopCapture(). | |
| 242 // |running_call_back_| is run when capture is successfully started, and when | |
| 243 // it is stopped or error happens. | |
| 244 RunningCallback running_callback_; | |
| 245 base::Closure stop_capture_cb_; | |
| 246 | |
| 247 // Placeholder keeping the callback between asynchronous device enumeration | |
| 248 // calls. | |
| 249 VideoCaptureDeviceFormatsCB formats_enumerated_callback_; | |
| 250 | |
| 251 // Bound to the main render thread. | |
| 252 base::ThreadChecker thread_checker_; | |
| 253 | |
| 254 base::WeakPtrFactory<LegacyLocalVideoCapturerSource> weak_factory_; | |
| 255 | |
| 256 DISALLOW_COPY_AND_ASSIGN(LegacyLocalVideoCapturerSource); | |
| 257 }; | |
| 258 | |
| 259 LegacyLocalVideoCapturerSource::LegacyLocalVideoCapturerSource( | |
| 260 const StreamDeviceInfo& device_info) | |
| 261 : session_id_(device_info.session_id), | |
| 262 manager_(RenderThreadImpl::current()->video_capture_impl_manager()), | |
| 263 release_device_cb_(manager_->UseDevice(session_id_)), | |
| 264 is_content_capture_(IsContentVideoCaptureDevice(device_info)), | |
| 265 weak_factory_(this) { | |
| 266 DCHECK(RenderThreadImpl::current()); | |
| 267 } | |
| 268 | |
| 269 LegacyLocalVideoCapturerSource::~LegacyLocalVideoCapturerSource() { | |
| 270 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 271 release_device_cb_.Run(); | |
| 272 } | |
| 273 | |
| 274 void LegacyLocalVideoCapturerSource::GetCurrentSupportedFormats( | |
| 275 int max_requested_width, | |
| 276 int max_requested_height, | |
| 277 double max_requested_frame_rate, | |
| 278 const VideoCaptureDeviceFormatsCB& callback) { | |
| 279 DVLOG(3) << "GetCurrentSupportedFormats({ max_requested_height = " | |
| 280 << max_requested_height << "}) { max_requested_width = " | |
| 281 << max_requested_width << "}) { max_requested_frame_rate = " | |
| 282 << max_requested_frame_rate << "})"; | |
| 283 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 284 | |
| 285 if (is_content_capture_) { | |
| 286 const int width = max_requested_width ? | |
| 287 max_requested_width : MediaStreamVideoSource::kDefaultWidth; | |
| 288 const int height = max_requested_height ? | |
| 289 max_requested_height : MediaStreamVideoSource::kDefaultHeight; | |
| 290 callback.Run(media::VideoCaptureFormats( | |
| 291 1, media::VideoCaptureFormat( | |
| 292 gfx::Size(width, height), | |
| 293 static_cast<float>( | |
| 294 std::min(kMaxScreenCastFrameRate, max_requested_frame_rate)), | |
| 295 media::PIXEL_FORMAT_I420))); | |
| 296 return; | |
| 297 } | |
| 298 | |
| 299 DCHECK(formats_enumerated_callback_.is_null()); | |
| 300 formats_enumerated_callback_ = callback; | |
| 301 manager_->GetDeviceFormatsInUse( | |
| 302 session_id_, | |
| 303 media::BindToCurrentLoop(base::Bind( | |
| 304 &LegacyLocalVideoCapturerSource::OnDeviceFormatsInUseReceived, | |
| 305 weak_factory_.GetWeakPtr()))); | |
| 306 } | |
| 307 | |
| 308 media::VideoCaptureFormats | |
| 309 LegacyLocalVideoCapturerSource::GetPreferredFormats() { | |
| 310 return media::VideoCaptureFormats(); | |
| 311 } | |
| 312 | |
| 313 void LegacyLocalVideoCapturerSource::StartCapture( | |
| 314 const media::VideoCaptureParams& params, | |
| 315 const VideoCaptureDeliverFrameCB& new_frame_callback, | |
| 316 const RunningCallback& running_callback) { | |
| 317 DCHECK(params.requested_format.IsValid()); | |
| 318 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 319 running_callback_ = running_callback; | |
| 320 | |
| 321 stop_capture_cb_ = | |
| 322 manager_->StartCapture(session_id_, params, | |
| 323 media::BindToCurrentLoop(base::Bind( | |
| 324 &LegacyLocalVideoCapturerSource::OnStateUpdate, | |
| 325 weak_factory_.GetWeakPtr())), | |
| 326 new_frame_callback); | |
| 327 } | |
| 328 | |
| 329 void LegacyLocalVideoCapturerSource::RequestRefreshFrame() { | |
| 330 DVLOG(3) << __func__; | |
| 331 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 332 if (stop_capture_cb_.is_null()) | |
| 333 return; // Do not request frames if the source is stopped. | |
| 334 manager_->RequestRefreshFrame(session_id_); | |
| 335 } | |
| 336 | |
| 337 void LegacyLocalVideoCapturerSource::MaybeSuspend() { | |
| 338 DVLOG(3) << __func__; | |
| 339 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 340 manager_->Suspend(session_id_); | |
| 341 } | |
| 342 | |
| 343 void LegacyLocalVideoCapturerSource::Resume() { | |
| 344 DVLOG(3) << __func__; | |
| 345 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 346 manager_->Resume(session_id_); | |
| 347 } | |
| 348 | |
| 349 void LegacyLocalVideoCapturerSource::StopCapture() { | |
| 350 DVLOG(3) << __func__; | |
| 351 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 352 // Immediately make sure we don't provide more frames. | |
| 353 if (!stop_capture_cb_.is_null()) | |
| 354 base::ResetAndReturn(&stop_capture_cb_).Run(); | |
| 355 running_callback_.Reset(); | |
| 356 // Invalidate any potential format enumerations going on. | |
| 357 formats_enumerated_callback_.Reset(); | |
| 358 } | |
| 359 | |
| 360 void LegacyLocalVideoCapturerSource::OnStateUpdate(VideoCaptureState state) { | |
| 361 DVLOG(3) << __func__ << " state = " << state; | |
| 362 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 363 if (running_callback_.is_null()) | |
| 364 return; | |
| 365 switch (state) { | |
| 366 case VIDEO_CAPTURE_STATE_STARTED: | |
| 367 running_callback_.Run(true); | |
| 368 break; | |
| 369 | |
| 370 case VIDEO_CAPTURE_STATE_STOPPING: | |
| 371 case VIDEO_CAPTURE_STATE_STOPPED: | |
| 372 case VIDEO_CAPTURE_STATE_ERROR: | |
| 373 case VIDEO_CAPTURE_STATE_ENDED: | |
| 374 base::ResetAndReturn(&running_callback_).Run(false); | |
| 375 break; | |
| 376 | |
| 377 case VIDEO_CAPTURE_STATE_STARTING: | |
| 378 case VIDEO_CAPTURE_STATE_PAUSED: | |
| 379 case VIDEO_CAPTURE_STATE_RESUMED: | |
| 380 // Not applicable to reporting on device starts or errors. | |
| 381 break; | |
| 382 } | |
| 383 } | |
| 384 | |
| 385 void LegacyLocalVideoCapturerSource::OnDeviceFormatsInUseReceived( | |
| 386 const media::VideoCaptureFormats& formats_in_use) { | |
| 387 DVLOG(3) << __func__ << ", #formats received: " << formats_in_use.size(); | |
| 388 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 389 // StopCapture() might have destroyed |formats_enumerated_callback_| before | |
| 390 // arriving here. | |
| 391 if (formats_enumerated_callback_.is_null()) | |
| 392 return; | |
| 393 if (formats_in_use.size()) { | |
| 394 base::ResetAndReturn(&formats_enumerated_callback_).Run(formats_in_use); | |
| 395 return; | |
| 396 } | |
| 397 | |
| 398 // The device doesn't seem to have formats in use so try and retrieve the | |
| 399 // whole list of supported ones. | |
| 400 manager_->GetDeviceSupportedFormats( | |
| 401 session_id_, | |
| 402 media::BindToCurrentLoop(base::Bind( | |
| 403 &LegacyLocalVideoCapturerSource::OnDeviceSupportedFormatsEnumerated, | |
| 404 weak_factory_.GetWeakPtr()))); | |
| 405 } | |
| 406 | |
| 407 void LegacyLocalVideoCapturerSource::OnDeviceSupportedFormatsEnumerated( | |
| 408 const media::VideoCaptureFormats& formats) { | |
| 409 DVLOG(3) << __func__ << ", #formats received: " << formats.size(); | |
| 410 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 411 // StopCapture() might have destroyed |formats_enumerated_callback_| before | |
| 412 // arriving here. | |
| 413 if (formats_enumerated_callback_.is_null()) | |
| 414 return; | |
| 415 if (formats.size()) { | |
| 416 base::ResetAndReturn(&formats_enumerated_callback_).Run(formats); | |
| 417 return; | |
| 418 } | |
| 419 | |
| 420 // The capture device doesn't seem to support capability enumeration, compose | |
| 421 // a fallback list of capabilities. | |
| 422 media::VideoCaptureFormats default_formats; | |
| 423 for (const auto& resolution : kVideoResolutions) { | |
| 424 for (const auto frame_rate : kVideoFrameRates) { | |
| 425 default_formats.push_back(media::VideoCaptureFormat( | |
| 426 gfx::Size(resolution.width, resolution.height), frame_rate, | |
| 427 media::PIXEL_FORMAT_I420)); | |
| 428 } | |
| 429 } | |
| 430 base::ResetAndReturn(&formats_enumerated_callback_).Run(default_formats); | |
| 431 } | |
| 432 | |
| 433 // LocalVideoCapturerSource is a delegate used by MediaStreamVideoCapturerSource | 33 // LocalVideoCapturerSource is a delegate used by MediaStreamVideoCapturerSource |
| 434 // for local video capture. It uses the Render singleton VideoCaptureImplManager | 34 // for local video capture. It uses the Render singleton VideoCaptureImplManager |
| 435 // to start / stop and receive I420 frames from Chrome's video capture | 35 // to start / stop and receive I420 frames from Chrome's video capture |
| 436 // implementation. This is a main Render thread only object. | 36 // implementation. This is a main Render thread only object. |
| 437 class LocalVideoCapturerSource final : public media::VideoCapturerSource { | 37 class LocalVideoCapturerSource final : public media::VideoCapturerSource { |
| 438 public: | 38 public: |
| 439 explicit LocalVideoCapturerSource(const StreamDeviceInfo& device_info); | 39 explicit LocalVideoCapturerSource(const StreamDeviceInfo& device_info); |
| 440 ~LocalVideoCapturerSource() override; | 40 ~LocalVideoCapturerSource() override; |
| 441 | 41 |
| 442 // VideoCaptureDelegate Implementation. | 42 // VideoCaptureDelegate Implementation. |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 556 break; | 156 break; |
| 557 } | 157 } |
| 558 } | 158 } |
| 559 | 159 |
| 560 } // namespace | 160 } // namespace |
| 561 | 161 |
| 562 MediaStreamVideoCapturerSource::MediaStreamVideoCapturerSource( | 162 MediaStreamVideoCapturerSource::MediaStreamVideoCapturerSource( |
| 563 const SourceStoppedCallback& stop_callback, | 163 const SourceStoppedCallback& stop_callback, |
| 564 std::unique_ptr<media::VideoCapturerSource> source) | 164 std::unique_ptr<media::VideoCapturerSource> source) |
| 565 : RenderFrameObserver(nullptr), source_(std::move(source)) { | 165 : RenderFrameObserver(nullptr), source_(std::move(source)) { |
| 566 if (!IsOldVideoConstraints()) { | 166 media::VideoCaptureFormats preferred_formats = source_->GetPreferredFormats(); |
| 567 media::VideoCaptureFormats preferred_formats = | 167 if (!preferred_formats.empty()) |
| 568 source_->GetPreferredFormats(); | 168 capture_params_.requested_format = preferred_formats.front(); |
| 569 if (!preferred_formats.empty()) | |
| 570 capture_params_.requested_format = preferred_formats.front(); | |
| 571 } | |
| 572 SetStopCallback(stop_callback); | 169 SetStopCallback(stop_callback); |
| 573 } | 170 } |
| 574 | 171 |
| 575 MediaStreamVideoCapturerSource::MediaStreamVideoCapturerSource( | 172 MediaStreamVideoCapturerSource::MediaStreamVideoCapturerSource( |
| 576 const SourceStoppedCallback& stop_callback, | 173 const SourceStoppedCallback& stop_callback, |
| 577 const StreamDeviceInfo& device_info, | 174 const StreamDeviceInfo& device_info, |
| 578 RenderFrame* render_frame) | |
| 579 : RenderFrameObserver(render_frame), | |
| 580 source_(new LegacyLocalVideoCapturerSource(device_info)) { | |
| 581 DCHECK(IsOldVideoConstraints()); | |
| 582 SetStopCallback(stop_callback); | |
| 583 SetDeviceInfo(device_info); | |
| 584 } | |
| 585 | |
| 586 MediaStreamVideoCapturerSource::MediaStreamVideoCapturerSource( | |
| 587 const SourceStoppedCallback& stop_callback, | |
| 588 const StreamDeviceInfo& device_info, | |
| 589 const media::VideoCaptureParams& capture_params, | 175 const media::VideoCaptureParams& capture_params, |
| 590 RenderFrame* render_frame) | 176 RenderFrame* render_frame) |
| 591 : RenderFrameObserver(render_frame), | 177 : RenderFrameObserver(render_frame), |
| 592 source_(new LocalVideoCapturerSource(device_info)), | 178 source_(new LocalVideoCapturerSource(device_info)), |
| 593 capture_params_(capture_params) { | 179 capture_params_(capture_params) { |
| 594 DCHECK(!IsOldVideoConstraints()); | |
| 595 SetStopCallback(stop_callback); | 180 SetStopCallback(stop_callback); |
| 596 SetDeviceInfo(device_info); | 181 SetDeviceInfo(device_info); |
| 597 } | 182 } |
| 598 | 183 |
| 599 MediaStreamVideoCapturerSource::~MediaStreamVideoCapturerSource() { | 184 MediaStreamVideoCapturerSource::~MediaStreamVideoCapturerSource() { |
| 600 } | 185 } |
| 601 | 186 |
| 602 void MediaStreamVideoCapturerSource::RequestRefreshFrame() { | 187 void MediaStreamVideoCapturerSource::RequestRefreshFrame() { |
| 603 source_->RequestRefreshFrame(); | 188 source_->RequestRefreshFrame(); |
| 604 } | 189 } |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 624 max_requested_width, | 209 max_requested_width, |
| 625 max_requested_height, | 210 max_requested_height, |
| 626 max_requested_frame_rate, | 211 max_requested_frame_rate, |
| 627 callback); | 212 callback); |
| 628 } | 213 } |
| 629 | 214 |
| 630 void MediaStreamVideoCapturerSource::StartSourceImpl( | 215 void MediaStreamVideoCapturerSource::StartSourceImpl( |
| 631 const media::VideoCaptureFormat& format, | 216 const media::VideoCaptureFormat& format, |
| 632 const blink::WebMediaConstraints& constraints, | 217 const blink::WebMediaConstraints& constraints, |
| 633 const VideoCaptureDeliverFrameCB& frame_callback) { | 218 const VideoCaptureDeliverFrameCB& frame_callback) { |
| 634 if (IsOldVideoConstraints()) { | |
| 635 capture_params_.requested_format = format; | |
| 636 if (IsContentVideoCaptureDevice(device_info())) { | |
| 637 SetContentCaptureParamsFromConstraints( | |
| 638 constraints, device_info().device.type, &capture_params_); | |
| 639 } else if (device_info().device.type == MEDIA_DEVICE_VIDEO_CAPTURE) { | |
| 640 SetPowerLineFrequencyParamFromConstraints(constraints, &capture_params_); | |
| 641 } | |
| 642 } | |
| 643 | |
| 644 is_capture_starting_ = true; | 219 is_capture_starting_ = true; |
| 645 source_->StartCapture( | 220 source_->StartCapture( |
| 646 capture_params_, frame_callback, | 221 capture_params_, frame_callback, |
| 647 base::Bind(&MediaStreamVideoCapturerSource::OnRunStateChanged, | 222 base::Bind(&MediaStreamVideoCapturerSource::OnRunStateChanged, |
| 648 base::Unretained(this))); | 223 base::Unretained(this))); |
| 649 } | 224 } |
| 650 | 225 |
| 651 void MediaStreamVideoCapturerSource::StopSourceImpl() { | 226 void MediaStreamVideoCapturerSource::StopSourceImpl() { |
| 652 source_->StopCapture(); | 227 source_->StopCapture(); |
| 653 } | 228 } |
| 654 | 229 |
| 655 base::Optional<media::VideoCaptureFormat> | 230 base::Optional<media::VideoCaptureFormat> |
| 656 MediaStreamVideoCapturerSource::GetCurrentFormatImpl() const { | 231 MediaStreamVideoCapturerSource::GetCurrentFormatImpl() const { |
| 657 DCHECK(!IsOldVideoConstraints()); | |
| 658 return base::Optional<media::VideoCaptureFormat>( | 232 return base::Optional<media::VideoCaptureFormat>( |
| 659 capture_params_.requested_format); | 233 capture_params_.requested_format); |
| 660 } | 234 } |
| 661 | 235 |
| 662 void MediaStreamVideoCapturerSource::OnRunStateChanged(bool is_running) { | 236 void MediaStreamVideoCapturerSource::OnRunStateChanged(bool is_running) { |
| 663 if (is_capture_starting_) { | 237 if (is_capture_starting_) { |
| 664 OnStartDone(is_running ? MEDIA_DEVICE_OK | 238 OnStartDone(is_running ? MEDIA_DEVICE_OK |
| 665 : MEDIA_DEVICE_TRACK_START_FAILURE); | 239 : MEDIA_DEVICE_TRACK_START_FAILURE); |
| 666 is_capture_starting_ = false; | 240 is_capture_starting_ = false; |
| 667 } else if (!is_running) { | 241 } else if (!is_running) { |
| 668 StopSource(); | 242 StopSource(); |
| 669 } | 243 } |
| 670 } | 244 } |
| 671 | 245 |
| 672 const char* | 246 const char* |
| 673 MediaStreamVideoCapturerSource::GetPowerLineFrequencyForTesting() const { | 247 MediaStreamVideoCapturerSource::GetPowerLineFrequencyForTesting() const { |
| 674 return kPowerLineFrequency; | 248 return kPowerLineFrequency; |
| 675 } | 249 } |
|
hbos_chromium
2017/06/30 15:04:12
Power line: remove this?
Guido Urdaneta
2017/07/03 18:43:16
Done.
| |
| 676 | 250 |
| 677 } // namespace content | 251 } // namespace content |
| OLD | NEW |