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

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

Issue 2777703002: Introduce SelectSettings algorithm for MediaStream video tracks. (Closed)
Patch Set: static asserts Created 3 years, 8 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 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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_constraints_util_video_content.h" 5 #include "content/renderer/media/media_stream_constraints_util_video_content.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
11 #include "content/renderer/media/media_stream_constraints_util_sets.h" 11 #include "content/renderer/media/media_stream_constraints_util_sets.h"
12 #include "content/renderer/media/media_stream_video_source.h" 12 #include "content/renderer/media/media_stream_video_source.h"
13 #include "media/base/limits.h" 13 #include "media/base/limits.h"
14 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" 14 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
15 #include "third_party/WebKit/public/platform/WebString.h" 15 #include "third_party/WebKit/public/platform/WebString.h"
16 16
17 namespace content { 17 namespace content {
18 18
19 // TODO(guidou): Change default width and height to larger values. See
20 // http://crbug.com/257097.
21 const int kDefaultScreenCastWidth = MediaStreamVideoSource::kDefaultWidth;
22 const int kDefaultScreenCastHeight = MediaStreamVideoSource::kDefaultHeight;
23 const double kDefaultScreenCastFrameRate =
24 MediaStreamVideoSource::kDefaultFrameRate;
25 const int kMinScreenCastDimension = 1;
26 const int kMaxScreenCastDimension = media::limits::kMaxDimension - 1;
27
19 namespace { 28 namespace {
20 29
21 using Point = ResolutionSet::Point; 30 using Point = ResolutionSet::Point;
22 using StringSet = DiscreteSet<std::string>; 31 using StringSet = DiscreteSet<std::string>;
23 using BoolSet = DiscreteSet<bool>; 32 using BoolSet = DiscreteSet<bool>;
24 33
25 // Hard upper and lower bound frame rates for tab/desktop capture. 34 // Hard upper and lower bound frame rates for tab/desktop capture.
26 constexpr double kMaxScreenCastFrameRate = 120.0; 35 const double kMaxScreenCastFrameRate = 120.0;
27 constexpr double kMinScreenCastFrameRate = 1.0 / 60.0; 36 const double kMinScreenCastFrameRate = 1.0 / 60.0;
28 37
29 constexpr double kDefaultFrameRate = MediaStreamVideoSource::kDefaultFrameRate;
30
31 constexpr int kMinScreenCastDimension = 1;
32 constexpr int kMaxScreenCastDimension = media::limits::kMaxDimension - 1;
33 constexpr double kMinScreenCastAspectRatio = 38 constexpr double kMinScreenCastAspectRatio =
34 static_cast<double>(kMinScreenCastDimension) / 39 static_cast<double>(kMinScreenCastDimension) /
35 static_cast<double>(kMaxScreenCastDimension); 40 static_cast<double>(kMaxScreenCastDimension);
36 constexpr double kMaxScreenCastAspectRatio = 41 constexpr double kMaxScreenCastAspectRatio =
37 static_cast<double>(kMaxScreenCastDimension) / 42 static_cast<double>(kMaxScreenCastDimension) /
38 static_cast<double>(kMinScreenCastDimension); 43 static_cast<double>(kMinScreenCastDimension);
39 44
40 StringSet StringSetFromConstraint(const blink::StringConstraint& constraint) { 45 StringSet StringSetFromConstraint(const blink::StringConstraint& constraint) {
41 if (!constraint.hasExact()) 46 if (!constraint.hasExact())
42 return StringSet::UniversalSet(); 47 return StringSet::UniversalSet();
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 int RoundToInt(double d) { 133 int RoundToInt(double d) {
129 return static_cast<int>(std::round(d)); 134 return static_cast<int>(std::round(d));
130 } 135 }
131 136
132 gfx::Size ToGfxSize(const Point& point) { 137 gfx::Size ToGfxSize(const Point& point) {
133 return gfx::Size(RoundToInt(point.width()), RoundToInt(point.height())); 138 return gfx::Size(RoundToInt(point.width()), RoundToInt(point.height()));
134 } 139 }
135 140
136 double SelectFrameRateFromCandidates( 141 double SelectFrameRateFromCandidates(
137 const DoubleRangeSet& candidate_set, 142 const DoubleRangeSet& candidate_set,
138 const blink::WebMediaTrackConstraintSet& basic_constraint_set) { 143 const blink::WebMediaTrackConstraintSet& basic_constraint_set,
144 double default_frame_rate) {
139 double frame_rate = basic_constraint_set.frameRate.hasIdeal() 145 double frame_rate = basic_constraint_set.frameRate.hasIdeal()
140 ? basic_constraint_set.frameRate.ideal() 146 ? basic_constraint_set.frameRate.ideal()
141 : kDefaultFrameRate; 147 : default_frame_rate;
142 if (frame_rate > candidate_set.Max()) 148 if (frame_rate > candidate_set.Max())
143 frame_rate = candidate_set.Max(); 149 frame_rate = candidate_set.Max();
144 else if (frame_rate < candidate_set.Min()) 150 else if (frame_rate < candidate_set.Min())
145 frame_rate = candidate_set.Min(); 151 frame_rate = candidate_set.Min();
146 152
147 return frame_rate; 153 return frame_rate;
148 } 154 }
149 155
150 media::VideoCaptureParams SelectVideoCaptureParamsFromCandidates( 156 media::VideoCaptureParams SelectVideoCaptureParamsFromCandidates(
151 const VideoContentCaptureCandidates& candidates, 157 const VideoContentCaptureCandidates& candidates,
152 const blink::WebMediaTrackConstraintSet& basic_constraint_set) { 158 const blink::WebMediaTrackConstraintSet& basic_constraint_set,
159 int default_height,
160 int default_width,
161 double default_frame_rate) {
153 double requested_frame_rate = SelectFrameRateFromCandidates( 162 double requested_frame_rate = SelectFrameRateFromCandidates(
154 candidates.frame_rate_set, basic_constraint_set); 163 candidates.frame_rate_set, basic_constraint_set, default_frame_rate);
155 Point requested_resolution = 164 Point requested_resolution =
156 candidates.resolution_set.SelectClosestPointToIdeal(basic_constraint_set); 165 candidates.resolution_set.SelectClosestPointToIdeal(
166 basic_constraint_set, default_height, default_width);
157 media::VideoCaptureParams params; 167 media::VideoCaptureParams params;
158 params.requested_format = media::VideoCaptureFormat( 168 params.requested_format = media::VideoCaptureFormat(
159 ToGfxSize(requested_resolution), static_cast<float>(requested_frame_rate), 169 ToGfxSize(requested_resolution), static_cast<float>(requested_frame_rate),
160 media::PIXEL_FORMAT_I420); 170 media::PIXEL_FORMAT_I420);
161 params.resolution_change_policy = 171 params.resolution_change_policy =
162 SelectResolutionPolicyFromCandidates(candidates.resolution_set); 172 SelectResolutionPolicyFromCandidates(candidates.resolution_set);
163 // Content capture always uses default power-line frequency. 173 // Content capture always uses default power-line frequency.
164 DCHECK(params.IsValid()); 174 DCHECK(params.IsValid());
165 175
166 return params; 176 return params;
(...skipping 18 matching lines...) Expand all
185 // The empty string is treated as a default device ID by the browser. 195 // The empty string is treated as a default device ID by the browser.
186 if (candidates.is_universal()) { 196 if (candidates.is_universal()) {
187 return std::string(); 197 return std::string();
188 } 198 }
189 199
190 // If there are multiple elements that satisfy the constraints, break ties by 200 // If there are multiple elements that satisfy the constraints, break ties by
191 // using the element that was specified first. 201 // using the element that was specified first.
192 return candidates.FirstElement(); 202 return candidates.FirstElement();
193 } 203 }
194 204
195 rtc::Optional<bool> SelectNoiseReductionFromCandidates( 205 base::Optional<bool> SelectNoiseReductionFromCandidates(
196 const BoolSet& candidates, 206 const BoolSet& candidates,
197 const blink::WebMediaTrackConstraintSet& basic_constraint_set) { 207 const blink::WebMediaTrackConstraintSet& basic_constraint_set) {
198 DCHECK(!candidates.IsEmpty()); 208 DCHECK(!candidates.IsEmpty());
199 if (basic_constraint_set.googNoiseReduction.hasIdeal() && 209 if (basic_constraint_set.googNoiseReduction.hasIdeal() &&
200 candidates.Contains(basic_constraint_set.googNoiseReduction.ideal())) { 210 candidates.Contains(basic_constraint_set.googNoiseReduction.ideal())) {
201 return rtc::Optional<bool>(basic_constraint_set.googNoiseReduction.ideal()); 211 return base::Optional<bool>(
212 basic_constraint_set.googNoiseReduction.ideal());
202 } 213 }
203 214
204 if (candidates.is_universal()) 215 if (candidates.is_universal())
205 return rtc::Optional<bool>(); 216 return base::Optional<bool>();
206 217
207 // A non-universal BoolSet can have at most one element. 218 // A non-universal BoolSet can have at most one element.
208 return rtc::Optional<bool>(candidates.FirstElement()); 219 return base::Optional<bool>(candidates.FirstElement());
209 } 220 }
210 221
211 VideoContentCaptureSourceSelectionResult SelectResultFromCandidates( 222 VideoCaptureSettings SelectResultFromCandidates(
212 const VideoContentCaptureCandidates& candidates, 223 const VideoContentCaptureCandidates& candidates,
213 const blink::WebMediaTrackConstraintSet& basic_constraint_set) { 224 const blink::WebMediaTrackConstraintSet& basic_constraint_set) {
214 std::string device_id = SelectDeviceIDFromCandidates(candidates.device_id_set, 225 std::string device_id = SelectDeviceIDFromCandidates(candidates.device_id_set,
215 basic_constraint_set); 226 basic_constraint_set);
227 // TODO(guidou): Use native screen-capture resolution as default.
228 // http://crbug.com/257097
216 media::VideoCaptureParams capture_params = 229 media::VideoCaptureParams capture_params =
217 SelectVideoCaptureParamsFromCandidates(candidates, basic_constraint_set); 230 SelectVideoCaptureParamsFromCandidates(
231 candidates, basic_constraint_set, kDefaultScreenCastHeight,
232 kDefaultScreenCastWidth, kDefaultScreenCastFrameRate);
218 233
219 rtc::Optional<bool> noise_reduction = SelectNoiseReductionFromCandidates( 234 base::Optional<bool> noise_reduction = SelectNoiseReductionFromCandidates(
220 candidates.noise_reduction_set, basic_constraint_set); 235 candidates.noise_reduction_set, basic_constraint_set);
221 236
222 return VideoContentCaptureSourceSelectionResult( 237 auto track_adapter_settings = SelectVideoTrackAdapterSettings(
223 std::move(device_id), noise_reduction, capture_params); 238 basic_constraint_set, candidates.resolution_set,
239 candidates.frame_rate_set, capture_params.requested_format);
240
241 return VideoCaptureSettings(std::move(device_id), capture_params,
242 noise_reduction, track_adapter_settings,
243 candidates.frame_rate_set.Min());
224 } 244 }
225 245
226 VideoContentCaptureSourceSelectionResult UnsatisfiedConstraintsResult( 246 VideoCaptureSettings UnsatisfiedConstraintsResult(
227 const VideoContentCaptureCandidates& candidates, 247 const VideoContentCaptureCandidates& candidates,
228 const blink::WebMediaTrackConstraintSet& constraint_set) { 248 const blink::WebMediaTrackConstraintSet& constraint_set) {
229 DCHECK(candidates.IsEmpty()); 249 DCHECK(candidates.IsEmpty());
230 if (candidates.resolution_set.IsHeightEmpty()) { 250 if (candidates.resolution_set.IsHeightEmpty()) {
231 return VideoContentCaptureSourceSelectionResult( 251 return VideoCaptureSettings(constraint_set.height.name());
232 constraint_set.height.name());
233 } else if (candidates.resolution_set.IsWidthEmpty()) { 252 } else if (candidates.resolution_set.IsWidthEmpty()) {
234 return VideoContentCaptureSourceSelectionResult( 253 return VideoCaptureSettings(constraint_set.width.name());
235 constraint_set.width.name());
236 } else if (candidates.resolution_set.IsAspectRatioEmpty()) { 254 } else if (candidates.resolution_set.IsAspectRatioEmpty()) {
237 return VideoContentCaptureSourceSelectionResult( 255 return VideoCaptureSettings(constraint_set.aspectRatio.name());
238 constraint_set.aspectRatio.name());
239 } else if (candidates.frame_rate_set.IsEmpty()) { 256 } else if (candidates.frame_rate_set.IsEmpty()) {
240 return VideoContentCaptureSourceSelectionResult( 257 return VideoCaptureSettings(constraint_set.frameRate.name());
241 constraint_set.frameRate.name());
242 } else if (candidates.noise_reduction_set.IsEmpty()) { 258 } else if (candidates.noise_reduction_set.IsEmpty()) {
243 return VideoContentCaptureSourceSelectionResult( 259 return VideoCaptureSettings(constraint_set.googNoiseReduction.name());
244 constraint_set.googNoiseReduction.name());
245 } else { 260 } else {
246 DCHECK(candidates.device_id_set.IsEmpty()); 261 DCHECK(candidates.device_id_set.IsEmpty());
247 return VideoContentCaptureSourceSelectionResult( 262 return VideoCaptureSettings(constraint_set.deviceId.name());
248 constraint_set.deviceId.name());
249 } 263 }
250 } 264 }
251 265
252 } // namespace 266 } // namespace
253 267
254 VideoContentCaptureSourceSelectionResult:: 268 VideoCaptureSettings SelectSettingsVideoContentCapture(
255 VideoContentCaptureSourceSelectionResult()
256 : VideoContentCaptureSourceSelectionResult("") {}
257
258 VideoContentCaptureSourceSelectionResult::
259 VideoContentCaptureSourceSelectionResult(const char* failed_constraint_name)
260 : failed_constraint_name_(failed_constraint_name) {}
261
262 VideoContentCaptureSourceSelectionResult::
263 VideoContentCaptureSourceSelectionResult(
264 std::string device_id,
265 const rtc::Optional<bool>& noise_reduction,
266 media::VideoCaptureParams capture_params)
267 : failed_constraint_name_(nullptr),
268 device_id_(std::move(device_id)),
269 noise_reduction_(noise_reduction),
270 capture_params_(capture_params) {}
271
272 VideoContentCaptureSourceSelectionResult::
273 VideoContentCaptureSourceSelectionResult(
274 const VideoContentCaptureSourceSelectionResult& other) = default;
275 VideoContentCaptureSourceSelectionResult::
276 VideoContentCaptureSourceSelectionResult(
277 VideoContentCaptureSourceSelectionResult&& other) = default;
278 VideoContentCaptureSourceSelectionResult::
279 ~VideoContentCaptureSourceSelectionResult() = default;
280 VideoContentCaptureSourceSelectionResult&
281 VideoContentCaptureSourceSelectionResult::operator=(
282 const VideoContentCaptureSourceSelectionResult& other) = default;
283 VideoContentCaptureSourceSelectionResult&
284 VideoContentCaptureSourceSelectionResult::operator=(
285 VideoContentCaptureSourceSelectionResult&& other) = default;
286
287 int VideoContentCaptureSourceSelectionResult::Height() const {
288 DCHECK(HasValue());
289 return capture_params_.requested_format.frame_size.height();
290 }
291
292 int VideoContentCaptureSourceSelectionResult::Width() const {
293 DCHECK(HasValue());
294 return capture_params_.requested_format.frame_size.width();
295 }
296
297 float VideoContentCaptureSourceSelectionResult::FrameRate() const {
298 DCHECK(HasValue());
299 return capture_params_.requested_format.frame_rate;
300 }
301
302 media::ResolutionChangePolicy
303 VideoContentCaptureSourceSelectionResult::ResolutionChangePolicy() const {
304 DCHECK(HasValue());
305 return capture_params_.resolution_change_policy;
306 }
307
308 VideoContentCaptureSourceSelectionResult
309 SelectVideoContentCaptureSourceSettings(
310 const blink::WebMediaConstraints& constraints) { 269 const blink::WebMediaConstraints& constraints) {
311 VideoContentCaptureCandidates candidates; 270 VideoContentCaptureCandidates candidates;
312 candidates.resolution_set = ScreenCastResolutionCapabilities(); 271 candidates.resolution_set = ScreenCastResolutionCapabilities();
313 candidates.frame_rate_set = 272 candidates.frame_rate_set =
314 DoubleRangeSet(kMinScreenCastFrameRate, kMaxScreenCastFrameRate); 273 DoubleRangeSet(kMinScreenCastFrameRate, kMaxScreenCastFrameRate);
315 // candidates.device_id_set and candidates.noise_reduction_set are 274 // candidates.device_id_set and candidates.noise_reduction_set are
316 // automatically initialized with the universal set. 275 // automatically initialized with the universal set.
317 276
318 candidates = candidates.Intersection( 277 candidates = candidates.Intersection(
319 VideoContentCaptureCandidates(constraints.basic())); 278 VideoContentCaptureCandidates(constraints.basic()));
320 if (candidates.IsEmpty()) 279 if (candidates.IsEmpty())
321 return UnsatisfiedConstraintsResult(candidates, constraints.basic()); 280 return UnsatisfiedConstraintsResult(candidates, constraints.basic());
322 281
323 for (const auto& advanced_set : constraints.advanced()) { 282 for (const auto& advanced_set : constraints.advanced()) {
324 VideoContentCaptureCandidates advanced_candidates(advanced_set); 283 VideoContentCaptureCandidates advanced_candidates(advanced_set);
325 VideoContentCaptureCandidates intersection = 284 VideoContentCaptureCandidates intersection =
326 candidates.Intersection(advanced_candidates); 285 candidates.Intersection(advanced_candidates);
327 if (!intersection.IsEmpty()) 286 if (!intersection.IsEmpty())
328 candidates = std::move(intersection); 287 candidates = std::move(intersection);
329 } 288 }
330 289
331 DCHECK(!candidates.IsEmpty()); 290 DCHECK(!candidates.IsEmpty());
332 return SelectResultFromCandidates(candidates, constraints.basic()); 291 return SelectResultFromCandidates(candidates, constraints.basic());
333 } 292 }
334 293
335 } // namespace content 294 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698