/* * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. * */ #include "media/engine/encoder_simulcast_proxy.h" #include #include "api/test/mock_video_encoder_factory.h" #include "api/video_codecs/vp8_temporal_layers.h" #include "modules/video_coding/include/video_codec_interface.h" #include "test/gmock.h" #include "test/gtest.h" #include "test/video_codec_settings.h" namespace webrtc { namespace testing { using ::testing::_; using ::testing::NiceMock; using ::testing::Return; class MockEncoder : public VideoEncoder { public: // TODO(nisse): Valid overrides commented out, because the gmock // methods don't use any override declarations, and we want to avoid // warnings from -Winconsistent-missing-override. See // http://crbug.com/428099. MockEncoder() {} virtual ~MockEncoder() {} MOCK_METHOD3(InitEncode, int32_t(const VideoCodec* codec_settings, int32_t number_of_cores, size_t max_payload_size)); MOCK_METHOD1(RegisterEncodeCompleteCallback, int32_t(EncodedImageCallback*)); MOCK_METHOD0(Release, int32_t()); MOCK_METHOD3( Encode, int32_t(const VideoFrame& inputImage, const CodecSpecificInfo* codecSpecificInfo, const std::vector* frame_types) /* override */); MOCK_CONST_METHOD0(GetEncoderInfo, VideoEncoder::EncoderInfo(void)); }; TEST(EncoderSimulcastProxy, ChoosesCorrectImplementation) { const std::string kImplementationName = "Fake"; const std::string kSimulcastAdaptedImplementationName = "SimulcastEncoderAdapter (Fake, Fake, Fake)"; VideoCodec codec_settings; webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings); codec_settings.simulcastStream[0] = {test::kTestWidth, test::kTestHeight, test::kTestFrameRate, 2, 2000, 1000, 1000, 56}; codec_settings.simulcastStream[1] = {test::kTestWidth, test::kTestHeight, test::kTestFrameRate, 2, 3000, 1000, 1000, 56}; codec_settings.simulcastStream[2] = {test::kTestWidth, test::kTestHeight, test::kTestFrameRate, 2, 5000, 1000, 1000, 56}; codec_settings.numberOfSimulcastStreams = 3; NiceMock* mock_encoder = new NiceMock(); NiceMock simulcast_factory; EXPECT_CALL(*mock_encoder, InitEncode(_, _, _)) .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); VideoEncoder::EncoderInfo encoder_info; encoder_info.implementation_name = kImplementationName; EXPECT_CALL(*mock_encoder, GetEncoderInfo()) .WillRepeatedly(Return(encoder_info)); EXPECT_CALL(simulcast_factory, CreateVideoEncoderProxy(_)) .Times(1) .WillOnce(Return(mock_encoder)); EncoderSimulcastProxy simulcast_enabled_proxy(&simulcast_factory, SdpVideoFormat("VP8")); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, simulcast_enabled_proxy.InitEncode(&codec_settings, 4, 1200)); EXPECT_EQ(kImplementationName, simulcast_enabled_proxy.GetEncoderInfo().implementation_name); NiceMock* mock_encoder1 = new NiceMock(); NiceMock* mock_encoder2 = new NiceMock(); NiceMock* mock_encoder3 = new NiceMock(); NiceMock* mock_encoder4 = new NiceMock(); NiceMock nonsimulcast_factory; EXPECT_CALL(*mock_encoder1, InitEncode(_, _, _)) .WillOnce( Return(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED)); EXPECT_CALL(*mock_encoder1, GetEncoderInfo()) .WillRepeatedly(Return(encoder_info)); EXPECT_CALL(*mock_encoder2, InitEncode(_, _, _)) .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); EXPECT_CALL(*mock_encoder2, GetEncoderInfo()) .WillRepeatedly(Return(encoder_info)); EXPECT_CALL(*mock_encoder3, InitEncode(_, _, _)) .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); EXPECT_CALL(*mock_encoder3, GetEncoderInfo()) .WillRepeatedly(Return(encoder_info)); EXPECT_CALL(*mock_encoder4, InitEncode(_, _, _)) .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); EXPECT_CALL(*mock_encoder4, GetEncoderInfo()) .WillRepeatedly(Return(encoder_info)); EXPECT_CALL(nonsimulcast_factory, CreateVideoEncoderProxy(_)) .Times(4) .WillOnce(Return(mock_encoder1)) .WillOnce(Return(mock_encoder2)) .WillOnce(Return(mock_encoder3)) .WillOnce(Return(mock_encoder4)); EncoderSimulcastProxy simulcast_disabled_proxy(&nonsimulcast_factory, SdpVideoFormat("VP8")); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, simulcast_disabled_proxy.InitEncode(&codec_settings, 4, 1200)); EXPECT_EQ(kSimulcastAdaptedImplementationName, simulcast_disabled_proxy.GetEncoderInfo().implementation_name); // Cleanup. simulcast_enabled_proxy.Release(); simulcast_disabled_proxy.Release(); } TEST(EncoderSimulcastProxy, ForwardsTrustedSetting) { NiceMock* mock_encoder = new NiceMock(); NiceMock simulcast_factory; EXPECT_CALL(*mock_encoder, InitEncode(_, _, _)) .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); EXPECT_CALL(simulcast_factory, CreateVideoEncoderProxy(_)) .Times(1) .WillOnce(Return(mock_encoder)); EncoderSimulcastProxy simulcast_enabled_proxy(&simulcast_factory, SdpVideoFormat("VP8")); VideoCodec codec_settings; webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, simulcast_enabled_proxy.InitEncode(&codec_settings, 4, 1200)); VideoEncoder::EncoderInfo info; info.has_trusted_rate_controller = true; EXPECT_CALL(*mock_encoder, GetEncoderInfo()).WillRepeatedly(Return(info)); EXPECT_TRUE( simulcast_enabled_proxy.GetEncoderInfo().has_trusted_rate_controller); } TEST(EncoderSimulcastProxy, ForwardsHardwareAccelerated) { NiceMock* mock_encoder = new NiceMock(); NiceMock simulcast_factory; EXPECT_CALL(*mock_encoder, InitEncode(_, _, _)) .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); EXPECT_CALL(simulcast_factory, CreateVideoEncoderProxy(_)) .Times(1) .WillOnce(Return(mock_encoder)); EncoderSimulcastProxy simulcast_enabled_proxy(&simulcast_factory, SdpVideoFormat("VP8")); VideoCodec codec_settings; webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, simulcast_enabled_proxy.InitEncode(&codec_settings, 4, 1200)); VideoEncoder::EncoderInfo info; info.is_hardware_accelerated = false; EXPECT_CALL(*mock_encoder, GetEncoderInfo()).WillOnce(Return(info)); EXPECT_FALSE( simulcast_enabled_proxy.GetEncoderInfo().is_hardware_accelerated); info.is_hardware_accelerated = true; EXPECT_CALL(*mock_encoder, GetEncoderInfo()).WillOnce(Return(info)); EXPECT_TRUE(simulcast_enabled_proxy.GetEncoderInfo().is_hardware_accelerated); } TEST(EncoderSimulcastProxy, ForwardsInternalSource) { NiceMock* mock_encoder = new NiceMock(); NiceMock simulcast_factory; EXPECT_CALL(*mock_encoder, InitEncode(_, _, _)) .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); EXPECT_CALL(simulcast_factory, CreateVideoEncoderProxy(_)) .Times(1) .WillOnce(Return(mock_encoder)); EncoderSimulcastProxy simulcast_enabled_proxy(&simulcast_factory, SdpVideoFormat("VP8")); VideoCodec codec_settings; webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings); EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, simulcast_enabled_proxy.InitEncode(&codec_settings, 4, 1200)); VideoEncoder::EncoderInfo info; info.has_internal_source = false; EXPECT_CALL(*mock_encoder, GetEncoderInfo()).WillOnce(Return(info)); EXPECT_FALSE(simulcast_enabled_proxy.GetEncoderInfo().has_internal_source); info.has_internal_source = true; EXPECT_CALL(*mock_encoder, GetEncoderInfo()).WillOnce(Return(info)); EXPECT_TRUE(simulcast_enabled_proxy.GetEncoderInfo().has_internal_source); } } // namespace testing } // namespace webrtc