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