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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "content/public/common/media_stream_request.h" | |
| 11 #include "content/renderer/media/media_stream_constraints_util.h" | |
| 10 #include "content/renderer/media/video_capture_impl_manager.h" | 12 #include "content/renderer/media/video_capture_impl_manager.h" |
| 11 #include "content/renderer/render_thread_impl.h" | 13 #include "content/renderer/render_thread_impl.h" |
| 12 #include "media/base/bind_to_current_loop.h" | 14 #include "media/base/bind_to_current_loop.h" |
| 13 #include "media/base/video_frame.h" | 15 #include "media/base/video_frame.h" |
| 14 | 16 |
| 17 namespace content { | |
| 18 | |
| 15 namespace { | 19 namespace { |
| 16 | 20 |
| 17 // Resolutions used if the source doesn't support capability enumeration. | 21 // Resolutions used if the source doesn't support capability enumeration. |
| 18 struct { | 22 struct { |
| 19 int width; | 23 int width; |
| 20 int height; | 24 int height; |
| 21 } const kVideoResolutions[] = {{1920, 1080}, | 25 } const kVideoResolutions[] = {{1920, 1080}, |
| 22 {1280, 720}, | 26 {1280, 720}, |
| 23 {960, 720}, | 27 {960, 720}, |
| 24 {640, 480}, | 28 {640, 480}, |
| 25 {640, 360}, | 29 {640, 360}, |
| 26 {320, 240}, | 30 {320, 240}, |
| 27 {320, 180}}; | 31 {320, 180}}; |
| 28 | 32 |
| 29 // Frame rates for sources with no support for capability enumeration. | 33 // Frame rates for sources with no support for capability enumeration. |
| 30 const int kVideoFrameRates[] = {30, 60}; | 34 const int kVideoFrameRates[] = {30, 60}; |
| 31 | 35 |
| 32 // Hard upper-bound frame rate for tab/desktop capture. | 36 // Hard upper-bound frame rate for tab/desktop capture. |
| 33 const double kMaxScreenCastFrameRate = 120.0; | 37 const double kMaxScreenCastFrameRate = 120.0; |
| 34 | 38 |
| 39 // Returns true if the value for width or height is reasonable. | |
| 40 bool DimensionValueIsValid(int x) { | |
| 41 return x >= 2 && // Lower-bound: Minimum valid I420 frame resolution. | |
| 42 x <= 16384; // Upper-bound: Common maximum frame size in encoders, etc. | |
|
mcasas
2015/05/07 22:10:00
Shouldn't we use GetArea(), for minimum size, and
miu
2015/05/08 06:43:34
Done. I thought about this again, and I think any
| |
| 43 } | |
| 44 | |
| 45 // Returns true if the value for frame rate is reasonable. | |
| 46 bool FrameRateValueIsValid(double frame_rate) { | |
| 47 return (frame_rate > (1.0 / 60.0)) && // Lower-bound: One frame per minute. | |
| 48 (frame_rate <= 120); // Upper-bound: 120 frames per second. | |
|
mcasas
2015/05/07 22:10:00
[1]?
[1] https://code.google.com/p/chromium/codes
miu
2015/05/08 06:43:34
Done. media/base/limits.h didn't have a minimum f
| |
| 49 } | |
| 50 | |
| 51 // Returns true if the aspect ratio of |a| and |b| are equivalent to two | |
| 52 // significant digits. | |
| 53 bool AreNearlyEquivalentInAspectRatio(const gfx::Size& a, const gfx::Size& b) { | |
| 54 DCHECK(!a.IsEmpty()); | |
| 55 DCHECK(!b.IsEmpty()); | |
| 56 const int aspect_ratio_a = (100 * a.width()) / a.height(); | |
| 57 const int aspect_ratio_b = (100 * b.width()) / b.height(); | |
| 58 return aspect_ratio_a == aspect_ratio_b; | |
| 59 } | |
| 60 | |
| 61 // Interprets the properties in |constraints| to override values in |params| and | |
| 62 // determine the resolution change policy. | |
| 63 void SetScreenCastParamsFromConstraints( | |
| 64 const blink::WebMediaConstraints& constraints, | |
| 65 MediaStreamType type, | |
| 66 media::VideoCaptureParams* params) { | |
| 67 // The default resolution change policies for tab versus desktop capture are | |
| 68 // the way they are for legacy reasons. | |
| 69 if (type == MEDIA_TAB_VIDEO_CAPTURE) { | |
| 70 params->resolution_change_policy = | |
| 71 media::RESOLUTION_POLICY_FIXED_RESOLUTION; | |
| 72 } else if (type == MEDIA_DESKTOP_VIDEO_CAPTURE) { | |
| 73 params->resolution_change_policy = | |
| 74 media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT; | |
| 75 } else { | |
| 76 NOTREACHED(); | |
| 77 } | |
| 78 | |
| 79 // If the maximum frame resolution was provided in the constraints, use it if | |
| 80 // either: 1) none has been set yet; or 2) the maximum specificed is smaller | |
| 81 // than the current setting. | |
| 82 int width = 0; | |
| 83 int height = 0; | |
| 84 gfx::Size desired_max_frame_size; | |
| 85 if (GetConstraintValueAsInteger(constraints, | |
| 86 MediaStreamVideoSource::kMaxWidth, | |
| 87 &width) && | |
| 88 GetConstraintValueAsInteger(constraints, | |
| 89 MediaStreamVideoSource::kMaxHeight, | |
| 90 &height) && | |
| 91 DimensionValueIsValid(width) && | |
| 92 DimensionValueIsValid(height)) { | |
| 93 desired_max_frame_size.SetSize(width, height); | |
| 94 if (params->requested_format.frame_size.IsEmpty() || | |
| 95 desired_max_frame_size.width() < | |
| 96 params->requested_format.frame_size.width() || | |
| 97 desired_max_frame_size.height() < | |
| 98 params->requested_format.frame_size.height()) { | |
| 99 params->requested_format.frame_size = desired_max_frame_size; | |
| 100 } | |
| 101 } | |
| 102 | |
| 103 // Set the default frame resolution if none was provided. | |
| 104 if (params->requested_format.frame_size.IsEmpty()) { | |
| 105 params->requested_format.frame_size.SetSize( | |
| 106 MediaStreamVideoSource::kDefaultWidth, | |
| 107 MediaStreamVideoSource::kDefaultHeight); | |
| 108 } | |
| 109 | |
| 110 // If the maximum frame rate was provided, use it if either: 1) none has been | |
| 111 // set yet; or 2) the maximum specificed is smaller than the current setting. | |
| 112 double frame_rate = 0.0; | |
| 113 if (GetConstraintValueAsDouble(constraints, | |
| 114 MediaStreamVideoSource::kMaxFrameRate, | |
| 115 &frame_rate) && | |
| 116 FrameRateValueIsValid(frame_rate)) { | |
| 117 if (params->requested_format.frame_rate <= 0.0f || | |
| 118 frame_rate < params->requested_format.frame_rate) { | |
| 119 params->requested_format.frame_rate = frame_rate; | |
| 120 } | |
| 121 } | |
| 122 | |
| 123 // Set the default frame rate if none was provided. | |
| 124 if (params->requested_format.frame_rate <= 0.0f) { | |
| 125 params->requested_format.frame_rate = | |
| 126 MediaStreamVideoSource::kDefaultFrameRate; | |
| 127 } | |
| 128 | |
| 129 // If the minimum frame resolution was provided, compare it to the maximum | |
| 130 // frame resolution to determine the intended resolution change policy. | |
| 131 if (!desired_max_frame_size.IsEmpty() && | |
| 132 GetConstraintValueAsInteger(constraints, | |
| 133 MediaStreamVideoSource::kMinWidth, | |
| 134 &width) && | |
| 135 GetConstraintValueAsInteger(constraints, | |
| 136 MediaStreamVideoSource::kMinHeight, | |
| 137 &height) && | |
| 138 width <= desired_max_frame_size.width() && | |
| 139 height <= desired_max_frame_size.height()) { | |
| 140 if (width == desired_max_frame_size.width() && | |
| 141 height == desired_max_frame_size.height()) { | |
| 142 // Constraints explicitly require a single frame resolution. | |
| 143 params->resolution_change_policy = | |
| 144 media::RESOLUTION_POLICY_FIXED_RESOLUTION; | |
| 145 } else if (DimensionValueIsValid(width) && | |
| 146 DimensionValueIsValid(height) && | |
|
mcasas
2015/05/07 22:10:00
Ni: shouldn't l.146-147 be justified @8th column (
miu
2015/05/08 06:43:34
I don't quite understand, and the auto-indent feat
mcasas
2015/05/08 18:38:41
I thought it should be
} else if (DimensionValueIs
| |
| 147 AreNearlyEquivalentInAspectRatio(gfx::Size(width, height), | |
| 148 desired_max_frame_size)) { | |
| 149 // Constraints only mention a single aspect ratio. | |
| 150 params->resolution_change_policy = | |
| 151 media::RESOLUTION_POLICY_FIXED_ASPECT_RATIO; | |
| 152 } else { | |
| 153 // Constraints specify a minimum resolution that is smaller than the | |
| 154 // maximum resolution and has a different aspect ratio (possibly even | |
| 155 // 0x0). This indicates any frame resolution and aspect ratio is | |
| 156 // acceptable. | |
| 157 params->resolution_change_policy = | |
| 158 media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT; | |
| 159 } | |
| 160 } | |
| 161 | |
| 162 DVLOG(1) << "SetScreenCastParamsFromConstraints: " | |
| 163 << params->requested_format.ToString() | |
| 164 << " with resolution change policy " | |
| 165 << params->resolution_change_policy; | |
| 166 } | |
| 167 | |
| 35 } // namespace | 168 } // namespace |
| 36 | 169 |
| 37 namespace content { | |
| 38 | |
| 39 VideoCapturerDelegate::VideoCapturerDelegate( | 170 VideoCapturerDelegate::VideoCapturerDelegate( |
| 40 const StreamDeviceInfo& device_info) | 171 const StreamDeviceInfo& device_info) |
| 41 : session_id_(device_info.session_id), | 172 : session_id_(device_info.session_id), |
| 42 is_screen_cast_(device_info.device.type == MEDIA_TAB_VIDEO_CAPTURE || | 173 is_screen_cast_(device_info.device.type == MEDIA_TAB_VIDEO_CAPTURE || |
| 43 device_info.device.type == MEDIA_DESKTOP_VIDEO_CAPTURE), | 174 device_info.device.type == MEDIA_DESKTOP_VIDEO_CAPTURE), |
| 44 weak_factory_(this) { | 175 weak_factory_(this) { |
| 45 DVLOG(3) << "VideoCapturerDelegate::ctor"; | 176 DVLOG(3) << "VideoCapturerDelegate::ctor"; |
| 46 | 177 |
| 47 // NULL in unit test. | 178 // NULL in unit test. |
| 48 if (RenderThreadImpl::current()) { | 179 if (RenderThreadImpl::current()) { |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 239 const VideoCaptureDeviceFormatsCB& callback) { | 370 const VideoCaptureDeviceFormatsCB& callback) { |
| 240 delegate_->GetCurrentSupportedFormats( | 371 delegate_->GetCurrentSupportedFormats( |
| 241 max_requested_width, | 372 max_requested_width, |
| 242 max_requested_height, | 373 max_requested_height, |
| 243 max_requested_frame_rate, | 374 max_requested_frame_rate, |
| 244 callback); | 375 callback); |
| 245 } | 376 } |
| 246 | 377 |
| 247 void MediaStreamVideoCapturerSource::StartSourceImpl( | 378 void MediaStreamVideoCapturerSource::StartSourceImpl( |
| 248 const media::VideoCaptureFormat& format, | 379 const media::VideoCaptureFormat& format, |
| 380 const blink::WebMediaConstraints& constraints, | |
| 249 const VideoCaptureDeliverFrameCB& frame_callback) { | 381 const VideoCaptureDeliverFrameCB& frame_callback) { |
| 250 media::VideoCaptureParams new_params; | 382 media::VideoCaptureParams new_params; |
| 251 new_params.requested_format = format; | 383 new_params.requested_format = format; |
| 252 if (device_info().device.type == MEDIA_TAB_VIDEO_CAPTURE || | 384 if (device_info().device.type == MEDIA_TAB_VIDEO_CAPTURE || |
| 253 device_info().device.type == MEDIA_DESKTOP_VIDEO_CAPTURE) { | 385 device_info().device.type == MEDIA_DESKTOP_VIDEO_CAPTURE) { |
| 254 new_params.resolution_change_policy = | 386 SetScreenCastParamsFromConstraints( |
| 255 media::RESOLUTION_POLICY_DYNAMIC_WITHIN_LIMIT; | 387 constraints, device_info().device.type, &new_params); |
| 256 } | 388 } |
|
mcasas
2015/05/07 22:10:00
Justiy two columns leftwards.
miu
2015/05/08 06:43:34
Done. Good catch.
| |
| 257 delegate_->StartCapture( | 389 delegate_->StartCapture( |
| 258 new_params, | 390 new_params, |
| 259 frame_callback, | 391 frame_callback, |
| 260 RenderThreadImpl::current() ? | 392 RenderThreadImpl::current() ? |
| 261 RenderThreadImpl::current()->GetIOMessageLoopProxy() : | 393 RenderThreadImpl::current()->GetIOMessageLoopProxy() : |
| 262 nullptr, | 394 nullptr, |
| 263 base::Bind(&MediaStreamVideoCapturerSource::OnStarted, | 395 base::Bind(&MediaStreamVideoCapturerSource::OnStarted, |
| 264 base::Unretained(this))); | 396 base::Unretained(this))); |
| 265 } | 397 } |
| 266 | 398 |
| 267 void MediaStreamVideoCapturerSource::StopSourceImpl() { | 399 void MediaStreamVideoCapturerSource::StopSourceImpl() { |
| 268 delegate_->StopCapture(); | 400 delegate_->StopCapture(); |
| 269 } | 401 } |
| 270 | 402 |
| 271 void MediaStreamVideoCapturerSource::OnStarted(bool result) { | 403 void MediaStreamVideoCapturerSource::OnStarted(bool result) { |
| 272 OnStartDone(result ? MEDIA_DEVICE_OK : MEDIA_DEVICE_TRACK_START_FAILURE); | 404 OnStartDone(result ? MEDIA_DEVICE_OK : MEDIA_DEVICE_TRACK_START_FAILURE); |
| 273 } | 405 } |
| 274 | 406 |
| 275 } // namespace content | 407 } // namespace content |
| OLD | NEW |