| Index: media/capture/service/video_capture_device_client_impl_unittest.cc
|
| diff --git a/media/capture/service/video_capture_device_client_impl_unittest.cc b/media/capture/service/video_capture_device_client_impl_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d1819dd0be8d6bb268245f9ffad47df10cf28132
|
| --- /dev/null
|
| +++ b/media/capture/service/video_capture_device_client_impl_unittest.cc
|
| @@ -0,0 +1,157 @@
|
| +// 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/bind.h"
|
| +#include "base/run_loop.h"
|
| +#include "media/capture/service/mojo_video_frame.h"
|
| +#include "media/capture/service/video_capture_device_client_impl.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +using ::testing::_;
|
| +using ::testing::InSequence;
|
| +using ::testing::SaveArg;
|
| +
|
| +namespace media {
|
| +
|
| +class VideoCaptureDeviceClientImplTest
|
| + : public testing::Test,
|
| + public VideoCaptureDeviceClientImpl::Delegate {
|
| + public:
|
| + VideoCaptureDeviceClientImplTest() : device_client_impl_(this) {}
|
| +
|
| + void SetUp() override {}
|
| + void TearDown() override {}
|
| +
|
| + // VideoCaptureDeviceClientImpl::Delegate
|
| + MOCK_METHOD2(OnFrame,
|
| + void(const scoped_refptr<MojoVideoFrame>& frame,
|
| + const base::TimeTicks& timestamp));
|
| + MOCK_METHOD1(OnError, void(const std::string& reason));
|
| +
|
| + void OnIncomingCapturedData(const uint8_t* data,
|
| + int length,
|
| + const media::VideoCaptureFormat& frame_format,
|
| + int clockwise_rotation,
|
| + const base::TimeTicks& timestamp) {
|
| + device_client_impl_.OnIncomingCapturedData(data, length, frame_format,
|
| + clockwise_rotation, timestamp);
|
| + }
|
| + void OnError(const tracked_objects::Location& from_here,
|
| + const std::string& reason) {
|
| + device_client_impl_.OnError(from_here, reason);
|
| + }
|
| +
|
| + protected:
|
| + base::MessageLoop loop_;
|
| +
|
| + // The mock of the (remote) video capture client.
|
| + VideoCaptureDeviceClientImpl device_client_impl_;
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(VideoCaptureDeviceClientImplTest);
|
| +};
|
| +
|
| +TEST_F(VideoCaptureDeviceClientImplTest, CreateAndDestroy) {}
|
| +
|
| +// Tests that OnError is correctly forwarded.
|
| +TEST_F(VideoCaptureDeviceClientImplTest, OnError) {
|
| + const std::string kBigError("Kaiju-size error");
|
| + EXPECT_CALL(*this, OnError(kBigError)).Times(1);
|
| + OnError(FROM_HERE, kBigError);
|
| + base::RunLoop().RunUntilIdle();
|
| +}
|
| +
|
| +// Tests that buffer-based capture API accepts all memory-backed pixel formats.
|
| +// Same as VideoCaptureDeviceClientTest's homonym test case.
|
| +TEST_F(VideoCaptureDeviceClientImplTest,
|
| + DataCaptureInEachVideoFormatInSequence) {
|
| + // The usual ReserveOutputBuffer() -> OnIncomingCapturedVideoFrame() cannot
|
| + // be used since it does not accept all pixel formats. The memory backed
|
| + // buffer OnIncomingCapturedData() is used instead, with a dummy scratchpad
|
| + // buffer.
|
| + const size_t kScratchpadSizeInBytes = 400;
|
| + unsigned char data[kScratchpadSizeInBytes] = {};
|
| + const gfx::Size capture_resolution(10, 10);
|
| + ASSERT_GE(kScratchpadSizeInBytes, capture_resolution.GetArea() * 4u)
|
| + << "Scratchpad is too small to hold the largest pixel format (ARGB).";
|
| +
|
| + const media::VideoPixelFormat kSupportedFormats[] = {
|
| + media::PIXEL_FORMAT_I420,
|
| + media::PIXEL_FORMAT_YV12,
|
| + media::PIXEL_FORMAT_NV12,
|
| + media::PIXEL_FORMAT_NV21,
|
| + media::PIXEL_FORMAT_YUY2,
|
| + media::PIXEL_FORMAT_UYVY,
|
| +#if defined(OS_LINUX) || defined(OS_WIN)
|
| + media::PIXEL_FORMAT_RGB24,
|
| +#endif
|
| + media::PIXEL_FORMAT_RGB32,
|
| + media::PIXEL_FORMAT_ARGB
|
| + };
|
| +
|
| + for (media::VideoPixelFormat format : kSupportedFormats) {
|
| + media::VideoCaptureParams params;
|
| + params.requested_format =
|
| + media::VideoCaptureFormat(capture_resolution, 30.0f, format);
|
| +
|
| + scoped_refptr<MojoVideoFrame> frame;
|
| + const base::TimeTicks now = base::TimeTicks::Now();
|
| +
|
| + EXPECT_CALL(*this, OnFrame(_, now)).Times(1).WillOnce(SaveArg<0>(&frame));
|
| + OnIncomingCapturedData(data, params.requested_format.ImageAllocationSize(),
|
| + params.requested_format, 0 /* clockwise_rotation */,
|
| + now);
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + EXPECT_EQ(media::PIXEL_FORMAT_I420, frame->format());
|
| + EXPECT_EQ(10, frame->coded_size().width());
|
| + EXPECT_EQ(10, frame->coded_size().height());
|
| + }
|
| +}
|
| +
|
| +// Test that we receive the expected resolution for a given captured frame
|
| +// resolution and rotation. Odd resolutions are also cropped.
|
| +// Same as VideoCaptureDeviceClientTest's homonym test case.
|
| +TEST_F(VideoCaptureDeviceClientImplTest, CheckRotationsAndCrops) {
|
| + const struct SizeAndRotation {
|
| + gfx::Size input_resolution;
|
| + int rotation;
|
| + gfx::Size output_resolution;
|
| + } kSizeAndRotations[] = {{{6, 4}, 0, {6, 4}}, {{6, 4}, 90, {4, 6}},
|
| + {{6, 4}, 180, {6, 4}}, {{6, 4}, 270, {4, 6}},
|
| + {{7, 4}, 0, {6, 4}}, {{7, 4}, 90, {4, 6}},
|
| + {{7, 4}, 180, {6, 4}}, {{7, 4}, 270, {4, 6}}};
|
| +
|
| + // The usual ReserveOutputBuffer() -> OnIncomingCapturedVideoFrame() cannot
|
| + // be used since it does not resolve rotations or crops. The memory backed
|
| + // buffer OnIncomingCapturedData() is used instead, with a dummy scratchpad
|
| + // buffer.
|
| + const size_t kScratchpadSizeInBytes = 400;
|
| + unsigned char data[kScratchpadSizeInBytes] = {};
|
| +
|
| + media::VideoCaptureParams params;
|
| + for (const auto& size_and_rotation : kSizeAndRotations) {
|
| + ASSERT_GE(kScratchpadSizeInBytes,
|
| + size_and_rotation.input_resolution.GetArea() * 4u)
|
| + << "Scratchpad is too small to hold the largest pixel format (ARGB).";
|
| + params.requested_format = media::VideoCaptureFormat(
|
| + size_and_rotation.input_resolution, 30.0f, media::PIXEL_FORMAT_ARGB);
|
| +
|
| + scoped_refptr<MojoVideoFrame> frame;
|
| + const base::TimeTicks now = base::TimeTicks::Now();
|
| + EXPECT_CALL(*this, OnFrame(_, now)).Times(1).WillOnce(SaveArg<0>(&frame));
|
| + OnIncomingCapturedData(data, params.requested_format.ImageAllocationSize(),
|
| + params.requested_format, size_and_rotation.rotation,
|
| + now);
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + EXPECT_EQ(frame->coded_size().width(),
|
| + size_and_rotation.output_resolution.width());
|
| + EXPECT_EQ(frame->coded_size().height(),
|
| + size_and_rotation.output_resolution.height());
|
| + }
|
| +}
|
| +
|
| +} // namespace media
|
|
|