aura_desktop_capturer.cc 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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
  3. // found in the LICENSE file.
  4. #include "remoting/host/chromeos/aura_desktop_capturer.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/callback.h"
  8. #include "base/feature_list.h"
  9. #include "remoting/host/chromeos/ash_display_util.h"
  10. #include "remoting/host/chromeos/features.h"
  11. #include "remoting/host/chromeos/skia_bitmap_desktop_frame.h"
  12. namespace remoting {
  13. namespace {
  14. std::unique_ptr<webrtc::DesktopFrame>
  15. ToDesktopFrame(int dpi, gfx::Point origin, absl::optional<SkBitmap> bitmap) {
  16. if (!bitmap)
  17. return nullptr;
  18. std::unique_ptr<webrtc::DesktopFrame> frame(SkiaBitmapDesktopFrame::Create(
  19. std::make_unique<SkBitmap>(std::move(bitmap.value()))));
  20. frame->set_dpi(webrtc::DesktopVector(dpi, dpi));
  21. frame->set_top_left(webrtc::DesktopVector(origin.x(), origin.y()));
  22. // |VideoFramePump| will not encode the frame if |updated_region| is empty.
  23. const webrtc::DesktopRect& rect = webrtc::DesktopRect::MakeWH(
  24. frame->size().width(), frame->size().height());
  25. frame->mutable_updated_region()->SetRect(rect);
  26. return frame;
  27. }
  28. } // namespace
  29. AuraDesktopCapturer::AuraDesktopCapturer()
  30. : AuraDesktopCapturer(AshDisplayUtil::Get()) {}
  31. AuraDesktopCapturer::AuraDesktopCapturer(AshDisplayUtil& util) : util_(util) {}
  32. AuraDesktopCapturer::~AuraDesktopCapturer() = default;
  33. void AuraDesktopCapturer::Start(webrtc::DesktopCapturer::Callback* callback) {
  34. DCHECK(!callback_) << "Start() can only be called once";
  35. callback_ = callback;
  36. DCHECK(callback_);
  37. source_display_id_ = util_.GetPrimaryDisplayId();
  38. }
  39. void AuraDesktopCapturer::CaptureFrame() {
  40. DCHECK(callback_) << "Call Start() first";
  41. const display::Display* source = GetSourceDisplay();
  42. if (!source) {
  43. callback_->OnCaptureResult(DesktopCapturer::Result::ERROR_TEMPORARY,
  44. nullptr);
  45. return;
  46. }
  47. util_.TakeScreenshotOfDisplay(
  48. source_display_id_,
  49. base::BindOnce(ToDesktopFrame, util_.GetDpi(*source),
  50. source->bounds().origin())
  51. .Then(base::BindOnce(&AuraDesktopCapturer::OnFrameCaptured,
  52. weak_factory_.GetWeakPtr())));
  53. }
  54. void AuraDesktopCapturer::OnFrameCaptured(
  55. std::unique_ptr<webrtc::DesktopFrame> frame) {
  56. if (!frame) {
  57. callback_->OnCaptureResult(DesktopCapturer::Result::ERROR_TEMPORARY,
  58. nullptr);
  59. return;
  60. }
  61. callback_->OnCaptureResult(DesktopCapturer::Result::SUCCESS,
  62. std::move(frame));
  63. }
  64. bool AuraDesktopCapturer::GetSourceList(SourceList* sources) {
  65. // TODO(zijiehe): Implement screen enumeration.
  66. sources->push_back({0});
  67. return true;
  68. }
  69. bool AuraDesktopCapturer::SelectSource(SourceId id) {
  70. if (!base::FeatureList::IsEnabled(features::kEnableMultiMonitorsInCrd))
  71. return false;
  72. if (!util_.GetDisplayForId(id))
  73. return false;
  74. source_display_id_ = id;
  75. return true;
  76. }
  77. const display::Display* AuraDesktopCapturer::GetSourceDisplay() const {
  78. return util_.GetDisplayForId(source_display_id_);
  79. }
  80. } // namespace remoting