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

Side by Side Diff: webrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc

Issue 2030333003: Revert of Use std::unique_ptr<> to pass frame ownership in DesktopCapturer impls. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 6 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 /* 1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 rtc::CritScope lock(&g_container->duplication_lock); 406 rtc::CritScope lock(&g_container->duplication_lock);
407 // Make sure nobody is using current instance. 407 // Make sure nobody is using current instance.
408 rtc::CritScope lock2(&g_container->acquire_lock); 408 rtc::CritScope lock2(&g_container->acquire_lock);
409 if (g_container->duplication) { 409 if (g_container->duplication) {
410 return true; 410 return true;
411 } 411 }
412 412
413 _com_error error = g_container->output1->DuplicateOutput( 413 _com_error error = g_container->output1->DuplicateOutput(
414 static_cast<IUnknown*>(g_container->device), 414 static_cast<IUnknown*>(g_container->device),
415 g_container->duplication.GetAddressOf()); 415 g_container->duplication.GetAddressOf());
416 if (error.Error() != S_OK || !g_container->duplication) { 416 if (error.Error() == S_OK && g_container->duplication) {
417 memset(&g_container->duplication_desc, 0, sizeof(DXGI_OUTDUPL_DESC));
418 g_container->duplication->GetDesc(&g_container->duplication_desc);
419 if (g_container->duplication_desc.ModeDesc.Format !=
420 DXGI_FORMAT_B8G8R8A8_UNORM) {
421 g_container->duplication.Reset();
422 LOG(LS_ERROR) << "IDXGIDuplicateOutput does not use RGBA (8 bit) "
423 "format, which is required by downstream components, "
424 "format is "
425 << g_container->duplication_desc.ModeDesc.Format;
426 return false;
427 }
428 return true;
429 } else {
430 // Make sure we have correct signal and duplicate the output next time.
417 g_container->duplication.Reset(); 431 g_container->duplication.Reset();
418 LOG(LS_WARNING) << "Failed to duplicate output from IDXGIOutput1, error " 432 LOG(LS_WARNING) << "Failed to duplicate output from IDXGIOutput1, error "
419 << error.ErrorMessage() << ", with code " 433 << error.ErrorMessage() << ", with code "
420 << error.Error(); 434 << error.Error();
421 return false;
422 } 435 }
423 436
424 memset(&g_container->duplication_desc, 0, sizeof(DXGI_OUTDUPL_DESC)); 437 return false;
425 g_container->duplication->GetDesc(&g_container->duplication_desc);
426 if (g_container->duplication_desc.ModeDesc.Format !=
427 DXGI_FORMAT_B8G8R8A8_UNORM) {
428 g_container->duplication.Reset();
429 LOG(LS_ERROR) << "IDXGIDuplicateOutput does not use RGBA (8 bit) "
430 "format, which is required by downstream components, "
431 "format is "
432 << g_container->duplication_desc.ModeDesc.Format;
433 return false;
434 }
435
436 return true;
437 } 438 }
438 439
439 bool ScreenCapturerWinDirectx::ForceDuplicateOutput() { 440 bool ScreenCapturerWinDirectx::ForceDuplicateOutput() {
440 // We are updating the instance. 441 // We are updating the instance.
441 rtc::CritScope lock(&g_container->duplication_lock); 442 rtc::CritScope lock(&g_container->duplication_lock);
442 // Make sure nobody is using current instance. 443 // Make sure nobody is using current instance.
443 rtc::CritScope lock2(&g_container->acquire_lock); 444 rtc::CritScope lock2(&g_container->acquire_lock);
444 445
445 if (g_container->duplication) { 446 if (g_container->duplication) {
446 g_container->duplication->ReleaseFrame(); 447 g_container->duplication->ReleaseFrame();
447 g_container->duplication.Reset(); 448 g_container->duplication.Reset();
448 } 449 }
449 450
450 return DuplicateOutput(); 451 return DuplicateOutput();
451 } 452 }
452 453
453 ScreenCapturerWinDirectx::ScreenCapturerWinDirectx( 454 ScreenCapturerWinDirectx::ScreenCapturerWinDirectx(
454 const DesktopCaptureOptions& options) 455 const DesktopCaptureOptions& options)
455 : callback_(nullptr), set_thread_execution_state_failed_(false) { 456 : callback_(nullptr), set_thread_execution_state_failed_(false) {
456 RTC_DCHECK(g_container && g_container->initialize_result); 457 RTC_DCHECK(g_container && g_container->initialize_result);
457 458
458 // Texture instance won't change forever. 459 // Texture instance won't change forever.
459 while (!surfaces_.current_frame()) { 460 while (!surfaces_.current_frame()) {
460 surfaces_.ReplaceCurrentFrame(std::unique_ptr<rtc::scoped_refptr<Texture>>( 461 surfaces_.ReplaceCurrentFrame(
461 new rtc::scoped_refptr<Texture>(new Texture()))); 462 new rtc::scoped_refptr<Texture>(new Texture()));
462 surfaces_.MoveToNextFrame(); 463 surfaces_.MoveToNextFrame();
463 } 464 }
464 } 465 }
465 466
466 ScreenCapturerWinDirectx::~ScreenCapturerWinDirectx() {} 467 ScreenCapturerWinDirectx::~ScreenCapturerWinDirectx() {}
467 468
468 void ScreenCapturerWinDirectx::Start(Callback* callback) { 469 void ScreenCapturerWinDirectx::Start(Callback* callback) {
469 RTC_DCHECK(!callback_); 470 RTC_DCHECK(!callback_);
470 RTC_DCHECK(callback); 471 RTC_DCHECK(callback);
471 472
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 // Current frame does not have a same size as last captured surface. 586 // Current frame does not have a same size as last captured surface.
586 std::unique_ptr<DesktopFrame> new_frame = 587 std::unique_ptr<DesktopFrame> new_frame =
587 SharedMemoryDesktopFrame::Create( 588 SharedMemoryDesktopFrame::Create(
588 surfaces_.current_frame()->get()->size(), 589 surfaces_.current_frame()->get()->size(),
589 shared_memory_factory_.get()); 590 shared_memory_factory_.get());
590 if (!new_frame) { 591 if (!new_frame) {
591 LOG(LS_ERROR) << "Failed to allocate a new SharedMemoryDesktopFrame"; 592 LOG(LS_ERROR) << "Failed to allocate a new SharedMemoryDesktopFrame";
592 return std::unique_ptr<DesktopFrame>(); 593 return std::unique_ptr<DesktopFrame>();
593 } 594 }
594 frames_.ReplaceCurrentFrame( 595 frames_.ReplaceCurrentFrame(
595 SharedDesktopFrame::Wrap(std::move(new_frame))); 596 SharedDesktopFrame::Wrap(new_frame.release()));
596 } 597 }
597 result = frames_.current_frame()->Share(); 598 result.reset(frames_.current_frame()->Share());
598 599
599 std::unique_ptr<DesktopFrame> frame( 600 std::unique_ptr<DesktopFrame> frame(
600 new DxgiDesktopFrame(*surfaces_.current_frame())); 601 new DxgiDesktopFrame(*surfaces_.current_frame()));
601 // Copy data into SharedMemory. 602 // Copy data into SharedMemory.
602 for (DesktopRegion::Iterator it( 603 for (DesktopRegion::Iterator it(
603 surfaces_.current_frame()->get()->copied_region()); 604 surfaces_.current_frame()->get()->copied_region());
604 !it.IsAtEnd(); 605 !it.IsAtEnd();
605 it.Advance()) { 606 it.Advance()) {
606 result->CopyPixelsFrom(*frame, it.rect().top_left(), it.rect()); 607 result->CopyPixelsFrom(*frame, it.rect().top_left(), it.rect());
607 } 608 }
608 result->set_dpi(frame->dpi()); 609 result->set_dpi(frame->dpi());
609 } else { 610 } else {
610 result.reset(new DxgiDesktopFrame(*surfaces_.current_frame())); 611 result.reset(new DxgiDesktopFrame(*surfaces_.current_frame()));
611 } 612 }
612 RTC_DCHECK(result); 613 RTC_DCHECK(result);
613 *result->mutable_updated_region() = 614 *result->mutable_updated_region() =
614 surfaces_.current_frame()->get()->updated_region(); 615 surfaces_.current_frame()->get()->updated_region();
615 return result; 616 return result;
616 } 617 }
617 618
618 void ScreenCapturerWinDirectx::Capture(const DesktopRegion& region) { 619 void ScreenCapturerWinDirectx::Capture(const DesktopRegion& region) {
619 RTC_DCHECK(callback_); 620 RTC_DCHECK(callback_);
620 621
621 if (!g_container->duplication && !DuplicateOutput()) { 622 if (!g_container->duplication && !DuplicateOutput()) {
622 // Failed to initialize desktop duplication. 623 // Receive a capture request when application is shutting down, or between
623 callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); 624 // mode change.
625 callback_->OnCaptureCompleted(nullptr);
624 return; 626 return;
625 } 627 }
626 628
627 RTC_DCHECK(g_container->duplication); 629 RTC_DCHECK(g_container->duplication);
628 int64_t capture_start_time_nanos = rtc::TimeNanos(); 630 int64_t capture_start_time_nanos = rtc::TimeNanos();
629 631
630 if (!SetThreadExecutionState(ES_DISPLAY_REQUIRED | ES_SYSTEM_REQUIRED)) { 632 if (!SetThreadExecutionState(ES_DISPLAY_REQUIRED | ES_SYSTEM_REQUIRED)) {
631 if (!set_thread_execution_state_failed_) { 633 if (!set_thread_execution_state_failed_) {
632 set_thread_execution_state_failed_ = true; 634 set_thread_execution_state_failed_ = true;
633 LOG(LS_WARNING) << "Failed to make system & display power assertion: " 635 LOG(LS_WARNING) << "Failed to make system & display power assertion: "
(...skipping 13 matching lines...) Expand all
647 EmitCurrentFrame(); 649 EmitCurrentFrame();
648 return; 650 return;
649 } 651 }
650 652
651 if (error.Error() != S_OK) { 653 if (error.Error() != S_OK) {
652 LOG(LS_ERROR) << "Failed to capture frame, error " << error.ErrorMessage() 654 LOG(LS_ERROR) << "Failed to capture frame, error " << error.ErrorMessage()
653 << ", code " << error.Error(); 655 << ", code " << error.Error();
654 if (ForceDuplicateOutput()) { 656 if (ForceDuplicateOutput()) {
655 EmitCurrentFrame(); 657 EmitCurrentFrame();
656 } else { 658 } else {
657 callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); 659 callback_->OnCaptureCompleted(nullptr);
658 } 660 }
659 return; 661 return;
660 } 662 }
661 663
662 if (frame_info.AccumulatedFrames == 0) { 664 if (frame_info.AccumulatedFrames == 0) {
663 g_container->duplication->ReleaseFrame(); 665 g_container->duplication->ReleaseFrame();
664 EmitCurrentFrame(); 666 EmitCurrentFrame();
665 return; 667 return;
666 } 668 }
667 669
668 // Everything looks good so far, build next frame. 670 // Everything looks good so far, build next frame.
669 std::unique_ptr<DesktopFrame> result = 671 std::unique_ptr<DesktopFrame> result =
670 ProcessFrame(frame_info, resource.Get()); 672 ProcessFrame(frame_info, resource.Get());
671 // DetectUpdatedRegion may release last g_container->duplication. But 673 // DetectUpdatedRegion may release last g_container->duplication. But
672 // ForctDuplicateOutput function will always release last frame, so there is 674 // ForctDuplicateOutput function will always release last frame, so there is
673 // no potential leak. 675 // no potential leak.
674 if (g_container->duplication) { 676 if (g_container->duplication) {
675 g_container->duplication->ReleaseFrame(); 677 g_container->duplication->ReleaseFrame();
676 } 678 }
677 if (!result) { 679 if (!result) {
678 callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); 680 callback_->OnCaptureCompleted(nullptr);
679 return; 681 return;
680 } 682 }
681 683
682 result->set_capture_time_ms( 684 result->set_capture_time_ms(
683 (rtc::TimeNanos() - capture_start_time_nanos) / 685 (rtc::TimeNanos() - capture_start_time_nanos) /
684 rtc::kNumNanosecsPerMillisec); 686 rtc::kNumNanosecsPerMillisec);
685 callback_->OnCaptureResult(Result::SUCCESS, std::move(result)); 687 callback_->OnCaptureCompleted(result.release());
686 } 688 }
687 689
688 bool ScreenCapturerWinDirectx::GetScreenList(ScreenList* screens) { 690 bool ScreenCapturerWinDirectx::GetScreenList(ScreenList* screens) {
689 return true; 691 return true;
690 } 692 }
691 693
692 bool ScreenCapturerWinDirectx::SelectScreen(ScreenId id) { 694 bool ScreenCapturerWinDirectx::SelectScreen(ScreenId id) {
693 // Only full desktop capture is supported. 695 // Only full desktop capture is supported.
694 return id == kFullDesktopScreenId; 696 return id == kFullDesktopScreenId;
695 } 697 }
696 698
697 void ScreenCapturerWinDirectx::EmitCurrentFrame() { 699 void ScreenCapturerWinDirectx::EmitCurrentFrame() {
698 if (!surfaces_.current_frame()->get()->bits()) { 700 if (!surfaces_.current_frame()->get()->bits()) {
699 // At the very begining, we have not captured any frames. 701 // At the very begining, we have not captured any frames.
700 callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); 702 callback_->OnCaptureCompleted(nullptr);
701 return; 703 return;
702 } 704 }
703 705
704 if (shared_memory_factory_) { 706 if (shared_memory_factory_) {
705 // If shared_memory_factory_ is provided, last frame is stored in frames_ 707 // If shared_memory_factory_ is provided, last frame is stored in frames_
706 // queue. If there is not an existing frame (at the very begining), we can 708 // queue. If there is not an existing frame (at the very begining), we can
707 // only return a nullptr. 709 // only return a nullptr.
708 if (frames_.current_frame()) { 710 if (frames_.current_frame()) {
709 std::unique_ptr<SharedDesktopFrame> frame = 711 std::unique_ptr<SharedDesktopFrame> frame(
710 frames_.current_frame()->Share(); 712 frames_.current_frame()->Share());
711 frame->mutable_updated_region()->Clear(); 713 frame->mutable_updated_region()->Clear();
712 callback_->OnCaptureResult(Result::SUCCESS, std::move(frame)); 714 callback_->OnCaptureCompleted(frame.release());
713 } else { 715 } else {
714 callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); 716 callback_->OnCaptureCompleted(nullptr);
715 } 717 }
716 return; 718 return;
717 } 719 }
718 720
719 // If there is no shared_memory_factory_, last frame is stored in surfaces_ 721 // If there is no shared_memory_factory_, last frame is stored in surfaces_
720 // queue. 722 // queue.
721 std::unique_ptr<DesktopFrame> frame( 723 std::unique_ptr<DesktopFrame> frame(
722 new DxgiDesktopFrame(*surfaces_.current_frame())); 724 new DxgiDesktopFrame(*surfaces_.current_frame()));
723 callback_->OnCaptureResult(Result::SUCCESS, std::move(frame)); 725 callback_->OnCaptureCompleted(frame.release());
724 } 726 }
725 727
726 } // namespace webrtc 728 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698