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 // Unit test for VideoCaptureController. | 5 // Unit test for VideoCaptureController. |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 #include "gpu/command_buffer/common/mailbox_holder.h" | 22 #include "gpu/command_buffer/common/mailbox_holder.h" |
23 #include "media/base/video_capture_types.h" | 23 #include "media/base/video_capture_types.h" |
24 #include "media/base/video_util.h" | 24 #include "media/base/video_util.h" |
25 #include "testing/gmock/include/gmock/gmock.h" | 25 #include "testing/gmock/include/gmock/gmock.h" |
26 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
27 | 27 |
28 #if !defined(OS_ANDROID) | 28 #if !defined(OS_ANDROID) |
29 #include "content/browser/compositor/test/no_transport_image_transport_factory.h
" | 29 #include "content/browser/compositor/test/no_transport_image_transport_factory.h
" |
30 #endif | 30 #endif |
31 | 31 |
| 32 using ::testing::_; |
32 using ::testing::InSequence; | 33 using ::testing::InSequence; |
33 using ::testing::Mock; | 34 using ::testing::Mock; |
| 35 using ::testing::SaveArg; |
34 | 36 |
35 namespace content { | 37 namespace content { |
36 | 38 |
37 class MockVideoCaptureControllerEventHandler | 39 class MockVideoCaptureControllerEventHandler |
38 : public VideoCaptureControllerEventHandler { | 40 : public VideoCaptureControllerEventHandler { |
39 public: | 41 public: |
40 explicit MockVideoCaptureControllerEventHandler( | 42 explicit MockVideoCaptureControllerEventHandler( |
41 VideoCaptureController* controller) | 43 VideoCaptureController* controller) |
42 : controller_(controller) {} | 44 : controller_(controller) {} |
43 virtual ~MockVideoCaptureControllerEventHandler() {} | 45 virtual ~MockVideoCaptureControllerEventHandler() {} |
44 | 46 |
45 // These mock methods are delegated to by our fake implementation of | 47 // These mock methods are delegated to by our fake implementation of |
46 // VideoCaptureControllerEventHandler, to be used in EXPECT_CALL(). | 48 // VideoCaptureControllerEventHandler, to be used in EXPECT_CALL(). |
47 MOCK_METHOD1(DoBufferCreated, void(const VideoCaptureControllerID&)); | 49 MOCK_METHOD1(DoBufferCreated, void(const VideoCaptureControllerID&)); |
48 MOCK_METHOD1(DoBufferDestroyed, void(const VideoCaptureControllerID&)); | 50 MOCK_METHOD1(DoBufferDestroyed, void(const VideoCaptureControllerID&)); |
49 MOCK_METHOD1(DoBufferReady, void(const VideoCaptureControllerID&)); | 51 MOCK_METHOD2(DoBufferReady, void(const VideoCaptureControllerID&, |
| 52 const gfx::Size&)); |
50 MOCK_METHOD1(DoMailboxBufferReady, void(const VideoCaptureControllerID&)); | 53 MOCK_METHOD1(DoMailboxBufferReady, void(const VideoCaptureControllerID&)); |
51 MOCK_METHOD1(DoEnded, void(const VideoCaptureControllerID&)); | 54 MOCK_METHOD1(DoEnded, void(const VideoCaptureControllerID&)); |
52 MOCK_METHOD1(DoError, void(const VideoCaptureControllerID&)); | 55 MOCK_METHOD1(DoError, void(const VideoCaptureControllerID&)); |
53 | 56 |
54 virtual void OnError(const VideoCaptureControllerID& id) override { | 57 virtual void OnError(const VideoCaptureControllerID& id) override { |
55 DoError(id); | 58 DoError(id); |
56 } | 59 } |
57 virtual void OnBufferCreated(const VideoCaptureControllerID& id, | 60 virtual void OnBufferCreated(const VideoCaptureControllerID& id, |
58 base::SharedMemoryHandle handle, | 61 base::SharedMemoryHandle handle, |
59 int length, int buffer_id) override { | 62 int length, int buffer_id) override { |
60 DoBufferCreated(id); | 63 DoBufferCreated(id); |
61 } | 64 } |
62 virtual void OnBufferDestroyed(const VideoCaptureControllerID& id, | 65 virtual void OnBufferDestroyed(const VideoCaptureControllerID& id, |
63 int buffer_id) override { | 66 int buffer_id) override { |
64 DoBufferDestroyed(id); | 67 DoBufferDestroyed(id); |
65 } | 68 } |
66 virtual void OnBufferReady( | 69 virtual void OnBufferReady( |
67 const VideoCaptureControllerID& id, | 70 const VideoCaptureControllerID& id, |
68 int buffer_id, | 71 int buffer_id, |
69 const gfx::Size& coded_size, | 72 const gfx::Size& coded_size, |
70 const gfx::Rect& visible_rect, | 73 const gfx::Rect& visible_rect, |
71 base::TimeTicks timestamp, | 74 base::TimeTicks timestamp, |
72 scoped_ptr<base::DictionaryValue> metadata) override { | 75 scoped_ptr<base::DictionaryValue> metadata) override { |
73 DoBufferReady(id); | 76 DoBufferReady(id, coded_size); |
74 base::MessageLoop::current()->PostTask( | 77 base::MessageLoop::current()->PostTask( |
75 FROM_HERE, | 78 FROM_HERE, |
76 base::Bind(&VideoCaptureController::ReturnBuffer, | 79 base::Bind(&VideoCaptureController::ReturnBuffer, |
77 base::Unretained(controller_), | 80 base::Unretained(controller_), |
78 id, | 81 id, |
79 this, | 82 this, |
80 buffer_id, | 83 buffer_id, |
81 0)); | 84 0)); |
82 } | 85 } |
83 virtual void OnMailboxBufferReady( | 86 virtual void OnMailboxBufferReady( |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 // side effect this will cause the first buffer to be shared with clients. | 325 // side effect this will cause the first buffer to be shared with clients. |
323 uint8 buffer_no = 1; | 326 uint8 buffer_no = 1; |
324 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> buffer; | 327 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> buffer; |
325 buffer = | 328 buffer = |
326 device_->ReserveOutputBuffer(media::VideoFrame::I420, capture_resolution); | 329 device_->ReserveOutputBuffer(media::VideoFrame::I420, capture_resolution); |
327 ASSERT_TRUE(buffer.get()); | 330 ASSERT_TRUE(buffer.get()); |
328 memset(buffer->data(), buffer_no++, buffer->size()); | 331 memset(buffer->data(), buffer_no++, buffer->size()); |
329 { | 332 { |
330 InSequence s; | 333 InSequence s; |
331 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_1)).Times(1); | 334 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_1)).Times(1); |
332 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1)).Times(1); | 335 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1,_)).Times(1); |
333 } | 336 } |
334 { | 337 { |
335 InSequence s; | 338 InSequence s; |
336 EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_1)).Times(1); | 339 EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_1)).Times(1); |
337 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1)).Times(1); | 340 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1,_)).Times(1); |
338 } | 341 } |
339 { | 342 { |
340 InSequence s; | 343 InSequence s; |
341 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_2)).Times(1); | 344 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_2)).Times(1); |
342 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2)).Times(1); | 345 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2,_)).Times(1); |
343 } | 346 } |
344 device_->OnIncomingCapturedVideoFrame( | 347 device_->OnIncomingCapturedVideoFrame( |
345 buffer, | 348 buffer, |
346 WrapI420Buffer(buffer, capture_resolution), | 349 WrapI420Buffer(buffer, capture_resolution), |
347 base::TimeTicks()); | 350 base::TimeTicks()); |
348 buffer = NULL; | 351 buffer = NULL; |
349 | 352 |
350 base::RunLoop().RunUntilIdle(); | 353 base::RunLoop().RunUntilIdle(); |
351 Mock::VerifyAndClearExpectations(client_a_.get()); | 354 Mock::VerifyAndClearExpectations(client_a_.get()); |
352 Mock::VerifyAndClearExpectations(client_b_.get()); | 355 Mock::VerifyAndClearExpectations(client_b_.get()); |
353 | 356 |
354 // Second buffer which ought to use the same shared memory buffer. In this | 357 // Second buffer which ought to use the same shared memory buffer. In this |
355 // case pretend that the Buffer pointer is held by the device for a long | 358 // case pretend that the Buffer pointer is held by the device for a long |
356 // delay. This shouldn't affect anything. | 359 // delay. This shouldn't affect anything. |
357 buffer = | 360 buffer = |
358 device_->ReserveOutputBuffer(media::VideoFrame::I420, capture_resolution); | 361 device_->ReserveOutputBuffer(media::VideoFrame::I420, capture_resolution); |
359 ASSERT_TRUE(buffer.get()); | 362 ASSERT_TRUE(buffer.get()); |
360 memset(buffer->data(), buffer_no++, buffer->size()); | 363 memset(buffer->data(), buffer_no++, buffer->size()); |
361 device_->OnIncomingCapturedVideoFrame( | 364 device_->OnIncomingCapturedVideoFrame( |
362 buffer, | 365 buffer, |
363 WrapI420Buffer(buffer, capture_resolution), | 366 WrapI420Buffer(buffer, capture_resolution), |
364 base::TimeTicks()); | 367 base::TimeTicks()); |
365 buffer = NULL; | 368 buffer = NULL; |
366 | 369 |
367 // The buffer should be delivered to the clients in any order. | 370 // The buffer should be delivered to the clients in any order. |
368 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1)).Times(1); | 371 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1,_)).Times(1); |
369 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1)).Times(1); | 372 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1,_)).Times(1); |
370 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2)).Times(1); | 373 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2,_)).Times(1); |
371 base::RunLoop().RunUntilIdle(); | 374 base::RunLoop().RunUntilIdle(); |
372 Mock::VerifyAndClearExpectations(client_a_.get()); | 375 Mock::VerifyAndClearExpectations(client_a_.get()); |
373 Mock::VerifyAndClearExpectations(client_b_.get()); | 376 Mock::VerifyAndClearExpectations(client_b_.get()); |
374 | 377 |
375 // Add a fourth client now that some buffers have come through. | 378 // Add a fourth client now that some buffers have come through. |
376 controller_->AddClient(client_b_route_2, | 379 controller_->AddClient(client_b_route_2, |
377 client_b_.get(), | 380 client_b_.get(), |
378 base::kNullProcessHandle, | 381 base::kNullProcessHandle, |
379 1, | 382 1, |
380 session_1); | 383 session_1); |
(...skipping 10 matching lines...) Expand all Loading... |
391 WrapI420Buffer(buffer, capture_resolution), | 394 WrapI420Buffer(buffer, capture_resolution), |
392 base::TimeTicks()); | 395 base::TimeTicks()); |
393 buffer = NULL; | 396 buffer = NULL; |
394 } | 397 } |
395 // ReserveOutputBuffer ought to fail now, because the pool is depleted. | 398 // ReserveOutputBuffer ought to fail now, because the pool is depleted. |
396 ASSERT_FALSE(device_->ReserveOutputBuffer(media::VideoFrame::I420, | 399 ASSERT_FALSE(device_->ReserveOutputBuffer(media::VideoFrame::I420, |
397 capture_resolution).get()); | 400 capture_resolution).get()); |
398 | 401 |
399 // The new client needs to be told of 3 buffers; the old clients only 2. | 402 // The new client needs to be told of 3 buffers; the old clients only 2. |
400 EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_2)).Times(kPoolSize); | 403 EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_2)).Times(kPoolSize); |
401 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_2)).Times(kPoolSize); | 404 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_2,_)).Times(kPoolSize); |
402 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_1)) | 405 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_1)) |
403 .Times(kPoolSize - 1); | 406 .Times(kPoolSize - 1); |
404 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1)).Times(kPoolSize); | 407 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1,_)).Times(kPoolSize); |
405 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_2)) | 408 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_2)) |
406 .Times(kPoolSize - 1); | 409 .Times(kPoolSize - 1); |
407 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2)).Times(kPoolSize); | 410 EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2,_)).Times(kPoolSize); |
408 EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_1)) | 411 EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_1)) |
409 .Times(kPoolSize - 1); | 412 .Times(kPoolSize - 1); |
410 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1)).Times(kPoolSize); | 413 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_1,_)).Times(kPoolSize); |
411 base::RunLoop().RunUntilIdle(); | 414 base::RunLoop().RunUntilIdle(); |
412 Mock::VerifyAndClearExpectations(client_a_.get()); | 415 Mock::VerifyAndClearExpectations(client_a_.get()); |
413 Mock::VerifyAndClearExpectations(client_b_.get()); | 416 Mock::VerifyAndClearExpectations(client_b_.get()); |
414 | 417 |
415 // Now test the interaction of client shutdown and buffer delivery. | 418 // Now test the interaction of client shutdown and buffer delivery. |
416 // Kill A1 via renderer disconnect (synchronous). | 419 // Kill A1 via renderer disconnect (synchronous). |
417 controller_->RemoveClient(client_a_route_1, client_a_.get()); | 420 controller_->RemoveClient(client_a_route_1, client_a_.get()); |
418 // Kill B1 via session close (posts a task to disconnect). | 421 // Kill B1 via session close (posts a task to disconnect). |
419 EXPECT_CALL(*client_b_, DoEnded(client_b_route_1)).Times(1); | 422 EXPECT_CALL(*client_b_, DoEnded(client_b_route_1)).Times(1); |
420 controller_->StopSession(300); | 423 controller_->StopSession(300); |
(...skipping 17 matching lines...) Expand all Loading... |
438 } | 441 } |
439 ASSERT_TRUE(buffer.get()); | 442 ASSERT_TRUE(buffer.get()); |
440 memset(buffer->data(), buffer_no++, buffer->size()); | 443 memset(buffer->data(), buffer_no++, buffer->size()); |
441 device_->OnIncomingCapturedVideoFrame( | 444 device_->OnIncomingCapturedVideoFrame( |
442 buffer, | 445 buffer, |
443 WrapI420Buffer(buffer, capture_resolution), | 446 WrapI420Buffer(buffer, capture_resolution), |
444 base::TimeTicks()); | 447 base::TimeTicks()); |
445 buffer = NULL; | 448 buffer = NULL; |
446 // B2 is the only client left, and is the only one that should | 449 // B2 is the only client left, and is the only one that should |
447 // get the buffer. | 450 // get the buffer. |
448 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_2)).Times(2); | 451 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_2,_)).Times(2); |
449 base::RunLoop().RunUntilIdle(); | 452 base::RunLoop().RunUntilIdle(); |
450 Mock::VerifyAndClearExpectations(client_a_.get()); | 453 Mock::VerifyAndClearExpectations(client_a_.get()); |
451 Mock::VerifyAndClearExpectations(client_b_.get()); | 454 Mock::VerifyAndClearExpectations(client_b_.get()); |
452 | 455 |
453 // Allocate all buffers from the buffer pool, half as SHM buffer and half as | 456 // Allocate all buffers from the buffer pool, half as SHM buffer and half as |
454 // mailbox buffers. Make sure of different counts though. | 457 // mailbox buffers. Make sure of different counts though. |
455 #if defined(OS_ANDROID) | 458 #if defined(OS_ANDROID) |
456 int mailbox_buffers = 0; | 459 int mailbox_buffers = 0; |
457 #else | 460 #else |
458 int mailbox_buffers = kPoolSize / 2; | 461 int mailbox_buffers = kPoolSize / 2; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 capture_resolution), | 494 capture_resolution), |
492 base::TimeTicks()); | 495 base::TimeTicks()); |
493 buffer = NULL; | 496 buffer = NULL; |
494 } | 497 } |
495 // ReserveOutputBuffers ought to fail now regardless of buffer format, because | 498 // ReserveOutputBuffers ought to fail now regardless of buffer format, because |
496 // the pool is depleted. | 499 // the pool is depleted. |
497 ASSERT_FALSE(device_->ReserveOutputBuffer(media::VideoFrame::I420, | 500 ASSERT_FALSE(device_->ReserveOutputBuffer(media::VideoFrame::I420, |
498 capture_resolution).get()); | 501 capture_resolution).get()); |
499 ASSERT_FALSE(device_->ReserveOutputBuffer(media::VideoFrame::NATIVE_TEXTURE, | 502 ASSERT_FALSE(device_->ReserveOutputBuffer(media::VideoFrame::NATIVE_TEXTURE, |
500 gfx::Size(0, 0)).get()); | 503 gfx::Size(0, 0)).get()); |
501 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_2)).Times(shm_buffers); | 504 EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_2,_)).Times(shm_buffers); |
502 EXPECT_CALL(*client_b_, DoMailboxBufferReady(client_b_route_2)) | 505 EXPECT_CALL(*client_b_, DoMailboxBufferReady(client_b_route_2)) |
503 .Times(mailbox_buffers); | 506 .Times(mailbox_buffers); |
504 base::RunLoop().RunUntilIdle(); | 507 base::RunLoop().RunUntilIdle(); |
505 for (size_t i = 0; i < mailbox_syncpoints.size(); ++i) { | 508 for (size_t i = 0; i < mailbox_syncpoints.size(); ++i) { |
506 // A new release sync point must be inserted when the video frame is | 509 // A new release sync point must be inserted when the video frame is |
507 // returned to the Browser process. | 510 // returned to the Browser process. |
508 // See: MockVideoCaptureControllerEventHandler::OnMailboxBufferReady() and | 511 // See: MockVideoCaptureControllerEventHandler::OnMailboxBufferReady() and |
509 // VideoCaptureController::ReturnBuffer() | 512 // VideoCaptureController::ReturnBuffer() |
510 ASSERT_NE(mailbox_syncpoints[i], release_syncpoints[i]); | 513 ASSERT_NE(mailbox_syncpoints[i], release_syncpoints[i]); |
511 } | 514 } |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 TEST_F(VideoCaptureControllerTest, DataCaptureInEachVideoFormatInSequence) { | 612 TEST_F(VideoCaptureControllerTest, DataCaptureInEachVideoFormatInSequence) { |
610 // The usual ReserveOutputBuffer() -> OnIncomingCapturedVideoFrame() cannot | 613 // The usual ReserveOutputBuffer() -> OnIncomingCapturedVideoFrame() cannot |
611 // be used since it does not accept all pixel formats. The memory backed | 614 // be used since it does not accept all pixel formats. The memory backed |
612 // buffer OnIncomingCapturedData() is used instead, with a dummy scratchpad | 615 // buffer OnIncomingCapturedData() is used instead, with a dummy scratchpad |
613 // buffer. | 616 // buffer. |
614 const size_t kScratchpadSizeInBytes = 400; | 617 const size_t kScratchpadSizeInBytes = 400; |
615 unsigned char data[kScratchpadSizeInBytes]; | 618 unsigned char data[kScratchpadSizeInBytes]; |
616 const gfx::Size capture_resolution(10, 10); | 619 const gfx::Size capture_resolution(10, 10); |
617 ASSERT_GE(kScratchpadSizeInBytes, capture_resolution.GetArea() * 4u) | 620 ASSERT_GE(kScratchpadSizeInBytes, capture_resolution.GetArea() * 4u) |
618 << "Scratchpad is too small to hold the largest pixel format (ARGB)."; | 621 << "Scratchpad is too small to hold the largest pixel format (ARGB)."; |
| 622 |
| 623 const int kSessionId = 100; |
619 // This Test skips PIXEL_FORMAT_TEXTURE and PIXEL_FORMAT_UNKNOWN. | 624 // This Test skips PIXEL_FORMAT_TEXTURE and PIXEL_FORMAT_UNKNOWN. |
620 for (int format = 0; format < media::PIXEL_FORMAT_TEXTURE; ++format) { | 625 for (int format = 0; format < media::PIXEL_FORMAT_TEXTURE; ++format) { |
621 media::VideoCaptureParams params; | 626 media::VideoCaptureParams params; |
622 params.requested_format = media::VideoCaptureFormat( | 627 params.requested_format = media::VideoCaptureFormat( |
623 capture_resolution, 30, media::VideoPixelFormat(format)); | 628 capture_resolution, 30, media::VideoPixelFormat(format)); |
624 | 629 |
625 const gfx::Size capture_resolution(320, 240); | |
626 | |
627 const VideoCaptureControllerID route(0x99); | |
628 | |
629 // Start with one client. | 630 // Start with one client. |
630 controller_->AddClient(route, | 631 const VideoCaptureControllerID route_id(0x99); |
| 632 controller_->AddClient(route_id, |
631 client_a_.get(), | 633 client_a_.get(), |
632 base::kNullProcessHandle, | 634 base::kNullProcessHandle, |
633 100, | 635 kSessionId, |
634 params); | 636 params); |
635 ASSERT_EQ(1, controller_->GetClientCount()); | 637 ASSERT_EQ(1, controller_->GetClientCount()); |
636 device_->OnIncomingCapturedData( | 638 device_->OnIncomingCapturedData( |
637 data, | 639 data, |
638 params.requested_format.ImageAllocationSize(), | 640 params.requested_format.ImageAllocationSize(), |
639 params.requested_format, | 641 params.requested_format, |
640 0 /* rotation */, | 642 0 /* clockwise_rotation */, |
641 base::TimeTicks()); | 643 base::TimeTicks()); |
642 EXPECT_EQ(100, controller_->RemoveClient(route, client_a_.get())); | 644 EXPECT_EQ(kSessionId, controller_->RemoveClient(route_id, client_a_.get())); |
643 Mock::VerifyAndClearExpectations(client_a_.get()); | 645 Mock::VerifyAndClearExpectations(client_a_.get()); |
644 } | 646 } |
645 } | 647 } |
| 648 |
| 649 // Test that we receive the expected resolution for a given captured frame |
| 650 // resolution and rotation. Odd resolutions are also cropped. |
| 651 TEST_F(VideoCaptureControllerTest, CheckRotationsAndCrops) { |
| 652 const int kSessionId = 100; |
| 653 const struct SizeAndRotation { |
| 654 gfx::Size input_resolution; |
| 655 int rotation; |
| 656 gfx::Size output_resolution; |
| 657 } kSizeAndRotations[] = {{{6, 4}, 0, {6, 4}}, |
| 658 {{6, 4}, 90, {4, 6}}, |
| 659 {{6, 4}, 180, {6, 4}}, |
| 660 {{6, 4}, 270, {4, 6}}, |
| 661 {{7, 4}, 0, {6, 4}}, |
| 662 {{7, 4}, 90, {4, 6}}, |
| 663 {{7, 4}, 180, {6, 4}}, |
| 664 {{7, 4}, 270, {4, 6}}}; |
| 665 // The usual ReserveOutputBuffer() -> OnIncomingCapturedVideoFrame() cannot |
| 666 // be used since it does not resolve rotations or crops. The memory backed |
| 667 // buffer OnIncomingCapturedData() is used instead, with a dummy scratchpad |
| 668 // buffer. |
| 669 const size_t kScratchpadSizeInBytes = 400; |
| 670 unsigned char data[kScratchpadSizeInBytes]; |
| 671 |
| 672 media::VideoCaptureParams params; |
| 673 for (const auto& size_and_rotation : kSizeAndRotations) { |
| 674 ASSERT_GE(kScratchpadSizeInBytes, |
| 675 size_and_rotation.input_resolution.GetArea() * 4u) |
| 676 << "Scratchpad is too small to hold the largest pixel format (ARGB)."; |
| 677 |
| 678 params.requested_format = media::VideoCaptureFormat( |
| 679 size_and_rotation.input_resolution, 30, media::PIXEL_FORMAT_ARGB); |
| 680 |
| 681 const VideoCaptureControllerID route_id(0x99); |
| 682 controller_->AddClient(route_id, client_a_.get(), base::kNullProcessHandle, |
| 683 kSessionId, params); |
| 684 ASSERT_EQ(1, controller_->GetClientCount()); |
| 685 |
| 686 device_->OnIncomingCapturedData( |
| 687 data, |
| 688 params.requested_format.ImageAllocationSize(), |
| 689 params.requested_format, |
| 690 size_and_rotation.rotation, |
| 691 base::TimeTicks()); |
| 692 gfx::Size coded_size; |
| 693 { |
| 694 InSequence s; |
| 695 EXPECT_CALL(*client_a_, DoBufferCreated(route_id)).Times(1); |
| 696 EXPECT_CALL(*client_a_, DoBufferReady(route_id, _)) |
| 697 .Times(1) |
| 698 .WillOnce(SaveArg<1>(&coded_size)); |
| 699 } |
| 700 base::RunLoop().RunUntilIdle(); |
| 701 |
| 702 EXPECT_EQ(coded_size.width(), size_and_rotation.output_resolution.width()); |
| 703 EXPECT_EQ(coded_size.height(), |
| 704 size_and_rotation.output_resolution.height()); |
| 705 |
| 706 EXPECT_EQ(kSessionId, controller_->RemoveClient(route_id, client_a_.get())); |
| 707 Mock::VerifyAndClearExpectations(client_a_.get()); |
| 708 } |
| 709 } |
646 | 710 |
647 } // namespace content | 711 } // namespace content |
OLD | NEW |