| 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 |