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

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

Issue 391703002: Implement ConstraintNotSatisfiedError for getusermedia (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 4 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_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
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
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 if (candidates.empty()) {
276 if (candidates.empty()) 277 *unsatisfied_constraint = mandatory[i].m_name;
277 return candidates; 278 return candidates;
279 }
280 }
278 281
279 // Ok - all mandatory checked and we still have candidates. 282 // Ok - all mandatory checked and we still have candidates.
280 // Let's try filtering using the optional constraints. The optional 283 // Let's try filtering using the optional constraints. The optional
281 // constraints must be filtered in the order they occur in |optional|. 284 // constraints must be filtered in the order they occur in |optional|.
282 // But if a constraint produce zero candidates, the constraint is ignored and 285 // But if a constraint produce zero candidates, the constraint is ignored and
283 // the next constraint is tested. 286 // the next constraint is tested.
284 // http://dev.w3.org/2011/webrtc/editor/getusermedia.html#idl-def-Constraints 287 // http://dev.w3.org/2011/webrtc/editor/getusermedia.html#idl-def-Constraints
285 for (size_t i = 0; i < optional.size(); ++i) { 288 for (size_t i = 0; i < optional.size(); ++i) {
286 media::VideoCaptureFormats current_candidates = candidates; 289 media::VideoCaptureFormats current_candidates = candidates;
287 FilterFormatsByConstraint(optional[i], false, &current_candidates); 290 FilterFormatsByConstraint(optional[i], false, &current_candidates);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 } 401 }
399 case STARTING: 402 case STARTING:
400 case RETRIEVING_CAPABILITIES: { 403 case RETRIEVING_CAPABILITIES: {
401 // The |callback| will be triggered once the source has started or 404 // The |callback| will be triggered once the source has started or
402 // the capabilities have been retrieved. 405 // the capabilities have been retrieved.
403 break; 406 break;
404 } 407 }
405 case ENDED: 408 case ENDED:
406 case STARTED: { 409 case STARTED: {
407 // Currently, reconfiguring the source is not supported. 410 // Currently, reconfiguring the source is not supported.
408 FinalizeAddTrack(); 411 FinalizeAddTrack(MEDIA_DEVICE_OK, "");
409 } 412 }
410 } 413 }
411 } 414 }
412 415
413 void MediaStreamVideoSource::RemoveTrack(MediaStreamVideoTrack* video_track) { 416 void MediaStreamVideoSource::RemoveTrack(MediaStreamVideoTrack* video_track) {
414 DCHECK(CalledOnValidThread()); 417 DCHECK(CalledOnValidThread());
415 std::vector<MediaStreamVideoTrack*>::iterator it = 418 std::vector<MediaStreamVideoTrack*>::iterator it =
416 std::find(tracks_.begin(), tracks_.end(), video_track); 419 std::find(tracks_.begin(), tracks_.end(), video_track);
417 DCHECK(it != tracks_.end()); 420 DCHECK(it != tracks_.end());
418 tracks_.erase(it); 421 tracks_.erase(it);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 state_ = ENDED; 453 state_ = ENDED;
451 SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded); 454 SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded);
452 } 455 }
453 456
454 void MediaStreamVideoSource::OnSupportedFormats( 457 void MediaStreamVideoSource::OnSupportedFormats(
455 const media::VideoCaptureFormats& formats) { 458 const media::VideoCaptureFormats& formats) {
456 DCHECK(CalledOnValidThread()); 459 DCHECK(CalledOnValidThread());
457 DCHECK_EQ(RETRIEVING_CAPABILITIES, state_); 460 DCHECK_EQ(RETRIEVING_CAPABILITIES, state_);
458 461
459 supported_formats_ = formats; 462 supported_formats_ = formats;
463 blink::WebString unsatisfied_constraint;
460 if (!FindBestFormatWithConstraints(supported_formats_, 464 if (!FindBestFormatWithConstraints(supported_formats_,
461 &current_format_)) { 465 &current_format_,
466 &unsatisfied_constraint)) {
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,
471 unsatisfied_constraint);
466 return; 472 return;
467 } 473 }
468 474
469 state_ = STARTING; 475 state_ = STARTING;
470 DVLOG(3) << "Starting the capturer with" 476 DVLOG(3) << "Starting the capturer with"
471 << " width = " << current_format_.frame_size.width() 477 << " width = " << current_format_.frame_size.width()
472 << " height = " << current_format_.frame_size.height() 478 << " height = " << current_format_.frame_size.height()
473 << " frame rate = " << current_format_.frame_rate 479 << " frame rate = " << current_format_.frame_rate
474 << " pixel format = " 480 << " pixel format = "
475 << media::VideoCaptureFormat::PixelFormatToString( 481 << media::VideoCaptureFormat::PixelFormatToString(
476 current_format_.pixel_format); 482 current_format_.pixel_format);
477 483
478 media::VideoCaptureParams params; 484 media::VideoCaptureParams params;
479 params.requested_format = current_format_; 485 params.requested_format = current_format_;
480 StartSourceImpl( 486 StartSourceImpl(
481 params, 487 params,
482 base::Bind(&VideoTrackAdapter::DeliverFrameOnIO, track_adapter_)); 488 base::Bind(&VideoTrackAdapter::DeliverFrameOnIO, track_adapter_));
483 } 489 }
484 490
485 bool MediaStreamVideoSource::FindBestFormatWithConstraints( 491 bool MediaStreamVideoSource::FindBestFormatWithConstraints(
486 const media::VideoCaptureFormats& formats, 492 const media::VideoCaptureFormats& formats,
487 media::VideoCaptureFormat* best_format) { 493 media::VideoCaptureFormat* best_format,
494 blink::WebString* unsatisfied_constraint) {
488 DCHECK(CalledOnValidThread()); 495 DCHECK(CalledOnValidThread());
489 // Find the first constraints that we can fulfill. 496 // Find the first constraints that we can fulfill.
490 for (std::vector<RequestedConstraints>::iterator request_it = 497 for (std::vector<RequestedConstraints>::iterator request_it =
491 requested_constraints_.begin(); 498 requested_constraints_.begin();
492 request_it != requested_constraints_.end(); ++request_it) { 499 request_it != requested_constraints_.end(); ++request_it) {
493 const blink::WebMediaConstraints& requested_constraints = 500 const blink::WebMediaConstraints& requested_constraints =
494 request_it->constraints; 501 request_it->constraints;
495 502
496 // If the source doesn't support capability enumeration it is still ok if 503 // If the source doesn't support capability enumeration it is still ok if
497 // no mandatory constraints have been specified. That just means that 504 // no mandatory constraints have been specified. That just means that
498 // we will start with whatever format is native to the source. 505 // we will start with whatever format is native to the source.
499 if (formats.empty() && !HasMandatoryConstraints(requested_constraints)) { 506 if (formats.empty() && !HasMandatoryConstraints(requested_constraints)) {
500 *best_format = media::VideoCaptureFormat(); 507 *best_format = media::VideoCaptureFormat();
501 return true; 508 return true;
502 } 509 }
503 media::VideoCaptureFormats filtered_formats = 510 media::VideoCaptureFormats filtered_formats =
504 FilterFormats(requested_constraints, formats); 511 FilterFormats(requested_constraints, formats, unsatisfied_constraint);
505 if (filtered_formats.size() > 0) { 512 if (filtered_formats.size() > 0) {
506 // A request with constraints that can be fulfilled. 513 // A request with constraints that can be fulfilled.
507 GetBestCaptureFormat(filtered_formats, 514 GetBestCaptureFormat(filtered_formats,
508 requested_constraints, 515 requested_constraints,
509 best_format); 516 best_format);
510 return true; 517 return true;
511 } 518 }
512 } 519 }
513 return false; 520 return false;
514 } 521 }
515 522
516 void MediaStreamVideoSource::OnStartDone(bool success) { 523 void MediaStreamVideoSource::OnStartDone(MediaStreamRequestResult result) {
517 DCHECK(CalledOnValidThread()); 524 DCHECK(CalledOnValidThread());
518 DVLOG(3) << "OnStartDone({success =" << success << "})"; 525 DVLOG(3) << "OnStartDone({result =" << result << "})";
519 if (success) { 526 if (result == MEDIA_DEVICE_OK) {
520 DCHECK_EQ(STARTING, state_); 527 DCHECK_EQ(STARTING, state_);
521 state_ = STARTED; 528 state_ = STARTED;
522 SetReadyState(blink::WebMediaStreamSource::ReadyStateLive); 529 SetReadyState(blink::WebMediaStreamSource::ReadyStateLive);
523 } else { 530 } else {
524 StopSource(); 531 StopSource();
525 } 532 }
526 533
527 // This object can be deleted after calling FinalizeAddTrack. See comment in 534 // This object can be deleted after calling FinalizeAddTrack. See comment in
528 // the header file. 535 // the header file.
529 FinalizeAddTrack(); 536 FinalizeAddTrack(result, "");
530 } 537 }
531 538
532 void MediaStreamVideoSource::FinalizeAddTrack() { 539 void MediaStreamVideoSource::FinalizeAddTrack(
540 MediaStreamRequestResult result,
541 const blink::WebString& result_name) {
533 DCHECK(CalledOnValidThread()); 542 DCHECK(CalledOnValidThread());
534 media::VideoCaptureFormats formats; 543 media::VideoCaptureFormats formats;
535 formats.push_back(current_format_); 544 formats.push_back(current_format_);
536 545
537 std::vector<RequestedConstraints> callbacks; 546 std::vector<RequestedConstraints> callbacks;
538 callbacks.swap(requested_constraints_); 547 callbacks.swap(requested_constraints_);
539 for (std::vector<RequestedConstraints>::iterator it = callbacks.begin(); 548 for (std::vector<RequestedConstraints>::iterator it = callbacks.begin();
540 it != callbacks.end(); ++it) { 549 it != callbacks.end(); ++it) {
541 // The track has been added successfully if the source has started and 550 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; 551 int max_width;
553 int max_height; 552 int max_height;
554 GetDesiredMaxWidthAndHeight(it->constraints, &max_width, &max_height); 553 GetDesiredMaxWidthAndHeight(it->constraints, &max_width, &max_height);
555 double max_aspect_ratio; 554 double max_aspect_ratio;
556 double min_aspect_ratio; 555 double min_aspect_ratio;
557 GetDesiredMinAndMaxAspectRatio(it->constraints, 556 GetDesiredMinAndMaxAspectRatio(it->constraints,
558 &min_aspect_ratio, 557 &min_aspect_ratio,
559 &max_aspect_ratio); 558 &max_aspect_ratio);
560 double max_frame_rate = 0.0f; 559 double max_frame_rate = 0.0f;
561 GetConstraintValueAsDouble(it->constraints, 560 GetConstraintValueAsDouble(it->constraints,
562 kMaxFrameRate, &max_frame_rate); 561 kMaxFrameRate, &max_frame_rate);
563 562
564 VideoTrackAdapter::OnMutedCallback on_mute_callback = 563 VideoTrackAdapter::OnMutedCallback on_mute_callback =
565 media::BindToCurrentLoop(base::Bind( 564 media::BindToCurrentLoop(base::Bind(
566 &MediaStreamVideoSource::SetMutedState, 565 &MediaStreamVideoSource::SetMutedState,
567 weak_factory_.GetWeakPtr())); 566 weak_factory_.GetWeakPtr()));
568 track_adapter_->AddTrack(it->track, it->frame_callback, 567 track_adapter_->AddTrack(it->track, it->frame_callback,
569 max_width, max_height, 568 max_width, max_height,
570 min_aspect_ratio, max_aspect_ratio, 569 min_aspect_ratio, max_aspect_ratio,
571 max_frame_rate, current_format_.frame_rate, 570 max_frame_rate, current_format_.frame_rate,
572 on_mute_callback); 571 on_mute_callback);
573 } 572 }
574 573
575 DVLOG(3) << "FinalizeAddTrack() success " << success; 574 DVLOG(3) << "FinalizeAddTrack() result " << result;
576 575
577 if (!it->callback.is_null()) 576 if (!it->callback.is_null())
578 it->callback.Run(this, success); 577 it->callback.Run(this, result, result_name);
579 } 578 }
580 } 579 }
581 580
582 void MediaStreamVideoSource::SetReadyState( 581 void MediaStreamVideoSource::SetReadyState(
583 blink::WebMediaStreamSource::ReadyState state) { 582 blink::WebMediaStreamSource::ReadyState state) {
584 DVLOG(3) << "MediaStreamVideoSource::SetReadyState state " << state; 583 DVLOG(3) << "MediaStreamVideoSource::SetReadyState state " << state;
585 DCHECK(CalledOnValidThread()); 584 DCHECK(CalledOnValidThread());
586 if (!owner().isNull()) { 585 if (!owner().isNull()) {
587 owner().setReadyState(state); 586 owner().setReadyState(state);
588 } 587 }
(...skipping 21 matching lines...) Expand all
610 : track(track), 609 : track(track),
611 frame_callback(frame_callback), 610 frame_callback(frame_callback),
612 constraints(constraints), 611 constraints(constraints),
613 callback(callback) { 612 callback(callback) {
614 } 613 }
615 614
616 MediaStreamVideoSource::RequestedConstraints::~RequestedConstraints() { 615 MediaStreamVideoSource::RequestedConstraints::~RequestedConstraints() {
617 } 616 }
618 617
619 } // namespace content 618 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698