| 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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 client_a_.reset(new MockVideoCaptureControllerEventHandler( | 115 client_a_.reset(new MockVideoCaptureControllerEventHandler( |
| 116 controller_.get())); | 116 controller_.get())); |
| 117 client_b_.reset(new MockVideoCaptureControllerEventHandler( | 117 client_b_.reset(new MockVideoCaptureControllerEventHandler( |
| 118 controller_.get())); | 118 controller_.get())); |
| 119 } | 119 } |
| 120 | 120 |
| 121 void TearDown() override { base::RunLoop().RunUntilIdle(); } | 121 void TearDown() override { base::RunLoop().RunUntilIdle(); } |
| 122 | 122 |
| 123 scoped_refptr<media::VideoFrame> WrapI420Buffer(gfx::Size dimensions, | 123 scoped_refptr<media::VideoFrame> WrapI420Buffer(gfx::Size dimensions, |
| 124 uint8_t* data) { | 124 uint8_t* data) { |
| 125 return media::VideoFrame::WrapExternalSharedMemory( | 125 scoped_refptr<media::VideoFrame> video_frame = |
| 126 media::PIXEL_FORMAT_I420, dimensions, gfx::Rect(dimensions), dimensions, | 126 media::VideoFrame::WrapExternalSharedMemory( |
| 127 data, | 127 media::PIXEL_FORMAT_I420, dimensions, gfx::Rect(dimensions), |
| 128 media::VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420, dimensions), | 128 dimensions, data, media::VideoFrame::AllocationSize( |
| 129 base::SharedMemory::NULLHandle(), 0u, base::TimeDelta()); | 129 media::PIXEL_FORMAT_I420, dimensions), |
| 130 base::SharedMemory::NULLHandle(), 0u, base::TimeDelta()); |
| 131 EXPECT_NE(nullptr, video_frame.get()); |
| 132 return video_frame; |
| 130 } | 133 } |
| 131 | 134 |
| 132 TestBrowserThreadBundle bundle_; | 135 TestBrowserThreadBundle bundle_; |
| 133 scoped_ptr<MockVideoCaptureControllerEventHandler> client_a_; | 136 scoped_ptr<MockVideoCaptureControllerEventHandler> client_a_; |
| 134 scoped_ptr<MockVideoCaptureControllerEventHandler> client_b_; | 137 scoped_ptr<MockVideoCaptureControllerEventHandler> client_b_; |
| 135 scoped_ptr<VideoCaptureController> controller_; | 138 scoped_ptr<VideoCaptureController> controller_; |
| 136 scoped_ptr<media::VideoCaptureDevice::Client> device_; | 139 scoped_ptr<media::VideoCaptureDevice::Client> device_; |
| 137 | 140 |
| 138 private: | 141 private: |
| 139 DISALLOW_COPY_AND_ASSIGN(VideoCaptureControllerTest); | 142 DISALLOW_COPY_AND_ASSIGN(VideoCaptureControllerTest); |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 } | 313 } |
| 311 { | 314 { |
| 312 InSequence s; | 315 InSequence s; |
| 313 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_2)).Times(1); | 316 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_2)).Times(1); |
| 314 EXPECT_CALL(*client_a_, | 317 EXPECT_CALL(*client_a_, |
| 315 DoI420BufferReady(client_a_route_2, capture_resolution)) | 318 DoI420BufferReady(client_a_route_2, capture_resolution)) |
| 316 .Times(1); | 319 .Times(1); |
| 317 } | 320 } |
| 318 scoped_refptr<media::VideoFrame> video_frame = | 321 scoped_refptr<media::VideoFrame> video_frame = |
| 319 WrapI420Buffer(capture_resolution, static_cast<uint8_t*>(buffer->data())); | 322 WrapI420Buffer(capture_resolution, static_cast<uint8_t*>(buffer->data())); |
| 323 ASSERT_TRUE(video_frame); |
| 320 ASSERT_FALSE(video_frame->metadata()->HasKey( | 324 ASSERT_FALSE(video_frame->metadata()->HasKey( |
| 321 media::VideoFrameMetadata::RESOURCE_UTILIZATION)); | 325 media::VideoFrameMetadata::RESOURCE_UTILIZATION)); |
| 322 client_a_->resource_utilization_ = 0.5; | 326 client_a_->resource_utilization_ = 0.5; |
| 323 client_b_->resource_utilization_ = -1.0; | 327 client_b_->resource_utilization_ = -1.0; |
| 324 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame, | 328 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame, |
| 325 base::TimeTicks()); | 329 base::TimeTicks()); |
| 326 | 330 |
| 327 base::RunLoop().RunUntilIdle(); | 331 base::RunLoop().RunUntilIdle(); |
| 328 Mock::VerifyAndClearExpectations(client_a_.get()); | 332 Mock::VerifyAndClearExpectations(client_a_.get()); |
| 329 Mock::VerifyAndClearExpectations(client_b_.get()); | 333 Mock::VerifyAndClearExpectations(client_b_.get()); |
| 330 // Expect VideoCaptureController set the metadata in |video_frame| to hold a | 334 // Expect VideoCaptureController set the metadata in |video_frame| to hold a |
| 331 // resource utilization of 0.5 (the largest of all reported values). | 335 // resource utilization of 0.5 (the largest of all reported values). |
| 332 double resource_utilization_in_metadata = -1.0; | 336 double resource_utilization_in_metadata = -1.0; |
| 333 ASSERT_TRUE(video_frame->metadata()->GetDouble( | 337 ASSERT_TRUE(video_frame->metadata()->GetDouble( |
| 334 media::VideoFrameMetadata::RESOURCE_UTILIZATION, | 338 media::VideoFrameMetadata::RESOURCE_UTILIZATION, |
| 335 &resource_utilization_in_metadata)); | 339 &resource_utilization_in_metadata)); |
| 336 ASSERT_EQ(0.5, resource_utilization_in_metadata); | 340 ASSERT_EQ(0.5, resource_utilization_in_metadata); |
| 337 | 341 |
| 338 // Second buffer which ought to use the same shared memory buffer. In this | 342 // Second buffer which ought to use the same shared memory buffer. In this |
| 339 // case pretend that the Buffer pointer is held by the device for a long | 343 // case pretend that the Buffer pointer is held by the device for a long |
| 340 // delay. This shouldn't affect anything. | 344 // delay. This shouldn't affect anything. |
| 341 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer2 = | 345 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer2 = |
| 342 device_->ReserveOutputBuffer(capture_resolution, | 346 device_->ReserveOutputBuffer(capture_resolution, |
| 343 media::PIXEL_FORMAT_I420, | 347 media::PIXEL_FORMAT_I420, |
| 344 media::PIXEL_STORAGE_CPU); | 348 media::PIXEL_STORAGE_CPU); |
| 345 ASSERT_TRUE(buffer2.get()); | 349 ASSERT_TRUE(buffer2.get()); |
| 346 memset(buffer2->data(), buffer_no++, buffer2->mapped_size()); | 350 memset(buffer2->data(), buffer_no++, buffer2->mapped_size()); |
| 347 video_frame = WrapI420Buffer(capture_resolution, | 351 video_frame = WrapI420Buffer(capture_resolution, |
| 348 static_cast<uint8_t*>(buffer2->data())); | 352 static_cast<uint8_t*>(buffer2->data())); |
| 353 ASSERT_TRUE(video_frame); |
| 349 ASSERT_FALSE(video_frame->metadata()->HasKey( | 354 ASSERT_FALSE(video_frame->metadata()->HasKey( |
| 350 media::VideoFrameMetadata::RESOURCE_UTILIZATION)); | 355 media::VideoFrameMetadata::RESOURCE_UTILIZATION)); |
| 351 client_a_->resource_utilization_ = 0.5; | 356 client_a_->resource_utilization_ = 0.5; |
| 352 client_b_->resource_utilization_ = 3.14; | 357 client_b_->resource_utilization_ = 3.14; |
| 353 device_->OnIncomingCapturedVideoFrame(std::move(buffer2), video_frame, | 358 device_->OnIncomingCapturedVideoFrame(std::move(buffer2), video_frame, |
| 354 base::TimeTicks()); | 359 base::TimeTicks()); |
| 355 | 360 |
| 356 // The buffer should be delivered to the clients in any order. | 361 // The buffer should be delivered to the clients in any order. |
| 357 EXPECT_CALL(*client_a_, | 362 EXPECT_CALL(*client_a_, |
| 358 DoI420BufferReady(client_a_route_1, capture_resolution)) | 363 DoI420BufferReady(client_a_route_1, capture_resolution)) |
| (...skipping 26 matching lines...) Expand all Loading... |
| 385 // 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. |
| 386 for (int i = 0; i < kPoolSize; i++) { | 391 for (int i = 0; i < kPoolSize; i++) { |
| 387 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer = | 392 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer = |
| 388 device_->ReserveOutputBuffer(capture_resolution, | 393 device_->ReserveOutputBuffer(capture_resolution, |
| 389 media::PIXEL_FORMAT_I420, | 394 media::PIXEL_FORMAT_I420, |
| 390 media::PIXEL_STORAGE_CPU); | 395 media::PIXEL_STORAGE_CPU); |
| 391 ASSERT_TRUE(buffer.get()); | 396 ASSERT_TRUE(buffer.get()); |
| 392 memset(buffer->data(), buffer_no++, buffer->mapped_size()); | 397 memset(buffer->data(), buffer_no++, buffer->mapped_size()); |
| 393 video_frame = WrapI420Buffer(capture_resolution, | 398 video_frame = WrapI420Buffer(capture_resolution, |
| 394 static_cast<uint8_t*>(buffer->data())); | 399 static_cast<uint8_t*>(buffer->data())); |
| 400 ASSERT_TRUE(video_frame); |
| 395 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame, | 401 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame, |
| 396 base::TimeTicks()); | 402 base::TimeTicks()); |
| 397 } | 403 } |
| 398 // ReserveOutputBuffer ought to fail now, because the pool is depleted. | 404 // ReserveOutputBuffer ought to fail now, because the pool is depleted. |
| 399 ASSERT_FALSE( | 405 ASSERT_FALSE( |
| 400 device_->ReserveOutputBuffer(capture_resolution, | 406 device_->ReserveOutputBuffer(capture_resolution, |
| 401 media::PIXEL_FORMAT_I420, | 407 media::PIXEL_FORMAT_I420, |
| 402 media::PIXEL_STORAGE_CPU).get()); | 408 media::PIXEL_STORAGE_CPU).get()); |
| 403 | 409 |
| 404 // The new client needs to be told of 3 buffers; the old clients only 2. | 410 // The new client needs to be told of 3 buffers; the old clients only 2. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 433 controller_->StopSession(300); | 439 controller_->StopSession(300); |
| 434 // Queue up another buffer. | 440 // Queue up another buffer. |
| 435 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer3 = | 441 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer3 = |
| 436 device_->ReserveOutputBuffer(capture_resolution, | 442 device_->ReserveOutputBuffer(capture_resolution, |
| 437 media::PIXEL_FORMAT_I420, | 443 media::PIXEL_FORMAT_I420, |
| 438 media::PIXEL_STORAGE_CPU); | 444 media::PIXEL_STORAGE_CPU); |
| 439 ASSERT_TRUE(buffer3.get()); | 445 ASSERT_TRUE(buffer3.get()); |
| 440 memset(buffer3->data(), buffer_no++, buffer3->mapped_size()); | 446 memset(buffer3->data(), buffer_no++, buffer3->mapped_size()); |
| 441 video_frame = WrapI420Buffer(capture_resolution, | 447 video_frame = WrapI420Buffer(capture_resolution, |
| 442 static_cast<uint8_t*>(buffer3->data())); | 448 static_cast<uint8_t*>(buffer3->data())); |
| 449 ASSERT_TRUE(video_frame); |
| 443 device_->OnIncomingCapturedVideoFrame(std::move(buffer3), video_frame, | 450 device_->OnIncomingCapturedVideoFrame(std::move(buffer3), video_frame, |
| 444 base::TimeTicks()); | 451 base::TimeTicks()); |
| 445 | 452 |
| 446 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer4 = | 453 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer4 = |
| 447 device_->ReserveOutputBuffer(capture_resolution, | 454 device_->ReserveOutputBuffer(capture_resolution, |
| 448 media::PIXEL_FORMAT_I420, | 455 media::PIXEL_FORMAT_I420, |
| 449 media::PIXEL_STORAGE_CPU); | 456 media::PIXEL_STORAGE_CPU); |
| 450 { | 457 { |
| 451 // Kill A2 via session close (posts a task to disconnect, but A2 must not | 458 // Kill A2 via session close (posts a task to disconnect, but A2 must not |
| 452 // be sent either of these two buffers). | 459 // be sent either of these two buffers). |
| 453 EXPECT_CALL(*client_a_, DoEnded(client_a_route_2)).Times(1); | 460 EXPECT_CALL(*client_a_, DoEnded(client_a_route_2)).Times(1); |
| 454 controller_->StopSession(200); | 461 controller_->StopSession(200); |
| 455 } | 462 } |
| 456 ASSERT_TRUE(buffer4.get()); | 463 ASSERT_TRUE(buffer4.get()); |
| 457 memset(buffer4->data(), buffer_no++, buffer4->mapped_size()); | 464 memset(buffer4->data(), buffer_no++, buffer4->mapped_size()); |
| 458 video_frame = WrapI420Buffer(capture_resolution, | 465 video_frame = WrapI420Buffer(capture_resolution, |
| 459 static_cast<uint8_t*>(buffer4->data())); | 466 static_cast<uint8_t*>(buffer4->data())); |
| 467 ASSERT_TRUE(video_frame); |
| 460 device_->OnIncomingCapturedVideoFrame(std::move(buffer4), video_frame, | 468 device_->OnIncomingCapturedVideoFrame(std::move(buffer4), video_frame, |
| 461 base::TimeTicks()); | 469 base::TimeTicks()); |
| 462 // B2 is the only client left, and is the only one that should | 470 // B2 is the only client left, and is the only one that should |
| 463 // get the buffer. | 471 // get the buffer. |
| 464 EXPECT_CALL(*client_b_, | 472 EXPECT_CALL(*client_b_, |
| 465 DoI420BufferReady(client_b_route_2, capture_resolution)) | 473 DoI420BufferReady(client_b_route_2, capture_resolution)) |
| 466 .Times(2); | 474 .Times(2); |
| 467 base::RunLoop().RunUntilIdle(); | 475 base::RunLoop().RunUntilIdle(); |
| 468 Mock::VerifyAndClearExpectations(client_a_.get()); | 476 Mock::VerifyAndClearExpectations(client_a_.get()); |
| 469 Mock::VerifyAndClearExpectations(client_b_.get()); | 477 Mock::VerifyAndClearExpectations(client_b_.get()); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 498 base::RunLoop().RunUntilIdle(); | 506 base::RunLoop().RunUntilIdle(); |
| 499 Mock::VerifyAndClearExpectations(client_b_.get()); | 507 Mock::VerifyAndClearExpectations(client_b_.get()); |
| 500 | 508 |
| 501 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer( | 509 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer( |
| 502 device_->ReserveOutputBuffer(capture_resolution, | 510 device_->ReserveOutputBuffer(capture_resolution, |
| 503 media::PIXEL_FORMAT_I420, | 511 media::PIXEL_FORMAT_I420, |
| 504 media::PIXEL_STORAGE_CPU)); | 512 media::PIXEL_STORAGE_CPU)); |
| 505 ASSERT_TRUE(buffer.get()); | 513 ASSERT_TRUE(buffer.get()); |
| 506 scoped_refptr<media::VideoFrame> video_frame = | 514 scoped_refptr<media::VideoFrame> video_frame = |
| 507 WrapI420Buffer(capture_resolution, static_cast<uint8_t*>(buffer->data())); | 515 WrapI420Buffer(capture_resolution, static_cast<uint8_t*>(buffer->data())); |
| 516 ASSERT_TRUE(video_frame); |
| 508 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame, | 517 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame, |
| 509 base::TimeTicks()); | 518 base::TimeTicks()); |
| 510 | 519 |
| 511 base::RunLoop().RunUntilIdle(); | 520 base::RunLoop().RunUntilIdle(); |
| 512 } | 521 } |
| 513 | 522 |
| 514 // Exercises the OnError() codepath of VideoCaptureController, and tests the | 523 // Exercises the OnError() codepath of VideoCaptureController, and tests the |
| 515 // behavior of various operations after the error state has been signalled. | 524 // behavior of various operations after the error state has been signalled. |
| 516 TEST_F(VideoCaptureControllerTest, ErrorAfterDeviceCreation) { | 525 TEST_F(VideoCaptureControllerTest, ErrorAfterDeviceCreation) { |
| 517 media::VideoCaptureParams session_100; | 526 media::VideoCaptureParams session_100; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 535 Mock::VerifyAndClearExpectations(client_a_.get()); | 544 Mock::VerifyAndClearExpectations(client_a_.get()); |
| 536 | 545 |
| 537 const gfx::Size dims(320, 240); | 546 const gfx::Size dims(320, 240); |
| 538 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer( | 547 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer( |
| 539 device_->ReserveOutputBuffer(dims, media::PIXEL_FORMAT_I420, | 548 device_->ReserveOutputBuffer(dims, media::PIXEL_FORMAT_I420, |
| 540 media::PIXEL_STORAGE_CPU)); | 549 media::PIXEL_STORAGE_CPU)); |
| 541 ASSERT_TRUE(buffer.get()); | 550 ASSERT_TRUE(buffer.get()); |
| 542 | 551 |
| 543 scoped_refptr<media::VideoFrame> video_frame = | 552 scoped_refptr<media::VideoFrame> video_frame = |
| 544 WrapI420Buffer(dims, static_cast<uint8_t*>(buffer->data())); | 553 WrapI420Buffer(dims, static_cast<uint8_t*>(buffer->data())); |
| 554 ASSERT_TRUE(video_frame); |
| 545 device_->OnError(FROM_HERE, "Test Error"); | 555 device_->OnError(FROM_HERE, "Test Error"); |
| 546 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame, | 556 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame, |
| 547 base::TimeTicks()); | 557 base::TimeTicks()); |
| 548 | 558 |
| 549 EXPECT_CALL(*client_a_, DoError(route_id)).Times(1); | 559 EXPECT_CALL(*client_a_, DoError(route_id)).Times(1); |
| 550 base::RunLoop().RunUntilIdle(); | 560 base::RunLoop().RunUntilIdle(); |
| 551 Mock::VerifyAndClearExpectations(client_a_.get()); | 561 Mock::VerifyAndClearExpectations(client_a_.get()); |
| 552 | 562 |
| 553 // 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 |
| 554 // the error. | 564 // the error. |
| 555 EXPECT_CALL(*client_b_, DoError(route_id)).Times(1); | 565 EXPECT_CALL(*client_b_, DoError(route_id)).Times(1); |
| 556 controller_->AddClient( | 566 controller_->AddClient( |
| 557 route_id, client_b_.get(), base::kNullProcessHandle, 200, session_200); | 567 route_id, client_b_.get(), base::kNullProcessHandle, 200, session_200); |
| 558 Mock::VerifyAndClearExpectations(client_b_.get()); | 568 Mock::VerifyAndClearExpectations(client_b_.get()); |
| 559 } | 569 } |
| 560 | 570 |
| 561 } // namespace content | 571 } // namespace content |
| OLD | NEW |