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); |
275 | 276 // Here we record the name of constraint that causes |
miu
2014/07/30 19:37:23
This comment is stating the obvious, so you should
jiajia.qin
2014/07/31 13:43:01
Done.
| |
276 if (candidates.empty()) | 277 // the ConstraintNotSatisfiedError |
277 return candidates; | 278 if (candidates.empty()) { |
279 *unsatisfied_constraint = mandatory[i].m_name; | |
280 return candidates; | |
miu
2014/07/30 19:37:23
Sanity-check: With this change, you're now abortin
jiajia.qin
2014/07/31 13:43:01
Yes, I am sure. According to the spec, 'Constraint
| |
281 } | |
282 } | |
278 | 283 |
279 // Ok - all mandatory checked and we still have candidates. | 284 // Ok - all mandatory checked and we still have candidates. |
280 // Let's try filtering using the optional constraints. The optional | 285 // Let's try filtering using the optional constraints. The optional |
281 // constraints must be filtered in the order they occur in |optional|. | 286 // constraints must be filtered in the order they occur in |optional|. |
282 // But if a constraint produce zero candidates, the constraint is ignored and | 287 // But if a constraint produce zero candidates, the constraint is ignored and |
283 // the next constraint is tested. | 288 // the next constraint is tested. |
284 // http://dev.w3.org/2011/webrtc/editor/getusermedia.html#idl-def-Constraints | 289 // http://dev.w3.org/2011/webrtc/editor/getusermedia.html#idl-def-Constraints |
285 for (size_t i = 0; i < optional.size(); ++i) { | 290 for (size_t i = 0; i < optional.size(); ++i) { |
286 media::VideoCaptureFormats current_candidates = candidates; | 291 media::VideoCaptureFormats current_candidates = candidates; |
287 FilterFormatsByConstraint(optional[i], false, ¤t_candidates); | 292 FilterFormatsByConstraint(optional[i], false, ¤t_candidates); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
398 } | 403 } |
399 case STARTING: | 404 case STARTING: |
400 case RETRIEVING_CAPABILITIES: { | 405 case RETRIEVING_CAPABILITIES: { |
401 // The |callback| will be triggered once the source has started or | 406 // The |callback| will be triggered once the source has started or |
402 // the capabilities have been retrieved. | 407 // the capabilities have been retrieved. |
403 break; | 408 break; |
404 } | 409 } |
405 case ENDED: | 410 case ENDED: |
406 case STARTED: { | 411 case STARTED: { |
407 // Currently, reconfiguring the source is not supported. | 412 // Currently, reconfiguring the source is not supported. |
408 FinalizeAddTrack(); | 413 FinalizeAddTrack(MEDIA_DEVICE_OK); |
409 } | 414 } |
410 } | 415 } |
411 } | 416 } |
412 | 417 |
413 void MediaStreamVideoSource::RemoveTrack(MediaStreamVideoTrack* video_track) { | 418 void MediaStreamVideoSource::RemoveTrack(MediaStreamVideoTrack* video_track) { |
414 DCHECK(CalledOnValidThread()); | 419 DCHECK(CalledOnValidThread()); |
415 std::vector<MediaStreamVideoTrack*>::iterator it = | 420 std::vector<MediaStreamVideoTrack*>::iterator it = |
416 std::find(tracks_.begin(), tracks_.end(), video_track); | 421 std::find(tracks_.begin(), tracks_.end(), video_track); |
417 DCHECK(it != tracks_.end()); | 422 DCHECK(it != tracks_.end()); |
418 tracks_.erase(it); | 423 tracks_.erase(it); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
455 const media::VideoCaptureFormats& formats) { | 460 const media::VideoCaptureFormats& formats) { |
456 DCHECK(CalledOnValidThread()); | 461 DCHECK(CalledOnValidThread()); |
457 DCHECK_EQ(RETRIEVING_CAPABILITIES, state_); | 462 DCHECK_EQ(RETRIEVING_CAPABILITIES, state_); |
458 | 463 |
459 supported_formats_ = formats; | 464 supported_formats_ = formats; |
460 if (!FindBestFormatWithConstraints(supported_formats_, | 465 if (!FindBestFormatWithConstraints(supported_formats_, |
461 ¤t_format_)) { | 466 ¤t_format_)) { |
462 SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded); | 467 SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded); |
463 // This object can be deleted after calling FinalizeAddTrack. See comment | 468 // This object can be deleted after calling FinalizeAddTrack. See comment |
464 // in the header file. | 469 // in the header file. |
465 FinalizeAddTrack(); | 470 FinalizeAddTrack(MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED); |
miu
2014/07/30 19:37:23
re: My comment in the .h file:
The call to FindBe
jiajia.qin
2014/07/31 13:43:01
Done.
| |
466 return; | 471 return; |
467 } | 472 } |
468 | 473 |
469 state_ = STARTING; | 474 state_ = STARTING; |
470 DVLOG(3) << "Starting the capturer with" | 475 DVLOG(3) << "Starting the capturer with" |
471 << " width = " << current_format_.frame_size.width() | 476 << " width = " << current_format_.frame_size.width() |
472 << " height = " << current_format_.frame_size.height() | 477 << " height = " << current_format_.frame_size.height() |
473 << " frame rate = " << current_format_.frame_rate | 478 << " frame rate = " << current_format_.frame_rate |
474 << " pixel format = " | 479 << " pixel format = " |
475 << media::VideoCaptureFormat::PixelFormatToString( | 480 << media::VideoCaptureFormat::PixelFormatToString( |
(...skipping 18 matching lines...) Expand all Loading... | |
494 request_it->constraints; | 499 request_it->constraints; |
495 | 500 |
496 // If the source doesn't support capability enumeration it is still ok if | 501 // If the source doesn't support capability enumeration it is still ok if |
497 // no mandatory constraints have been specified. That just means that | 502 // no mandatory constraints have been specified. That just means that |
498 // we will start with whatever format is native to the source. | 503 // we will start with whatever format is native to the source. |
499 if (formats.empty() && !HasMandatoryConstraints(requested_constraints)) { | 504 if (formats.empty() && !HasMandatoryConstraints(requested_constraints)) { |
500 *best_format = media::VideoCaptureFormat(); | 505 *best_format = media::VideoCaptureFormat(); |
501 return true; | 506 return true; |
502 } | 507 } |
503 media::VideoCaptureFormats filtered_formats = | 508 media::VideoCaptureFormats filtered_formats = |
504 FilterFormats(requested_constraints, formats); | 509 FilterFormats(requested_constraints, formats, &unsatisfied_constraint_); |
505 if (filtered_formats.size() > 0) { | 510 if (filtered_formats.size() > 0) { |
506 // A request with constraints that can be fulfilled. | 511 // A request with constraints that can be fulfilled. |
507 GetBestCaptureFormat(filtered_formats, | 512 GetBestCaptureFormat(filtered_formats, |
508 requested_constraints, | 513 requested_constraints, |
509 best_format); | 514 best_format); |
510 return true; | 515 return true; |
511 } | 516 } |
512 } | 517 } |
513 return false; | 518 return false; |
514 } | 519 } |
515 | 520 |
516 void MediaStreamVideoSource::OnStartDone(bool success) { | 521 void MediaStreamVideoSource::OnStartDone(MediaStreamRequestResult result) { |
517 DCHECK(CalledOnValidThread()); | 522 DCHECK(CalledOnValidThread()); |
518 DVLOG(3) << "OnStartDone({success =" << success << "})"; | 523 DVLOG(3) << "OnStartDone({result =" << result << "})"; |
519 if (success) { | 524 if (result == MEDIA_DEVICE_OK) { |
520 DCHECK_EQ(STARTING, state_); | 525 DCHECK_EQ(STARTING, state_); |
521 state_ = STARTED; | 526 state_ = STARTED; |
522 SetReadyState(blink::WebMediaStreamSource::ReadyStateLive); | 527 SetReadyState(blink::WebMediaStreamSource::ReadyStateLive); |
523 } else { | 528 } else { |
524 StopSource(); | 529 StopSource(); |
525 } | 530 } |
526 | 531 |
527 // This object can be deleted after calling FinalizeAddTrack. See comment in | 532 // This object can be deleted after calling FinalizeAddTrack. See comment in |
528 // the header file. | 533 // the header file. |
529 FinalizeAddTrack(); | 534 FinalizeAddTrack(result); |
530 } | 535 } |
531 | 536 |
532 void MediaStreamVideoSource::FinalizeAddTrack() { | 537 void MediaStreamVideoSource::FinalizeAddTrack(MediaStreamRequestResult result) { |
533 DCHECK(CalledOnValidThread()); | 538 DCHECK(CalledOnValidThread()); |
534 media::VideoCaptureFormats formats; | 539 media::VideoCaptureFormats formats; |
535 formats.push_back(current_format_); | 540 formats.push_back(current_format_); |
536 | 541 |
537 std::vector<RequestedConstraints> callbacks; | 542 std::vector<RequestedConstraints> callbacks; |
538 callbacks.swap(requested_constraints_); | 543 callbacks.swap(requested_constraints_); |
539 for (std::vector<RequestedConstraints>::iterator it = callbacks.begin(); | 544 for (std::vector<RequestedConstraints>::iterator it = callbacks.begin(); |
540 it != callbacks.end(); ++it) { | 545 it != callbacks.end(); ++it) { |
541 // The track has been added successfully if the source has started and | 546 if (result == MEDIA_DEVICE_OK) { |
542 // there are either no mandatory constraints and the source doesn't expose | |
543 // its format capabilities, or the constraints and the format match. | |
544 // For example, a remote source doesn't expose its format capabilities. | |
545 bool success = | |
546 state_ == STARTED && | |
547 ((!current_format_.IsValid() && !HasMandatoryConstraints( | |
548 it->constraints)) || | |
549 !FilterFormats(it->constraints, formats).empty()); | |
550 | |
551 if (success) { | |
552 int max_width; | 547 int max_width; |
553 int max_height; | 548 int max_height; |
554 GetDesiredMaxWidthAndHeight(it->constraints, &max_width, &max_height); | 549 GetDesiredMaxWidthAndHeight(it->constraints, &max_width, &max_height); |
555 double max_aspect_ratio; | 550 double max_aspect_ratio; |
556 double min_aspect_ratio; | 551 double min_aspect_ratio; |
557 GetDesiredMinAndMaxAspectRatio(it->constraints, | 552 GetDesiredMinAndMaxAspectRatio(it->constraints, |
558 &min_aspect_ratio, | 553 &min_aspect_ratio, |
559 &max_aspect_ratio); | 554 &max_aspect_ratio); |
560 double max_frame_rate = 0.0f; | 555 double max_frame_rate = 0.0f; |
561 GetConstraintValueAsDouble(it->constraints, | 556 GetConstraintValueAsDouble(it->constraints, |
562 kMaxFrameRate, &max_frame_rate); | 557 kMaxFrameRate, &max_frame_rate); |
563 | 558 |
564 VideoTrackAdapter::OnMutedCallback on_mute_callback = | 559 VideoTrackAdapter::OnMutedCallback on_mute_callback = |
565 media::BindToCurrentLoop(base::Bind( | 560 media::BindToCurrentLoop(base::Bind( |
566 &MediaStreamVideoSource::SetMutedState, | 561 &MediaStreamVideoSource::SetMutedState, |
567 weak_factory_.GetWeakPtr())); | 562 weak_factory_.GetWeakPtr())); |
568 track_adapter_->AddTrack(it->track, it->frame_callback, | 563 track_adapter_->AddTrack(it->track, it->frame_callback, |
569 max_width, max_height, | 564 max_width, max_height, |
570 min_aspect_ratio, max_aspect_ratio, | 565 min_aspect_ratio, max_aspect_ratio, |
571 max_frame_rate, current_format_.frame_rate, | 566 max_frame_rate, current_format_.frame_rate, |
572 on_mute_callback); | 567 on_mute_callback); |
573 } | 568 } |
574 | 569 |
575 DVLOG(3) << "FinalizeAddTrack() success " << success; | 570 DVLOG(3) << "FinalizeAddTrack() result " << result; |
576 | 571 |
577 if (!it->callback.is_null()) | 572 if (!it->callback.is_null()) |
578 it->callback.Run(this, success); | 573 it->callback.Run(this, result, unsatisfied_constraint_); |
579 } | 574 } |
580 } | 575 } |
581 | 576 |
582 void MediaStreamVideoSource::SetReadyState( | 577 void MediaStreamVideoSource::SetReadyState( |
583 blink::WebMediaStreamSource::ReadyState state) { | 578 blink::WebMediaStreamSource::ReadyState state) { |
584 DVLOG(3) << "MediaStreamVideoSource::SetReadyState state " << state; | 579 DVLOG(3) << "MediaStreamVideoSource::SetReadyState state " << state; |
585 DCHECK(CalledOnValidThread()); | 580 DCHECK(CalledOnValidThread()); |
586 if (!owner().isNull()) { | 581 if (!owner().isNull()) { |
587 owner().setReadyState(state); | 582 owner().setReadyState(state); |
588 } | 583 } |
(...skipping 21 matching lines...) Expand all Loading... | |
610 : track(track), | 605 : track(track), |
611 frame_callback(frame_callback), | 606 frame_callback(frame_callback), |
612 constraints(constraints), | 607 constraints(constraints), |
613 callback(callback) { | 608 callback(callback) { |
614 } | 609 } |
615 | 610 |
616 MediaStreamVideoSource::RequestedConstraints::~RequestedConstraints() { | 611 MediaStreamVideoSource::RequestedConstraints::~RequestedConstraints() { |
617 } | 612 } |
618 | 613 |
619 } // namespace content | 614 } // namespace content |
OLD | NEW |