| 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 DoBufferDestroyed(id); | 79 DoBufferDestroyed(id); |
| 80 } | 80 } |
| 81 void OnBufferReady(VideoCaptureControllerID id, | 81 void OnBufferReady(VideoCaptureControllerID id, |
| 82 int buffer_id, | 82 int buffer_id, |
| 83 const scoped_refptr<media::VideoFrame>& frame, | 83 const scoped_refptr<media::VideoFrame>& frame, |
| 84 const base::TimeTicks& timestamp) override { | 84 const base::TimeTicks& timestamp) override { |
| 85 if (!frame->HasTextures()) { | 85 if (!frame->HasTextures()) { |
| 86 EXPECT_EQ(frame->format(), media::PIXEL_FORMAT_I420); | 86 EXPECT_EQ(frame->format(), media::PIXEL_FORMAT_I420); |
| 87 DoI420BufferReady(id, frame->coded_size()); | 87 DoI420BufferReady(id, frame->coded_size()); |
| 88 base::ThreadTaskRunnerHandle::Get()->PostTask( | 88 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 89 FROM_HERE, base::Bind(&VideoCaptureController::ReturnBuffer, | 89 FROM_HERE, |
| 90 base::Unretained(controller_), id, this, | 90 base::Bind(&VideoCaptureController::ReturnBuffer, |
| 91 buffer_id, 0, resource_utilization_)); | 91 base::Unretained(controller_), id, this, buffer_id, |
| 92 gpu::SyncToken(), resource_utilization_)); |
| 92 } else { | 93 } else { |
| 93 EXPECT_EQ(frame->format(), media::PIXEL_FORMAT_ARGB); | 94 EXPECT_EQ(frame->format(), media::PIXEL_FORMAT_ARGB); |
| 94 DoTextureBufferReady(id, frame->coded_size()); | 95 DoTextureBufferReady(id, frame->coded_size()); |
| 95 base::ThreadTaskRunnerHandle::Get()->PostTask( | 96 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 96 FROM_HERE, base::Bind(&VideoCaptureController::ReturnBuffer, | 97 FROM_HERE, base::Bind(&VideoCaptureController::ReturnBuffer, |
| 97 base::Unretained(controller_), id, this, | 98 base::Unretained(controller_), id, this, |
| 98 buffer_id, frame->mailbox_holder(0).sync_point, | 99 buffer_id, frame->mailbox_holder(0).sync_token, |
| 99 resource_utilization_)); | 100 resource_utilization_)); |
| 100 } | 101 } |
| 101 } | 102 } |
| 102 void OnEnded(VideoCaptureControllerID id) override { | 103 void OnEnded(VideoCaptureControllerID id) override { |
| 103 DoEnded(id); | 104 DoEnded(id); |
| 104 // OnEnded() must respond by (eventually) unregistering the client. | 105 // OnEnded() must respond by (eventually) unregistering the client. |
| 105 base::ThreadTaskRunnerHandle::Get()->PostTask( | 106 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 106 FROM_HERE, | 107 FROM_HERE, |
| 107 base::Bind(base::IgnoreResult(&VideoCaptureController::RemoveClient), | 108 base::Bind(base::IgnoreResult(&VideoCaptureController::RemoveClient), |
| 108 base::Unretained(controller_), id, this)); | 109 base::Unretained(controller_), id, this)); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 ASSERT_EQ(1, controller_->GetClientCount()) | 254 ASSERT_EQ(1, controller_->GetClientCount()) |
| 254 << "Removing non-existant session 200 should be a no-op."; | 255 << "Removing non-existant session 200 should be a no-op."; |
| 255 ASSERT_EQ(400, | 256 ASSERT_EQ(400, |
| 256 controller_->RemoveClient(client_b_route_2, client_b_.get())) | 257 controller_->RemoveClient(client_b_route_2, client_b_.get())) |
| 257 << "Removing client B/2 should return its session_id."; | 258 << "Removing client B/2 should return its session_id."; |
| 258 // Clients in controller: [] | 259 // Clients in controller: [] |
| 259 ASSERT_EQ(0, controller_->GetClientCount()) | 260 ASSERT_EQ(0, controller_->GetClientCount()) |
| 260 << "Client count should return to zero after all clients are gone."; | 261 << "Client count should return to zero after all clients are gone."; |
| 261 } | 262 } |
| 262 | 263 |
| 263 static void CacheSyncPoint(uint32* called_release_sync_point, | 264 static void CacheSyncToken(gpu::SyncToken* called_release_sync_token, |
| 264 uint32 release_sync_point) { | 265 const gpu::SyncToken& release_sync_token) { |
| 265 *called_release_sync_point = release_sync_point; | 266 *called_release_sync_token = release_sync_token; |
| 266 } | 267 } |
| 267 | 268 |
| 268 // This test will connect and disconnect several clients while simulating an | 269 // This test will connect and disconnect several clients while simulating an |
| 269 // active capture device being started and generating frames. It runs on one | 270 // active capture device being started and generating frames. It runs on one |
| 270 // thread and is intended to behave deterministically. | 271 // thread and is intended to behave deterministically. |
| 271 TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) { | 272 TEST_F(VideoCaptureControllerTest, NormalCaptureMultipleClients) { |
| 272 // VideoCaptureController::ReturnBuffer() uses ImageTransportFactory. | 273 // VideoCaptureController::ReturnBuffer() uses ImageTransportFactory. |
| 273 #if !defined(OS_ANDROID) | 274 #if !defined(OS_ANDROID) |
| 274 ImageTransportFactory::InitializeForUnitTests( | 275 ImageTransportFactory::InitializeForUnitTests( |
| 275 scoped_ptr<ImageTransportFactory>(new NoTransportImageTransportFactory)); | 276 scoped_ptr<ImageTransportFactory>(new NoTransportImageTransportFactory)); |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 517 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer = | 518 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer = |
| 518 device_->ReserveOutputBuffer(capture_resolution, | 519 device_->ReserveOutputBuffer(capture_resolution, |
| 519 media::PIXEL_FORMAT_I420, | 520 media::PIXEL_FORMAT_I420, |
| 520 media::PIXEL_STORAGE_CPU); | 521 media::PIXEL_STORAGE_CPU); |
| 521 ASSERT_TRUE(buffer.get()); | 522 ASSERT_TRUE(buffer.get()); |
| 522 video_frame = | 523 video_frame = |
| 523 WrapI420Buffer(capture_resolution, static_cast<uint8*>(buffer->data())); | 524 WrapI420Buffer(capture_resolution, static_cast<uint8*>(buffer->data())); |
| 524 device_->OnIncomingCapturedVideoFrame(buffer.Pass(), video_frame, | 525 device_->OnIncomingCapturedVideoFrame(buffer.Pass(), video_frame, |
| 525 base::TimeTicks()); | 526 base::TimeTicks()); |
| 526 } | 527 } |
| 527 std::vector<uint32> mailbox_syncpoints(mailbox_buffers); | 528 std::vector<gpu::SyncToken> mailbox_synctokens(mailbox_buffers); |
| 528 std::vector<uint32> release_syncpoints(mailbox_buffers); | 529 std::vector<gpu::SyncToken> release_synctokens(mailbox_buffers); |
| 529 for (int i = 0; i < mailbox_buffers; ++i) { | 530 for (int i = 0; i < mailbox_buffers; ++i) { |
| 530 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer = | 531 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer = |
| 531 device_->ReserveOutputBuffer(capture_resolution, | 532 device_->ReserveOutputBuffer(capture_resolution, |
| 532 media::PIXEL_FORMAT_ARGB, | 533 media::PIXEL_FORMAT_ARGB, |
| 533 media::PIXEL_STORAGE_TEXTURE); | 534 media::PIXEL_STORAGE_TEXTURE); |
| 534 ASSERT_TRUE(buffer.get()); | 535 ASSERT_TRUE(buffer.get()); |
| 535 #if !defined(OS_ANDROID) | 536 #if !defined(OS_ANDROID) |
| 536 mailbox_syncpoints[i] = | 537 mailbox_synctokens[i] = gpu::SyncToken( |
| 537 ImageTransportFactory::GetInstance()->GetGLHelper()->InsertSyncPoint(); | 538 ImageTransportFactory::GetInstance()->GetGLHelper()->InsertSyncPoint()); |
| 538 #endif | 539 #endif |
| 539 device_->OnIncomingCapturedVideoFrame( | 540 device_->OnIncomingCapturedVideoFrame( |
| 540 buffer.Pass(), | 541 buffer.Pass(), |
| 541 WrapMailboxBuffer(gpu::MailboxHolder(gpu::Mailbox::Generate(), 0, | 542 WrapMailboxBuffer(gpu::MailboxHolder(gpu::Mailbox::Generate(), |
| 542 mailbox_syncpoints[i]), | 543 mailbox_synctokens[i], 0), |
| 543 base::Bind(&CacheSyncPoint, &release_syncpoints[i]), | 544 base::Bind(&CacheSyncToken, &release_synctokens[i]), |
| 544 capture_resolution), | 545 capture_resolution), |
| 545 base::TimeTicks()); | 546 base::TimeTicks()); |
| 546 } | 547 } |
| 547 // ReserveOutputBuffers ought to fail now regardless of buffer format, because | 548 // ReserveOutputBuffers ought to fail now regardless of buffer format, because |
| 548 // the pool is depleted. | 549 // the pool is depleted. |
| 549 ASSERT_FALSE( | 550 ASSERT_FALSE( |
| 550 device_->ReserveOutputBuffer(capture_resolution, | 551 device_->ReserveOutputBuffer(capture_resolution, |
| 551 media::PIXEL_FORMAT_I420, | 552 media::PIXEL_FORMAT_I420, |
| 552 media::PIXEL_STORAGE_CPU).get()); | 553 media::PIXEL_STORAGE_CPU).get()); |
| 553 ASSERT_FALSE( | 554 ASSERT_FALSE( |
| 554 device_->ReserveOutputBuffer(capture_resolution, | 555 device_->ReserveOutputBuffer(capture_resolution, |
| 555 media::PIXEL_FORMAT_ARGB, | 556 media::PIXEL_FORMAT_ARGB, |
| 556 media::PIXEL_STORAGE_TEXTURE).get()); | 557 media::PIXEL_STORAGE_TEXTURE).get()); |
| 557 EXPECT_CALL(*client_b_, | 558 EXPECT_CALL(*client_b_, |
| 558 DoI420BufferReady(client_b_route_2, capture_resolution)) | 559 DoI420BufferReady(client_b_route_2, capture_resolution)) |
| 559 .Times(shm_buffers); | 560 .Times(shm_buffers); |
| 560 EXPECT_CALL(*client_b_, | 561 EXPECT_CALL(*client_b_, |
| 561 DoTextureBufferReady(client_b_route_2, capture_resolution)) | 562 DoTextureBufferReady(client_b_route_2, capture_resolution)) |
| 562 .Times(mailbox_buffers); | 563 .Times(mailbox_buffers); |
| 563 #if !defined(OS_ANDROID) | 564 #if !defined(OS_ANDROID) |
| 564 EXPECT_CALL(*client_b_, DoBufferDestroyed(client_b_route_2)); | 565 EXPECT_CALL(*client_b_, DoBufferDestroyed(client_b_route_2)); |
| 565 #endif | 566 #endif |
| 566 base::RunLoop().RunUntilIdle(); | 567 base::RunLoop().RunUntilIdle(); |
| 567 for (size_t i = 0; i < mailbox_syncpoints.size(); ++i) { | 568 for (size_t i = 0; i < mailbox_synctokens.size(); ++i) { |
| 568 // A new release sync point must be inserted when the video frame is | 569 // A new release sync point must be inserted when the video frame is |
| 569 // returned to the Browser process. | 570 // returned to the Browser process. |
| 570 // See: MockVideoCaptureControllerEventHandler::OnMailboxBufferReady() and | 571 // See: MockVideoCaptureControllerEventHandler::OnMailboxBufferReady() and |
| 571 // VideoCaptureController::ReturnBuffer() | 572 // VideoCaptureController::ReturnBuffer() |
| 572 ASSERT_NE(mailbox_syncpoints[i], release_syncpoints[i]); | 573 ASSERT_NE(mailbox_synctokens[i], release_synctokens[i]); |
| 573 } | 574 } |
| 574 Mock::VerifyAndClearExpectations(client_b_.get()); | 575 Mock::VerifyAndClearExpectations(client_b_.get()); |
| 575 | 576 |
| 576 #if !defined(OS_ANDROID) | 577 #if !defined(OS_ANDROID) |
| 577 ImageTransportFactory::Terminate(); | 578 ImageTransportFactory::Terminate(); |
| 578 #endif | 579 #endif |
| 579 } | 580 } |
| 580 | 581 |
| 581 // Exercises the OnError() codepath of VideoCaptureController, and tests the | 582 // Exercises the OnError() codepath of VideoCaptureController, and tests the |
| 582 // behavior of various operations after the error state has been signalled. | 583 // behavior of various operations after the error state has been signalled. |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 661 | 662 |
| 662 // Second client connects after the error state. It also should get told of | 663 // Second client connects after the error state. It also should get told of |
| 663 // the error. | 664 // the error. |
| 664 EXPECT_CALL(*client_b_, DoError(route_id)).Times(1); | 665 EXPECT_CALL(*client_b_, DoError(route_id)).Times(1); |
| 665 controller_->AddClient( | 666 controller_->AddClient( |
| 666 route_id, client_b_.get(), base::kNullProcessHandle, 200, session_200); | 667 route_id, client_b_.get(), base::kNullProcessHandle, 200, session_200); |
| 667 Mock::VerifyAndClearExpectations(client_b_.get()); | 668 Mock::VerifyAndClearExpectations(client_b_.get()); |
| 668 } | 669 } |
| 669 | 670 |
| 670 } // namespace content | 671 } // namespace content |
| OLD | NEW |