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

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

Issue 2790823002: Spec compliant video constraints for getUserMedia behind flag. (Closed)
Patch Set: rebase Created 3 years, 8 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 <memory>
9 #include <string> 10 #include <string>
11 #include <utility>
10 12
13 #include "base/feature_list.h"
11 #include "base/logging.h" 14 #include "base/logging.h"
12 #include "base/macros.h" 15 #include "base/macros.h"
13 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/string_number_conversions.h"
14 #include "base/trace_event/trace_event.h" 17 #include "base/trace_event/trace_event.h"
15 #include "content/child/child_process.h" 18 #include "content/child/child_process.h"
19 #include "content/public/common/content_features.h"
16 #include "content/renderer/media/media_stream_constraints_util_video_device.h" 20 #include "content/renderer/media/media_stream_constraints_util_video_device.h"
17 #include "content/renderer/media/media_stream_video_track.h" 21 #include "content/renderer/media/media_stream_video_track.h"
18 #include "content/renderer/media/video_track_adapter.h" 22 #include "content/renderer/media/video_track_adapter.h"
19 23
20 namespace content { 24 namespace content {
21 25
22 namespace { 26 namespace {
23 27
24 const char* const kLegalVideoConstraints[] = {"width", 28 const char* const kLegalVideoConstraints[] = {"width",
25 "height", 29 "height",
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 std::min(max_width, 304 std::min(max_width,
301 static_cast<int>(MediaStreamVideoSource::kDefaultWidth)) * 305 static_cast<int>(MediaStreamVideoSource::kDefaultWidth)) *
302 std::min(max_height, 306 std::min(max_height,
303 static_cast<int>(MediaStreamVideoSource::kDefaultHeight)); 307 static_cast<int>(MediaStreamVideoSource::kDefaultHeight));
304 308
305 return GetBestFormatBasedOnArea(formats, area); 309 return GetBestFormatBasedOnArea(formats, area);
306 } 310 }
307 311
308 } // anonymous namespace 312 } // anonymous namespace
309 313
314 bool IsOldVideoConstraints() {
315 return base::FeatureList::IsEnabled(
316 features::kMediaStreamOldVideoConstraints);
317 }
318
310 // static 319 // static
311 MediaStreamVideoSource* MediaStreamVideoSource::GetVideoSource( 320 MediaStreamVideoSource* MediaStreamVideoSource::GetVideoSource(
312 const blink::WebMediaStreamSource& source) { 321 const blink::WebMediaStreamSource& source) {
313 if (source.isNull() || 322 if (source.isNull() ||
314 source.getType() != blink::WebMediaStreamSource::TypeVideo) { 323 source.getType() != blink::WebMediaStreamSource::TypeVideo) {
315 return nullptr; 324 return nullptr;
316 } 325 }
317 return static_cast<MediaStreamVideoSource*>(source.getExtraData()); 326 return static_cast<MediaStreamVideoSource*>(source.getExtraData());
318 } 327 }
319 328
320 MediaStreamVideoSource::MediaStreamVideoSource() 329 MediaStreamVideoSource::MediaStreamVideoSource()
321 : state_(NEW), 330 : state_(NEW),
322 track_adapter_( 331 track_adapter_(
323 new VideoTrackAdapter(ChildProcess::current()->io_task_runner())), 332 new VideoTrackAdapter(ChildProcess::current()->io_task_runner())),
324 weak_factory_(this) {} 333 weak_factory_(this) {}
325 334
326 MediaStreamVideoSource::~MediaStreamVideoSource() { 335 MediaStreamVideoSource::~MediaStreamVideoSource() {
327 DCHECK(CalledOnValidThread()); 336 DCHECK(CalledOnValidThread());
328 } 337 }
329 338
330 void MediaStreamVideoSource::AddTrack( 339 void MediaStreamVideoSource::AddTrackLegacy(
331 MediaStreamVideoTrack* track, 340 MediaStreamVideoTrack* track,
332 const VideoCaptureDeliverFrameCB& frame_callback, 341 const VideoCaptureDeliverFrameCB& frame_callback,
333 const blink::WebMediaConstraints& constraints, 342 const blink::WebMediaConstraints& constraints,
334 const ConstraintsCallback& callback) { 343 const ConstraintsCallback& callback) {
335 DCHECK(CalledOnValidThread()); 344 DCHECK(CalledOnValidThread());
345 DCHECK(IsOldVideoConstraints());
336 DCHECK(!constraints.isNull()); 346 DCHECK(!constraints.isNull());
337 DCHECK(std::find(tracks_.begin(), tracks_.end(), track) == tracks_.end()); 347 DCHECK(std::find(tracks_.begin(), tracks_.end(), track) == tracks_.end());
338 tracks_.push_back(track); 348 tracks_.push_back(track);
339 secure_tracker_.Add(track, true); 349 secure_tracker_.Add(track, true);
340 350
341 track_descriptors_.push_back( 351 track_descriptors_.push_back(
342 TrackDescriptor(track, frame_callback, constraints, callback)); 352 TrackDescriptor(track, frame_callback, constraints, callback));
343 353
344 switch (state_) { 354 switch (state_) {
345 case NEW: { 355 case NEW: {
(...skipping 24 matching lines...) Expand all
370 } 380 }
371 case STARTING: 381 case STARTING:
372 case RETRIEVING_CAPABILITIES: { 382 case RETRIEVING_CAPABILITIES: {
373 // The |callback| will be triggered once the source has started or 383 // The |callback| will be triggered once the source has started or
374 // the capabilities have been retrieved. 384 // the capabilities have been retrieved.
375 break; 385 break;
376 } 386 }
377 case ENDED: 387 case ENDED:
378 case STARTED: { 388 case STARTED: {
379 // Currently, reconfiguring the source is not supported. 389 // Currently, reconfiguring the source is not supported.
390 FinalizeAddTrackLegacy();
391 }
392 }
393 }
394
395 void MediaStreamVideoSource::AddTrack(
396 MediaStreamVideoTrack* track,
397 const VideoTrackAdapterSettings& track_adapter_settings,
398 const VideoCaptureDeliverFrameCB& frame_callback,
399 const ConstraintsCallback& callback) {
400 DCHECK(CalledOnValidThread());
401 DCHECK(std::find(tracks_.begin(), tracks_.end(), track) == tracks_.end());
402 tracks_.push_back(track);
403 secure_tracker_.Add(track, true);
404
405 track_descriptors_.push_back(TrackDescriptor(
406 track, frame_callback,
407 base::MakeUnique<VideoTrackAdapterSettings>(track_adapter_settings),
408 callback));
409
410 switch (state_) {
411 case NEW: {
412 state_ = STARTING;
413 blink::WebMediaConstraints ignored_constraints;
414 StartSourceImpl(
415 media::VideoCaptureFormat() /* ignored */, ignored_constraints,
416 base::Bind(&VideoTrackAdapter::DeliverFrameOnIO, track_adapter_));
417 break;
418 }
419 case STARTING: {
420 break;
421 }
422 case RETRIEVING_CAPABILITIES: {
423 NOTREACHED();
424 break;
425 }
426 case ENDED:
427 case STARTED: {
428 // Currently, reconfiguring the source is not supported.
380 FinalizeAddTrack(); 429 FinalizeAddTrack();
381 } 430 }
382 } 431 }
383 } 432 }
384 433
385 void MediaStreamVideoSource::RemoveTrack(MediaStreamVideoTrack* video_track) { 434 void MediaStreamVideoSource::RemoveTrack(MediaStreamVideoTrack* video_track) {
386 DCHECK(CalledOnValidThread()); 435 DCHECK(CalledOnValidThread());
387 std::vector<MediaStreamVideoTrack*>::iterator it = 436 std::vector<MediaStreamVideoTrack*>::iterator it =
388 std::find(tracks_.begin(), tracks_.end(), video_track); 437 std::find(tracks_.begin(), tracks_.end(), video_track);
389 DCHECK(it != tracks_.end()); 438 DCHECK(it != tracks_.end());
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 DCHECK(CalledOnValidThread()); 475 DCHECK(CalledOnValidThread());
427 secure_tracker_.Update(track, is_secure); 476 secure_tracker_.Update(track, is_secure);
428 OnCapturingLinkSecured(secure_tracker_.is_capturing_secure()); 477 OnCapturingLinkSecured(secure_tracker_.is_capturing_secure());
429 } 478 }
430 479
431 base::SingleThreadTaskRunner* MediaStreamVideoSource::io_task_runner() const { 480 base::SingleThreadTaskRunner* MediaStreamVideoSource::io_task_runner() const {
432 DCHECK(CalledOnValidThread()); 481 DCHECK(CalledOnValidThread());
433 return track_adapter_->io_task_runner(); 482 return track_adapter_->io_task_runner();
434 } 483 }
435 484
436 const media::VideoCaptureFormat* 485 base::Optional<media::VideoCaptureFormat>
437 MediaStreamVideoSource::GetCurrentFormat() const { 486 MediaStreamVideoSource::GetCurrentFormat() const {
438 DCHECK(CalledOnValidThread()); 487 DCHECK(CalledOnValidThread());
439 if (state_ == STARTING || state_ == STARTED) 488 if (IsOldVideoConstraints()) {
440 return &current_format_; 489 if (state_ == STARTING || state_ == STARTED)
441 return nullptr; 490 return current_format_;
491 return base::Optional<media::VideoCaptureFormat>();
492 } else {
493 return GetCurrentFormatImpl();
494 }
495 }
496
497 base::Optional<media::VideoCaptureFormat>
498 MediaStreamVideoSource::GetCurrentFormatImpl() const {
499 return base::Optional<media::VideoCaptureFormat>();
442 } 500 }
443 501
444 void MediaStreamVideoSource::DoStopSource() { 502 void MediaStreamVideoSource::DoStopSource() {
445 DCHECK(CalledOnValidThread()); 503 DCHECK(CalledOnValidThread());
446 DVLOG(3) << "DoStopSource()"; 504 DVLOG(3) << "DoStopSource()";
447 if (state_ == ENDED) 505 if (state_ == ENDED)
448 return; 506 return;
449 track_adapter_->StopFrameMonitoring(); 507 track_adapter_->StopFrameMonitoring();
450 StopSourceImpl(); 508 StopSourceImpl();
451 state_ = ENDED; 509 state_ = ENDED;
452 SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded); 510 SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded);
453 } 511 }
454 512
455 void MediaStreamVideoSource::OnSupportedFormats( 513 void MediaStreamVideoSource::OnSupportedFormats(
456 const media::VideoCaptureFormats& formats) { 514 const media::VideoCaptureFormats& formats) {
457 DCHECK(CalledOnValidThread()); 515 DCHECK(CalledOnValidThread());
516 DCHECK(IsOldVideoConstraints());
458 DCHECK_EQ(RETRIEVING_CAPABILITIES, state_); 517 DCHECK_EQ(RETRIEVING_CAPABILITIES, state_);
459 518
460 supported_formats_ = formats; 519 supported_formats_ = formats;
461 blink::WebMediaConstraints fulfilled_constraints; 520 blink::WebMediaConstraints fulfilled_constraints;
462 if (!FindBestFormatWithConstraints(supported_formats_, 521 if (!FindBestFormatWithConstraints(supported_formats_,
463 &current_format_, 522 &current_format_,
464 &fulfilled_constraints)) { 523 &fulfilled_constraints)) {
465 SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded); 524 SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded);
466 DVLOG(3) << "OnSupportedFormats failed to find an usable format"; 525 DVLOG(3) << "OnSupportedFormats failed to find an usable format";
467 // This object can be deleted after calling FinalizeAddTrack. See comment 526 // This object can be deleted after calling FinalizeAddTrack. See comment
468 // in the header file. 527 // in the header file.
469 FinalizeAddTrack(); 528 FinalizeAddTrackLegacy();
470 return; 529 return;
471 } 530 }
472 531
473 state_ = STARTING; 532 state_ = STARTING;
474 DVLOG(3) << "Starting the capturer with " 533 DVLOG(3) << "Starting the capturer with "
475 << media::VideoCaptureFormat::ToString(current_format_); 534 << media::VideoCaptureFormat::ToString(current_format_);
476 535
477 StartSourceImpl( 536 StartSourceImpl(
478 current_format_, 537 current_format_,
479 fulfilled_constraints, 538 fulfilled_constraints,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 return false; 580 return false;
522 } 581 }
523 582
524 void MediaStreamVideoSource::OnStartDone(MediaStreamRequestResult result) { 583 void MediaStreamVideoSource::OnStartDone(MediaStreamRequestResult result) {
525 DCHECK(CalledOnValidThread()); 584 DCHECK(CalledOnValidThread());
526 DVLOG(3) << "OnStartDone({result =" << result << "})"; 585 DVLOG(3) << "OnStartDone({result =" << result << "})";
527 if (result == MEDIA_DEVICE_OK) { 586 if (result == MEDIA_DEVICE_OK) {
528 DCHECK_EQ(STARTING, state_); 587 DCHECK_EQ(STARTING, state_);
529 state_ = STARTED; 588 state_ = STARTED;
530 SetReadyState(blink::WebMediaStreamSource::ReadyStateLive); 589 SetReadyState(blink::WebMediaStreamSource::ReadyStateLive);
531 590 double frame_rate =
591 GetCurrentFormat() ? GetCurrentFormat()->frame_rate : 0.0;
532 track_adapter_->StartFrameMonitoring( 592 track_adapter_->StartFrameMonitoring(
533 current_format_.frame_rate, 593 frame_rate, base::Bind(&MediaStreamVideoSource::SetMutedState,
534 base::Bind(&MediaStreamVideoSource::SetMutedState, 594 weak_factory_.GetWeakPtr()));
535 weak_factory_.GetWeakPtr()));
536
537 } else { 595 } else {
538 StopSource(); 596 StopSource();
539 } 597 }
540 598
541 // This object can be deleted after calling FinalizeAddTrack. See comment in 599 // This object can be deleted after calling FinalizeAddTrack. See comment in
542 // the header file. 600 // the header file.
543 FinalizeAddTrack(); 601 if (IsOldVideoConstraints())
602 FinalizeAddTrackLegacy();
603 else
604 FinalizeAddTrack();
544 } 605 }
545 606
546 void MediaStreamVideoSource::FinalizeAddTrack() { 607 void MediaStreamVideoSource::FinalizeAddTrackLegacy() {
547 DCHECK(CalledOnValidThread()); 608 DCHECK(CalledOnValidThread());
609 DCHECK(IsOldVideoConstraints());
548 const media::VideoCaptureFormats formats(1, current_format_); 610 const media::VideoCaptureFormats formats(1, current_format_);
549 611
550 std::vector<TrackDescriptor> track_descriptors; 612 std::vector<TrackDescriptor> track_descriptors;
551 track_descriptors.swap(track_descriptors_); 613 track_descriptors.swap(track_descriptors_);
552 for (const auto& track : track_descriptors) { 614 for (const auto& track : track_descriptors) {
553 MediaStreamRequestResult result = MEDIA_DEVICE_OK; 615 MediaStreamRequestResult result = MEDIA_DEVICE_OK;
554 std::string unsatisfied_constraint; 616 std::string unsatisfied_constraint;
555 617
556 if (HasMandatoryConstraints(track.constraints) && 618 if (HasMandatoryConstraints(track.constraints) &&
557 FilterFormats(track.constraints, formats, &unsatisfied_constraint) 619 FilterFormats(track.constraints, formats, &unsatisfied_constraint)
558 .empty()) { 620 .empty()) {
559 result = MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED; 621 result = MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED;
560 DVLOG(3) << "FinalizeAddTrack() ignoring device on constraint " 622 DVLOG(3) << "FinalizeAddTrackLegacy() ignoring device on constraint "
561 << unsatisfied_constraint; 623 << unsatisfied_constraint;
562 } 624 }
563 625
564 if (state_ != STARTED && result == MEDIA_DEVICE_OK) 626 if (state_ != STARTED && result == MEDIA_DEVICE_OK)
565 result = MEDIA_DEVICE_TRACK_START_FAILURE; 627 result = MEDIA_DEVICE_TRACK_START_FAILURE;
566 628
567 if (result == MEDIA_DEVICE_OK) { 629 if (result == MEDIA_DEVICE_OK) {
568 int max_width; 630 int max_width;
569 int max_height; 631 int max_height;
570 GetDesiredMaxWidthAndHeight(track.constraints, &max_width, &max_height); 632 GetDesiredMaxWidthAndHeight(track.constraints, &max_width, &max_height);
(...skipping 14 matching lines...) Expand all
585 max_aspect_ratio, max_frame_rate)); 647 max_aspect_ratio, max_frame_rate));
586 // Calculate resulting frame size if the source delivers frames 648 // Calculate resulting frame size if the source delivers frames
587 // according to the current format. Note: Format may change later. 649 // according to the current format. Note: Format may change later.
588 gfx::Size desired_size; 650 gfx::Size desired_size;
589 VideoTrackAdapter::CalculateTargetSize( 651 VideoTrackAdapter::CalculateTargetSize(
590 current_format_.frame_size, gfx::Size(max_width, max_height), 652 current_format_.frame_size, gfx::Size(max_width, max_height),
591 min_aspect_ratio, max_aspect_ratio, &desired_size); 653 min_aspect_ratio, max_aspect_ratio, &desired_size);
592 track.track->SetTargetSize(desired_size.width(), desired_size.height()); 654 track.track->SetTargetSize(desired_size.width(), desired_size.height());
593 } 655 }
594 656
595 DVLOG(3) << "FinalizeAddTrack() result " << result; 657 DVLOG(3) << "FinalizeAddTrackLegacy() result " << result;
596 658
597 if (!track.callback.is_null()) 659 if (!track.callback.is_null())
598 track.callback.Run(this, result, 660 track.callback.Run(this, result,
599 blink::WebString::fromUTF8(unsatisfied_constraint)); 661 blink::WebString::fromUTF8(unsatisfied_constraint));
600 } 662 }
601 } 663 }
602 664
665 void MediaStreamVideoSource::FinalizeAddTrack() {
666 DCHECK(CalledOnValidThread());
667 DCHECK(!IsOldVideoConstraints());
668 std::vector<TrackDescriptor> track_descriptors;
669 track_descriptors.swap(track_descriptors_);
670 for (const auto& track : track_descriptors) {
671 MediaStreamRequestResult result = MEDIA_DEVICE_OK;
672 if (state_ != STARTED)
673 result = MEDIA_DEVICE_TRACK_START_FAILURE;
674
675 if (result == MEDIA_DEVICE_OK) {
676 track_adapter_->AddTrack(track.track, track.frame_callback,
677 *track.adapter_settings);
678
679 // Calculate resulting frame size if the source delivers frames
680 // according to the current format. Note: Format may change later.
681 gfx::Size desired_size;
682 VideoTrackAdapter::CalculateTargetSize(
683 GetCurrentFormat() ? GetCurrentFormat()->frame_size
684 : gfx::Size(track.adapter_settings->max_width,
685 track.adapter_settings->max_height),
686 gfx::Size(track.adapter_settings->max_width,
687 track.adapter_settings->max_height),
688 track.adapter_settings->min_aspect_ratio,
689 track.adapter_settings->max_aspect_ratio, &desired_size);
690 track.track->SetTargetSize(desired_size.width(), desired_size.height());
691 }
692
693 if (!track.callback.is_null())
694 track.callback.Run(this, result, blink::WebString());
695 }
696 }
697
603 void MediaStreamVideoSource::SetReadyState( 698 void MediaStreamVideoSource::SetReadyState(
604 blink::WebMediaStreamSource::ReadyState state) { 699 blink::WebMediaStreamSource::ReadyState state) {
605 DVLOG(3) << "MediaStreamVideoSource::SetReadyState state " << state; 700 DVLOG(3) << "MediaStreamVideoSource::SetReadyState state " << state;
606 DCHECK(CalledOnValidThread()); 701 DCHECK(CalledOnValidThread());
607 if (!owner().isNull()) 702 if (!owner().isNull())
608 owner().setReadyState(state); 703 owner().setReadyState(state);
609 for (auto* track : tracks_) 704 for (auto* track : tracks_)
610 track->OnReadyStateChanged(state); 705 track->OnReadyStateChanged(state);
611 } 706 }
612 707
613 void MediaStreamVideoSource::SetMutedState(bool muted_state) { 708 void MediaStreamVideoSource::SetMutedState(bool muted_state) {
614 DVLOG(3) << "MediaStreamVideoSource::SetMutedState state=" << muted_state; 709 DVLOG(3) << "MediaStreamVideoSource::SetMutedState state=" << muted_state;
615 DCHECK(CalledOnValidThread()); 710 DCHECK(CalledOnValidThread());
616 if (!owner().isNull()) { 711 if (!owner().isNull()) {
617 owner().setReadyState(muted_state 712 owner().setReadyState(muted_state
618 ? blink::WebMediaStreamSource::ReadyStateMuted 713 ? blink::WebMediaStreamSource::ReadyStateMuted
619 : blink::WebMediaStreamSource::ReadyStateLive); 714 : blink::WebMediaStreamSource::ReadyStateLive);
620 } 715 }
621 } 716 }
622 717
623 MediaStreamVideoSource::TrackDescriptor::TrackDescriptor( 718 MediaStreamVideoSource::TrackDescriptor::TrackDescriptor(
624 MediaStreamVideoTrack* track, 719 MediaStreamVideoTrack* track,
625 const VideoCaptureDeliverFrameCB& frame_callback, 720 const VideoCaptureDeliverFrameCB& frame_callback,
626 const blink::WebMediaConstraints& constraints, 721 const blink::WebMediaConstraints& constraints,
627 const ConstraintsCallback& callback) 722 const ConstraintsCallback& callback)
628 : track(track), 723 : track(track),
629 frame_callback(frame_callback), 724 frame_callback(frame_callback),
630 constraints(constraints), 725 constraints(constraints),
631 callback(callback) { 726 callback(callback) {
727 DCHECK(IsOldVideoConstraints());
632 } 728 }
633 729
634 MediaStreamVideoSource::TrackDescriptor::TrackDescriptor( 730 MediaStreamVideoSource::TrackDescriptor::TrackDescriptor(
635 const TrackDescriptor& other) = default; 731 MediaStreamVideoTrack* track,
732 const VideoCaptureDeliverFrameCB& frame_callback,
733 std::unique_ptr<VideoTrackAdapterSettings> adapter_settings,
734 const ConstraintsCallback& callback)
735 : track(track),
736 frame_callback(frame_callback),
737 adapter_settings(std::move(adapter_settings)),
738 callback(callback) {
739 DCHECK(!IsOldVideoConstraints());
740 }
741
742 MediaStreamVideoSource::TrackDescriptor::TrackDescriptor(
743 TrackDescriptor&& other) = default;
744 MediaStreamVideoSource::TrackDescriptor&
745 MediaStreamVideoSource::TrackDescriptor::operator=(
746 MediaStreamVideoSource::TrackDescriptor&& other) = default;
636 747
637 MediaStreamVideoSource::TrackDescriptor::~TrackDescriptor() { 748 MediaStreamVideoSource::TrackDescriptor::~TrackDescriptor() {
638 } 749 }
639 750
640 } // namespace content 751 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/media_stream_video_source.h ('k') | content/renderer/media/media_stream_video_source_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698