Chromium Code Reviews| 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 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 212 format_it = formats->erase(format_it); | 212 format_it = formats->erase(format_it); |
| 213 } else { | 213 } else { |
| 214 ++format_it; | 214 ++format_it; |
| 215 } | 215 } |
| 216 } | 216 } |
| 217 } | 217 } |
| 218 | 218 |
| 219 // Returns the media::VideoCaptureFormats that matches |constraints|. | 219 // Returns the media::VideoCaptureFormats that matches |constraints|. |
| 220 media::VideoCaptureFormats FilterFormats( | 220 media::VideoCaptureFormats FilterFormats( |
| 221 const blink::WebMediaConstraints& constraints, | 221 const blink::WebMediaConstraints& constraints, |
| 222 const media::VideoCaptureFormats& supported_formats) { | 222 const media::VideoCaptureFormats& supported_formats, |
| 223 blink::WebString* constraintName) { | |
|
no longer working on chromium
2014/07/28 19:55:08
constraint_name or unsatisfied_constraint
jiajia.qin
2014/07/30 05:18:07
Done.
| |
| 223 if (constraints.isNull()) { | 224 if (constraints.isNull()) { |
| 224 return supported_formats; | 225 return supported_formats; |
| 225 } | 226 } |
| 226 | 227 |
| 227 double max_aspect_ratio; | 228 double max_aspect_ratio; |
| 228 double min_aspect_ratio; | 229 double min_aspect_ratio; |
| 229 GetDesiredMinAndMaxAspectRatio(constraints, | 230 GetDesiredMinAndMaxAspectRatio(constraints, |
| 230 &min_aspect_ratio, | 231 &min_aspect_ratio, |
| 231 &max_aspect_ratio); | 232 &max_aspect_ratio); |
| 232 | 233 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 248 GetDesiredMaxWidthAndHeight(constraints, &max_width, &max_height); | 249 GetDesiredMaxWidthAndHeight(constraints, &max_width, &max_height); |
| 249 | 250 |
| 250 if (min_width > max_width || min_height > max_height) | 251 if (min_width > max_width || min_height > max_height) |
| 251 return media::VideoCaptureFormats(); | 252 return media::VideoCaptureFormats(); |
| 252 | 253 |
| 253 blink::WebVector<blink::WebMediaConstraint> mandatory; | 254 blink::WebVector<blink::WebMediaConstraint> mandatory; |
| 254 blink::WebVector<blink::WebMediaConstraint> optional; | 255 blink::WebVector<blink::WebMediaConstraint> optional; |
| 255 constraints.getMandatoryConstraints(mandatory); | 256 constraints.getMandatoryConstraints(mandatory); |
| 256 constraints.getOptionalConstraints(optional); | 257 constraints.getOptionalConstraints(optional); |
| 257 media::VideoCaptureFormats candidates = supported_formats; | 258 media::VideoCaptureFormats candidates = supported_formats; |
| 258 for (size_t i = 0; i < mandatory.size(); ++i) | 259 for (size_t i = 0; i < mandatory.size(); ++i) { |
| 259 FilterFormatsByConstraint(mandatory[i], true, &candidates); | 260 FilterFormatsByConstraint(mandatory[i], true, &candidates); |
| 260 | 261 // Here we record the name of constraint that causes |
| 261 if (candidates.empty()) | 262 // the ConstraintNotSatisfiedError |
| 262 return candidates; | 263 if (candidates.empty()) { |
| 264 *constraintName = mandatory[i].m_name; | |
| 265 return candidates; | |
| 266 } | |
| 267 } | |
| 263 | 268 |
| 264 // Ok - all mandatory checked and we still have candidates. | 269 // Ok - all mandatory checked and we still have candidates. |
| 265 // Let's try filtering using the optional constraints. The optional | 270 // Let's try filtering using the optional constraints. The optional |
| 266 // constraints must be filtered in the order they occur in |optional|. | 271 // constraints must be filtered in the order they occur in |optional|. |
| 267 // But if a constraint produce zero candidates, the constraint is ignored and | 272 // But if a constraint produce zero candidates, the constraint is ignored and |
| 268 // the next constraint is tested. | 273 // the next constraint is tested. |
| 269 // http://dev.w3.org/2011/webrtc/editor/getusermedia.html#idl-def-Constraints | 274 // http://dev.w3.org/2011/webrtc/editor/getusermedia.html#idl-def-Constraints |
| 270 for (size_t i = 0; i < optional.size(); ++i) { | 275 for (size_t i = 0; i < optional.size(); ++i) { |
| 271 media::VideoCaptureFormats current_candidates = candidates; | 276 media::VideoCaptureFormats current_candidates = candidates; |
| 272 FilterFormatsByConstraint(optional[i], false, ¤t_candidates); | 277 FilterFormatsByConstraint(optional[i], false, ¤t_candidates); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 382 } | 387 } |
| 383 case STARTING: | 388 case STARTING: |
| 384 case RETRIEVING_CAPABILITIES: { | 389 case RETRIEVING_CAPABILITIES: { |
| 385 // The |callback| will be triggered once the source has started or | 390 // The |callback| will be triggered once the source has started or |
| 386 // the capabilities have been retrieved. | 391 // the capabilities have been retrieved. |
| 387 break; | 392 break; |
| 388 } | 393 } |
| 389 case ENDED: | 394 case ENDED: |
| 390 case STARTED: { | 395 case STARTED: { |
| 391 // Currently, reconfiguring the source is not supported. | 396 // Currently, reconfiguring the source is not supported. |
| 392 FinalizeAddTrack(); | 397 FinalizeAddTrack(MEDIA_DEVICE_OK); |
| 393 } | 398 } |
| 394 } | 399 } |
| 395 } | 400 } |
| 396 | 401 |
| 397 void MediaStreamVideoSource::RemoveTrack(MediaStreamVideoTrack* video_track) { | 402 void MediaStreamVideoSource::RemoveTrack(MediaStreamVideoTrack* video_track) { |
| 398 DCHECK(CalledOnValidThread()); | 403 DCHECK(CalledOnValidThread()); |
| 399 std::vector<MediaStreamVideoTrack*>::iterator it = | 404 std::vector<MediaStreamVideoTrack*>::iterator it = |
| 400 std::find(tracks_.begin(), tracks_.end(), video_track); | 405 std::find(tracks_.begin(), tracks_.end(), video_track); |
| 401 DCHECK(it != tracks_.end()); | 406 DCHECK(it != tracks_.end()); |
| 402 tracks_.erase(it); | 407 tracks_.erase(it); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 439 const media::VideoCaptureFormats& formats) { | 444 const media::VideoCaptureFormats& formats) { |
| 440 DCHECK(CalledOnValidThread()); | 445 DCHECK(CalledOnValidThread()); |
| 441 DCHECK_EQ(RETRIEVING_CAPABILITIES, state_); | 446 DCHECK_EQ(RETRIEVING_CAPABILITIES, state_); |
| 442 | 447 |
| 443 supported_formats_ = formats; | 448 supported_formats_ = formats; |
| 444 if (!FindBestFormatWithConstraints(supported_formats_, | 449 if (!FindBestFormatWithConstraints(supported_formats_, |
| 445 ¤t_format_)) { | 450 ¤t_format_)) { |
| 446 SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded); | 451 SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded); |
| 447 // This object can be deleted after calling FinalizeAddTrack. See comment | 452 // This object can be deleted after calling FinalizeAddTrack. See comment |
| 448 // in the header file. | 453 // in the header file. |
| 449 FinalizeAddTrack(); | 454 FinalizeAddTrack(MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED); |
| 450 return; | 455 return; |
| 451 } | 456 } |
| 452 | 457 |
| 453 state_ = STARTING; | 458 state_ = STARTING; |
| 454 DVLOG(3) << "Starting the capturer with" | 459 DVLOG(3) << "Starting the capturer with" |
| 455 << " width = " << current_format_.frame_size.width() | 460 << " width = " << current_format_.frame_size.width() |
| 456 << " height = " << current_format_.frame_size.height() | 461 << " height = " << current_format_.frame_size.height() |
| 457 << " frame rate = " << current_format_.frame_rate; | 462 << " frame rate = " << current_format_.frame_rate; |
| 458 | 463 |
| 459 media::VideoCaptureParams params; | 464 media::VideoCaptureParams params; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 474 request_it->constraints; | 479 request_it->constraints; |
| 475 | 480 |
| 476 // If the source doesn't support capability enumeration it is still ok if | 481 // If the source doesn't support capability enumeration it is still ok if |
| 477 // no mandatory constraints have been specified. That just means that | 482 // no mandatory constraints have been specified. That just means that |
| 478 // we will start with whatever format is native to the source. | 483 // we will start with whatever format is native to the source. |
| 479 if (formats.empty() && !HasMandatoryConstraints(requested_constraints)) { | 484 if (formats.empty() && !HasMandatoryConstraints(requested_constraints)) { |
| 480 *best_format = media::VideoCaptureFormat(); | 485 *best_format = media::VideoCaptureFormat(); |
| 481 return true; | 486 return true; |
| 482 } | 487 } |
| 483 media::VideoCaptureFormats filtered_formats = | 488 media::VideoCaptureFormats filtered_formats = |
| 484 FilterFormats(requested_constraints, formats); | 489 FilterFormats(requested_constraints, formats, &constraintName_); |
| 485 if (filtered_formats.size() > 0) { | 490 if (filtered_formats.size() > 0) { |
| 486 // A request with constraints that can be fulfilled. | 491 // A request with constraints that can be fulfilled. |
| 487 GetBestCaptureFormat(filtered_formats, | 492 GetBestCaptureFormat(filtered_formats, |
| 488 requested_constraints, | 493 requested_constraints, |
| 489 best_format); | 494 best_format); |
| 490 return true; | 495 return true; |
| 491 } | 496 } |
| 492 } | 497 } |
| 493 return false; | 498 return false; |
| 494 } | 499 } |
| 495 | 500 |
| 496 void MediaStreamVideoSource::OnStartDone(bool success) { | 501 void MediaStreamVideoSource::OnStartDone( |
| 502 content::MediaStreamRequestResult result) { | |
| 497 DCHECK(CalledOnValidThread()); | 503 DCHECK(CalledOnValidThread()); |
| 498 DVLOG(3) << "OnStartDone({success =" << success << "})"; | 504 DVLOG(3) << "OnStartDone({result =" << result << "})"; |
| 499 if (success) { | 505 if (result == MEDIA_DEVICE_OK) { |
| 500 DCHECK_EQ(STARTING, state_); | 506 DCHECK_EQ(STARTING, state_); |
| 501 state_ = STARTED; | 507 state_ = STARTED; |
| 502 SetReadyState(blink::WebMediaStreamSource::ReadyStateLive); | 508 SetReadyState(blink::WebMediaStreamSource::ReadyStateLive); |
| 503 } else { | 509 } else { |
| 504 state_ = ENDED; | 510 state_ = ENDED; |
| 505 SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded); | 511 SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded); |
| 506 StopSourceImpl(); | 512 StopSourceImpl(); |
| 507 } | 513 } |
| 508 | 514 |
| 509 // This object can be deleted after calling FinalizeAddTrack. See comment in | 515 // This object can be deleted after calling FinalizeAddTrack. See comment in |
| 510 // the header file. | 516 // the header file. |
| 511 FinalizeAddTrack(); | 517 FinalizeAddTrack(result); |
| 512 } | 518 } |
| 513 | 519 |
| 514 void MediaStreamVideoSource::FinalizeAddTrack() { | 520 void MediaStreamVideoSource::FinalizeAddTrack( |
| 521 content::MediaStreamRequestResult result) { | |
| 515 media::VideoCaptureFormats formats; | 522 media::VideoCaptureFormats formats; |
| 516 formats.push_back(current_format_); | 523 formats.push_back(current_format_); |
| 517 | 524 |
| 518 std::vector<RequestedConstraints> callbacks; | 525 std::vector<RequestedConstraints> callbacks; |
| 519 callbacks.swap(requested_constraints_); | 526 callbacks.swap(requested_constraints_); |
| 520 for (std::vector<RequestedConstraints>::iterator it = callbacks.begin(); | 527 for (std::vector<RequestedConstraints>::iterator it = callbacks.begin(); |
| 521 it != callbacks.end(); ++it) { | 528 it != callbacks.end(); ++it) { |
| 522 // The track has been added successfully if the source has started and | 529 if (result == MEDIA_DEVICE_OK) { |
| 523 // there are either no mandatory constraints and the source doesn't expose | |
| 524 // its format capabilities, or the constraints and the format match. | |
| 525 // For example, a remote source doesn't expose its format capabilities. | |
| 526 bool success = | |
| 527 state_ == STARTED && | |
| 528 ((!current_format_.IsValid() && !HasMandatoryConstraints( | |
| 529 it->constraints)) || | |
| 530 !FilterFormats(it->constraints, formats).empty()); | |
| 531 | |
| 532 if (success) { | |
| 533 int max_width; | 530 int max_width; |
| 534 int max_height; | 531 int max_height; |
| 535 GetDesiredMaxWidthAndHeight(it->constraints, &max_width, &max_height); | 532 GetDesiredMaxWidthAndHeight(it->constraints, &max_width, &max_height); |
| 536 double max_aspect_ratio; | 533 double max_aspect_ratio; |
| 537 double min_aspect_ratio; | 534 double min_aspect_ratio; |
| 538 GetDesiredMinAndMaxAspectRatio(it->constraints, | 535 GetDesiredMinAndMaxAspectRatio(it->constraints, |
| 539 &min_aspect_ratio, | 536 &min_aspect_ratio, |
| 540 &max_aspect_ratio); | 537 &max_aspect_ratio); |
| 541 track_adapter_->AddTrack(it->track,it->frame_callback, | 538 track_adapter_->AddTrack(it->track,it->frame_callback, |
| 542 max_width, max_height, | 539 max_width, max_height, |
| 543 min_aspect_ratio, max_aspect_ratio); | 540 min_aspect_ratio, max_aspect_ratio); |
| 544 } | 541 } |
| 545 | 542 |
| 546 DVLOG(3) << "FinalizeAddTrack() success " << success; | 543 DVLOG(3) << "FinalizeAddTrack() result " << result; |
| 547 | 544 |
| 548 if (!it->callback.is_null()) | 545 if (!it->callback.is_null()) |
| 549 it->callback.Run(this, success); | 546 it->callback.Run(this, result, constraintName_); |
| 550 } | 547 } |
| 551 } | 548 } |
| 552 | 549 |
| 553 void MediaStreamVideoSource::SetReadyState( | 550 void MediaStreamVideoSource::SetReadyState( |
| 554 blink::WebMediaStreamSource::ReadyState state) { | 551 blink::WebMediaStreamSource::ReadyState state) { |
| 555 if (!owner().isNull()) { | 552 if (!owner().isNull()) { |
| 556 owner().setReadyState(state); | 553 owner().setReadyState(state); |
| 557 } | 554 } |
| 558 for (std::vector<MediaStreamVideoTrack*>::iterator it = tracks_.begin(); | 555 for (std::vector<MediaStreamVideoTrack*>::iterator it = tracks_.begin(); |
| 559 it != tracks_.end(); ++it) { | 556 it != tracks_.end(); ++it) { |
| 560 (*it)->OnReadyStateChanged(state); | 557 (*it)->OnReadyStateChanged(state); |
| 561 } | 558 } |
| 562 } | 559 } |
| 563 | 560 |
| 564 MediaStreamVideoSource::RequestedConstraints::RequestedConstraints( | 561 MediaStreamVideoSource::RequestedConstraints::RequestedConstraints( |
| 565 MediaStreamVideoTrack* track, | 562 MediaStreamVideoTrack* track, |
| 566 const VideoCaptureDeliverFrameCB& frame_callback, | 563 const VideoCaptureDeliverFrameCB& frame_callback, |
| 567 const blink::WebMediaConstraints& constraints, | 564 const blink::WebMediaConstraints& constraints, |
| 568 const ConstraintsCallback& callback) | 565 const ConstraintsCallback& callback) |
| 569 : track(track), | 566 : track(track), |
| 570 frame_callback(frame_callback), | 567 frame_callback(frame_callback), |
| 571 constraints(constraints), | 568 constraints(constraints), |
| 572 callback(callback) { | 569 callback(callback) { |
| 573 } | 570 } |
| 574 | 571 |
| 575 MediaStreamVideoSource::RequestedConstraints::~RequestedConstraints() { | 572 MediaStreamVideoSource::RequestedConstraints::~RequestedConstraints() { |
| 576 } | 573 } |
| 577 | 574 |
| 578 } // namespace content | 575 } // namespace content |
| OLD | NEW |