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 |