OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "remoting/host/fake_screen_capturer.h" | 5 #include "remoting/host/fake_screen_capturer.h" |
6 | 6 |
| 7 #include "base/bind.h" |
7 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/memory/ref_counted.h" |
8 #include "base/time/time.h" | 10 #include "base/time/time.h" |
9 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" | 11 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" |
10 | 12 |
11 namespace remoting { | 13 namespace remoting { |
12 | 14 |
13 // FakeScreenCapturer generates a white picture of size kWidth x kHeight | 15 // FakeScreenCapturer generates a white picture of size kWidth x kHeight |
14 // with a rectangle of size kBoxWidth x kBoxHeight. The rectangle moves kSpeed | 16 // with a rectangle of size kBoxWidth x kBoxHeight. The rectangle moves kSpeed |
15 // pixels per frame along both axes, and bounces off the sides of the screen. | 17 // pixels per frame along both axes, and bounces off the sides of the screen. |
16 static const int kWidth = FakeScreenCapturer::kWidth; | 18 static const int kWidth = FakeScreenCapturer::kWidth; |
17 static const int kHeight = FakeScreenCapturer::kHeight; | 19 static const int kHeight = FakeScreenCapturer::kHeight; |
18 static const int kBoxWidth = 140; | 20 static const int kBoxWidth = 140; |
19 static const int kBoxHeight = 140; | 21 static const int kBoxHeight = 140; |
20 static const int kSpeed = 20; | 22 static const int kSpeed = 20; |
21 | 23 |
22 COMPILE_ASSERT(kBoxWidth < kWidth && kBoxHeight < kHeight, bad_box_size); | 24 COMPILE_ASSERT(kBoxWidth < kWidth && kBoxHeight < kHeight, bad_box_size); |
23 COMPILE_ASSERT((kBoxWidth % kSpeed == 0) && (kWidth % kSpeed == 0) && | 25 COMPILE_ASSERT((kBoxWidth % kSpeed == 0) && (kWidth % kSpeed == 0) && |
24 (kBoxHeight % kSpeed == 0) && (kHeight % kSpeed == 0), | 26 (kBoxHeight % kSpeed == 0) && (kHeight % kSpeed == 0), |
25 sizes_must_be_multiple_of_kSpeed); | 27 sizes_must_be_multiple_of_kSpeed); |
26 | 28 |
| 29 namespace { |
| 30 |
| 31 class DefaultFrameGenerator |
| 32 : public base::RefCountedThreadSafe<DefaultFrameGenerator> { |
| 33 public: |
| 34 DefaultFrameGenerator() |
| 35 : bytes_per_row_(0), |
| 36 box_pos_x_(0), |
| 37 box_pos_y_(0), |
| 38 box_speed_x_(kSpeed), |
| 39 box_speed_y_(kSpeed), |
| 40 first_frame_(true) {} |
| 41 |
| 42 scoped_ptr<webrtc::DesktopFrame> GenerateFrame( |
| 43 webrtc::ScreenCapturer::Callback* callback); |
| 44 |
| 45 private: |
| 46 friend class base::RefCountedThreadSafe<DefaultFrameGenerator>; |
| 47 ~DefaultFrameGenerator() {} |
| 48 |
| 49 webrtc::DesktopSize size_; |
| 50 int bytes_per_row_; |
| 51 int box_pos_x_; |
| 52 int box_pos_y_; |
| 53 int box_speed_x_; |
| 54 int box_speed_y_; |
| 55 bool first_frame_; |
| 56 |
| 57 DISALLOW_COPY_AND_ASSIGN(DefaultFrameGenerator); |
| 58 }; |
| 59 |
| 60 scoped_ptr<webrtc::DesktopFrame> DefaultFrameGenerator::GenerateFrame( |
| 61 webrtc::ScreenCapturer::Callback* callback) { |
| 62 const int kBytesPerPixel = webrtc::DesktopFrame::kBytesPerPixel; |
| 63 int buffer_size = kWidth * kHeight * kBytesPerPixel; |
| 64 webrtc::SharedMemory* shared_memory = |
| 65 callback->CreateSharedMemory(buffer_size); |
| 66 scoped_ptr<webrtc::DesktopFrame> frame; |
| 67 if (shared_memory) { |
| 68 frame.reset(new webrtc::SharedMemoryDesktopFrame( |
| 69 webrtc::DesktopSize(kWidth, kHeight), bytes_per_row_, shared_memory)); |
| 70 } else { |
| 71 frame.reset( |
| 72 new webrtc::BasicDesktopFrame(webrtc::DesktopSize(kWidth, kHeight))); |
| 73 } |
| 74 |
| 75 // Move the box. |
| 76 bool old_box_pos_x = box_pos_x_; |
| 77 box_pos_x_ += box_speed_x_; |
| 78 if (box_pos_x_ + kBoxWidth >= kWidth || box_pos_x_ == 0) |
| 79 box_speed_x_ = -box_speed_x_; |
| 80 |
| 81 bool old_box_pos_y = box_pos_y_; |
| 82 box_pos_y_ += box_speed_y_; |
| 83 if (box_pos_y_ + kBoxHeight >= kHeight || box_pos_y_ == 0) |
| 84 box_speed_y_ = -box_speed_y_; |
| 85 |
| 86 memset(frame->data(), 0xff, kHeight * frame->stride()); |
| 87 |
| 88 // Draw rectangle with the following colors in its corners: |
| 89 // cyan....yellow |
| 90 // .............. |
| 91 // blue.......red |
| 92 uint8* row = frame->data() + |
| 93 (box_pos_y_ * size_.width() + box_pos_x_) * kBytesPerPixel; |
| 94 for (int y = 0; y < kBoxHeight; ++y) { |
| 95 for (int x = 0; x < kBoxWidth; ++x) { |
| 96 int r = x * 255 / kBoxWidth; |
| 97 int g = y * 255 / kBoxHeight; |
| 98 int b = 255 - (x * 255 / kBoxWidth); |
| 99 row[x * kBytesPerPixel] = r; |
| 100 row[x * kBytesPerPixel + 1] = g; |
| 101 row[x * kBytesPerPixel + 2] = b; |
| 102 row[x * kBytesPerPixel + 3] = 0xff; |
| 103 } |
| 104 row += frame->stride(); |
| 105 } |
| 106 |
| 107 if (first_frame_) { |
| 108 frame->mutable_updated_region()->SetRect( |
| 109 webrtc::DesktopRect::MakeXYWH(0, 0, kWidth, kHeight)); |
| 110 first_frame_ = false; |
| 111 } else { |
| 112 frame->mutable_updated_region()->SetRect(webrtc::DesktopRect::MakeXYWH( |
| 113 old_box_pos_x, old_box_pos_y, kBoxWidth, kBoxHeight)); |
| 114 frame->mutable_updated_region()->AddRect(webrtc::DesktopRect::MakeXYWH( |
| 115 box_pos_x_, box_pos_y_, kBoxWidth, kBoxHeight)); |
| 116 } |
| 117 |
| 118 return frame.Pass(); |
| 119 } |
| 120 |
| 121 } // namespace |
| 122 |
27 FakeScreenCapturer::FakeScreenCapturer() | 123 FakeScreenCapturer::FakeScreenCapturer() |
28 : callback_(NULL), | 124 : callback_(NULL), |
29 mouse_shape_observer_(NULL), | 125 mouse_shape_observer_(NULL) { |
30 bytes_per_row_(0), | 126 frame_generator_ = base::Bind(&DefaultFrameGenerator::GenerateFrame, |
31 box_pos_x_(0), | 127 new DefaultFrameGenerator()); |
32 box_pos_y_(0), | |
33 box_speed_x_(kSpeed), | |
34 box_speed_y_(kSpeed) { | |
35 ScreenConfigurationChanged(); | |
36 } | 128 } |
37 | 129 |
38 FakeScreenCapturer::~FakeScreenCapturer() { | 130 FakeScreenCapturer::~FakeScreenCapturer() {} |
| 131 |
| 132 void FakeScreenCapturer::set_frame_generator( |
| 133 const FrameGenerator& frame_generator) { |
| 134 DCHECK(!callback_); |
| 135 frame_generator_ = frame_generator; |
39 } | 136 } |
40 | 137 |
41 void FakeScreenCapturer::Start(Callback* callback) { | 138 void FakeScreenCapturer::Start(Callback* callback) { |
42 DCHECK(!callback_); | 139 DCHECK(!callback_); |
43 DCHECK(callback); | 140 DCHECK(callback); |
44 callback_ = callback; | 141 callback_ = callback; |
45 } | 142 } |
46 | 143 |
47 void FakeScreenCapturer::Capture(const webrtc::DesktopRegion& region) { | 144 void FakeScreenCapturer::Capture(const webrtc::DesktopRegion& region) { |
48 base::Time capture_start_time = base::Time::Now(); | 145 base::Time capture_start_time = base::Time::Now(); |
49 | 146 scoped_ptr<webrtc::DesktopFrame> frame = frame_generator_.Run(callback_); |
50 queue_.MoveToNextFrame(); | 147 frame->set_capture_time_ms( |
51 | |
52 if (!queue_.current_frame()) { | |
53 int buffer_size = size_.height() * bytes_per_row_; | |
54 webrtc::SharedMemory* shared_memory = | |
55 callback_->CreateSharedMemory(buffer_size); | |
56 scoped_ptr<webrtc::DesktopFrame> frame; | |
57 webrtc::DesktopSize frame_size(size_.width(), size_.height()); | |
58 if (shared_memory) { | |
59 frame.reset(new webrtc::SharedMemoryDesktopFrame( | |
60 frame_size, bytes_per_row_, shared_memory)); | |
61 } else { | |
62 frame.reset(new webrtc::BasicDesktopFrame(frame_size)); | |
63 } | |
64 queue_.ReplaceCurrentFrame(frame.release()); | |
65 } | |
66 | |
67 DCHECK(queue_.current_frame()); | |
68 GenerateImage(); | |
69 | |
70 queue_.current_frame()->mutable_updated_region()->SetRect( | |
71 webrtc::DesktopRect::MakeSize(size_)); | |
72 queue_.current_frame()->set_capture_time_ms( | |
73 (base::Time::Now() - capture_start_time).InMillisecondsRoundedUp()); | 148 (base::Time::Now() - capture_start_time).InMillisecondsRoundedUp()); |
74 | 149 callback_->OnCaptureCompleted(frame.release()); |
75 callback_->OnCaptureCompleted(queue_.current_frame()->Share()); | |
76 } | 150 } |
77 | 151 |
78 void FakeScreenCapturer::SetMouseShapeObserver( | 152 void FakeScreenCapturer::SetMouseShapeObserver( |
79 MouseShapeObserver* mouse_shape_observer) { | 153 MouseShapeObserver* mouse_shape_observer) { |
80 DCHECK(!mouse_shape_observer_); | 154 DCHECK(!mouse_shape_observer_); |
81 DCHECK(mouse_shape_observer); | 155 DCHECK(mouse_shape_observer); |
82 mouse_shape_observer_ = mouse_shape_observer; | 156 mouse_shape_observer_ = mouse_shape_observer; |
83 } | 157 } |
84 | 158 |
85 bool FakeScreenCapturer::GetScreenList(ScreenList* screens) { | 159 bool FakeScreenCapturer::GetScreenList(ScreenList* screens) { |
86 NOTIMPLEMENTED(); | 160 NOTIMPLEMENTED(); |
87 return false; | 161 return false; |
88 } | 162 } |
89 | 163 |
90 bool FakeScreenCapturer::SelectScreen(webrtc::ScreenId id) { | 164 bool FakeScreenCapturer::SelectScreen(webrtc::ScreenId id) { |
91 NOTIMPLEMENTED(); | 165 NOTIMPLEMENTED(); |
92 return false; | 166 return false; |
93 } | 167 } |
94 | 168 |
95 void FakeScreenCapturer::GenerateImage() { | |
96 webrtc::DesktopFrame* frame = queue_.current_frame(); | |
97 | |
98 const int kBytesPerPixel = webrtc::DesktopFrame::kBytesPerPixel; | |
99 | |
100 memset(frame->data(), 0xff, | |
101 size_.width() * size_.height() * kBytesPerPixel); | |
102 | |
103 uint8* row = frame->data() + | |
104 (box_pos_y_ * size_.width() + box_pos_x_) * kBytesPerPixel; | |
105 | |
106 box_pos_x_ += box_speed_x_; | |
107 if (box_pos_x_ + kBoxWidth >= size_.width() || box_pos_x_ == 0) | |
108 box_speed_x_ = -box_speed_x_; | |
109 | |
110 box_pos_y_ += box_speed_y_; | |
111 if (box_pos_y_ + kBoxHeight >= size_.height() || box_pos_y_ == 0) | |
112 box_speed_y_ = -box_speed_y_; | |
113 | |
114 // Draw rectangle with the following colors in its corners: | |
115 // cyan....yellow | |
116 // .............. | |
117 // blue.......red | |
118 for (int y = 0; y < kBoxHeight; ++y) { | |
119 for (int x = 0; x < kBoxWidth; ++x) { | |
120 int r = x * 255 / kBoxWidth; | |
121 int g = y * 255 / kBoxHeight; | |
122 int b = 255 - (x * 255 / kBoxWidth); | |
123 row[x * kBytesPerPixel] = r; | |
124 row[x * kBytesPerPixel + 1] = g; | |
125 row[x * kBytesPerPixel + 2] = b; | |
126 row[x * kBytesPerPixel + 3] = 0xff; | |
127 } | |
128 row += bytes_per_row_; | |
129 } | |
130 } | |
131 | |
132 void FakeScreenCapturer::ScreenConfigurationChanged() { | |
133 size_.set(kWidth, kHeight); | |
134 queue_.Reset(); | |
135 bytes_per_row_ = size_.width() * webrtc::DesktopFrame::kBytesPerPixel; | |
136 } | |
137 | |
138 } // namespace remoting | 169 } // namespace remoting |
OLD | NEW |