| 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_source.h" | 5 #include "content/renderer/media/media_stream_video_source.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 constraints, | 97 constraints, |
| 98 MediaStreamVideoSource::kMinAspectRatio, | 98 MediaStreamVideoSource::kMinAspectRatio, |
| 99 min_aspect_ratio); | 99 min_aspect_ratio); |
| 100 mandatory |= GetMandatoryConstraintValueAsDouble( | 100 mandatory |= GetMandatoryConstraintValueAsDouble( |
| 101 constraints, | 101 constraints, |
| 102 MediaStreamVideoSource::kMaxAspectRatio, | 102 MediaStreamVideoSource::kMaxAspectRatio, |
| 103 max_aspect_ratio); | 103 max_aspect_ratio); |
| 104 if (mandatory) | 104 if (mandatory) |
| 105 return; | 105 return; |
| 106 | 106 |
| 107 GetOptionalConstraintValueAsDouble( | 107 GetOptionalConstraintValueAsDouble(constraints, |
| 108 constraints, | 108 MediaStreamVideoSource::kMinAspectRatio, |
| 109 MediaStreamVideoSource::kMinAspectRatio, | 109 min_aspect_ratio); |
| 110 min_aspect_ratio); | 110 GetOptionalConstraintValueAsDouble(constraints, |
| 111 GetOptionalConstraintValueAsDouble( | 111 MediaStreamVideoSource::kMaxAspectRatio, |
| 112 constraints, | 112 max_aspect_ratio); |
| 113 MediaStreamVideoSource::kMaxAspectRatio, | |
| 114 max_aspect_ratio); | |
| 115 } | 113 } |
| 116 | 114 |
| 117 // Returns true if |constraint| is fulfilled. |format| can be changed by a | 115 // Returns true if |constraint| is fulfilled. |format| can be changed by a |
| 118 // constraint, e.g. the frame rate can be changed by setting maxFrameRate. | 116 // constraint, e.g. the frame rate can be changed by setting maxFrameRate. |
| 119 bool UpdateFormatForConstraint( | 117 bool UpdateFormatForConstraint(const blink::WebMediaConstraint& constraint, |
| 120 const blink::WebMediaConstraint& constraint, | 118 bool mandatory, |
| 121 bool mandatory, | 119 media::VideoCaptureFormat* format) { |
| 122 media::VideoCaptureFormat* format) { | |
| 123 DCHECK(format != NULL); | 120 DCHECK(format != NULL); |
| 124 | 121 |
| 125 if (!format->IsValid()) | 122 if (!format->IsValid()) |
| 126 return false; | 123 return false; |
| 127 | 124 |
| 128 std::string constraint_name = constraint.m_name.utf8(); | 125 const std::string constraint_name = constraint.m_name.utf8(); |
| 129 std::string constraint_value = constraint.m_value.utf8(); | 126 const std::string constraint_value = constraint.m_value.utf8(); |
| 130 | 127 |
| 131 if (constraint_name.find(kGooglePrefix) == 0) { | 128 if (constraint_name.find(kGooglePrefix) == 0) { |
| 132 // These are actually options, not constraints, so they can be satisfied | 129 // These are actually options, not constraints, so they can be satisfied |
| 133 // regardless of the format. | 130 // regardless of the format. |
| 134 return true; | 131 return true; |
| 135 } | 132 } |
| 136 | 133 |
| 137 if (constraint_name == MediaStreamSource::kSourceId) { | 134 if (constraint_name == MediaStreamSource::kSourceId) { |
| 138 // This is a constraint that doesn't affect the format. | 135 // This is a constraint that doesn't affect the format. |
| 139 return true; | 136 return true; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 return true; | 182 return true; |
| 186 } else { | 183 } else { |
| 187 LOG(WARNING) << "Found unknown MediaStream constraint. Name:" | 184 LOG(WARNING) << "Found unknown MediaStream constraint. Name:" |
| 188 << constraint_name << " Value:" << constraint_value; | 185 << constraint_name << " Value:" << constraint_value; |
| 189 return false; | 186 return false; |
| 190 } | 187 } |
| 191 } | 188 } |
| 192 | 189 |
| 193 // Removes media::VideoCaptureFormats from |formats| that don't meet | 190 // Removes media::VideoCaptureFormats from |formats| that don't meet |
| 194 // |constraint|. | 191 // |constraint|. |
| 195 void FilterFormatsByConstraint( | 192 void FilterFormatsByConstraint(const blink::WebMediaConstraint& constraint, |
| 196 const blink::WebMediaConstraint& constraint, | 193 bool mandatory, |
| 197 bool mandatory, | 194 media::VideoCaptureFormats* formats) { |
| 198 media::VideoCaptureFormats* formats) { | |
| 199 DVLOG(3) << "FilterFormatsByConstraint(" | 195 DVLOG(3) << "FilterFormatsByConstraint(" |
| 200 << "{ constraint.m_name = " << constraint.m_name.utf8() | 196 << "{ constraint.m_name = " << constraint.m_name.utf8() |
| 201 << " constraint.m_value = " << constraint.m_value.utf8() | 197 << " constraint.m_value = " << constraint.m_value.utf8() |
| 202 << " mandatory = " << mandatory << "})"; | 198 << " mandatory = " << mandatory << "})"; |
| 203 media::VideoCaptureFormats::iterator format_it = formats->begin(); | 199 media::VideoCaptureFormats::iterator format_it = formats->begin(); |
| 204 while (format_it != formats->end()) { | 200 while (format_it != formats->end()) { |
| 205 // Modify the format_it to fulfill the constraint if possible. | 201 // Modify the format_it to fulfill the constraint if possible. |
| 206 // Delete it otherwise. | 202 // Delete it otherwise. |
| 207 if (!UpdateFormatForConstraint(constraint, mandatory, &(*format_it))) | 203 if (!UpdateFormatForConstraint(constraint, mandatory, &(*format_it))) |
| 208 format_it = formats->erase(format_it); | 204 format_it = formats->erase(format_it); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 DLOG(WARNING) << "Wrong requested frame rate."; | 253 DLOG(WARNING) << "Wrong requested frame rate."; |
| 258 return media::VideoCaptureFormats(); | 254 return media::VideoCaptureFormats(); |
| 259 } | 255 } |
| 260 } | 256 } |
| 261 | 257 |
| 262 blink::WebVector<blink::WebMediaConstraint> mandatory; | 258 blink::WebVector<blink::WebMediaConstraint> mandatory; |
| 263 blink::WebVector<blink::WebMediaConstraint> optional; | 259 blink::WebVector<blink::WebMediaConstraint> optional; |
| 264 constraints.getMandatoryConstraints(mandatory); | 260 constraints.getMandatoryConstraints(mandatory); |
| 265 constraints.getOptionalConstraints(optional); | 261 constraints.getOptionalConstraints(optional); |
| 266 media::VideoCaptureFormats candidates = supported_formats; | 262 media::VideoCaptureFormats candidates = supported_formats; |
| 267 for (size_t i = 0; i < mandatory.size(); ++i) { | 263 for (const auto& constraint : mandatory) { |
| 268 FilterFormatsByConstraint(mandatory[i], true, &candidates); | 264 FilterFormatsByConstraint(constraint, true, &candidates); |
| 269 if (candidates.empty()) { | 265 if (candidates.empty()) { |
| 270 *unsatisfied_constraint = mandatory[i].m_name; | 266 *unsatisfied_constraint = constraint.m_name; |
| 271 return candidates; | 267 return candidates; |
| 272 } | 268 } |
| 273 } | 269 } |
| 274 | 270 |
| 275 if (candidates.empty()) | 271 if (candidates.empty()) |
| 276 return candidates; | 272 return candidates; |
| 277 | 273 |
| 278 // Ok - all mandatory checked and we still have candidates. | 274 // Ok - all mandatory checked and we still have candidates. |
| 279 // Let's try filtering using the optional constraints. The optional | 275 // Let's try filtering using the optional constraints. The optional |
| 280 // constraints must be filtered in the order they occur in |optional|. | 276 // constraints must be filtered in the order they occur in |optional|. |
| 281 // But if a constraint produce zero candidates, the constraint is ignored and | 277 // But if a constraint produce zero candidates, the constraint is ignored and |
| 282 // the next constraint is tested. | 278 // the next constraint is tested. |
| 283 // http://dev.w3.org/2011/webrtc/editor/getusermedia.html#idl-def-Constraints | 279 // http://dev.w3.org/2011/webrtc/editor/getusermedia.html#idl-def-Constraints |
| 284 for (size_t i = 0; i < optional.size(); ++i) { | 280 for (const auto& constraint : optional) { |
| 285 media::VideoCaptureFormats current_candidates = candidates; | 281 media::VideoCaptureFormats current_candidates = candidates; |
| 286 FilterFormatsByConstraint(optional[i], false, ¤t_candidates); | 282 FilterFormatsByConstraint(constraint, false, ¤t_candidates); |
| 287 if (!current_candidates.empty()) | 283 if (!current_candidates.empty()) |
| 288 candidates = current_candidates; | 284 candidates = current_candidates; |
| 289 } | 285 } |
| 290 | 286 |
| 291 // We have done as good as we can to filter the supported resolutions. | 287 // We have done as good as we can to filter the supported resolutions. |
| 292 return candidates; | 288 return candidates; |
| 293 } | 289 } |
| 294 | 290 |
| 295 const media::VideoCaptureFormat& GetBestFormatBasedOnArea( | 291 const media::VideoCaptureFormat& GetBestFormatBasedOnArea( |
| 296 const media::VideoCaptureFormats& formats, | 292 const media::VideoCaptureFormats& formats, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 307 } | 303 } |
| 308 return *best_it; | 304 return *best_it; |
| 309 } | 305 } |
| 310 | 306 |
| 311 // Find the format that best matches the default video size. | 307 // Find the format that best matches the default video size. |
| 312 // This algorithm is chosen since a resolution must be picked even if no | 308 // This algorithm is chosen since a resolution must be picked even if no |
| 313 // constraints are provided. We don't just select the maximum supported | 309 // constraints are provided. We don't just select the maximum supported |
| 314 // resolution since higher resolutions cost more in terms of complexity and | 310 // resolution since higher resolutions cost more in terms of complexity and |
| 315 // many cameras have lower frame rate and have more noise in the image at | 311 // many cameras have lower frame rate and have more noise in the image at |
| 316 // their maximum supported resolution. | 312 // their maximum supported resolution. |
| 317 void GetBestCaptureFormat( | 313 void GetBestCaptureFormat(const media::VideoCaptureFormats& formats, |
| 318 const media::VideoCaptureFormats& formats, | 314 const blink::WebMediaConstraints& constraints, |
| 319 const blink::WebMediaConstraints& constraints, | 315 media::VideoCaptureFormat* capture_format) { |
| 320 media::VideoCaptureFormat* capture_format) { | |
| 321 DCHECK(!formats.empty()); | 316 DCHECK(!formats.empty()); |
| 322 | 317 |
| 323 int max_width; | 318 int max_width; |
| 324 int max_height; | 319 int max_height; |
| 325 GetDesiredMaxWidthAndHeight(constraints, &max_width, &max_height); | 320 GetDesiredMaxWidthAndHeight(constraints, &max_width, &max_height); |
| 326 | 321 |
| 327 *capture_format = GetBestFormatBasedOnArea( | 322 *capture_format = GetBestFormatBasedOnArea( |
| 328 formats, | 323 formats, |
| 329 std::min(max_width, | 324 std::min(max_width, |
| 330 static_cast<int>(MediaStreamVideoSource::kDefaultWidth)) * | 325 static_cast<int>(MediaStreamVideoSource::kDefaultWidth)) * |
| (...skipping 29 matching lines...) Expand all Loading... |
| 360 DCHECK(CalledOnValidThread()); | 355 DCHECK(CalledOnValidThread()); |
| 361 } | 356 } |
| 362 | 357 |
| 363 void MediaStreamVideoSource::AddTrack( | 358 void MediaStreamVideoSource::AddTrack( |
| 364 MediaStreamVideoTrack* track, | 359 MediaStreamVideoTrack* track, |
| 365 const VideoCaptureDeliverFrameCB& frame_callback, | 360 const VideoCaptureDeliverFrameCB& frame_callback, |
| 366 const blink::WebMediaConstraints& constraints, | 361 const blink::WebMediaConstraints& constraints, |
| 367 const ConstraintsCallback& callback) { | 362 const ConstraintsCallback& callback) { |
| 368 DCHECK(CalledOnValidThread()); | 363 DCHECK(CalledOnValidThread()); |
| 369 DCHECK(!constraints.isNull()); | 364 DCHECK(!constraints.isNull()); |
| 370 DCHECK(std::find(tracks_.begin(), tracks_.end(), | 365 DCHECK(std::find(tracks_.begin(), tracks_.end(), track) == tracks_.end()); |
| 371 track) == tracks_.end()); | |
| 372 tracks_.push_back(track); | 366 tracks_.push_back(track); |
| 373 | 367 |
| 374 requested_constraints_.push_back( | 368 requested_constraints_.push_back( |
| 375 RequestedConstraints(track, frame_callback, constraints, callback)); | 369 RequestedConstraints(track, frame_callback, constraints, callback)); |
| 376 | 370 |
| 377 switch (state_) { | 371 switch (state_) { |
| 378 case NEW: { | 372 case NEW: { |
| 379 // Tab capture and Screen capture needs the maximum requested height | 373 // Tab capture and Screen capture needs the maximum requested height |
| 380 // and width to decide on the resolution. | 374 // and width to decide on the resolution. |
| 381 int max_requested_width = 0; | 375 int max_requested_width = 0; |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 : track(track), | 608 : track(track), |
| 615 frame_callback(frame_callback), | 609 frame_callback(frame_callback), |
| 616 constraints(constraints), | 610 constraints(constraints), |
| 617 callback(callback) { | 611 callback(callback) { |
| 618 } | 612 } |
| 619 | 613 |
| 620 MediaStreamVideoSource::RequestedConstraints::~RequestedConstraints() { | 614 MediaStreamVideoSource::RequestedConstraints::~RequestedConstraints() { |
| 621 } | 615 } |
| 622 | 616 |
| 623 } // namespace content | 617 } // namespace content |
| OLD | NEW |