OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <deque> | 5 #include <deque> |
6 #include <stdlib.h> | 6 #include <stdlib.h> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "media/base/video_frame.h" | 11 #include "media/base/video_frame.h" |
12 #include "remoting/codec/codec_test.h" | 12 #include "remoting/codec/codec_test.h" |
13 #include "remoting/codec/video_decoder.h" | 13 #include "remoting/codec/video_decoder.h" |
14 #include "remoting/codec/video_encoder.h" | 14 #include "remoting/codec/video_encoder.h" |
15 #include "remoting/base/util.h" | 15 #include "remoting/base/util.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" |
| 18 |
| 19 using webrtc::DesktopRect; |
| 20 using webrtc::DesktopSize; |
17 | 21 |
18 namespace { | 22 namespace { |
19 | 23 |
20 const int kBytesPerPixel = 4; | 24 const int kBytesPerPixel = 4; |
21 | 25 |
22 // Some sample rects for testing. | 26 // Some sample rects for testing. |
23 std::vector<std::vector<SkIRect> > MakeTestRectLists(const SkISize& size) { | 27 std::vector<std::vector<DesktopRect> > MakeTestRectLists(DesktopSize size) { |
24 std::vector<std::vector<SkIRect> > rect_lists; | 28 std::vector<std::vector<DesktopRect> > rect_lists; |
25 std::vector<SkIRect> rects; | 29 std::vector<DesktopRect> rects; |
26 rects.push_back(SkIRect::MakeXYWH(0, 0, size.width(), size.height())); | 30 rects.push_back(DesktopRect::MakeXYWH(0, 0, size.width(), size.height())); |
27 rect_lists.push_back(rects); | 31 rect_lists.push_back(rects); |
28 rects.clear(); | 32 rects.clear(); |
29 rects.push_back(SkIRect::MakeXYWH(0, 0, size.width() / 2, size.height() / 2)); | 33 rects.push_back(DesktopRect::MakeXYWH( |
| 34 0, 0, size.width() / 2, size.height() / 2)); |
30 rect_lists.push_back(rects); | 35 rect_lists.push_back(rects); |
31 rects.clear(); | 36 rects.clear(); |
32 rects.push_back(SkIRect::MakeXYWH(size.width() / 2, size.height() / 2, | 37 rects.push_back(DesktopRect::MakeXYWH( |
33 size.width() / 2, size.height() / 2)); | 38 size.width() / 2, size.height() / 2, |
| 39 size.width() / 2, size.height() / 2)); |
34 rect_lists.push_back(rects); | 40 rect_lists.push_back(rects); |
35 rects.clear(); | 41 rects.clear(); |
36 rects.push_back(SkIRect::MakeXYWH(16, 16, 16, 16)); | 42 rects.push_back(DesktopRect::MakeXYWH(16, 16, 16, 16)); |
37 rects.push_back(SkIRect::MakeXYWH(128, 64, 32, 32)); | 43 rects.push_back(DesktopRect::MakeXYWH(128, 64, 32, 32)); |
38 rect_lists.push_back(rects); | 44 rect_lists.push_back(rects); |
39 return rect_lists; | 45 return rect_lists; |
40 } | 46 } |
41 | 47 |
42 } // namespace | 48 } // namespace |
43 | 49 |
44 namespace remoting { | 50 namespace remoting { |
45 | 51 |
46 // A class to test the message output of the encoder. | 52 // A class to test the message output of the encoder. |
47 class VideoEncoderMessageTester { | 53 class VideoEncoderMessageTester { |
(...skipping 17 matching lines...) Expand all Loading... |
65 } | 71 } |
66 | 72 |
67 // Test that we received the correct packet. | 73 // Test that we received the correct packet. |
68 void ReceivedPacket(VideoPacket* packet) { | 74 void ReceivedPacket(VideoPacket* packet) { |
69 if (state_ == kWaitingForBeginRect) { | 75 if (state_ == kWaitingForBeginRect) { |
70 EXPECT_TRUE((packet->flags() & VideoPacket::FIRST_PACKET) != 0); | 76 EXPECT_TRUE((packet->flags() & VideoPacket::FIRST_PACKET) != 0); |
71 state_ = kWaitingForRectData; | 77 state_ = kWaitingForRectData; |
72 ++begin_rect_; | 78 ++begin_rect_; |
73 | 79 |
74 if (strict_) { | 80 if (strict_) { |
75 SkIRect rect = rects_.front(); | 81 DesktopRect rect = rects_.front(); |
76 rects_.pop_front(); | 82 rects_.pop_front(); |
77 EXPECT_EQ(rect.fLeft, packet->format().x()); | 83 EXPECT_EQ(rect.left(), packet->format().x()); |
78 EXPECT_EQ(rect.fTop, packet->format().y()); | 84 EXPECT_EQ(rect.top(), packet->format().y()); |
79 EXPECT_EQ(rect.width(), packet->format().width()); | 85 EXPECT_EQ(rect.width(), packet->format().width()); |
80 EXPECT_EQ(rect.height(), packet->format().height()); | 86 EXPECT_EQ(rect.height(), packet->format().height()); |
81 } | 87 } |
82 } else { | 88 } else { |
83 EXPECT_FALSE((packet->flags() & VideoPacket::FIRST_PACKET) != 0); | 89 EXPECT_FALSE((packet->flags() & VideoPacket::FIRST_PACKET) != 0); |
84 } | 90 } |
85 | 91 |
86 if (state_ == kWaitingForRectData) { | 92 if (state_ == kWaitingForRectData) { |
87 if (packet->has_data()) { | 93 if (packet->has_data()) { |
88 ++rect_data_; | 94 ++rect_data_; |
(...skipping 11 matching lines...) Expand all Loading... |
100 // LAST_PARTITION must always be marked with LAST_PACKET. | 106 // LAST_PARTITION must always be marked with LAST_PACKET. |
101 EXPECT_TRUE((packet->flags() & VideoPacket::LAST_PACKET) != 0); | 107 EXPECT_TRUE((packet->flags() & VideoPacket::LAST_PACKET) != 0); |
102 } | 108 } |
103 } | 109 } |
104 } | 110 } |
105 | 111 |
106 void set_strict(bool strict) { | 112 void set_strict(bool strict) { |
107 strict_ = strict; | 113 strict_ = strict; |
108 } | 114 } |
109 | 115 |
110 void AddRects(const SkIRect* rects, int count) { | 116 void AddRects(const DesktopRect* rects, int count) { |
111 rects_.insert(rects_.begin() + rects_.size(), rects, rects + count); | 117 rects_.insert(rects_.begin() + rects_.size(), rects, rects + count); |
112 added_rects_ += count; | 118 added_rects_ += count; |
113 } | 119 } |
114 | 120 |
115 private: | 121 private: |
116 enum State { | 122 enum State { |
117 kWaitingForBeginRect, | 123 kWaitingForBeginRect, |
118 kWaitingForRectData, | 124 kWaitingForRectData, |
119 }; | 125 }; |
120 | 126 |
121 int begin_rect_; | 127 int begin_rect_; |
122 int rect_data_; | 128 int rect_data_; |
123 int end_rect_; | 129 int end_rect_; |
124 int added_rects_; | 130 int added_rects_; |
125 State state_; | 131 State state_; |
126 bool strict_; | 132 bool strict_; |
127 | 133 |
128 std::deque<SkIRect> rects_; | 134 std::deque<DesktopRect> rects_; |
129 | 135 |
130 DISALLOW_COPY_AND_ASSIGN(VideoEncoderMessageTester); | 136 DISALLOW_COPY_AND_ASSIGN(VideoEncoderMessageTester); |
131 }; | 137 }; |
132 | 138 |
133 class VideoDecoderTester { | 139 class VideoDecoderTester { |
134 public: | 140 public: |
135 VideoDecoderTester(VideoDecoder* decoder, const SkISize& screen_size, | 141 VideoDecoderTester(VideoDecoder* decoder, |
136 const SkISize& view_size) | 142 const DesktopSize& screen_size, |
| 143 const DesktopSize& view_size) |
137 : screen_size_(screen_size), | 144 : screen_size_(screen_size), |
138 view_size_(view_size), | 145 view_size_(view_size), |
139 strict_(false), | 146 strict_(false), |
140 decoder_(decoder) { | 147 decoder_(decoder) { |
141 image_data_.reset(new uint8[ | 148 image_data_.reset(new uint8[ |
142 view_size_.width() * view_size_.height() * kBytesPerPixel]); | 149 view_size_.width() * view_size_.height() * kBytesPerPixel]); |
143 EXPECT_TRUE(image_data_.get()); | 150 EXPECT_TRUE(image_data_.get()); |
144 decoder_->Initialize(screen_size_); | 151 decoder_->Initialize( |
| 152 SkISize::Make(screen_size_.width(), screen_size_.height())); |
145 } | 153 } |
146 | 154 |
147 void Reset() { | 155 void Reset() { |
148 expected_region_.setEmpty(); | 156 expected_region_.Clear(); |
149 update_region_.setEmpty(); | 157 update_region_.setEmpty(); |
150 } | 158 } |
151 | 159 |
152 void ResetRenderedData() { | 160 void ResetRenderedData() { |
153 memset(image_data_.get(), 0, | 161 memset(image_data_.get(), 0, |
154 view_size_.width() * view_size_.height() * kBytesPerPixel); | 162 view_size_.width() * view_size_.height() * kBytesPerPixel); |
155 } | 163 } |
156 | 164 |
157 void ReceivedPacket(VideoPacket* packet) { | 165 void ReceivedPacket(VideoPacket* packet) { |
158 VideoDecoder::DecodeResult result = decoder_->DecodePacket(packet); | 166 VideoDecoder::DecodeResult result = decoder_->DecodePacket(packet); |
159 | 167 |
160 ASSERT_NE(VideoDecoder::DECODE_ERROR, result); | 168 ASSERT_NE(VideoDecoder::DECODE_ERROR, result); |
161 | 169 |
162 if (result == VideoDecoder::DECODE_DONE) { | 170 if (result == VideoDecoder::DECODE_DONE) { |
163 RenderFrame(); | 171 RenderFrame(); |
164 } | 172 } |
165 } | 173 } |
166 | 174 |
167 void RenderFrame() { | 175 void RenderFrame() { |
168 decoder_->RenderFrame(view_size_, | 176 decoder_->RenderFrame( |
169 SkIRect::MakeSize(view_size_), | 177 SkISize::Make(view_size_.width(), view_size_.height()), |
170 image_data_.get(), | 178 SkIRect::MakeWH(view_size_.width(), view_size_.height()), |
171 view_size_.width() * kBytesPerPixel, | 179 image_data_.get(), |
172 &update_region_); | 180 view_size_.width() * kBytesPerPixel, |
| 181 &update_region_); |
173 } | 182 } |
174 | 183 |
175 void ReceivedScopedPacket(scoped_ptr<VideoPacket> packet) { | 184 void ReceivedScopedPacket(scoped_ptr<VideoPacket> packet) { |
176 ReceivedPacket(packet.get()); | 185 ReceivedPacket(packet.get()); |
177 } | 186 } |
178 | 187 |
179 void set_strict(bool strict) { | 188 void set_strict(bool strict) { |
180 strict_ = strict; | 189 strict_ = strict; |
181 } | 190 } |
182 | 191 |
183 void set_capture_data(scoped_refptr<media::ScreenCaptureData> data) { | 192 void set_frame(webrtc::DesktopFrame* frame) { |
184 capture_data_ = data; | 193 frame_ = frame; |
185 } | 194 } |
186 | 195 |
187 void AddRects(const SkIRect* rects, int count) { | 196 void AddRects(const DesktopRect* rects, int count) { |
188 SkRegion new_rects; | 197 for (int i = 0; i < count; ++i) { |
189 new_rects.setRects(rects, count); | 198 expected_region_.AddRect(rects[i]); |
190 AddRegion(new_rects); | 199 } |
191 } | 200 } |
192 | 201 |
193 void AddRegion(const SkRegion& region) { | 202 void AddRegion(const webrtc::DesktopRegion& region) { |
194 expected_region_.op(region, SkRegion::kUnion_Op); | 203 expected_region_.AddRegion(region); |
195 } | 204 } |
196 | 205 |
197 void VerifyResults() { | 206 void VerifyResults() { |
198 if (!strict_) | 207 if (!strict_) |
199 return; | 208 return; |
200 | 209 |
201 ASSERT_TRUE(capture_data_.get()); | 210 ASSERT_TRUE(frame_); |
202 | 211 |
203 // Test the content of the update region. | 212 // Test the content of the update region. |
204 EXPECT_EQ(expected_region_, update_region_); | 213 // |
| 214 // TODO(sergeyu): Change this to use DesktopRegion when it's capable of |
| 215 // merging the rectangles. |
| 216 SkRegion expected_region; |
| 217 for (webrtc::DesktopRegion::Iterator it(expected_region_); |
| 218 !it.IsAtEnd(); it.Advance()) { |
| 219 expected_region.op( |
| 220 SkIRect::MakeXYWH(it.rect().top(), it.rect().left(), |
| 221 it.rect().width(), it.rect().height()), |
| 222 SkRegion::kUnion_Op); |
| 223 } |
| 224 EXPECT_EQ(expected_region, update_region_); |
| 225 |
205 for (SkRegion::Iterator i(update_region_); !i.done(); i.next()) { | 226 for (SkRegion::Iterator i(update_region_); !i.done(); i.next()) { |
206 const int stride = view_size_.width() * kBytesPerPixel; | 227 const int stride = view_size_.width() * kBytesPerPixel; |
207 EXPECT_EQ(stride, capture_data_->stride()); | 228 EXPECT_EQ(stride, frame_->stride()); |
208 const int offset = stride * i.rect().top() + | 229 const int offset = stride * i.rect().top() + |
209 kBytesPerPixel * i.rect().left(); | 230 kBytesPerPixel * i.rect().left(); |
210 const uint8* original = capture_data_->data() + offset; | 231 const uint8* original = frame_->data() + offset; |
211 const uint8* decoded = image_data_.get() + offset; | 232 const uint8* decoded = image_data_.get() + offset; |
212 const int row_size = kBytesPerPixel * i.rect().width(); | 233 const int row_size = kBytesPerPixel * i.rect().width(); |
213 for (int y = 0; y < i.rect().height(); ++y) { | 234 for (int y = 0; y < i.rect().height(); ++y) { |
214 EXPECT_EQ(0, memcmp(original, decoded, row_size)) | 235 EXPECT_EQ(0, memcmp(original, decoded, row_size)) |
215 << "Row " << y << " is different"; | 236 << "Row " << y << " is different"; |
216 original += stride; | 237 original += stride; |
217 decoded += stride; | 238 decoded += stride; |
218 } | 239 } |
219 } | 240 } |
220 } | 241 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 static_cast<double>(*decoded++); | 279 static_cast<double>(*decoded++); |
259 error /= 255.0; | 280 error /= 255.0; |
260 error_sum_squares += error * error; | 281 error_sum_squares += error * error; |
261 } | 282 } |
262 original++; | 283 original++; |
263 decoded++; | 284 decoded++; |
264 return sqrt(error_sum_squares / 3.0); | 285 return sqrt(error_sum_squares / 3.0); |
265 } | 286 } |
266 | 287 |
267 private: | 288 private: |
268 SkISize screen_size_; | 289 DesktopSize screen_size_; |
269 SkISize view_size_; | 290 DesktopSize view_size_; |
270 bool strict_; | 291 bool strict_; |
271 SkRegion expected_region_; | 292 webrtc::DesktopRegion expected_region_; |
272 SkRegion update_region_; | 293 SkRegion update_region_; |
273 VideoDecoder* decoder_; | 294 VideoDecoder* decoder_; |
274 scoped_ptr<uint8[]> image_data_; | 295 scoped_ptr<uint8[]> image_data_; |
275 scoped_refptr<media::ScreenCaptureData> capture_data_; | 296 webrtc::DesktopFrame* frame_; |
276 | 297 |
277 DISALLOW_COPY_AND_ASSIGN(VideoDecoderTester); | 298 DISALLOW_COPY_AND_ASSIGN(VideoDecoderTester); |
278 }; | 299 }; |
279 | 300 |
280 // The VideoEncoderTester provides a hook for retrieving the data, and passing | 301 // The VideoEncoderTester provides a hook for retrieving the data, and passing |
281 // the message to other subprograms for validaton. | 302 // the message to other subprograms for validaton. |
282 class VideoEncoderTester { | 303 class VideoEncoderTester { |
283 public: | 304 public: |
284 VideoEncoderTester(VideoEncoderMessageTester* message_tester) | 305 VideoEncoderTester(VideoEncoderMessageTester* message_tester) |
285 : message_tester_(message_tester), | 306 : message_tester_(message_tester), |
286 decoder_tester_(NULL), | 307 decoder_tester_(NULL), |
287 data_available_(0) { | 308 data_available_(0) { |
288 } | 309 } |
289 | 310 |
290 ~VideoEncoderTester() { | 311 ~VideoEncoderTester() { |
291 EXPECT_GT(data_available_, 0); | 312 EXPECT_GT(data_available_, 0); |
292 } | 313 } |
293 | 314 |
294 void DataAvailable(scoped_ptr<VideoPacket> packet) { | 315 void DataAvailable(scoped_ptr<VideoPacket> packet) { |
295 ++data_available_; | 316 ++data_available_; |
296 message_tester_->ReceivedPacket(packet.get()); | 317 message_tester_->ReceivedPacket(packet.get()); |
297 | 318 |
298 // Send the message to the VideoDecoderTester. | 319 // Send the message to the VideoDecoderTester. |
299 if (decoder_tester_) { | 320 if (decoder_tester_) { |
300 decoder_tester_->ReceivedPacket(packet.get()); | 321 decoder_tester_->ReceivedPacket(packet.get()); |
301 } | 322 } |
302 } | 323 } |
303 | 324 |
304 void AddRects(const SkIRect* rects, int count) { | 325 void AddRects(const DesktopRect* rects, int count) { |
305 message_tester_->AddRects(rects, count); | 326 message_tester_->AddRects(rects, count); |
306 } | 327 } |
307 | 328 |
308 void set_decoder_tester(VideoDecoderTester* decoder_tester) { | 329 void set_decoder_tester(VideoDecoderTester* decoder_tester) { |
309 decoder_tester_ = decoder_tester; | 330 decoder_tester_ = decoder_tester; |
310 } | 331 } |
311 | 332 |
312 private: | 333 private: |
313 VideoEncoderMessageTester* message_tester_; | 334 VideoEncoderMessageTester* message_tester_; |
314 VideoDecoderTester* decoder_tester_; | 335 VideoDecoderTester* decoder_tester_; |
315 int data_available_; | 336 int data_available_; |
316 | 337 |
317 DISALLOW_COPY_AND_ASSIGN(VideoEncoderTester); | 338 DISALLOW_COPY_AND_ASSIGN(VideoEncoderTester); |
318 }; | 339 }; |
319 | 340 |
320 scoped_refptr<media::ScreenCaptureData> PrepareEncodeData( | 341 scoped_ptr<webrtc::DesktopFrame> PrepareFrame(const DesktopSize& size) { |
321 const SkISize& size, | 342 scoped_ptr<webrtc::DesktopFrame> frame(new webrtc::BasicDesktopFrame(size)); |
322 scoped_ptr<uint8[]>* memory) { | |
323 int memory_size = size.width() * size.height() * kBytesPerPixel; | |
324 | |
325 memory->reset(new uint8[memory_size]); | |
326 | 343 |
327 srand(0); | 344 srand(0); |
| 345 int memory_size = size.width() * size.height() * kBytesPerPixel; |
328 for (int i = 0; i < memory_size; ++i) { | 346 for (int i = 0; i < memory_size; ++i) { |
329 (*memory)[i] = rand() % 256; | 347 frame->data()[i] = rand() % 256; |
330 } | 348 } |
331 | 349 |
332 scoped_refptr<media::ScreenCaptureData> data = new media::ScreenCaptureData( | 350 return frame.Pass(); |
333 memory->get(), size.width() * kBytesPerPixel, size); | |
334 return data; | |
335 } | 351 } |
336 | 352 |
337 static void TestEncodingRects(VideoEncoder* encoder, | 353 static void TestEncodingRects(VideoEncoder* encoder, |
338 VideoEncoderTester* tester, | 354 VideoEncoderTester* tester, |
339 scoped_refptr<media::ScreenCaptureData> data, | 355 webrtc::DesktopFrame* frame, |
340 const SkIRect* rects, int count) { | 356 const DesktopRect* rects, |
341 data->mutable_dirty_region().setEmpty(); | 357 int count) { |
| 358 frame->mutable_updated_region()->Clear(); |
342 for (int i = 0; i < count; ++i) { | 359 for (int i = 0; i < count; ++i) { |
343 data->mutable_dirty_region().op(rects[i], SkRegion::kUnion_Op); | 360 frame->mutable_updated_region()->AddRect(rects[i]); |
344 } | 361 } |
345 tester->AddRects(rects, count); | 362 tester->AddRects(rects, count); |
346 | 363 |
347 encoder->Encode(data, true, base::Bind( | 364 encoder->Encode(frame, base::Bind( |
348 &VideoEncoderTester::DataAvailable, base::Unretained(tester))); | 365 &VideoEncoderTester::DataAvailable, base::Unretained(tester))); |
349 } | 366 } |
350 | 367 |
351 void TestVideoEncoder(VideoEncoder* encoder, bool strict) { | 368 void TestVideoEncoder(VideoEncoder* encoder, bool strict) { |
352 const int kSizes[] = {320, 319, 317, 150}; | 369 const int kSizes[] = {320, 319, 317, 150}; |
353 | 370 |
354 VideoEncoderMessageTester message_tester; | 371 VideoEncoderMessageTester message_tester; |
355 message_tester.set_strict(strict); | 372 message_tester.set_strict(strict); |
356 | 373 |
357 VideoEncoderTester tester(&message_tester); | 374 VideoEncoderTester tester(&message_tester); |
358 | 375 |
359 scoped_ptr<uint8[]> memory; | |
360 | |
361 for (size_t xi = 0; xi < arraysize(kSizes); ++xi) { | 376 for (size_t xi = 0; xi < arraysize(kSizes); ++xi) { |
362 for (size_t yi = 0; yi < arraysize(kSizes); ++yi) { | 377 for (size_t yi = 0; yi < arraysize(kSizes); ++yi) { |
363 SkISize size = SkISize::Make(kSizes[xi], kSizes[yi]); | 378 DesktopSize size = DesktopSize(kSizes[xi], kSizes[yi]); |
364 scoped_refptr<media::ScreenCaptureData> data = | 379 scoped_ptr<webrtc::DesktopFrame> frame = PrepareFrame(size); |
365 PrepareEncodeData(size, &memory); | 380 std::vector<std::vector<DesktopRect> > test_rect_lists = |
366 std::vector<std::vector<SkIRect> > test_rect_lists = | |
367 MakeTestRectLists(size); | 381 MakeTestRectLists(size); |
368 for (size_t i = 0; i < test_rect_lists.size(); ++i) { | 382 for (size_t i = 0; i < test_rect_lists.size(); ++i) { |
369 const std::vector<SkIRect>& test_rects = test_rect_lists[i]; | 383 const std::vector<DesktopRect>& test_rects = test_rect_lists[i]; |
370 TestEncodingRects(encoder, &tester, data, | 384 TestEncodingRects(encoder, &tester, frame.get(), |
371 &test_rects[0], test_rects.size()); | 385 &test_rects[0], test_rects.size()); |
372 } | 386 } |
373 } | 387 } |
374 } | 388 } |
375 } | 389 } |
376 | 390 |
377 static void TestEncodeDecodeRects(VideoEncoder* encoder, | 391 static void TestEncodeDecodeRects(VideoEncoder* encoder, |
378 VideoEncoderTester* encoder_tester, | 392 VideoEncoderTester* encoder_tester, |
379 VideoDecoderTester* decoder_tester, | 393 VideoDecoderTester* decoder_tester, |
380 scoped_refptr<media::ScreenCaptureData> data, | 394 webrtc::DesktopFrame* frame, |
381 const SkIRect* rects, int count) { | 395 const DesktopRect* rects, int count) { |
382 data->mutable_dirty_region().setRects(rects, count); | 396 frame->mutable_updated_region()->Clear(); |
| 397 for (int i = 0; i < count; ++i) { |
| 398 frame->mutable_updated_region()->AddRect(rects[i]); |
| 399 } |
383 encoder_tester->AddRects(rects, count); | 400 encoder_tester->AddRects(rects, count); |
384 decoder_tester->AddRects(rects, count); | 401 decoder_tester->AddRects(rects, count); |
385 | 402 |
386 // Generate random data for the updated region. | 403 // Generate random data for the updated region. |
387 srand(0); | 404 srand(0); |
388 for (int i = 0; i < count; ++i) { | 405 for (int i = 0; i < count; ++i) { |
389 const int bytes_per_pixel = 4; // Because of RGB32 on previous line. | 406 const int row_size = |
390 const int row_size = bytes_per_pixel * rects[i].width(); | 407 webrtc::DesktopFrame::kBytesPerPixel * rects[i].width(); |
391 uint8* memory = data->data() + | 408 uint8* memory = frame->data() + |
392 data->stride() * rects[i].top() + | 409 frame->stride() * rects[i].top() + |
393 bytes_per_pixel * rects[i].left(); | 410 webrtc::DesktopFrame::kBytesPerPixel * rects[i].left(); |
394 for (int y = 0; y < rects[i].height(); ++y) { | 411 for (int y = 0; y < rects[i].height(); ++y) { |
395 for (int x = 0; x < row_size; ++x) | 412 for (int x = 0; x < row_size; ++x) |
396 memory[x] = rand() % 256; | 413 memory[x] = rand() % 256; |
397 memory += data->stride(); | 414 memory += frame->stride(); |
398 } | 415 } |
399 } | 416 } |
400 | 417 |
401 encoder->Encode(data, true, base::Bind(&VideoEncoderTester::DataAvailable, | 418 encoder->Encode(frame, base::Bind(&VideoEncoderTester::DataAvailable, |
402 base::Unretained(encoder_tester))); | 419 base::Unretained(encoder_tester))); |
403 decoder_tester->VerifyResults(); | 420 decoder_tester->VerifyResults(); |
404 decoder_tester->Reset(); | 421 decoder_tester->Reset(); |
405 } | 422 } |
406 | 423 |
407 void TestVideoEncoderDecoder( | 424 void TestVideoEncoderDecoder( |
408 VideoEncoder* encoder, VideoDecoder* decoder, bool strict) { | 425 VideoEncoder* encoder, VideoDecoder* decoder, bool strict) { |
409 SkISize kSize = SkISize::Make(320, 240); | 426 DesktopSize kSize = DesktopSize(320, 240); |
410 | 427 |
411 VideoEncoderMessageTester message_tester; | 428 VideoEncoderMessageTester message_tester; |
412 message_tester.set_strict(strict); | 429 message_tester.set_strict(strict); |
413 | 430 |
414 VideoEncoderTester encoder_tester(&message_tester); | 431 VideoEncoderTester encoder_tester(&message_tester); |
415 | 432 |
416 scoped_ptr<uint8[]> memory; | 433 scoped_ptr<webrtc::DesktopFrame> frame = PrepareFrame(kSize); |
417 scoped_refptr<media::ScreenCaptureData> data = | |
418 PrepareEncodeData(kSize, &memory); | |
419 | 434 |
420 VideoDecoderTester decoder_tester(decoder, kSize, kSize); | 435 VideoDecoderTester decoder_tester(decoder, kSize, kSize); |
421 decoder_tester.set_strict(strict); | 436 decoder_tester.set_strict(strict); |
422 decoder_tester.set_capture_data(data); | 437 decoder_tester.set_frame(frame.get()); |
423 encoder_tester.set_decoder_tester(&decoder_tester); | 438 encoder_tester.set_decoder_tester(&decoder_tester); |
424 | 439 |
425 std::vector<std::vector<SkIRect> > test_rect_lists = MakeTestRectLists(kSize); | 440 std::vector<std::vector<DesktopRect> > test_rect_lists = |
| 441 MakeTestRectLists(kSize); |
426 for (size_t i = 0; i < test_rect_lists.size(); ++i) { | 442 for (size_t i = 0; i < test_rect_lists.size(); ++i) { |
427 const std::vector<SkIRect> test_rects = test_rect_lists[i]; | 443 const std::vector<DesktopRect> test_rects = test_rect_lists[i]; |
428 TestEncodeDecodeRects(encoder, &encoder_tester, &decoder_tester, data, | 444 TestEncodeDecodeRects(encoder, &encoder_tester, &decoder_tester, |
429 &test_rects[0], test_rects.size()); | 445 frame.get(), &test_rects[0], test_rects.size()); |
430 } | 446 } |
431 } | 447 } |
432 | 448 |
433 static void FillWithGradient(uint8* memory, const SkISize& frame_size, | 449 static void FillWithGradient(webrtc::DesktopFrame* frame) { |
434 const SkIRect& rect) { | 450 for (int j = 0; j < frame->size().height(); ++j) { |
435 for (int j = rect.top(); j < rect.bottom(); ++j) { | 451 uint8* p = frame->data() + j * frame->stride(); |
436 uint8* p = memory + ((j * frame_size.width()) + rect.left()) * 4; | 452 for (int i = 0; i < frame->size().width(); ++i) { |
437 for (int i = rect.left(); i < rect.right(); ++i) { | 453 *p++ = (255.0 * i) / frame->size().width(); |
438 *p++ = static_cast<uint8>((255.0 * i) / frame_size.width()); | 454 *p++ = (164.0 * j) / frame->size().height(); |
439 *p++ = static_cast<uint8>((164.0 * j) / frame_size.height()); | 455 *p++ = (82.0 * (i + j)) / |
440 *p++ = static_cast<uint8>((82.0 * (i + j)) / | 456 (frame->size().width() + frame->size().height()); |
441 (frame_size.width() + frame_size.height())); | |
442 *p++ = 0; | 457 *p++ = 0; |
443 } | 458 } |
444 } | 459 } |
445 } | 460 } |
446 | 461 |
447 void TestVideoEncoderDecoderGradient(VideoEncoder* encoder, | 462 void TestVideoEncoderDecoderGradient(VideoEncoder* encoder, |
448 VideoDecoder* decoder, | 463 VideoDecoder* decoder, |
449 const SkISize& screen_size, | 464 const DesktopSize& screen_size, |
450 const SkISize& view_size, | 465 const DesktopSize& view_size, |
451 double max_error_limit, | 466 double max_error_limit, |
452 double mean_error_limit) { | 467 double mean_error_limit) { |
453 SkIRect screen_rect = SkIRect::MakeSize(screen_size); | 468 scoped_ptr<webrtc::BasicDesktopFrame> frame( |
454 scoped_ptr<uint8[]> screen_data(new uint8[ | 469 new webrtc::BasicDesktopFrame(screen_size)); |
455 screen_size.width() * screen_size.height() * kBytesPerPixel]); | 470 FillWithGradient(frame.get()); |
456 FillWithGradient(screen_data.get(), screen_size, screen_rect); | 471 frame->mutable_updated_region()->SetRect(DesktopRect::MakeSize(screen_size)); |
457 | 472 |
458 SkIRect view_rect = SkIRect::MakeSize(view_size); | 473 scoped_ptr<webrtc::BasicDesktopFrame> expected_result( |
459 scoped_ptr<uint8[]> expected_view_data(new uint8[ | 474 new webrtc::BasicDesktopFrame(view_size)); |
460 view_size.width() * view_size.height() * kBytesPerPixel]); | 475 FillWithGradient(expected_result.get()); |
461 FillWithGradient(expected_view_data.get(), view_size, view_rect); | |
462 | |
463 scoped_refptr<media::ScreenCaptureData> capture_data = | |
464 new media::ScreenCaptureData( | |
465 screen_data.get(), screen_size.width() * kBytesPerPixel, screen_size); | |
466 capture_data->mutable_dirty_region().op(screen_rect, SkRegion::kUnion_Op); | |
467 | 476 |
468 VideoDecoderTester decoder_tester(decoder, screen_size, view_size); | 477 VideoDecoderTester decoder_tester(decoder, screen_size, view_size); |
469 decoder_tester.set_capture_data(capture_data); | 478 decoder_tester.set_frame(frame.get()); |
470 decoder_tester.AddRegion(capture_data->dirty_region()); | 479 decoder_tester.AddRegion(frame->updated_region()); |
471 | 480 |
472 encoder->Encode(capture_data, true, | 481 encoder->Encode(frame.get(), |
473 base::Bind(&VideoDecoderTester::ReceivedScopedPacket, | 482 base::Bind(&VideoDecoderTester::ReceivedScopedPacket, |
474 base::Unretained(&decoder_tester))); | 483 base::Unretained(&decoder_tester))); |
475 | 484 |
476 decoder_tester.VerifyResultsApprox(expected_view_data.get(), | 485 decoder_tester.VerifyResultsApprox(expected_result->data(), |
477 max_error_limit, mean_error_limit); | 486 max_error_limit, mean_error_limit); |
478 | 487 |
479 // Check that the decoder correctly re-renders the frame if its client | 488 // Check that the decoder correctly re-renders the frame if its client |
480 // invalidates the frame. | 489 // invalidates the frame. |
481 decoder_tester.ResetRenderedData(); | 490 decoder_tester.ResetRenderedData(); |
482 decoder->Invalidate(view_size, SkRegion(view_rect)); | 491 decoder->Invalidate( |
| 492 SkISize::Make(view_size.width(), view_size.height()), |
| 493 SkRegion(SkIRect::MakeWH(view_size.width(), view_size.height()))); |
483 decoder_tester.RenderFrame(); | 494 decoder_tester.RenderFrame(); |
484 decoder_tester.VerifyResultsApprox(expected_view_data.get(), | 495 decoder_tester.VerifyResultsApprox(expected_result->data(), |
485 max_error_limit, mean_error_limit); | 496 max_error_limit, mean_error_limit); |
486 } | 497 } |
487 | 498 |
488 } // namespace remoting | 499 } // namespace remoting |
OLD | NEW |