OLD | NEW |
---|---|
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> |
9 #include <vector> | |
8 | 10 |
9 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
10 #include "base/synchronization/waitable_event.h" | 12 #include "base/synchronization/waitable_event.h" |
11 #include "base/test/test_timeouts.h" | 13 #include "base/test/test_timeouts.h" |
12 #include "base/time/time.h" | 14 #include "base/time/time.h" |
13 #include "content/public/test/test_browser_thread_bundle.h" | 15 #include "content/public/test/test_browser_thread_bundle.h" |
14 #include "testing/gmock/include/gmock/gmock.h" | 16 #include "testing/gmock/include/gmock/gmock.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
16 #include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h" | 18 #include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h" |
17 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" | 19 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" |
18 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" | 20 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" |
19 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" | 21 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" |
20 | 22 |
21 using ::testing::_; | 23 using ::testing::_; |
22 using ::testing::AnyNumber; | 24 using ::testing::AnyNumber; |
23 using ::testing::DoAll; | 25 using ::testing::DoAll; |
24 using ::testing::Expectation; | 26 using ::testing::Expectation; |
27 using ::testing::Invoke; | |
25 using ::testing::InvokeWithoutArgs; | 28 using ::testing::InvokeWithoutArgs; |
26 using ::testing::SaveArg; | 29 using ::testing::SaveArg; |
30 using ::testing::WithArg; | |
27 | 31 |
28 namespace content { | 32 namespace content { |
29 | 33 |
30 namespace { | 34 namespace { |
31 | 35 |
32 MATCHER_P2(EqualsCaptureCapability, width, height, "") { | 36 MATCHER_P2(EqualsCaptureCapability, width, height, "") { |
33 return arg.width == width && arg.height == height; | 37 return arg.width == width && arg.height == height; |
34 } | 38 } |
35 | 39 |
36 const int kTestFrameWidth1 = 100; | 40 const int kTestFrameWidth1 = 500; |
37 const int kTestFrameHeight1 = 100; | 41 const int kTestFrameHeight1 = 500; |
38 const int kTestFrameWidth2 = 200; | 42 const int kTestFrameWidth2 = 400; |
39 const int kTestFrameHeight2 = 150; | 43 const int kTestFrameHeight2 = 300; |
40 | 44 |
41 const int kFrameRate = 30; | 45 const int kFrameRate = 30; |
42 | 46 |
43 // The value of the padding bytes in unpacked frames. | 47 // The value of the padding bytes in unpacked frames. |
44 const uint8_t kFramePaddingValue = 0; | 48 const uint8_t kFramePaddingValue = 0; |
45 | 49 |
46 // Use a special value for frame pixels to tell pixel bytes apart from the | 50 // Use a special value for frame pixels to tell pixel bytes apart from the |
47 // padding bytes in the unpacked frame test. | 51 // padding bytes in the unpacked frame test. |
48 const uint8_t kFakePixelValue = 1; | 52 const uint8_t kFakePixelValue = 1; |
49 | 53 |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
286 EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly( | 290 EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly( |
287 DoAll(SaveArg<1>(&frame_size), | 291 DoAll(SaveArg<1>(&frame_size), |
288 SaveArg<2>(&format), | 292 SaveArg<2>(&format), |
289 InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal))); | 293 InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal))); |
290 | 294 |
291 media::VideoCaptureParams capture_params; | 295 media::VideoCaptureParams capture_params; |
292 capture_params.requested_format.frame_size.SetSize(kTestFrameWidth1, | 296 capture_params.requested_format.frame_size.SetSize(kTestFrameWidth1, |
293 kTestFrameHeight1); | 297 kTestFrameHeight1); |
294 capture_params.requested_format.frame_rate = kFrameRate; | 298 capture_params.requested_format.frame_rate = kFrameRate; |
295 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; | 299 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; |
300 capture_params.resolution_change_policy = | |
301 media::RESOLUTION_POLICY_FIXED_RESOLUTION; | |
296 | 302 |
297 capture_device_->AllocateAndStart(capture_params, client.Pass()); | 303 capture_device_->AllocateAndStart(capture_params, client.Pass()); |
298 | 304 |
299 // Capture at least two frames, to ensure that the source frame size has | 305 // Capture at least two frames, to ensure that the source frame size has |
300 // changed while capturing. | 306 // changed while capturing. |
301 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); | 307 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); |
302 done_event.Reset(); | 308 done_event.Reset(); |
303 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); | 309 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); |
304 | 310 |
305 capture_device_->StopAndDeAllocate(); | 311 capture_device_->StopAndDeAllocate(); |
306 | 312 |
307 EXPECT_EQ(kTestFrameWidth1, format.frame_size.width()); | 313 EXPECT_EQ(kTestFrameWidth1, format.frame_size.width()); |
308 EXPECT_EQ(kTestFrameHeight1, format.frame_size.height()); | 314 EXPECT_EQ(kTestFrameHeight1, format.frame_size.height()); |
309 EXPECT_EQ(kFrameRate, format.frame_rate); | 315 EXPECT_EQ(kFrameRate, format.frame_rate); |
310 EXPECT_EQ(media::PIXEL_FORMAT_ARGB, format.pixel_format); | 316 EXPECT_EQ(media::PIXEL_FORMAT_ARGB, format.pixel_format); |
311 | 317 |
312 EXPECT_EQ(format.frame_size.GetArea() * 4, frame_size); | 318 EXPECT_EQ(format.frame_size.GetArea() * 4, frame_size); |
313 } | 319 } |
314 | 320 |
321 // Test that screen capturer behaves correctly if the source frame size changes, | |
322 // where the video frames sent the the client vary in resolution but maintain | |
323 // the same aspect ratio. | |
324 TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeFixedAspectRatio) { | |
325 FakeScreenCapturer* mock_capturer = new FakeScreenCapturer(); | |
326 | |
327 CreateScreenCaptureDevice(scoped_ptr<webrtc::DesktopCapturer>(mock_capturer)); | |
328 | |
329 media::VideoCaptureFormats formats; | |
330 base::WaitableEvent done_event(false, false); | |
331 | |
332 scoped_ptr<MockDeviceClient> client(new MockDeviceClient()); | |
333 EXPECT_CALL(*client, OnError(_)).Times(0); | |
334 void (media::VideoCaptureFormats::*push_back_method)( | |
335 const media::VideoCaptureFormat&) = | |
336 &media::VideoCaptureFormats::push_back; | |
337 EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly( | |
338 DoAll(WithArg<2>(Invoke(&formats, push_back_method)), | |
339 InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal))); | |
340 | |
341 media::VideoCaptureParams capture_params; | |
342 const gfx::Size high_def_16_by_9(1920, 1080); | |
343 ASSERT_GE(high_def_16_by_9.width(), | |
344 std::max(kTestFrameWidth1, kTestFrameWidth2)); | |
345 ASSERT_GE(high_def_16_by_9.height(), | |
346 std::max(kTestFrameHeight1, kTestFrameHeight2)); | |
347 capture_params.requested_format.frame_size = high_def_16_by_9; | |
348 capture_params.requested_format.frame_rate = kFrameRate; | |
349 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; | |
350 capture_params.resolution_change_policy = | |
351 media::RESOLUTION_POLICY_FIXED_ASPECT_RATIO; | |
352 | |
353 capture_device_->AllocateAndStart( | |
354 capture_params, client.Pass()); | |
355 | |
356 // Capture at least three frames, to ensure that the source frame size has | |
357 // changed at least twice while capturing. | |
Wez
2015/05/14 01:44:55
nit: Why is this not a loop?
Why do we care that
miu
2015/05/14 21:12:26
I originally wrote this test by forking the existi
| |
358 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); | |
359 done_event.Reset(); | |
360 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); | |
361 done_event.Reset(); | |
362 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); | |
363 | |
364 capture_device_->StopAndDeAllocate(); | |
365 | |
366 std::vector<gfx::Size> distinct_sizes_seen; | |
367 for (const media::VideoCaptureFormat& f : formats) { | |
Wez
2015/05/14 01:44:55
nit: Could this be:
for (auto format : formats)
miu
2015/05/14 21:12:26
Reply 1: It could, but the style guide suggests on
| |
368 ASSERT_FALSE(f.frame_size.IsEmpty()); | |
369 if (std::find(distinct_sizes_seen.begin(), | |
370 distinct_sizes_seen.end(), | |
371 f.frame_size) == distinct_sizes_seen.end()) { | |
372 distinct_sizes_seen.push_back(f.frame_size); | |
373 } | |
374 EXPECT_EQ(kFrameRate, f.frame_rate); | |
375 EXPECT_EQ(media::PIXEL_FORMAT_ARGB, f.pixel_format); | |
376 } | |
377 EXPECT_EQ(2u, distinct_sizes_seen.size()); | |
Wez
2015/05/14 01:44:55
Is there something about the mock capturer that ca
miu
2015/05/14 21:12:26
Done. Elaborated on this in code comments.
| |
378 for (const gfx::Size& s : distinct_sizes_seen) | |
Wez
2015/05/14 01:44:55
nit: auto here?
miu
2015/05/14 21:12:26
No longer applicable since I've replaced this code
| |
379 EXPECT_NEAR(16.0 / 9.0, static_cast<double>(s.width()) / s.height(), 0.01); | |
380 } | |
381 | |
315 // Test that screen capturer behaves correctly if the source frame size changes | 382 // Test that screen capturer behaves correctly if the source frame size changes |
316 // and the caller can cope with variable resolution output. | 383 // and the caller can cope with variable resolution output. |
317 TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeVariableResolution) { | 384 TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeVariableResolution) { |
318 FakeScreenCapturer* mock_capturer = new FakeScreenCapturer(); | 385 FakeScreenCapturer* mock_capturer = new FakeScreenCapturer(); |
319 | 386 |
320 CreateScreenCaptureDevice(scoped_ptr<webrtc::DesktopCapturer>(mock_capturer)); | 387 CreateScreenCaptureDevice(scoped_ptr<webrtc::DesktopCapturer>(mock_capturer)); |
321 | 388 |
322 media::VideoCaptureFormat format; | 389 media::VideoCaptureFormats formats; |
323 base::WaitableEvent done_event(false, false); | 390 base::WaitableEvent done_event(false, false); |
324 | 391 |
325 scoped_ptr<MockDeviceClient> client(new MockDeviceClient()); | 392 scoped_ptr<MockDeviceClient> client(new MockDeviceClient()); |
326 EXPECT_CALL(*client, OnError(_)).Times(0); | 393 EXPECT_CALL(*client, OnError(_)).Times(0); |
394 void (media::VideoCaptureFormats::*push_back_method)( | |
395 const media::VideoCaptureFormat&) = | |
396 &media::VideoCaptureFormats::push_back; | |
327 EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly( | 397 EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _)).WillRepeatedly( |
328 DoAll(SaveArg<2>(&format), | 398 DoAll(WithArg<2>(Invoke(&formats, push_back_method)), |
329 InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal))); | 399 InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal))); |
330 | 400 |
331 media::VideoCaptureParams capture_params; | 401 media::VideoCaptureParams capture_params; |
332 capture_params.requested_format.frame_size.SetSize(kTestFrameWidth2, | 402 const gfx::Size high_def_16_by_9(1920, 1080); |
333 kTestFrameHeight2); | 403 ASSERT_GE(high_def_16_by_9.width(), |
404 std::max(kTestFrameWidth1, kTestFrameWidth2)); | |
405 ASSERT_GE(high_def_16_by_9.height(), | |
406 std::max(kTestFrameHeight1, kTestFrameHeight2)); | |
407 capture_params.requested_format.frame_size = high_def_16_by_9; | |
334 capture_params.requested_format.frame_rate = kFrameRate; | 408 capture_params.requested_format.frame_rate = kFrameRate; |
335 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; | 409 capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; |
410 capture_params.resolution_change_policy = | |
411 media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT; | |
336 | 412 |
337 capture_device_->AllocateAndStart( | 413 capture_device_->AllocateAndStart( |
338 capture_params, client.Pass()); | 414 capture_params, client.Pass()); |
339 | 415 |
340 // Capture at least three frames, to ensure that the source frame size has | 416 // Capture at least three frames, to ensure that the source frame size has |
341 // changed at least twice while capturing. | 417 // changed at least twice while capturing. |
342 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); | 418 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); |
343 done_event.Reset(); | 419 done_event.Reset(); |
344 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); | 420 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); |
345 done_event.Reset(); | 421 done_event.Reset(); |
346 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); | 422 EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); |
347 | 423 |
348 capture_device_->StopAndDeAllocate(); | 424 capture_device_->StopAndDeAllocate(); |
349 | 425 |
350 EXPECT_EQ(kTestFrameWidth1, format.frame_size.width()); | 426 bool have_seen_frame_size_1 = false; |
351 EXPECT_EQ(kTestFrameHeight1, format.frame_size.height()); | 427 bool have_seen_frame_size_2 = false; |
352 EXPECT_EQ(kFrameRate, format.frame_rate); | 428 bool have_seen_other_frame_size = false; |
353 EXPECT_EQ(media::PIXEL_FORMAT_ARGB, format.pixel_format); | 429 for (const media::VideoCaptureFormat& f : formats) { |
430 if (f.frame_size == gfx::Size(kTestFrameWidth1, kTestFrameHeight1)) | |
431 have_seen_frame_size_1 = true; | |
432 else if (f.frame_size == gfx::Size(kTestFrameWidth2, kTestFrameHeight2)) | |
433 have_seen_frame_size_2 = true; | |
434 else | |
435 have_seen_other_frame_size = true; | |
436 EXPECT_EQ(kFrameRate, f.frame_rate); | |
437 EXPECT_EQ(media::PIXEL_FORMAT_ARGB, f.pixel_format); | |
438 } | |
439 EXPECT_TRUE(have_seen_frame_size_1); | |
440 EXPECT_TRUE(have_seen_frame_size_2); | |
441 EXPECT_FALSE(have_seen_other_frame_size); | |
Wez
2015/05/14 01:44:55
nit: The fixed aspect-ratio test collates a list o
miu
2015/05/14 21:12:26
Done.
| |
354 } | 442 } |
355 | 443 |
356 // This test verifies that an unpacked frame is converted to a packed frame. | 444 // This test verifies that an unpacked frame is converted to a packed frame. |
357 TEST_F(DesktopCaptureDeviceTest, UnpackedFrame) { | 445 TEST_F(DesktopCaptureDeviceTest, UnpackedFrame) { |
358 FakeScreenCapturer* mock_capturer = new FakeScreenCapturer(); | 446 FakeScreenCapturer* mock_capturer = new FakeScreenCapturer(); |
359 mock_capturer->set_generate_cropped_frames(true); | 447 mock_capturer->set_generate_cropped_frames(true); |
360 CreateScreenCaptureDevice(scoped_ptr<webrtc::DesktopCapturer>(mock_capturer)); | 448 CreateScreenCaptureDevice(scoped_ptr<webrtc::DesktopCapturer>(mock_capturer)); |
361 | 449 |
362 media::VideoCaptureFormat format; | 450 media::VideoCaptureFormat format; |
363 base::WaitableEvent done_event(false, false); | 451 base::WaitableEvent done_event(false, false); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
436 frame_size); | 524 frame_size); |
437 for (int i = 0; i < output_frame_->size().height(); ++i) { | 525 for (int i = 0; i < output_frame_->size().height(); ++i) { |
438 EXPECT_EQ(0, | 526 EXPECT_EQ(0, |
439 memcmp(inverted_frame->data() + i * inverted_frame->stride(), | 527 memcmp(inverted_frame->data() + i * inverted_frame->stride(), |
440 output_frame_->data() + i * output_frame_->stride(), | 528 output_frame_->data() + i * output_frame_->stride(), |
441 output_frame_->stride())); | 529 output_frame_->stride())); |
442 } | 530 } |
443 } | 531 } |
444 | 532 |
445 } // namespace content | 533 } // namespace content |
OLD | NEW |