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 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 format_it = formats->erase(format_it); | 213 format_it = formats->erase(format_it); |
214 } else { | 214 } else { |
215 ++format_it; | 215 ++format_it; |
216 } | 216 } |
217 } | 217 } |
218 } | 218 } |
219 | 219 |
220 // Returns the media::VideoCaptureFormats that matches |constraints|. | 220 // Returns the media::VideoCaptureFormats that matches |constraints|. |
221 media::VideoCaptureFormats FilterFormats( | 221 media::VideoCaptureFormats FilterFormats( |
222 const blink::WebMediaConstraints& constraints, | 222 const blink::WebMediaConstraints& constraints, |
223 const media::VideoCaptureFormats& supported_formats) { | 223 const media::VideoCaptureFormats& supported_formats, |
| 224 blink::WebString* unsatisfied_constraint) { |
224 if (constraints.isNull()) { | 225 if (constraints.isNull()) { |
225 return supported_formats; | 226 return supported_formats; |
226 } | 227 } |
227 | 228 |
228 double max_aspect_ratio; | 229 double max_aspect_ratio; |
229 double min_aspect_ratio; | 230 double min_aspect_ratio; |
230 GetDesiredMinAndMaxAspectRatio(constraints, | 231 GetDesiredMinAndMaxAspectRatio(constraints, |
231 &min_aspect_ratio, | 232 &min_aspect_ratio, |
232 &max_aspect_ratio); | 233 &max_aspect_ratio); |
233 | 234 |
(...skipping 29 matching lines...) Expand all Loading... |
263 DLOG(WARNING) << "Wrong requested frame rate."; | 264 DLOG(WARNING) << "Wrong requested frame rate."; |
264 return media::VideoCaptureFormats(); | 265 return media::VideoCaptureFormats(); |
265 } | 266 } |
266 } | 267 } |
267 | 268 |
268 blink::WebVector<blink::WebMediaConstraint> mandatory; | 269 blink::WebVector<blink::WebMediaConstraint> mandatory; |
269 blink::WebVector<blink::WebMediaConstraint> optional; | 270 blink::WebVector<blink::WebMediaConstraint> optional; |
270 constraints.getMandatoryConstraints(mandatory); | 271 constraints.getMandatoryConstraints(mandatory); |
271 constraints.getOptionalConstraints(optional); | 272 constraints.getOptionalConstraints(optional); |
272 media::VideoCaptureFormats candidates = supported_formats; | 273 media::VideoCaptureFormats candidates = supported_formats; |
273 for (size_t i = 0; i < mandatory.size(); ++i) | 274 for (size_t i = 0; i < mandatory.size(); ++i) { |
274 FilterFormatsByConstraint(mandatory[i], true, &candidates); | 275 FilterFormatsByConstraint(mandatory[i], true, &candidates); |
| 276 if (candidates.empty()) { |
| 277 *unsatisfied_constraint = mandatory[i].m_name; |
| 278 return candidates; |
| 279 } |
| 280 } |
275 | 281 |
276 if (candidates.empty()) | 282 if (candidates.empty()) |
277 return candidates; | 283 return candidates; |
278 | 284 |
279 // Ok - all mandatory checked and we still have candidates. | 285 // Ok - all mandatory checked and we still have candidates. |
280 // Let's try filtering using the optional constraints. The optional | 286 // Let's try filtering using the optional constraints. The optional |
281 // constraints must be filtered in the order they occur in |optional|. | 287 // constraints must be filtered in the order they occur in |optional|. |
282 // But if a constraint produce zero candidates, the constraint is ignored and | 288 // But if a constraint produce zero candidates, the constraint is ignored and |
283 // the next constraint is tested. | 289 // the next constraint is tested. |
284 // http://dev.w3.org/2011/webrtc/editor/getusermedia.html#idl-def-Constraints | 290 // http://dev.w3.org/2011/webrtc/editor/getusermedia.html#idl-def-Constraints |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
500 const blink::WebMediaConstraints& requested_constraints = | 506 const blink::WebMediaConstraints& requested_constraints = |
501 request_it->constraints; | 507 request_it->constraints; |
502 | 508 |
503 // If the source doesn't support capability enumeration it is still ok if | 509 // If the source doesn't support capability enumeration it is still ok if |
504 // no mandatory constraints have been specified. That just means that | 510 // no mandatory constraints have been specified. That just means that |
505 // we will start with whatever format is native to the source. | 511 // we will start with whatever format is native to the source. |
506 if (formats.empty() && !HasMandatoryConstraints(requested_constraints)) { | 512 if (formats.empty() && !HasMandatoryConstraints(requested_constraints)) { |
507 *best_format = media::VideoCaptureFormat(); | 513 *best_format = media::VideoCaptureFormat(); |
508 return true; | 514 return true; |
509 } | 515 } |
| 516 blink::WebString unsatisfied_constraint; |
510 media::VideoCaptureFormats filtered_formats = | 517 media::VideoCaptureFormats filtered_formats = |
511 FilterFormats(requested_constraints, formats); | 518 FilterFormats(requested_constraints, formats, &unsatisfied_constraint); |
512 if (filtered_formats.size() > 0) { | 519 if (filtered_formats.size() > 0) { |
513 // A request with constraints that can be fulfilled. | 520 // A request with constraints that can be fulfilled. |
514 GetBestCaptureFormat(filtered_formats, | 521 GetBestCaptureFormat(filtered_formats, |
515 requested_constraints, | 522 requested_constraints, |
516 best_format); | 523 best_format); |
517 return true; | 524 return true; |
518 } | 525 } |
519 } | 526 } |
520 return false; | 527 return false; |
521 } | 528 } |
522 | 529 |
523 void MediaStreamVideoSource::OnStartDone(bool success) { | 530 void MediaStreamVideoSource::OnStartDone(MediaStreamRequestResult result) { |
524 DCHECK(CalledOnValidThread()); | 531 DCHECK(CalledOnValidThread()); |
525 DVLOG(3) << "OnStartDone({success =" << success << "})"; | 532 DVLOG(3) << "OnStartDone({result =" << result << "})"; |
526 if (success) { | 533 if (result == MEDIA_DEVICE_OK) { |
527 DCHECK_EQ(STARTING, state_); | 534 DCHECK_EQ(STARTING, state_); |
528 state_ = STARTED; | 535 state_ = STARTED; |
529 SetReadyState(blink::WebMediaStreamSource::ReadyStateLive); | 536 SetReadyState(blink::WebMediaStreamSource::ReadyStateLive); |
530 } else { | 537 } else { |
531 StopSource(); | 538 StopSource(); |
532 } | 539 } |
533 | 540 |
534 // This object can be deleted after calling FinalizeAddTrack. See comment in | 541 // This object can be deleted after calling FinalizeAddTrack. See comment in |
535 // the header file. | 542 // the header file. |
536 FinalizeAddTrack(); | 543 FinalizeAddTrack(); |
537 } | 544 } |
538 | 545 |
539 void MediaStreamVideoSource::FinalizeAddTrack() { | 546 void MediaStreamVideoSource::FinalizeAddTrack() { |
540 DCHECK(CalledOnValidThread()); | 547 DCHECK(CalledOnValidThread()); |
541 media::VideoCaptureFormats formats; | 548 media::VideoCaptureFormats formats; |
542 formats.push_back(current_format_); | 549 formats.push_back(current_format_); |
543 | 550 |
544 std::vector<RequestedConstraints> callbacks; | 551 std::vector<RequestedConstraints> callbacks; |
545 callbacks.swap(requested_constraints_); | 552 callbacks.swap(requested_constraints_); |
546 for (std::vector<RequestedConstraints>::iterator it = callbacks.begin(); | 553 for (std::vector<RequestedConstraints>::iterator it = callbacks.begin(); |
547 it != callbacks.end(); ++it) { | 554 it != callbacks.end(); ++it) { |
548 // The track has been added successfully if the source has started and | 555 MediaStreamRequestResult result = MEDIA_DEVICE_OK; |
549 // there are either no mandatory constraints and the source doesn't expose | 556 blink::WebString unsatisfied_constraint; |
550 // its format capabilities, or the constraints and the format match. | |
551 // For example, a remote source doesn't expose its format capabilities. | |
552 bool success = | |
553 state_ == STARTED && | |
554 ((!current_format_.IsValid() && !HasMandatoryConstraints( | |
555 it->constraints)) || | |
556 !FilterFormats(it->constraints, formats).empty()); | |
557 | 557 |
558 if (success) { | 558 if (HasMandatoryConstraints(it->constraints) && |
| 559 FilterFormats(it->constraints, formats, |
| 560 &unsatisfied_constraint).empty()) |
| 561 result = MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED; |
| 562 |
| 563 if (state_ != STARTED && result == MEDIA_DEVICE_OK) |
| 564 result = MEDIA_DEVICE_TRACK_START_FAILURE; |
| 565 |
| 566 if (result == MEDIA_DEVICE_OK) { |
559 int max_width; | 567 int max_width; |
560 int max_height; | 568 int max_height; |
561 GetDesiredMaxWidthAndHeight(it->constraints, &max_width, &max_height); | 569 GetDesiredMaxWidthAndHeight(it->constraints, &max_width, &max_height); |
562 double max_aspect_ratio; | 570 double max_aspect_ratio; |
563 double min_aspect_ratio; | 571 double min_aspect_ratio; |
564 GetDesiredMinAndMaxAspectRatio(it->constraints, | 572 GetDesiredMinAndMaxAspectRatio(it->constraints, |
565 &min_aspect_ratio, | 573 &min_aspect_ratio, |
566 &max_aspect_ratio); | 574 &max_aspect_ratio); |
567 double max_frame_rate = 0.0f; | 575 double max_frame_rate = 0.0f; |
568 GetConstraintValueAsDouble(it->constraints, | 576 GetConstraintValueAsDouble(it->constraints, |
569 kMaxFrameRate, &max_frame_rate); | 577 kMaxFrameRate, &max_frame_rate); |
570 | 578 |
571 VideoTrackAdapter::OnMutedCallback on_mute_callback = | 579 VideoTrackAdapter::OnMutedCallback on_mute_callback = |
572 media::BindToCurrentLoop(base::Bind( | 580 media::BindToCurrentLoop(base::Bind( |
573 &MediaStreamVideoSource::SetMutedState, | 581 &MediaStreamVideoSource::SetMutedState, |
574 weak_factory_.GetWeakPtr())); | 582 weak_factory_.GetWeakPtr())); |
575 track_adapter_->AddTrack(it->track, it->frame_callback, | 583 track_adapter_->AddTrack(it->track, it->frame_callback, |
576 max_width, max_height, | 584 max_width, max_height, |
577 min_aspect_ratio, max_aspect_ratio, | 585 min_aspect_ratio, max_aspect_ratio, |
578 max_frame_rate, current_format_.frame_rate, | 586 max_frame_rate, current_format_.frame_rate, |
579 on_mute_callback); | 587 on_mute_callback); |
580 } | 588 } |
581 | 589 |
582 DVLOG(3) << "FinalizeAddTrack() success " << success; | 590 DVLOG(3) << "FinalizeAddTrack() result " << result; |
583 | 591 |
584 if (!it->callback.is_null()) | 592 if (!it->callback.is_null()) { |
585 it->callback.Run(this, success); | 593 it->callback.Run(this, result, unsatisfied_constraint); |
| 594 } |
586 } | 595 } |
587 } | 596 } |
588 | 597 |
589 void MediaStreamVideoSource::SetReadyState( | 598 void MediaStreamVideoSource::SetReadyState( |
590 blink::WebMediaStreamSource::ReadyState state) { | 599 blink::WebMediaStreamSource::ReadyState state) { |
591 DVLOG(3) << "MediaStreamVideoSource::SetReadyState state " << state; | 600 DVLOG(3) << "MediaStreamVideoSource::SetReadyState state " << state; |
592 DCHECK(CalledOnValidThread()); | 601 DCHECK(CalledOnValidThread()); |
593 if (!owner().isNull()) { | 602 if (!owner().isNull()) { |
594 owner().setReadyState(state); | 603 owner().setReadyState(state); |
595 } | 604 } |
(...skipping 21 matching lines...) Expand all Loading... |
617 : track(track), | 626 : track(track), |
618 frame_callback(frame_callback), | 627 frame_callback(frame_callback), |
619 constraints(constraints), | 628 constraints(constraints), |
620 callback(callback) { | 629 callback(callback) { |
621 } | 630 } |
622 | 631 |
623 MediaStreamVideoSource::RequestedConstraints::~RequestedConstraints() { | 632 MediaStreamVideoSource::RequestedConstraints::~RequestedConstraints() { |
624 } | 633 } |
625 | 634 |
626 } // namespace content | 635 } // namespace content |
OLD | NEW |