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

Side by Side Diff: content/browser/media/capture/desktop_capture_device_unittest.cc

Issue 1135823004: Implement all resolution change policies for desktop and tab capture. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@resolution_change_policy_constraints_ITEM1_CR1
Patch Set: REBASE Created 5 years, 7 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 (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 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 "content/browser/media/capture/desktop_capture_device.h" 5 #include "content/browser/media/capture/desktop_capture_device.h"
6 6
7 #include <algorithm>
7 #include <string> 8 #include <string>
8 9
9 #include "base/basictypes.h" 10 #include "base/basictypes.h"
10 #include "base/synchronization/waitable_event.h" 11 #include "base/synchronization/waitable_event.h"
11 #include "base/test/test_timeouts.h" 12 #include "base/test/test_timeouts.h"
12 #include "base/time/time.h" 13 #include "base/time/time.h"
13 #include "content/public/test/test_browser_thread_bundle.h" 14 #include "content/public/test/test_browser_thread_bundle.h"
14 #include "testing/gmock/include/gmock/gmock.h" 15 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h" 17 #include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
17 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" 18 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
18 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" 19 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
19 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" 20 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
20 21
21 using ::testing::_; 22 using ::testing::_;
22 using ::testing::AnyNumber; 23 using ::testing::AnyNumber;
23 using ::testing::DoAll; 24 using ::testing::DoAll;
24 using ::testing::Expectation; 25 using ::testing::Expectation;
26 using ::testing::Invoke;
25 using ::testing::InvokeWithoutArgs; 27 using ::testing::InvokeWithoutArgs;
26 using ::testing::SaveArg; 28 using ::testing::SaveArg;
29 using ::testing::WithArg;
27 30
28 namespace content { 31 namespace content {
29 32
30 namespace { 33 namespace {
31 34
32 MATCHER_P2(EqualsCaptureCapability, width, height, "") { 35 MATCHER_P2(EqualsCaptureCapability, width, height, "") {
33 return arg.width == width && arg.height == height; 36 return arg.width == width && arg.height == height;
34 } 37 }
35 38
36 const int kTestFrameWidth1 = 100; 39 const int kTestFrameWidth1 = 500;
37 const int kTestFrameHeight1 = 100; 40 const int kTestFrameHeight1 = 500;
38 const int kTestFrameWidth2 = 200; 41 const int kTestFrameWidth2 = 400;
39 const int kTestFrameHeight2 = 150; 42 const int kTestFrameHeight2 = 300;
40 43
41 const int kFrameRate = 30; 44 const int kFrameRate = 30;
42 45
43 // The value of the padding bytes in unpacked frames. 46 // The value of the padding bytes in unpacked frames.
44 const uint8_t kFramePaddingValue = 0; 47 const uint8_t kFramePaddingValue = 0;
45 48
46 // Use a special value for frame pixels to tell pixel bytes apart from the 49 // Use a special value for frame pixels to tell pixel bytes apart from the
47 // padding bytes in the unpacked frame test. 50 // padding bytes in the unpacked frame test.
48 const uint8_t kFakePixelValue = 1; 51 const uint8_t kFakePixelValue = 1;
49 52
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 204
202 bool SelectScreen(webrtc::ScreenId id) override { return false; } 205 bool SelectScreen(webrtc::ScreenId id) override { return false; }
203 206
204 private: 207 private:
205 Callback* callback_; 208 Callback* callback_;
206 int frame_index_; 209 int frame_index_;
207 bool generate_inverted_frames_; 210 bool generate_inverted_frames_;
208 bool generate_cropped_frames_; 211 bool generate_cropped_frames_;
209 }; 212 };
210 213
214 // Helper used to check that only two specific frame sizes are delivered to the
215 // OnIncomingCapturedData() callback.
216 class FormatChecker {
217 public:
218 FormatChecker(const gfx::Size& size_for_even_frames,
219 const gfx::Size& size_for_odd_frames)
220 : size_for_even_frames_(size_for_even_frames),
221 size_for_odd_frames_(size_for_odd_frames),
222 frame_count_(0) {}
223
224 void ExpectAcceptableSize(const media::VideoCaptureFormat& format) {
225 if (frame_count_ % 2 == 0)
226 EXPECT_EQ(size_for_even_frames_, format.frame_size);
227 else
228 EXPECT_EQ(size_for_odd_frames_, format.frame_size);
229 ++frame_count_;
230 EXPECT_EQ(kFrameRate, format.frame_rate);
231 EXPECT_EQ(media::PIXEL_FORMAT_ARGB, format.pixel_format);
232 }
233
234 private:
235 const gfx::Size size_for_even_frames_;
236 const gfx::Size size_for_odd_frames_;
237 int frame_count_;
238 };
239
211 } // namespace 240 } // namespace
212 241
213 class DesktopCaptureDeviceTest : public testing::Test { 242 class DesktopCaptureDeviceTest : public testing::Test {
214 public: 243 public:
215 void CreateScreenCaptureDevice(scoped_ptr<webrtc::DesktopCapturer> capturer) { 244 void CreateScreenCaptureDevice(scoped_ptr<webrtc::DesktopCapturer> capturer) {
216 capture_device_.reset( 245 capture_device_.reset(
217 new DesktopCaptureDevice(capturer.Pass(), DesktopMediaID::TYPE_SCREEN)); 246 new DesktopCaptureDevice(capturer.Pass(), DesktopMediaID::TYPE_SCREEN));
218 } 247 }
219 248
220 void CopyFrame(const uint8_t* frame, int size, 249 void CopyFrame(const uint8_t* frame, int size,
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 EXPECT_EQ(format.frame_size.GetArea() * 4, frame_size); 299 EXPECT_EQ(format.frame_size.GetArea() * 4, frame_size);
271 } 300 }
272 301
273 // Test that screen capturer behaves correctly if the source frame size changes 302 // Test that screen capturer behaves correctly if the source frame size changes
274 // but the caller cannot cope with variable resolution output. 303 // but the caller cannot cope with variable resolution output.
275 TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeConstantResolution) { 304 TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeConstantResolution) {
276 FakeScreenCapturer* mock_capturer = new FakeScreenCapturer(); 305 FakeScreenCapturer* mock_capturer = new FakeScreenCapturer();
277 306
278 CreateScreenCaptureDevice(scoped_ptr<webrtc::DesktopCapturer>(mock_capturer)); 307 CreateScreenCaptureDevice(scoped_ptr<webrtc::DesktopCapturer>(mock_capturer));
279 308
280 media::VideoCaptureFormat format; 309 FormatChecker format_checker(gfx::Size(kTestFrameWidth1, kTestFrameHeight1),
310 gfx::Size(kTestFrameWidth1, kTestFrameHeight1));
281 base::WaitableEvent done_event(false, false); 311 base::WaitableEvent done_event(false, false);
282 int frame_size;
283 312
284 scoped_ptr<MockDeviceClient> client(new MockDeviceClient()); 313 scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
285 EXPECT_CALL(*client, OnError(_)).Times(0); 314 EXPECT_CALL(*client, OnError(_)).Times(0);
286 EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly( 315 EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly(
287 DoAll(SaveArg<1>(&frame_size), 316 DoAll(WithArg<2>(Invoke(&format_checker,
288 SaveArg<2>(&format), 317 &FormatChecker::ExpectAcceptableSize)),
289 InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal))); 318 InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal)));
290 319
291 media::VideoCaptureParams capture_params; 320 media::VideoCaptureParams capture_params;
292 capture_params.requested_format.frame_size.SetSize(kTestFrameWidth1, 321 capture_params.requested_format.frame_size.SetSize(kTestFrameWidth1,
293 kTestFrameHeight1); 322 kTestFrameHeight1);
294 capture_params.requested_format.frame_rate = kFrameRate; 323 capture_params.requested_format.frame_rate = kFrameRate;
295 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; 324 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
325 capture_params.resolution_change_policy =
326 media::RESOLUTION_POLICY_FIXED_RESOLUTION;
296 327
297 capture_device_->AllocateAndStart(capture_params, client.Pass()); 328 capture_device_->AllocateAndStart(capture_params, client.Pass());
298 329
299 // Capture at least two frames, to ensure that the source frame size has 330 // Capture at least two frames, to ensure that the source frame size has
300 // changed while capturing. 331 // changed to two different sizes while capturing. The mock for
301 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); 332 // OnIncomingCapturedData() will use FormatChecker to examine the format of
302 done_event.Reset(); 333 // each frame being delivered.
303 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); 334 for (int i = 0; i < 2; ++i) {
335 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
336 done_event.Reset();
337 }
304 338
305 capture_device_->StopAndDeAllocate(); 339 capture_device_->StopAndDeAllocate();
340 }
306 341
307 EXPECT_EQ(kTestFrameWidth1, format.frame_size.width()); 342 // Test that screen capturer behaves correctly if the source frame size changes,
308 EXPECT_EQ(kTestFrameHeight1, format.frame_size.height()); 343 // where the video frames sent the the client vary in resolution but maintain
309 EXPECT_EQ(kFrameRate, format.frame_rate); 344 // the same aspect ratio.
310 EXPECT_EQ(media::PIXEL_FORMAT_ARGB, format.pixel_format); 345 TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeFixedAspectRatio) {
346 FakeScreenCapturer* mock_capturer = new FakeScreenCapturer();
311 347
312 EXPECT_EQ(format.frame_size.GetArea() * 4, frame_size); 348 CreateScreenCaptureDevice(scoped_ptr<webrtc::DesktopCapturer>(mock_capturer));
349
350 FormatChecker format_checker(gfx::Size(888, 500), gfx::Size(532, 300));
351 base::WaitableEvent done_event(false, false);
352
353 scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
354 EXPECT_CALL(*client, OnError(_)).Times(0);
355 EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly(
356 DoAll(WithArg<2>(Invoke(&format_checker,
357 &FormatChecker::ExpectAcceptableSize)),
358 InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal)));
359
360 media::VideoCaptureParams capture_params;
361 const gfx::Size high_def_16_by_9(1920, 1080);
362 ASSERT_GE(high_def_16_by_9.width(),
363 std::max(kTestFrameWidth1, kTestFrameWidth2));
364 ASSERT_GE(high_def_16_by_9.height(),
365 std::max(kTestFrameHeight1, kTestFrameHeight2));
366 capture_params.requested_format.frame_size = high_def_16_by_9;
367 capture_params.requested_format.frame_rate = kFrameRate;
368 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
369 capture_params.resolution_change_policy =
370 media::RESOLUTION_POLICY_FIXED_ASPECT_RATIO;
371
372 capture_device_->AllocateAndStart(
373 capture_params, client.Pass());
374
375 // Capture at least three frames, to ensure that the source frame size has
376 // changed to two different sizes while capturing. The mock for
377 // OnIncomingCapturedData() will use FormatChecker to examine the format of
378 // each frame being delivered.
379 for (int i = 0; i < 3; ++i) {
380 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
381 done_event.Reset();
382 }
383
384 capture_device_->StopAndDeAllocate();
313 } 385 }
314 386
315 // Test that screen capturer behaves correctly if the source frame size changes 387 // Test that screen capturer behaves correctly if the source frame size changes
316 // and the caller can cope with variable resolution output. 388 // and the caller can cope with variable resolution output.
317 TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeVariableResolution) { 389 TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeVariableResolution) {
318 FakeScreenCapturer* mock_capturer = new FakeScreenCapturer(); 390 FakeScreenCapturer* mock_capturer = new FakeScreenCapturer();
319 391
320 CreateScreenCaptureDevice(scoped_ptr<webrtc::DesktopCapturer>(mock_capturer)); 392 CreateScreenCaptureDevice(scoped_ptr<webrtc::DesktopCapturer>(mock_capturer));
321 393
322 media::VideoCaptureFormat format; 394 FormatChecker format_checker(gfx::Size(kTestFrameWidth1, kTestFrameHeight1),
395 gfx::Size(kTestFrameWidth2, kTestFrameHeight2));
323 base::WaitableEvent done_event(false, false); 396 base::WaitableEvent done_event(false, false);
324 397
325 scoped_ptr<MockDeviceClient> client(new MockDeviceClient()); 398 scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
326 EXPECT_CALL(*client, OnError(_)).Times(0); 399 EXPECT_CALL(*client, OnError(_)).Times(0);
327 EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly( 400 EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly(
328 DoAll(SaveArg<2>(&format), 401 DoAll(WithArg<2>(Invoke(&format_checker,
402 &FormatChecker::ExpectAcceptableSize)),
329 InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal))); 403 InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal)));
330 404
331 media::VideoCaptureParams capture_params; 405 media::VideoCaptureParams capture_params;
332 capture_params.requested_format.frame_size.SetSize(kTestFrameWidth2, 406 const gfx::Size high_def_16_by_9(1920, 1080);
333 kTestFrameHeight2); 407 ASSERT_GE(high_def_16_by_9.width(),
408 std::max(kTestFrameWidth1, kTestFrameWidth2));
409 ASSERT_GE(high_def_16_by_9.height(),
410 std::max(kTestFrameHeight1, kTestFrameHeight2));
411 capture_params.requested_format.frame_size = high_def_16_by_9;
334 capture_params.requested_format.frame_rate = kFrameRate; 412 capture_params.requested_format.frame_rate = kFrameRate;
335 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; 413 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
414 capture_params.resolution_change_policy =
415 media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT;
336 416
337 capture_device_->AllocateAndStart( 417 capture_device_->AllocateAndStart(
338 capture_params, client.Pass()); 418 capture_params, client.Pass());
339 419
340 // Capture at least three frames, to ensure that the source frame size has 420 // Capture at least three frames, to ensure that the source frame size has
341 // changed at least twice while capturing. 421 // changed to two different sizes while capturing. The mock for
342 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); 422 // OnIncomingCapturedData() will use FormatChecker to examine the format of
343 done_event.Reset(); 423 // each frame being delivered.
344 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); 424 for (int i = 0; i < 3; ++i) {
345 done_event.Reset(); 425 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
346 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); 426 done_event.Reset();
427 }
347 428
348 capture_device_->StopAndDeAllocate(); 429 capture_device_->StopAndDeAllocate();
349
350 EXPECT_EQ(kTestFrameWidth1, format.frame_size.width());
351 EXPECT_EQ(kTestFrameHeight1, format.frame_size.height());
352 EXPECT_EQ(kFrameRate, format.frame_rate);
353 EXPECT_EQ(media::PIXEL_FORMAT_ARGB, format.pixel_format);
354 } 430 }
355 431
356 // This test verifies that an unpacked frame is converted to a packed frame. 432 // This test verifies that an unpacked frame is converted to a packed frame.
357 TEST_F(DesktopCaptureDeviceTest, UnpackedFrame) { 433 TEST_F(DesktopCaptureDeviceTest, UnpackedFrame) {
358 FakeScreenCapturer* mock_capturer = new FakeScreenCapturer(); 434 FakeScreenCapturer* mock_capturer = new FakeScreenCapturer();
359 mock_capturer->set_generate_cropped_frames(true); 435 mock_capturer->set_generate_cropped_frames(true);
360 CreateScreenCaptureDevice(scoped_ptr<webrtc::DesktopCapturer>(mock_capturer)); 436 CreateScreenCaptureDevice(scoped_ptr<webrtc::DesktopCapturer>(mock_capturer));
361 437
362 media::VideoCaptureFormat format; 438 media::VideoCaptureFormat format;
363 base::WaitableEvent done_event(false, false); 439 base::WaitableEvent done_event(false, false);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 frame_size); 512 frame_size);
437 for (int i = 0; i < output_frame_->size().height(); ++i) { 513 for (int i = 0; i < output_frame_->size().height(); ++i) {
438 EXPECT_EQ(0, 514 EXPECT_EQ(0,
439 memcmp(inverted_frame->data() + i * inverted_frame->stride(), 515 memcmp(inverted_frame->data() + i * inverted_frame->stride(),
440 output_frame_->data() + i * output_frame_->stride(), 516 output_frame_->data() + i * output_frame_->stride(),
441 output_frame_->stride())); 517 output_frame_->stride()));
442 } 518 }
443 } 519 }
444 520
445 } // namespace content 521 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698