| /* |
| * 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] = {.width = test::kTestWidth, |
| .height = test::kTestHeight, |
| .maxFramerate = test::kTestFrameRate, |
| .numberOfTemporalLayers = 2, |
| .maxBitrate = 2000, |
| .targetBitrate = 1000, |
| .minBitrate = 1000, |
| .qpMax = 56, |
| .active = true}; |
| codec_settings.simulcastStream[1] = {.width = test::kTestWidth, |
| .height = test::kTestHeight, |
| .maxFramerate = test::kTestFrameRate, |
| .numberOfTemporalLayers = 2, |
| .maxBitrate = 3000, |
| .targetBitrate = 1000, |
| .minBitrate = 1000, |
| .qpMax = 56, |
| .active = true}; |
| codec_settings.simulcastStream[2] = {.width = test::kTestWidth, |
| .height = test::kTestHeight, |
| .maxFramerate = test::kTestFrameRate, |
| .numberOfTemporalLayers = 2, |
| .maxBitrate = 5000, |
| .targetBitrate = 1000, |
| .minBitrate = 1000, |
| .qpMax = 56, |
| .active = 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); |
| } |
| |
| } // namespace testing |
| } // namespace webrtc |