| Index: content/browser/renderer_host/media/video_capture_controller_unittest.cc
|
| diff --git a/content/browser/renderer_host/media/video_capture_controller_unittest.cc b/content/browser/renderer_host/media/video_capture_controller_unittest.cc
|
| index 2529e8959f48cfd64de6419ac9ffaf10b7da4327..337e6d0511bcf17661b3ea2d34e9147f02c62d4f 100644
|
| --- a/content/browser/renderer_host/media/video_capture_controller_unittest.cc
|
| +++ b/content/browser/renderer_host/media/video_capture_controller_unittest.cc
|
| @@ -23,11 +23,16 @@
|
| #include "base/threading/thread_task_runner_handle.h"
|
| #include "content/browser/renderer_host/media/media_stream_provider.h"
|
| #include "content/browser/renderer_host/media/video_capture_controller_event_handler.h"
|
| +#include "content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h"
|
| #include "content/browser/renderer_host/media/video_capture_manager.h"
|
| +#include "content/browser/renderer_host/media/video_frame_receiver_on_io_thread.h"
|
| #include "content/common/media/media_stream_options.h"
|
| #include "content/public/test/test_browser_thread_bundle.h"
|
| #include "media/base/video_frame_metadata.h"
|
| #include "media/base/video_util.h"
|
| +#include "media/capture/video/video_capture_buffer_pool_impl.h"
|
| +#include "media/capture/video/video_capture_buffer_tracker_factory_impl.h"
|
| +#include "media/capture/video/video_capture_device_client.h"
|
| #include "media/capture/video_capture_types.h"
|
| #include "testing/gmock/include/gmock/gmock.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| @@ -40,13 +45,17 @@ using ::testing::SaveArg;
|
|
|
| namespace content {
|
|
|
| +std::unique_ptr<media::VideoCaptureJpegDecoder> CreateGpuJpegDecoder(
|
| + const media::VideoCaptureJpegDecoder::DecodeDoneCB& decode_done_cb) {
|
| + return base::MakeUnique<content::VideoCaptureGpuJpegDecoder>(decode_done_cb);
|
| +}
|
| +
|
| class MockVideoCaptureControllerEventHandler
|
| : public VideoCaptureControllerEventHandler {
|
| public:
|
| explicit MockVideoCaptureControllerEventHandler(
|
| VideoCaptureController* controller)
|
| - : controller_(controller),
|
| - resource_utilization_(-1.0) {}
|
| + : controller_(controller), resource_utilization_(-1.0) {}
|
| ~MockVideoCaptureControllerEventHandler() override {}
|
|
|
| // These mock methods are delegated to by our fake implementation of
|
| @@ -57,12 +66,11 @@ class MockVideoCaptureControllerEventHandler
|
| MOCK_METHOD1(DoEnded, void(VideoCaptureControllerID));
|
| MOCK_METHOD1(DoError, void(VideoCaptureControllerID));
|
|
|
| - void OnError(VideoCaptureControllerID id) override {
|
| - DoError(id);
|
| - }
|
| + void OnError(VideoCaptureControllerID id) override { DoError(id); }
|
| void OnBufferCreated(VideoCaptureControllerID id,
|
| mojo::ScopedSharedBufferHandle handle,
|
| - int length, int buffer_id) override {
|
| + int length,
|
| + int buffer_id) override {
|
| DoBufferCreated(id);
|
| }
|
| void OnBufferDestroyed(VideoCaptureControllerID id, int buffer_id) override {
|
| @@ -103,6 +111,14 @@ class MockConsumerFeedbackObserver
|
| void(int frame_feedback_id, double utilization));
|
| };
|
|
|
| +class MockFrameBufferPool : public media::FrameBufferPool {
|
| + public:
|
| + MOCK_METHOD1(SetBufferHold, void(int buffer_id));
|
| + MOCK_METHOD1(ReleaseBufferHold, void(int buffer_id));
|
| + MOCK_METHOD1(GetHandleForTransit,
|
| + mojo::ScopedSharedBufferHandle(int buffer_id));
|
| +};
|
| +
|
| // Test class.
|
| class VideoCaptureControllerTest
|
| : public testing::Test,
|
| @@ -115,8 +131,22 @@ class VideoCaptureControllerTest
|
| static const int kPoolSize = 3;
|
|
|
| void SetUp() override {
|
| - controller_.reset(new VideoCaptureController(kPoolSize));
|
| - device_ = controller_->NewDeviceClient();
|
| + scoped_refptr<media::VideoCaptureBufferPool> buffer_pool(
|
| + new media::VideoCaptureBufferPoolImpl(
|
| + base::MakeUnique<media::VideoCaptureBufferTrackerFactoryImpl>(),
|
| + kPoolSize));
|
| + controller_.reset(new VideoCaptureController());
|
| + device_client_.reset(new media::VideoCaptureDeviceClient(
|
| + base::MakeUnique<VideoFrameReceiverOnIOThread>(
|
| + controller_->GetWeakPtrForIOThread()),
|
| + buffer_pool,
|
| + base::Bind(
|
| + &CreateGpuJpegDecoder,
|
| + base::Bind(&media::VideoFrameReceiver::OnIncomingCapturedVideoFrame,
|
| + controller_->GetWeakPtrForIOThread()))));
|
| + auto frame_receiver_observer = base::MakeUnique<MockFrameBufferPool>();
|
| + mock_frame_receiver_observer_ = frame_receiver_observer.get();
|
| + controller_->SetFrameBufferPool(std::move(frame_receiver_observer));
|
| auto consumer_feedback_observer =
|
| base::MakeUnique<MockConsumerFeedbackObserver>();
|
| mock_consumer_feedback_observer_ = consumer_feedback_observer.get();
|
| @@ -147,7 +177,8 @@ class VideoCaptureControllerTest
|
| std::unique_ptr<MockVideoCaptureControllerEventHandler> client_a_;
|
| std::unique_ptr<MockVideoCaptureControllerEventHandler> client_b_;
|
| std::unique_ptr<VideoCaptureController> controller_;
|
| - std::unique_ptr<media::VideoCaptureDevice::Client> device_;
|
| + std::unique_ptr<media::VideoCaptureDevice::Client> device_client_;
|
| + MockFrameBufferPool* mock_frame_receiver_observer_;
|
| MockConsumerFeedbackObserver* mock_consumer_feedback_observer_;
|
|
|
| private:
|
| @@ -299,13 +330,13 @@ TEST_P(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
|
| // side effect this will cause the first buffer to be shared with clients.
|
| uint8_t buffer_no = 1;
|
| const int arbitrary_frame_feedback_id = 101;
|
| - ASSERT_EQ(0.0, device_->GetBufferPoolUtilization());
|
| + ASSERT_EQ(0.0, device_client_->GetBufferPoolUtilization());
|
| std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer(
|
| - device_->ReserveOutputBuffer(capture_resolution, format,
|
| - media::PIXEL_STORAGE_CPU,
|
| - arbitrary_frame_feedback_id));
|
| + device_client_->ReserveOutputBuffer(capture_resolution, format,
|
| + media::PIXEL_STORAGE_CPU,
|
| + arbitrary_frame_feedback_id));
|
| ASSERT_TRUE(buffer.get());
|
| - ASSERT_EQ(1.0 / kPoolSize, device_->GetBufferPoolUtilization());
|
| + ASSERT_EQ(1.0 / kPoolSize, device_client_->GetBufferPoolUtilization());
|
| memset(buffer->data(), buffer_no++, buffer->mapped_size());
|
| {
|
| InSequence s;
|
| @@ -332,30 +363,37 @@ TEST_P(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
|
| media::VideoFrameMetadata::RESOURCE_UTILIZATION));
|
| client_a_->resource_utilization_ = 0.5;
|
| client_b_->resource_utilization_ = -1.0;
|
| -
|
| - // Expect VideoCaptureController to call the load observer with a
|
| - // resource utilization of 0.5 (the largest of all reported values).
|
| - EXPECT_CALL(*mock_consumer_feedback_observer_,
|
| - OnUtilizationReport(arbitrary_frame_feedback_id, 0.5))
|
| - .Times(1);
|
| + {
|
| + InSequence s;
|
| + EXPECT_CALL(*mock_frame_receiver_observer_, SetBufferHold(buffer->id()))
|
| + .Times(1);
|
| + // Expect VideoCaptureController to call the load observer with a
|
| + // resource utilization of 0.5 (the largest of all reported values).
|
| + EXPECT_CALL(*mock_consumer_feedback_observer_,
|
| + OnUtilizationReport(arbitrary_frame_feedback_id, 0.5))
|
| + .Times(1);
|
| + EXPECT_CALL(*mock_frame_receiver_observer_, ReleaseBufferHold(buffer->id()))
|
| + .Times(1);
|
| + }
|
|
|
| video_frame->metadata()->SetTimeTicks(
|
| media::VideoFrameMetadata::REFERENCE_TIME, base::TimeTicks());
|
| - device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame);
|
| + device_client_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame);
|
|
|
| base::RunLoop().RunUntilIdle();
|
| Mock::VerifyAndClearExpectations(client_a_.get());
|
| Mock::VerifyAndClearExpectations(client_b_.get());
|
| Mock::VerifyAndClearExpectations(mock_consumer_feedback_observer_);
|
| + Mock::VerifyAndClearExpectations(mock_frame_receiver_observer_);
|
|
|
| // Second buffer which ought to use the same shared memory buffer. In this
|
| // case pretend that the Buffer pointer is held by the device for a long
|
| // delay. This shouldn't affect anything.
|
| const int arbitrary_frame_feedback_id_2 = 102;
|
| std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer2 =
|
| - device_->ReserveOutputBuffer(capture_resolution, format,
|
| - media::PIXEL_STORAGE_CPU,
|
| - arbitrary_frame_feedback_id_2);
|
| + device_client_->ReserveOutputBuffer(capture_resolution, format,
|
| + media::PIXEL_STORAGE_CPU,
|
| + arbitrary_frame_feedback_id_2);
|
| ASSERT_TRUE(buffer2.get());
|
| memset(buffer2->data(), buffer_no++, buffer2->mapped_size());
|
| video_frame = WrapBuffer(capture_resolution,
|
| @@ -366,11 +404,21 @@ TEST_P(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
|
| media::VideoFrameMetadata::REFERENCE_TIME, base::TimeTicks());
|
| // Expect VideoCaptureController to call the load observer with a
|
| // resource utilization of 3.14 (the largest of all reported values).
|
| - EXPECT_CALL(*mock_consumer_feedback_observer_,
|
| - OnUtilizationReport(arbitrary_frame_feedback_id_2, 3.14))
|
| - .Times(1);
|
| + {
|
| + InSequence s;
|
| + EXPECT_CALL(*mock_frame_receiver_observer_, SetBufferHold(buffer2->id()))
|
| + .Times(1);
|
| + // Expect VideoCaptureController to call the load observer with a
|
| + // resource utilization of 3.14 (the largest of all reported values).
|
| + EXPECT_CALL(*mock_consumer_feedback_observer_,
|
| + OnUtilizationReport(arbitrary_frame_feedback_id_2, 3.14))
|
| + .Times(1);
|
| + EXPECT_CALL(*mock_frame_receiver_observer_,
|
| + ReleaseBufferHold(buffer2->id()))
|
| + .Times(1);
|
| + }
|
|
|
| - device_->OnIncomingCapturedVideoFrame(std::move(buffer2), video_frame);
|
| + device_client_->OnIncomingCapturedVideoFrame(std::move(buffer2), video_frame);
|
|
|
| // The buffer should be delivered to the clients in any order.
|
| {
|
| @@ -395,6 +443,7 @@ TEST_P(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
|
| Mock::VerifyAndClearExpectations(client_a_.get());
|
| Mock::VerifyAndClearExpectations(client_b_.get());
|
| Mock::VerifyAndClearExpectations(mock_consumer_feedback_observer_);
|
| + Mock::VerifyAndClearExpectations(mock_frame_receiver_observer_);
|
|
|
| // Add a fourth client now that some buffers have come through.
|
| controller_->AddClient(client_b_route_2,
|
| @@ -407,9 +456,9 @@ TEST_P(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
|
| for (int i = 0; i < kPoolSize; i++) {
|
| const int arbitrary_frame_feedback_id = 200 + i;
|
| std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer =
|
| - device_->ReserveOutputBuffer(capture_resolution, format,
|
| - media::PIXEL_STORAGE_CPU,
|
| - arbitrary_frame_feedback_id);
|
| + device_client_->ReserveOutputBuffer(capture_resolution, format,
|
| + media::PIXEL_STORAGE_CPU,
|
| + arbitrary_frame_feedback_id);
|
| ASSERT_TRUE(buffer.get());
|
| memset(buffer->data(), buffer_no++, buffer->mapped_size());
|
| video_frame = WrapBuffer(capture_resolution,
|
| @@ -417,10 +466,11 @@ TEST_P(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
|
| ASSERT_TRUE(video_frame);
|
| video_frame->metadata()->SetTimeTicks(
|
| media::VideoFrameMetadata::REFERENCE_TIME, base::TimeTicks());
|
| - device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame);
|
| + device_client_->OnIncomingCapturedVideoFrame(std::move(buffer),
|
| + video_frame);
|
| }
|
| // ReserveOutputBuffer ought to fail now, because the pool is depleted.
|
| - ASSERT_FALSE(device_
|
| + ASSERT_FALSE(device_client_
|
| ->ReserveOutputBuffer(capture_resolution, format,
|
| media::PIXEL_STORAGE_CPU,
|
| arbitrary_frame_feedback_id)
|
| @@ -455,9 +505,9 @@ TEST_P(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
|
| controller_->StopSession(300);
|
| // Queue up another buffer.
|
| std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer3 =
|
| - device_->ReserveOutputBuffer(capture_resolution, format,
|
| - media::PIXEL_STORAGE_CPU,
|
| - arbitrary_frame_feedback_id);
|
| + device_client_->ReserveOutputBuffer(capture_resolution, format,
|
| + media::PIXEL_STORAGE_CPU,
|
| + arbitrary_frame_feedback_id);
|
| ASSERT_TRUE(buffer3.get());
|
| memset(buffer3->data(), buffer_no++, buffer3->mapped_size());
|
| video_frame = WrapBuffer(capture_resolution,
|
| @@ -465,12 +515,12 @@ TEST_P(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
|
| ASSERT_TRUE(video_frame);
|
| video_frame->metadata()->SetTimeTicks(
|
| media::VideoFrameMetadata::REFERENCE_TIME, base::TimeTicks());
|
| - device_->OnIncomingCapturedVideoFrame(std::move(buffer3), video_frame);
|
| + device_client_->OnIncomingCapturedVideoFrame(std::move(buffer3), video_frame);
|
|
|
| std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer4 =
|
| - device_->ReserveOutputBuffer(capture_resolution, format,
|
| - media::PIXEL_STORAGE_CPU,
|
| - arbitrary_frame_feedback_id);
|
| + device_client_->ReserveOutputBuffer(capture_resolution, format,
|
| + media::PIXEL_STORAGE_CPU,
|
| + arbitrary_frame_feedback_id);
|
| {
|
| // Kill A2 via session close (posts a task to disconnect, but A2 must not
|
| // be sent either of these two buffers).
|
| @@ -484,7 +534,7 @@ TEST_P(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
|
| ASSERT_TRUE(video_frame);
|
| video_frame->metadata()->SetTimeTicks(
|
| media::VideoFrameMetadata::REFERENCE_TIME, base::TimeTicks());
|
| - device_->OnIncomingCapturedVideoFrame(std::move(buffer4), video_frame);
|
| + device_client_->OnIncomingCapturedVideoFrame(std::move(buffer4), video_frame);
|
| // B2 is the only client left, and is the only one that should
|
| // get the buffer.
|
| EXPECT_CALL(*client_b_, DoBufferReady(client_b_route_2, capture_resolution))
|
| @@ -514,7 +564,7 @@ TEST_F(VideoCaptureControllerTest, ErrorBeforeDeviceCreation) {
|
|
|
| // Start with one client.
|
| controller_->AddClient(route_id, client_a_.get(), 100, session_100);
|
| - device_->OnError(FROM_HERE, "Test Error");
|
| + device_client_->OnError(FROM_HERE, "Test Error");
|
| EXPECT_CALL(*client_a_, DoError(route_id)).Times(1);
|
| base::RunLoop().RunUntilIdle();
|
| Mock::VerifyAndClearExpectations(client_a_.get());
|
| @@ -528,16 +578,16 @@ TEST_F(VideoCaptureControllerTest, ErrorBeforeDeviceCreation) {
|
|
|
| const int arbitrary_frame_feedback_id = 101;
|
| std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer(
|
| - device_->ReserveOutputBuffer(capture_resolution, media::PIXEL_FORMAT_I420,
|
| - media::PIXEL_STORAGE_CPU,
|
| - arbitrary_frame_feedback_id));
|
| + device_client_->ReserveOutputBuffer(
|
| + capture_resolution, media::PIXEL_FORMAT_I420,
|
| + media::PIXEL_STORAGE_CPU, arbitrary_frame_feedback_id));
|
| ASSERT_TRUE(buffer.get());
|
| scoped_refptr<media::VideoFrame> video_frame =
|
| WrapBuffer(capture_resolution, static_cast<uint8_t*>(buffer->data()));
|
| ASSERT_TRUE(video_frame);
|
| video_frame->metadata()->SetTimeTicks(
|
| media::VideoFrameMetadata::REFERENCE_TIME, base::TimeTicks());
|
| - device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame);
|
| + device_client_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame);
|
|
|
| base::RunLoop().RunUntilIdle();
|
| }
|
| @@ -567,18 +617,18 @@ TEST_F(VideoCaptureControllerTest, ErrorAfterDeviceCreation) {
|
| const gfx::Size dims(320, 240);
|
| const int arbitrary_frame_feedback_id = 101;
|
| std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer(
|
| - device_->ReserveOutputBuffer(dims, media::PIXEL_FORMAT_I420,
|
| - media::PIXEL_STORAGE_CPU,
|
| - arbitrary_frame_feedback_id));
|
| + device_client_->ReserveOutputBuffer(dims, media::PIXEL_FORMAT_I420,
|
| + media::PIXEL_STORAGE_CPU,
|
| + arbitrary_frame_feedback_id));
|
| ASSERT_TRUE(buffer.get());
|
|
|
| scoped_refptr<media::VideoFrame> video_frame =
|
| WrapBuffer(dims, static_cast<uint8_t*>(buffer->data()));
|
| ASSERT_TRUE(video_frame);
|
| - device_->OnError(FROM_HERE, "Test Error");
|
| + device_client_->OnError(FROM_HERE, "Test Error");
|
| video_frame->metadata()->SetTimeTicks(
|
| media::VideoFrameMetadata::REFERENCE_TIME, base::TimeTicks());
|
| - device_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame);
|
| + device_client_->OnIncomingCapturedVideoFrame(std::move(buffer), video_frame);
|
|
|
| EXPECT_CALL(*client_a_, DoError(route_id)).Times(1);
|
| base::RunLoop().RunUntilIdle();
|
|
|