|  | /* | 
|  | *  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 <memory> | 
|  | #include <string> | 
|  | #include <utility> | 
|  |  | 
|  | #include "api/test/mock_video_encoder.h" | 
|  | #include "api/test/mock_video_encoder_factory.h" | 
|  | #include "api/video_codecs/video_encoder.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 { | 
|  | namespace { | 
|  | const VideoEncoder::Capabilities kCapabilities(false); | 
|  | const VideoEncoder::Settings kSettings(kCapabilities, 4, 1200); | 
|  | }  // namespace | 
|  |  | 
|  | using ::testing::_; | 
|  | using ::testing::ByMove; | 
|  | using ::testing::NiceMock; | 
|  | using ::testing::Return; | 
|  |  | 
|  | 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, | 
|  | true}; | 
|  | codec_settings.simulcastStream[1] = {test::kTestWidth, | 
|  | test::kTestHeight, | 
|  | test::kTestFrameRate, | 
|  | 2, | 
|  | 3000, | 
|  | 1000, | 
|  | 1000, | 
|  | 56, | 
|  | true}; | 
|  | codec_settings.simulcastStream[2] = {test::kTestWidth, | 
|  | test::kTestHeight, | 
|  | test::kTestFrameRate, | 
|  | 2, | 
|  | 5000, | 
|  | 1000, | 
|  | 1000, | 
|  | 56, | 
|  | true}; | 
|  | codec_settings.numberOfSimulcastStreams = 3; | 
|  |  | 
|  | auto mock_encoder = std::make_unique<NiceMock<MockVideoEncoder>>(); | 
|  | NiceMock<MockVideoEncoderFactory> 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, CreateVideoEncoder) | 
|  | .Times(1) | 
|  | .WillOnce(Return(ByMove(std::move(mock_encoder)))); | 
|  |  | 
|  | EncoderSimulcastProxy simulcast_enabled_proxy(&simulcast_factory, | 
|  | SdpVideoFormat("VP8")); | 
|  | EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | 
|  | simulcast_enabled_proxy.InitEncode(&codec_settings, kSettings)); | 
|  | EXPECT_EQ(kImplementationName, | 
|  | simulcast_enabled_proxy.GetEncoderInfo().implementation_name); | 
|  |  | 
|  | NiceMock<MockVideoEncoderFactory> nonsimulcast_factory; | 
|  |  | 
|  | EXPECT_CALL(nonsimulcast_factory, CreateVideoEncoder) | 
|  | .Times(4) | 
|  | .WillOnce([&] { | 
|  | auto mock_encoder = std::make_unique<NiceMock<MockVideoEncoder>>(); | 
|  | EXPECT_CALL(*mock_encoder, InitEncode(_, _)) | 
|  | .WillOnce(Return( | 
|  | WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED)); | 
|  | ON_CALL(*mock_encoder, GetEncoderInfo) | 
|  | .WillByDefault(Return(encoder_info)); | 
|  | return mock_encoder; | 
|  | }) | 
|  | .WillRepeatedly([&] { | 
|  | auto mock_encoder = std::make_unique<NiceMock<MockVideoEncoder>>(); | 
|  | EXPECT_CALL(*mock_encoder, InitEncode(_, _)) | 
|  | .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); | 
|  | ON_CALL(*mock_encoder, GetEncoderInfo) | 
|  | .WillByDefault(Return(encoder_info)); | 
|  | return mock_encoder; | 
|  | }); | 
|  |  | 
|  | EncoderSimulcastProxy simulcast_disabled_proxy(&nonsimulcast_factory, | 
|  | SdpVideoFormat("VP8")); | 
|  | EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | 
|  | simulcast_disabled_proxy.InitEncode(&codec_settings, kSettings)); | 
|  | EXPECT_EQ(kSimulcastAdaptedImplementationName, | 
|  | simulcast_disabled_proxy.GetEncoderInfo().implementation_name); | 
|  |  | 
|  | // Cleanup. | 
|  | simulcast_enabled_proxy.Release(); | 
|  | simulcast_disabled_proxy.Release(); | 
|  | } | 
|  |  | 
|  | TEST(EncoderSimulcastProxy, ForwardsTrustedSetting) { | 
|  | auto mock_encoder_owned = std::make_unique<NiceMock<MockVideoEncoder>>(); | 
|  | auto* mock_encoder = mock_encoder_owned.get(); | 
|  | NiceMock<MockVideoEncoderFactory> simulcast_factory; | 
|  |  | 
|  | EXPECT_CALL(*mock_encoder, InitEncode(_, _)) | 
|  | .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); | 
|  |  | 
|  | EXPECT_CALL(simulcast_factory, CreateVideoEncoder) | 
|  | .Times(1) | 
|  | .WillOnce(Return(ByMove(std::move(mock_encoder_owned)))); | 
|  |  | 
|  | 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, kSettings)); | 
|  |  | 
|  | 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) { | 
|  | auto mock_encoder_owned = std::make_unique<NiceMock<MockVideoEncoder>>(); | 
|  | NiceMock<MockVideoEncoder>* mock_encoder = mock_encoder_owned.get(); | 
|  | NiceMock<MockVideoEncoderFactory> simulcast_factory; | 
|  |  | 
|  | EXPECT_CALL(*mock_encoder, InitEncode(_, _)) | 
|  | .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); | 
|  |  | 
|  | EXPECT_CALL(simulcast_factory, CreateVideoEncoder) | 
|  | .Times(1) | 
|  | .WillOnce(Return(ByMove(std::move(mock_encoder_owned)))); | 
|  |  | 
|  | 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, kSettings)); | 
|  |  | 
|  | 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) { | 
|  | auto mock_encoder_owned = std::make_unique<NiceMock<MockVideoEncoder>>(); | 
|  | NiceMock<MockVideoEncoder>* mock_encoder = mock_encoder_owned.get(); | 
|  | NiceMock<MockVideoEncoderFactory> simulcast_factory; | 
|  |  | 
|  | EXPECT_CALL(*mock_encoder, InitEncode(_, _)) | 
|  | .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK)); | 
|  |  | 
|  | EXPECT_CALL(simulcast_factory, CreateVideoEncoder) | 
|  | .Times(1) | 
|  | .WillOnce(Return(ByMove(std::move(mock_encoder_owned)))); | 
|  |  | 
|  | 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, kSettings)); | 
|  |  | 
|  | 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 |