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

Side by Side Diff: content/renderer/media/media_stream_video_capturer_source.cc

Issue 1124263004: New resolution change policies for desktop and tab capture. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed comments from mcasas. Created 5 years, 7 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 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"
15 #include "media/base/limits.h"
13 #include "media/base/video_frame.h" 16 #include "media/base/video_frame.h"
14 17
18 namespace content {
19
15 namespace { 20 namespace {
16 21
17 // Resolutions used if the source doesn't support capability enumeration. 22 // Resolutions used if the source doesn't support capability enumeration.
18 struct { 23 struct {
19 int width; 24 int width;
20 int height; 25 int height;
21 } const kVideoResolutions[] = {{1920, 1080}, 26 } const kVideoResolutions[] = {{1920, 1080},
22 {1280, 720}, 27 {1280, 720},
23 {960, 720}, 28 {960, 720},
24 {640, 480}, 29 {640, 480},
25 {640, 360}, 30 {640, 360},
26 {320, 240}, 31 {320, 240},
27 {320, 180}}; 32 {320, 180}};
28 33
29 // Frame rates for sources with no support for capability enumeration. 34 // Frame rates for sources with no support for capability enumeration.
30 const int kVideoFrameRates[] = {30, 60}; 35 const int kVideoFrameRates[] = {30, 60};
31 36
32 // Hard upper-bound frame rate for tab/desktop capture. 37 // Hard upper-bound frame rate for tab/desktop capture.
33 const double kMaxScreenCastFrameRate = 120.0; 38 const double kMaxScreenCastFrameRate = 120.0;
34 39
40 // Returns true if the value for width or height is reasonable.
41 bool DimensionValueIsValid(int x) {
42 return x > 0 && x <= media::limits::kMaxDimension;
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 <= media::limits::kMaxFramesPerSecond);
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) &&
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
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 }
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698