| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/memory/ref_counted.h" |
| #include "base/run_loop.h" |
| #include "media/base/video_frame.h" |
| #include "media/mojo/common/media_type_converters.h" |
| #include "services/video_capture/fake_device_test.h" |
| #include "services/video_capture/mock_video_frame_receiver.h" |
| #include "services/video_capture/public/cpp/video_capture_settings.h" |
| #include "services/video_capture/public/interfaces/video_capture_device_factory.mojom.h" |
| #include "services/video_capture/video_capture_service_test.h" |
| |
| using testing::_; |
| using testing::Invoke; |
| using testing::InvokeWithoutArgs; |
| |
| namespace { |
| |
| struct FrameInfo { |
| gfx::Size size; |
| media::VideoPixelFormat pixel_format; |
| media::VideoFrame::StorageType storage_type; |
| bool is_mappable; |
| base::TimeDelta timestamp; |
| }; |
| |
| } // anonymous namespace |
| |
| namespace video_capture { |
| |
| TEST_F(FakeDeviceTest, FrameCallbacksArrive) { |
| base::RunLoop wait_loop; |
| const int kNumFramesToWaitFor = 3; |
| int num_frames_arrived = 0; |
| mojom::VideoFrameReceiverPtr receiver_proxy; |
| MockVideoFrameReceiver receiver(mojo::GetProxy(&receiver_proxy)); |
| EXPECT_CALL(receiver, OnIncomingCapturedVideoFramePtr(_)) |
| .WillRepeatedly(InvokeWithoutArgs( |
| [&wait_loop, &kNumFramesToWaitFor, &num_frames_arrived]() { |
| num_frames_arrived += 1; |
| if (num_frames_arrived >= kNumFramesToWaitFor) { |
| wait_loop.Quit(); |
| } |
| })); |
| |
| fake_device_proxy_->Start(requestable_settings_, |
| std::move(receiver_proxy)); |
| wait_loop.Run(); |
| } |
| |
| // Tests that frames received from a fake capture device match the requested |
| // format and have increasing timestamps. |
| TEST_F(FakeDeviceTest, ReceiveFramesFromFakeCaptureDevice) { |
| base::RunLoop wait_loop; |
| mojom::VideoFrameReceiverPtr receiver_proxy; |
| constexpr int num_frames_to_receive = 2; |
| FrameInfo received_frame_infos[num_frames_to_receive]; |
| int received_frame_count = 0; |
| MockVideoFrameReceiver receiver(mojo::GetProxy(&receiver_proxy)); |
| EXPECT_CALL(receiver, OnIncomingCapturedVideoFramePtr(_)) |
| .WillRepeatedly( |
| Invoke([&received_frame_infos, &received_frame_count, |
| &num_frames_to_receive, &wait_loop]( |
| const media::mojom::VideoFramePtr* frame) { |
| if (received_frame_count >= num_frames_to_receive) |
| return; |
| auto video_frame = frame->To<scoped_refptr<media::VideoFrame>>(); |
| auto& frame_info = received_frame_infos[received_frame_count]; |
| frame_info.pixel_format = video_frame->format(); |
| frame_info.storage_type = video_frame->storage_type(); |
| frame_info.is_mappable = video_frame->IsMappable(); |
| frame_info.size = video_frame->natural_size(); |
| frame_info.timestamp = video_frame->timestamp(); |
| received_frame_count += 1; |
| if (received_frame_count == num_frames_to_receive) |
| wait_loop.Quit(); |
| })); |
| |
| fake_device_proxy_->Start( |
| requestable_settings_, std::move(receiver_proxy)); |
| |
| wait_loop.Run(); |
| |
| base::TimeDelta previous_timestamp; |
| for (int i = 0; i < num_frames_to_receive; i++) { |
| auto& frame_info = received_frame_infos[i]; |
| // Service is expected to always output I420 |
| EXPECT_EQ(media::PIXEL_FORMAT_I420, frame_info.pixel_format); |
| // Service is expected to always use STORAGE_MOJO_SHARED_BUFFER |
| EXPECT_EQ(media::VideoFrame::STORAGE_MOJO_SHARED_BUFFER, |
| frame_info.storage_type); |
| EXPECT_TRUE(frame_info.is_mappable); |
| EXPECT_EQ(requestable_settings_.format.frame_size, |
| frame_info.size); |
| // Timestamps are expected to increase |
| if (i > 0) |
| EXPECT_GT(frame_info.timestamp, previous_timestamp); |
| previous_timestamp = frame_info.timestamp; |
| } |
| } |
| |
| } // namespace video_capture |