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 "content/browser/renderer_host/media/video_capture_controller.h" | 7 #include "content/browser/renderer_host/media/video_capture_controller.h" |
8 | 8 |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 #include <string.h> | 10 #include <string.h> |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 MOCK_METHOD1(DoBufferDestroyed, void(VideoCaptureControllerID)); | 54 MOCK_METHOD1(DoBufferDestroyed, void(VideoCaptureControllerID)); |
55 MOCK_METHOD2(DoI420BufferReady, | 55 MOCK_METHOD2(DoI420BufferReady, |
56 void(VideoCaptureControllerID, const gfx::Size&)); | 56 void(VideoCaptureControllerID, const gfx::Size&)); |
57 MOCK_METHOD1(DoEnded, void(VideoCaptureControllerID)); | 57 MOCK_METHOD1(DoEnded, void(VideoCaptureControllerID)); |
58 MOCK_METHOD1(DoError, void(VideoCaptureControllerID)); | 58 MOCK_METHOD1(DoError, void(VideoCaptureControllerID)); |
59 | 59 |
60 void OnError(VideoCaptureControllerID id) override { | 60 void OnError(VideoCaptureControllerID id) override { |
61 DoError(id); | 61 DoError(id); |
62 } | 62 } |
63 void OnBufferCreated(VideoCaptureControllerID id, | 63 void OnBufferCreated(VideoCaptureControllerID id, |
64 base::SharedMemoryHandle handle, | 64 mojo::ScopedSharedBufferHandle handle, |
65 int length, int buffer_id) override { | 65 int length, int buffer_id) override { |
66 DoBufferCreated(id); | 66 DoBufferCreated(id); |
67 } | 67 } |
68 void OnBufferDestroyed(VideoCaptureControllerID id, int buffer_id) override { | 68 void OnBufferDestroyed(VideoCaptureControllerID id, int buffer_id) override { |
69 DoBufferDestroyed(id); | 69 DoBufferDestroyed(id); |
70 } | 70 } |
71 void OnBufferReady(VideoCaptureControllerID id, | 71 void OnBufferReady(VideoCaptureControllerID id, |
72 int buffer_id, | 72 int buffer_id, |
73 const scoped_refptr<media::VideoFrame>& frame) override { | 73 const scoped_refptr<media::VideoFrame>& frame) override { |
74 EXPECT_EQ(frame->format(), media::PIXEL_FORMAT_I420); | 74 EXPECT_EQ(frame->format(), media::PIXEL_FORMAT_I420); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 const VideoCaptureControllerID client_a_route_1(44); | 154 const VideoCaptureControllerID client_a_route_1(44); |
155 const VideoCaptureControllerID client_a_route_2(30); | 155 const VideoCaptureControllerID client_a_route_2(30); |
156 const VideoCaptureControllerID client_b_route_1(30); | 156 const VideoCaptureControllerID client_b_route_1(30); |
157 const VideoCaptureControllerID client_b_route_2(1); | 157 const VideoCaptureControllerID client_b_route_2(1); |
158 | 158 |
159 // Clients in controller: [] | 159 // Clients in controller: [] |
160 ASSERT_EQ(0, controller_->GetClientCount()) | 160 ASSERT_EQ(0, controller_->GetClientCount()) |
161 << "Client count should initially be zero."; | 161 << "Client count should initially be zero."; |
162 controller_->AddClient(client_a_route_1, | 162 controller_->AddClient(client_a_route_1, |
163 client_a_.get(), | 163 client_a_.get(), |
164 base::kNullProcessHandle, | |
165 100, | 164 100, |
166 session_100); | 165 session_100); |
167 // Clients in controller: [A/1] | 166 // Clients in controller: [A/1] |
168 ASSERT_EQ(1, controller_->GetClientCount()) | 167 ASSERT_EQ(1, controller_->GetClientCount()) |
169 << "Adding client A/1 should bump client count."; | 168 << "Adding client A/1 should bump client count."; |
170 controller_->AddClient(client_a_route_2, | 169 controller_->AddClient(client_a_route_2, |
171 client_a_.get(), | 170 client_a_.get(), |
172 base::kNullProcessHandle, | |
173 200, | 171 200, |
174 session_200); | 172 session_200); |
175 // Clients in controller: [A/1, A/2] | 173 // Clients in controller: [A/1, A/2] |
176 ASSERT_EQ(2, controller_->GetClientCount()) | 174 ASSERT_EQ(2, controller_->GetClientCount()) |
177 << "Adding client A/2 should bump client count."; | 175 << "Adding client A/2 should bump client count."; |
178 controller_->AddClient(client_b_route_1, | 176 controller_->AddClient(client_b_route_1, |
179 client_b_.get(), | 177 client_b_.get(), |
180 base::kNullProcessHandle, | |
181 300, | 178 300, |
182 session_300); | 179 session_300); |
183 // Clients in controller: [A/1, A/2, B/1] | 180 // Clients in controller: [A/1, A/2, B/1] |
184 ASSERT_EQ(3, controller_->GetClientCount()) | 181 ASSERT_EQ(3, controller_->GetClientCount()) |
185 << "Adding client B/1 should bump client count."; | 182 << "Adding client B/1 should bump client count."; |
186 ASSERT_EQ(200, | 183 ASSERT_EQ(200, |
187 controller_->RemoveClient(client_a_route_2, client_a_.get())) | 184 controller_->RemoveClient(client_a_route_2, client_a_.get())) |
188 << "Removing client A/1 should return its session_id."; | 185 << "Removing client A/1 should return its session_id."; |
189 // Clients in controller: [A/1, B/1] | 186 // Clients in controller: [A/1, B/1] |
190 ASSERT_EQ(2, controller_->GetClientCount()); | 187 ASSERT_EQ(2, controller_->GetClientCount()); |
191 ASSERT_EQ(static_cast<int>(kInvalidMediaCaptureSessionId), | 188 ASSERT_EQ(static_cast<int>(kInvalidMediaCaptureSessionId), |
192 controller_->RemoveClient(client_a_route_2, client_a_.get())) | 189 controller_->RemoveClient(client_a_route_2, client_a_.get())) |
193 << "Removing a nonexistant client should fail."; | 190 << "Removing a nonexistant client should fail."; |
194 // Clients in controller: [A/1, B/1] | 191 // Clients in controller: [A/1, B/1] |
195 ASSERT_EQ(2, controller_->GetClientCount()); | 192 ASSERT_EQ(2, controller_->GetClientCount()); |
196 ASSERT_EQ(300, | 193 ASSERT_EQ(300, |
197 controller_->RemoveClient(client_b_route_1, client_b_.get())) | 194 controller_->RemoveClient(client_b_route_1, client_b_.get())) |
198 << "Removing client B/1 should return its session_id."; | 195 << "Removing client B/1 should return its session_id."; |
199 // Clients in controller: [A/1] | 196 // Clients in controller: [A/1] |
200 ASSERT_EQ(1, controller_->GetClientCount()); | 197 ASSERT_EQ(1, controller_->GetClientCount()); |
201 controller_->AddClient(client_b_route_2, | 198 controller_->AddClient(client_b_route_2, |
202 client_b_.get(), | 199 client_b_.get(), |
203 base::kNullProcessHandle, | |
204 400, | 200 400, |
205 session_400); | 201 session_400); |
206 // Clients in controller: [A/1, B/2] | 202 // Clients in controller: [A/1, B/2] |
207 | 203 |
208 EXPECT_CALL(*client_a_, DoEnded(client_a_route_1)).Times(1); | 204 EXPECT_CALL(*client_a_, DoEnded(client_a_route_1)).Times(1); |
209 controller_->StopSession(100); // Session 100 == client A/1 | 205 controller_->StopSession(100); // Session 100 == client A/1 |
210 Mock::VerifyAndClearExpectations(client_a_.get()); | 206 Mock::VerifyAndClearExpectations(client_a_.get()); |
211 ASSERT_EQ(2, controller_->GetClientCount()) | 207 ASSERT_EQ(2, controller_->GetClientCount()) |
212 << "Client should be closed but still exist after StopSession."; | 208 << "Client should be closed but still exist after StopSession."; |
213 // Clients in controller: [A/1 (closed, removal pending), B/2] | 209 // Clients in controller: [A/1 (closed, removal pending), B/2] |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 gfx::Size(10, 10), 25, media::PIXEL_FORMAT_RGB24); | 255 gfx::Size(10, 10), 25, media::PIXEL_FORMAT_RGB24); |
260 | 256 |
261 const VideoCaptureControllerID client_a_route_1(0xa1a1a1a1); | 257 const VideoCaptureControllerID client_a_route_1(0xa1a1a1a1); |
262 const VideoCaptureControllerID client_a_route_2(0xa2a2a2a2); | 258 const VideoCaptureControllerID client_a_route_2(0xa2a2a2a2); |
263 const VideoCaptureControllerID client_b_route_1(0xb1b1b1b1); | 259 const VideoCaptureControllerID client_b_route_1(0xb1b1b1b1); |
264 const VideoCaptureControllerID client_b_route_2(0xb2b2b2b2); | 260 const VideoCaptureControllerID client_b_route_2(0xb2b2b2b2); |
265 | 261 |
266 // Start with two clients. | 262 // Start with two clients. |
267 controller_->AddClient(client_a_route_1, | 263 controller_->AddClient(client_a_route_1, |
268 client_a_.get(), | 264 client_a_.get(), |
269 base::kNullProcessHandle, | |
270 100, | 265 100, |
271 session_100); | 266 session_100); |
272 controller_->AddClient(client_b_route_1, | 267 controller_->AddClient(client_b_route_1, |
273 client_b_.get(), | 268 client_b_.get(), |
274 base::kNullProcessHandle, | |
275 300, | 269 300, |
276 session_300); | 270 session_300); |
277 controller_->AddClient(client_a_route_2, | 271 controller_->AddClient(client_a_route_2, |
278 client_a_.get(), | 272 client_a_.get(), |
279 base::kNullProcessHandle, | |
280 200, | 273 200, |
281 session_200); | 274 session_200); |
282 ASSERT_EQ(3, controller_->GetClientCount()); | 275 ASSERT_EQ(3, controller_->GetClientCount()); |
283 | 276 |
284 // Now, simulate an incoming captured buffer from the capture device. As a | 277 // Now, simulate an incoming captured buffer from the capture device. As a |
285 // side effect this will cause the first buffer to be shared with clients. | 278 // side effect this will cause the first buffer to be shared with clients. |
286 uint8_t buffer_no = 1; | 279 uint8_t buffer_no = 1; |
287 ASSERT_EQ(0.0, device_->GetBufferPoolUtilization()); | 280 ASSERT_EQ(0.0, device_->GetBufferPoolUtilization()); |
288 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer( | 281 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer( |
289 device_->ReserveOutputBuffer(capture_resolution, media::PIXEL_FORMAT_I420, | 282 device_->ReserveOutputBuffer(capture_resolution, media::PIXEL_FORMAT_I420, |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 // resource utilization of 3.14 (the largest of all reported values). | 376 // resource utilization of 3.14 (the largest of all reported values). |
384 resource_utilization_in_metadata = -1.0; | 377 resource_utilization_in_metadata = -1.0; |
385 ASSERT_TRUE(video_frame->metadata()->GetDouble( | 378 ASSERT_TRUE(video_frame->metadata()->GetDouble( |
386 media::VideoFrameMetadata::RESOURCE_UTILIZATION, | 379 media::VideoFrameMetadata::RESOURCE_UTILIZATION, |
387 &resource_utilization_in_metadata)); | 380 &resource_utilization_in_metadata)); |
388 ASSERT_EQ(3.14, resource_utilization_in_metadata); | 381 ASSERT_EQ(3.14, resource_utilization_in_metadata); |
389 | 382 |
390 // Add a fourth client now that some buffers have come through. | 383 // Add a fourth client now that some buffers have come through. |
391 controller_->AddClient(client_b_route_2, | 384 controller_->AddClient(client_b_route_2, |
392 client_b_.get(), | 385 client_b_.get(), |
393 base::kNullProcessHandle, | |
394 1, | 386 1, |
395 session_1); | 387 session_1); |
396 Mock::VerifyAndClearExpectations(client_b_.get()); | 388 Mock::VerifyAndClearExpectations(client_b_.get()); |
397 | 389 |
398 // Third, fourth, and fifth buffers. Pretend they all arrive at the same time. | 390 // Third, fourth, and fifth buffers. Pretend they all arrive at the same time. |
399 for (int i = 0; i < kPoolSize; i++) { | 391 for (int i = 0; i < kPoolSize; i++) { |
400 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer = | 392 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer = |
401 device_->ReserveOutputBuffer(capture_resolution, | 393 device_->ReserveOutputBuffer(capture_resolution, |
402 media::PIXEL_FORMAT_I420, | 394 media::PIXEL_FORMAT_I420, |
403 media::PIXEL_STORAGE_CPU); | 395 media::PIXEL_STORAGE_CPU); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 session_100.requested_format = media::VideoCaptureFormat( | 486 session_100.requested_format = media::VideoCaptureFormat( |
495 gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420); | 487 gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420); |
496 | 488 |
497 media::VideoCaptureParams session_200 = session_100; | 489 media::VideoCaptureParams session_200 = session_100; |
498 | 490 |
499 const gfx::Size capture_resolution(320, 240); | 491 const gfx::Size capture_resolution(320, 240); |
500 | 492 |
501 const VideoCaptureControllerID route_id(0x99); | 493 const VideoCaptureControllerID route_id(0x99); |
502 | 494 |
503 // Start with one client. | 495 // Start with one client. |
504 controller_->AddClient( | 496 controller_->AddClient(route_id, client_a_.get(), 100, session_100); |
505 route_id, client_a_.get(), base::kNullProcessHandle, 100, session_100); | |
506 device_->OnError(FROM_HERE, "Test Error"); | 497 device_->OnError(FROM_HERE, "Test Error"); |
507 EXPECT_CALL(*client_a_, DoError(route_id)).Times(1); | 498 EXPECT_CALL(*client_a_, DoError(route_id)).Times(1); |
508 base::RunLoop().RunUntilIdle(); | 499 base::RunLoop().RunUntilIdle(); |
509 Mock::VerifyAndClearExpectations(client_a_.get()); | 500 Mock::VerifyAndClearExpectations(client_a_.get()); |
510 | 501 |
511 // Second client connects after the error state. It also should get told of | 502 // Second client connects after the error state. It also should get told of |
512 // the error. | 503 // the error. |
513 EXPECT_CALL(*client_b_, DoError(route_id)).Times(1); | 504 EXPECT_CALL(*client_b_, DoError(route_id)).Times(1); |
514 controller_->AddClient( | 505 controller_->AddClient(route_id, client_b_.get(), 200, session_200); |
515 route_id, client_b_.get(), base::kNullProcessHandle, 200, session_200); | |
516 base::RunLoop().RunUntilIdle(); | 506 base::RunLoop().RunUntilIdle(); |
517 Mock::VerifyAndClearExpectations(client_b_.get()); | 507 Mock::VerifyAndClearExpectations(client_b_.get()); |
518 | 508 |
519 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer( | 509 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer( |
520 device_->ReserveOutputBuffer(capture_resolution, media::PIXEL_FORMAT_I420, | 510 device_->ReserveOutputBuffer(capture_resolution, media::PIXEL_FORMAT_I420, |
521 media::PIXEL_STORAGE_CPU)); | 511 media::PIXEL_STORAGE_CPU)); |
522 ASSERT_TRUE(buffer.get()); | 512 ASSERT_TRUE(buffer.get()); |
523 scoped_refptr<media::VideoFrame> video_frame = | 513 scoped_refptr<media::VideoFrame> video_frame = |
524 WrapI420Buffer(capture_resolution, static_cast<uint8_t*>(buffer->data())); | 514 WrapI420Buffer(capture_resolution, static_cast<uint8_t*>(buffer->data())); |
525 ASSERT_TRUE(video_frame); | 515 ASSERT_TRUE(video_frame); |
526 video_frame->metadata()->SetTimeTicks( | 516 video_frame->metadata()->SetTimeTicks( |
527 media::VideoFrameMetadata::REFERENCE_TIME, base::TimeTicks()); | 517 media::VideoFrameMetadata::REFERENCE_TIME, base::TimeTicks()); |
528 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame); | 518 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame); |
529 | 519 |
530 base::RunLoop().RunUntilIdle(); | 520 base::RunLoop().RunUntilIdle(); |
531 } | 521 } |
532 | 522 |
533 // Exercises the OnError() codepath of VideoCaptureController, and tests the | 523 // Exercises the OnError() codepath of VideoCaptureController, and tests the |
534 // behavior of various operations after the error state has been signalled. | 524 // behavior of various operations after the error state has been signalled. |
535 TEST_F(VideoCaptureControllerTest, ErrorAfterDeviceCreation) { | 525 TEST_F(VideoCaptureControllerTest, ErrorAfterDeviceCreation) { |
536 media::VideoCaptureParams session_100; | 526 media::VideoCaptureParams session_100; |
537 session_100.requested_format = media::VideoCaptureFormat( | 527 session_100.requested_format = media::VideoCaptureFormat( |
538 gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420); | 528 gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420); |
539 | 529 |
540 media::VideoCaptureParams session_200 = session_100; | 530 media::VideoCaptureParams session_200 = session_100; |
541 | 531 |
542 const VideoCaptureControllerID route_id(0x99); | 532 const VideoCaptureControllerID route_id(0x99); |
543 | 533 |
544 // Start with one client. | 534 // Start with one client. |
545 controller_->AddClient( | 535 controller_->AddClient(route_id, client_a_.get(), 100, session_100); |
546 route_id, client_a_.get(), base::kNullProcessHandle, 100, session_100); | |
547 media::VideoCaptureFormat device_format( | 536 media::VideoCaptureFormat device_format( |
548 gfx::Size(10, 10), 25, media::PIXEL_FORMAT_ARGB); | 537 gfx::Size(10, 10), 25, media::PIXEL_FORMAT_ARGB); |
549 | 538 |
550 // Start the device. Then, before the first buffer, signal an error and | 539 // Start the device. Then, before the first buffer, signal an error and |
551 // deliver the buffer. The error should be propagated to clients; the buffer | 540 // deliver the buffer. The error should be propagated to clients; the buffer |
552 // should not be. | 541 // should not be. |
553 base::RunLoop().RunUntilIdle(); | 542 base::RunLoop().RunUntilIdle(); |
554 Mock::VerifyAndClearExpectations(client_a_.get()); | 543 Mock::VerifyAndClearExpectations(client_a_.get()); |
555 | 544 |
556 const gfx::Size dims(320, 240); | 545 const gfx::Size dims(320, 240); |
(...skipping 10 matching lines...) Expand all Loading... |
567 media::VideoFrameMetadata::REFERENCE_TIME, base::TimeTicks()); | 556 media::VideoFrameMetadata::REFERENCE_TIME, base::TimeTicks()); |
568 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame); | 557 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame); |
569 | 558 |
570 EXPECT_CALL(*client_a_, DoError(route_id)).Times(1); | 559 EXPECT_CALL(*client_a_, DoError(route_id)).Times(1); |
571 base::RunLoop().RunUntilIdle(); | 560 base::RunLoop().RunUntilIdle(); |
572 Mock::VerifyAndClearExpectations(client_a_.get()); | 561 Mock::VerifyAndClearExpectations(client_a_.get()); |
573 | 562 |
574 // Second client connects after the error state. It also should get told of | 563 // Second client connects after the error state. It also should get told of |
575 // the error. | 564 // the error. |
576 EXPECT_CALL(*client_b_, DoError(route_id)).Times(1); | 565 EXPECT_CALL(*client_b_, DoError(route_id)).Times(1); |
577 controller_->AddClient( | 566 controller_->AddClient(route_id, client_b_.get(), 200, session_200); |
578 route_id, client_b_.get(), base::kNullProcessHandle, 200, session_200); | |
579 Mock::VerifyAndClearExpectations(client_b_.get()); | 567 Mock::VerifyAndClearExpectations(client_b_.get()); |
580 } | 568 } |
581 | 569 |
582 } // namespace content | 570 } // namespace content |
OLD | NEW |