| 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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 const std::vector<gfx::GpuMemoryBufferHandle>& handles, | 71 const std::vector<gfx::GpuMemoryBufferHandle>& handles, |
| 72 const gfx::Size& size, | 72 const gfx::Size& size, |
| 73 int buffer_id) override { | 73 int buffer_id) override { |
| 74 DoBufferCreated2(id); | 74 DoBufferCreated2(id); |
| 75 } | 75 } |
| 76 void OnBufferDestroyed(VideoCaptureControllerID id, int buffer_id) override { | 76 void OnBufferDestroyed(VideoCaptureControllerID id, int buffer_id) override { |
| 77 DoBufferDestroyed(id); | 77 DoBufferDestroyed(id); |
| 78 } | 78 } |
| 79 void OnBufferReady(VideoCaptureControllerID id, | 79 void OnBufferReady(VideoCaptureControllerID id, |
| 80 int buffer_id, | 80 int buffer_id, |
| 81 const scoped_refptr<media::VideoFrame>& frame, | 81 const scoped_refptr<media::VideoFrame>& frame) override { |
| 82 const base::TimeTicks& timestamp) override { | 82 EXPECT_EQ(frame->format(), media::PIXEL_FORMAT_I420); |
| 83 EXPECT_EQ(frame->format(), media::PIXEL_FORMAT_I420); | 83 base::TimeTicks reference_time; |
| 84 DoI420BufferReady(id, frame->coded_size()); | 84 EXPECT_TRUE(frame->metadata()->GetTimeTicks( |
| 85 base::ThreadTaskRunnerHandle::Get()->PostTask( | 85 media::VideoFrameMetadata::REFERENCE_TIME, &reference_time)); |
| 86 FROM_HERE, | 86 DoI420BufferReady(id, frame->coded_size()); |
| 87 base::Bind(&VideoCaptureController::ReturnBuffer, | 87 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 88 base::Unretained(controller_), id, this, buffer_id, | 88 FROM_HERE, |
| 89 gpu::SyncToken(), resource_utilization_)); | 89 base::Bind(&VideoCaptureController::ReturnBuffer, |
| 90 base::Unretained(controller_), id, this, buffer_id, |
| 91 gpu::SyncToken(), resource_utilization_)); |
| 90 } | 92 } |
| 91 void OnEnded(VideoCaptureControllerID id) override { | 93 void OnEnded(VideoCaptureControllerID id) override { |
| 92 DoEnded(id); | 94 DoEnded(id); |
| 93 // OnEnded() must respond by (eventually) unregistering the client. | 95 // OnEnded() must respond by (eventually) unregistering the client. |
| 94 base::ThreadTaskRunnerHandle::Get()->PostTask( | 96 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 95 FROM_HERE, | 97 FROM_HERE, |
| 96 base::Bind(base::IgnoreResult(&VideoCaptureController::RemoveClient), | 98 base::Bind(base::IgnoreResult(&VideoCaptureController::RemoveClient), |
| 97 base::Unretained(controller_), id, this)); | 99 base::Unretained(controller_), id, this)); |
| 98 } | 100 } |
| 99 | 101 |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 DoI420BufferReady(client_a_route_2, capture_resolution)) | 320 DoI420BufferReady(client_a_route_2, capture_resolution)) |
| 319 .Times(1); | 321 .Times(1); |
| 320 } | 322 } |
| 321 scoped_refptr<media::VideoFrame> video_frame = | 323 scoped_refptr<media::VideoFrame> video_frame = |
| 322 WrapI420Buffer(capture_resolution, static_cast<uint8_t*>(buffer->data())); | 324 WrapI420Buffer(capture_resolution, static_cast<uint8_t*>(buffer->data())); |
| 323 ASSERT_TRUE(video_frame); | 325 ASSERT_TRUE(video_frame); |
| 324 ASSERT_FALSE(video_frame->metadata()->HasKey( | 326 ASSERT_FALSE(video_frame->metadata()->HasKey( |
| 325 media::VideoFrameMetadata::RESOURCE_UTILIZATION)); | 327 media::VideoFrameMetadata::RESOURCE_UTILIZATION)); |
| 326 client_a_->resource_utilization_ = 0.5; | 328 client_a_->resource_utilization_ = 0.5; |
| 327 client_b_->resource_utilization_ = -1.0; | 329 client_b_->resource_utilization_ = -1.0; |
| 328 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame, | 330 video_frame->metadata()->SetTimeTicks( |
| 329 base::TimeTicks()); | 331 media::VideoFrameMetadata::REFERENCE_TIME, base::TimeTicks()); |
| 332 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame); |
| 330 | 333 |
| 331 base::RunLoop().RunUntilIdle(); | 334 base::RunLoop().RunUntilIdle(); |
| 332 Mock::VerifyAndClearExpectations(client_a_.get()); | 335 Mock::VerifyAndClearExpectations(client_a_.get()); |
| 333 Mock::VerifyAndClearExpectations(client_b_.get()); | 336 Mock::VerifyAndClearExpectations(client_b_.get()); |
| 334 | 337 |
| 335 // Expect VideoCaptureController set the metadata in |video_frame| to hold a | 338 // Expect VideoCaptureController set the metadata in |video_frame| to hold a |
| 336 // resource utilization of 0.5 (the largest of all reported values). | 339 // resource utilization of 0.5 (the largest of all reported values). |
| 337 double resource_utilization_in_metadata = -1.0; | 340 double resource_utilization_in_metadata = -1.0; |
| 338 ASSERT_TRUE(video_frame->metadata()->GetDouble( | 341 ASSERT_TRUE(video_frame->metadata()->GetDouble( |
| 339 media::VideoFrameMetadata::RESOURCE_UTILIZATION, | 342 media::VideoFrameMetadata::RESOURCE_UTILIZATION, |
| 340 &resource_utilization_in_metadata)); | 343 &resource_utilization_in_metadata)); |
| 341 ASSERT_EQ(0.5, resource_utilization_in_metadata); | 344 ASSERT_EQ(0.5, resource_utilization_in_metadata); |
| 342 | 345 |
| 343 // Second buffer which ought to use the same shared memory buffer. In this | 346 // Second buffer which ought to use the same shared memory buffer. In this |
| 344 // case pretend that the Buffer pointer is held by the device for a long | 347 // case pretend that the Buffer pointer is held by the device for a long |
| 345 // delay. This shouldn't affect anything. | 348 // delay. This shouldn't affect anything. |
| 346 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer2 = | 349 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer2 = |
| 347 device_->ReserveOutputBuffer(capture_resolution, media::PIXEL_FORMAT_I420, | 350 device_->ReserveOutputBuffer(capture_resolution, media::PIXEL_FORMAT_I420, |
| 348 media::PIXEL_STORAGE_CPU); | 351 media::PIXEL_STORAGE_CPU); |
| 349 ASSERT_TRUE(buffer2.get()); | 352 ASSERT_TRUE(buffer2.get()); |
| 350 memset(buffer2->data(), buffer_no++, buffer2->mapped_size()); | 353 memset(buffer2->data(), buffer_no++, buffer2->mapped_size()); |
| 351 video_frame = WrapI420Buffer(capture_resolution, | 354 video_frame = WrapI420Buffer(capture_resolution, |
| 352 static_cast<uint8_t*>(buffer2->data())); | 355 static_cast<uint8_t*>(buffer2->data())); |
| 353 ASSERT_TRUE(video_frame); | 356 ASSERT_TRUE(video_frame); |
| 354 ASSERT_FALSE(video_frame->metadata()->HasKey( | 357 ASSERT_FALSE(video_frame->metadata()->HasKey( |
| 355 media::VideoFrameMetadata::RESOURCE_UTILIZATION)); | 358 media::VideoFrameMetadata::RESOURCE_UTILIZATION)); |
| 356 client_a_->resource_utilization_ = 0.5; | 359 client_a_->resource_utilization_ = 0.5; |
| 357 client_b_->resource_utilization_ = 3.14; | 360 client_b_->resource_utilization_ = 3.14; |
| 358 device_->OnIncomingCapturedVideoFrame(std::move(buffer2), video_frame, | 361 video_frame->metadata()->SetTimeTicks( |
| 359 base::TimeTicks()); | 362 media::VideoFrameMetadata::REFERENCE_TIME, base::TimeTicks()); |
| 363 device_->OnIncomingCapturedVideoFrame(std::move(buffer2), video_frame); |
| 360 | 364 |
| 361 // The buffer should be delivered to the clients in any order. | 365 // The buffer should be delivered to the clients in any order. |
| 362 { | 366 { |
| 363 InSequence s; | 367 InSequence s; |
| 364 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_1)).Times(1); | 368 EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_1)).Times(1); |
| 365 EXPECT_CALL(*client_a_, | 369 EXPECT_CALL(*client_a_, |
| 366 DoI420BufferReady(client_a_route_1, capture_resolution)) | 370 DoI420BufferReady(client_a_route_1, capture_resolution)) |
| 367 .Times(1); | 371 .Times(1); |
| 368 } | 372 } |
| 369 { | 373 { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 for (int i = 0; i < kPoolSize; i++) { | 407 for (int i = 0; i < kPoolSize; i++) { |
| 404 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer = | 408 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer = |
| 405 device_->ReserveOutputBuffer(capture_resolution, | 409 device_->ReserveOutputBuffer(capture_resolution, |
| 406 media::PIXEL_FORMAT_I420, | 410 media::PIXEL_FORMAT_I420, |
| 407 media::PIXEL_STORAGE_CPU); | 411 media::PIXEL_STORAGE_CPU); |
| 408 ASSERT_TRUE(buffer.get()); | 412 ASSERT_TRUE(buffer.get()); |
| 409 memset(buffer->data(), buffer_no++, buffer->mapped_size()); | 413 memset(buffer->data(), buffer_no++, buffer->mapped_size()); |
| 410 video_frame = WrapI420Buffer(capture_resolution, | 414 video_frame = WrapI420Buffer(capture_resolution, |
| 411 static_cast<uint8_t*>(buffer->data())); | 415 static_cast<uint8_t*>(buffer->data())); |
| 412 ASSERT_TRUE(video_frame); | 416 ASSERT_TRUE(video_frame); |
| 413 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame, | 417 video_frame->metadata()->SetTimeTicks( |
| 414 base::TimeTicks()); | 418 media::VideoFrameMetadata::REFERENCE_TIME, base::TimeTicks()); |
| 419 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame); |
| 415 } | 420 } |
| 416 // ReserveOutputBuffer ought to fail now, because the pool is depleted. | 421 // ReserveOutputBuffer ought to fail now, because the pool is depleted. |
| 417 ASSERT_FALSE( | 422 ASSERT_FALSE( |
| 418 device_->ReserveOutputBuffer(capture_resolution, | 423 device_->ReserveOutputBuffer(capture_resolution, |
| 419 media::PIXEL_FORMAT_I420, | 424 media::PIXEL_FORMAT_I420, |
| 420 media::PIXEL_STORAGE_CPU).get()); | 425 media::PIXEL_STORAGE_CPU).get()); |
| 421 | 426 |
| 422 // The new client needs to be notified of the creation of |kPoolSize| buffers; | 427 // The new client needs to be notified of the creation of |kPoolSize| buffers; |
| 423 // the old clients only |kPoolSize - 2|. | 428 // the old clients only |kPoolSize - 2|. |
| 424 EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_2)).Times(kPoolSize); | 429 EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_2)).Times(kPoolSize); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 452 controller_->StopSession(300); | 457 controller_->StopSession(300); |
| 453 // Queue up another buffer. | 458 // Queue up another buffer. |
| 454 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer3 = | 459 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer3 = |
| 455 device_->ReserveOutputBuffer(capture_resolution, media::PIXEL_FORMAT_I420, | 460 device_->ReserveOutputBuffer(capture_resolution, media::PIXEL_FORMAT_I420, |
| 456 media::PIXEL_STORAGE_CPU); | 461 media::PIXEL_STORAGE_CPU); |
| 457 ASSERT_TRUE(buffer3.get()); | 462 ASSERT_TRUE(buffer3.get()); |
| 458 memset(buffer3->data(), buffer_no++, buffer3->mapped_size()); | 463 memset(buffer3->data(), buffer_no++, buffer3->mapped_size()); |
| 459 video_frame = WrapI420Buffer(capture_resolution, | 464 video_frame = WrapI420Buffer(capture_resolution, |
| 460 static_cast<uint8_t*>(buffer3->data())); | 465 static_cast<uint8_t*>(buffer3->data())); |
| 461 ASSERT_TRUE(video_frame); | 466 ASSERT_TRUE(video_frame); |
| 462 device_->OnIncomingCapturedVideoFrame(std::move(buffer3), video_frame, | 467 video_frame->metadata()->SetTimeTicks( |
| 463 base::TimeTicks()); | 468 media::VideoFrameMetadata::REFERENCE_TIME, base::TimeTicks()); |
| 469 device_->OnIncomingCapturedVideoFrame(std::move(buffer3), video_frame); |
| 464 | 470 |
| 465 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer4 = | 471 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer4 = |
| 466 device_->ReserveOutputBuffer(capture_resolution, media::PIXEL_FORMAT_I420, | 472 device_->ReserveOutputBuffer(capture_resolution, media::PIXEL_FORMAT_I420, |
| 467 media::PIXEL_STORAGE_CPU); | 473 media::PIXEL_STORAGE_CPU); |
| 468 { | 474 { |
| 469 // Kill A2 via session close (posts a task to disconnect, but A2 must not | 475 // Kill A2 via session close (posts a task to disconnect, but A2 must not |
| 470 // be sent either of these two buffers). | 476 // be sent either of these two buffers). |
| 471 EXPECT_CALL(*client_a_, DoEnded(client_a_route_2)).Times(1); | 477 EXPECT_CALL(*client_a_, DoEnded(client_a_route_2)).Times(1); |
| 472 controller_->StopSession(200); | 478 controller_->StopSession(200); |
| 473 } | 479 } |
| 474 ASSERT_TRUE(buffer4.get()); | 480 ASSERT_TRUE(buffer4.get()); |
| 475 memset(buffer4->data(), buffer_no++, buffer4->mapped_size()); | 481 memset(buffer4->data(), buffer_no++, buffer4->mapped_size()); |
| 476 video_frame = WrapI420Buffer(capture_resolution, | 482 video_frame = WrapI420Buffer(capture_resolution, |
| 477 static_cast<uint8_t*>(buffer4->data())); | 483 static_cast<uint8_t*>(buffer4->data())); |
| 478 ASSERT_TRUE(video_frame); | 484 ASSERT_TRUE(video_frame); |
| 479 device_->OnIncomingCapturedVideoFrame(std::move(buffer4), video_frame, | 485 video_frame->metadata()->SetTimeTicks( |
| 480 base::TimeTicks()); | 486 media::VideoFrameMetadata::REFERENCE_TIME, base::TimeTicks()); |
| 487 device_->OnIncomingCapturedVideoFrame(std::move(buffer4), video_frame); |
| 481 // B2 is the only client left, and is the only one that should | 488 // B2 is the only client left, and is the only one that should |
| 482 // get the buffer. | 489 // get the buffer. |
| 483 EXPECT_CALL(*client_b_, | 490 EXPECT_CALL(*client_b_, |
| 484 DoI420BufferReady(client_b_route_2, capture_resolution)) | 491 DoI420BufferReady(client_b_route_2, capture_resolution)) |
| 485 .Times(2); | 492 .Times(2); |
| 486 base::RunLoop().RunUntilIdle(); | 493 base::RunLoop().RunUntilIdle(); |
| 487 Mock::VerifyAndClearExpectations(client_a_.get()); | 494 Mock::VerifyAndClearExpectations(client_a_.get()); |
| 488 Mock::VerifyAndClearExpectations(client_b_.get()); | 495 Mock::VerifyAndClearExpectations(client_b_.get()); |
| 489 } | 496 } |
| 490 | 497 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 517 base::RunLoop().RunUntilIdle(); | 524 base::RunLoop().RunUntilIdle(); |
| 518 Mock::VerifyAndClearExpectations(client_b_.get()); | 525 Mock::VerifyAndClearExpectations(client_b_.get()); |
| 519 | 526 |
| 520 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer( | 527 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer( |
| 521 device_->ReserveOutputBuffer(capture_resolution, media::PIXEL_FORMAT_I420, | 528 device_->ReserveOutputBuffer(capture_resolution, media::PIXEL_FORMAT_I420, |
| 522 media::PIXEL_STORAGE_CPU)); | 529 media::PIXEL_STORAGE_CPU)); |
| 523 ASSERT_TRUE(buffer.get()); | 530 ASSERT_TRUE(buffer.get()); |
| 524 scoped_refptr<media::VideoFrame> video_frame = | 531 scoped_refptr<media::VideoFrame> video_frame = |
| 525 WrapI420Buffer(capture_resolution, static_cast<uint8_t*>(buffer->data())); | 532 WrapI420Buffer(capture_resolution, static_cast<uint8_t*>(buffer->data())); |
| 526 ASSERT_TRUE(video_frame); | 533 ASSERT_TRUE(video_frame); |
| 527 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame, | 534 video_frame->metadata()->SetTimeTicks( |
| 528 base::TimeTicks()); | 535 media::VideoFrameMetadata::REFERENCE_TIME, base::TimeTicks()); |
| 536 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame); |
| 529 | 537 |
| 530 base::RunLoop().RunUntilIdle(); | 538 base::RunLoop().RunUntilIdle(); |
| 531 } | 539 } |
| 532 | 540 |
| 533 // Exercises the OnError() codepath of VideoCaptureController, and tests the | 541 // Exercises the OnError() codepath of VideoCaptureController, and tests the |
| 534 // behavior of various operations after the error state has been signalled. | 542 // behavior of various operations after the error state has been signalled. |
| 535 TEST_F(VideoCaptureControllerTest, ErrorAfterDeviceCreation) { | 543 TEST_F(VideoCaptureControllerTest, ErrorAfterDeviceCreation) { |
| 536 media::VideoCaptureParams session_100; | 544 media::VideoCaptureParams session_100; |
| 537 session_100.requested_format = media::VideoCaptureFormat( | 545 session_100.requested_format = media::VideoCaptureFormat( |
| 538 gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420); | 546 gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 556 const gfx::Size dims(320, 240); | 564 const gfx::Size dims(320, 240); |
| 557 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer( | 565 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer( |
| 558 device_->ReserveOutputBuffer(dims, media::PIXEL_FORMAT_I420, | 566 device_->ReserveOutputBuffer(dims, media::PIXEL_FORMAT_I420, |
| 559 media::PIXEL_STORAGE_CPU)); | 567 media::PIXEL_STORAGE_CPU)); |
| 560 ASSERT_TRUE(buffer.get()); | 568 ASSERT_TRUE(buffer.get()); |
| 561 | 569 |
| 562 scoped_refptr<media::VideoFrame> video_frame = | 570 scoped_refptr<media::VideoFrame> video_frame = |
| 563 WrapI420Buffer(dims, static_cast<uint8_t*>(buffer->data())); | 571 WrapI420Buffer(dims, static_cast<uint8_t*>(buffer->data())); |
| 564 ASSERT_TRUE(video_frame); | 572 ASSERT_TRUE(video_frame); |
| 565 device_->OnError(FROM_HERE, "Test Error"); | 573 device_->OnError(FROM_HERE, "Test Error"); |
| 566 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame, | 574 video_frame->metadata()->SetTimeTicks( |
| 567 base::TimeTicks()); | 575 media::VideoFrameMetadata::REFERENCE_TIME, base::TimeTicks()); |
| 576 device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame); |
| 568 | 577 |
| 569 EXPECT_CALL(*client_a_, DoError(route_id)).Times(1); | 578 EXPECT_CALL(*client_a_, DoError(route_id)).Times(1); |
| 570 base::RunLoop().RunUntilIdle(); | 579 base::RunLoop().RunUntilIdle(); |
| 571 Mock::VerifyAndClearExpectations(client_a_.get()); | 580 Mock::VerifyAndClearExpectations(client_a_.get()); |
| 572 | 581 |
| 573 // Second client connects after the error state. It also should get told of | 582 // Second client connects after the error state. It also should get told of |
| 574 // the error. | 583 // the error. |
| 575 EXPECT_CALL(*client_b_, DoError(route_id)).Times(1); | 584 EXPECT_CALL(*client_b_, DoError(route_id)).Times(1); |
| 576 controller_->AddClient( | 585 controller_->AddClient( |
| 577 route_id, client_b_.get(), base::kNullProcessHandle, 200, session_200); | 586 route_id, client_b_.get(), base::kNullProcessHandle, 200, session_200); |
| 578 Mock::VerifyAndClearExpectations(client_b_.get()); | 587 Mock::VerifyAndClearExpectations(client_b_.get()); |
| 579 } | 588 } |
| 580 | 589 |
| 581 } // namespace content | 590 } // namespace content |
| OLD | NEW |