1 /*
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 *
10 */
11
12 #include "media/engine/encoder_simulcast_proxy.h"
13
14 #include <memory>
15 #include <string>
16 #include <utility>
17
18 #include "api/test/mock_video_encoder.h"
19 #include "api/test/mock_video_encoder_factory.h"
20 #include "api/video_codecs/video_encoder.h"
21 #include "api/video_codecs/vp8_temporal_layers.h"
22 #include "modules/video_coding/include/video_codec_interface.h"
23 #include "test/gmock.h"
24 #include "test/gtest.h"
25 #include "test/video_codec_settings.h"
26
27 namespace webrtc {
28 namespace testing {
29 namespace {
30 const VideoEncoder::Capabilities kCapabilities(false);
31 const VideoEncoder::Settings kSettings(kCapabilities, 4, 1200);
32 } // namespace
33
34 using ::testing::_;
35 using ::testing::ByMove;
36 using ::testing::NiceMock;
37 using ::testing::Return;
38
TEST(EncoderSimulcastProxy,ChoosesCorrectImplementation)39 TEST(EncoderSimulcastProxy, ChoosesCorrectImplementation) {
40 const std::string kImplementationName = "Fake";
41 const std::string kSimulcastAdaptedImplementationName =
42 "SimulcastEncoderAdapter (Fake, Fake, Fake)";
43 VideoCodec codec_settings;
44 webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings);
45 codec_settings.simulcastStream[0] = {test::kTestWidth,
46 test::kTestHeight,
47 test::kTestFrameRate,
48 2,
49 2000,
50 1000,
51 1000,
52 56};
53 codec_settings.simulcastStream[1] = {test::kTestWidth,
54 test::kTestHeight,
55 test::kTestFrameRate,
56 2,
57 3000,
58 1000,
59 1000,
60 56};
61 codec_settings.simulcastStream[2] = {test::kTestWidth,
62 test::kTestHeight,
63 test::kTestFrameRate,
64 2,
65 5000,
66 1000,
67 1000,
68 56};
69 codec_settings.numberOfSimulcastStreams = 3;
70
71 auto mock_encoder = std::make_unique<NiceMock<MockVideoEncoder>>();
72 NiceMock<MockVideoEncoderFactory> simulcast_factory;
73
74 EXPECT_CALL(*mock_encoder, InitEncode(_, _))
75 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
76 VideoEncoder::EncoderInfo encoder_info;
77 encoder_info.implementation_name = kImplementationName;
78 EXPECT_CALL(*mock_encoder, GetEncoderInfo())
79 .WillRepeatedly(Return(encoder_info));
80
81 EXPECT_CALL(simulcast_factory, CreateVideoEncoder)
82 .Times(1)
83 .WillOnce(Return(ByMove(std::move(mock_encoder))));
84
85 EncoderSimulcastProxy simulcast_enabled_proxy(&simulcast_factory,
86 SdpVideoFormat("VP8"));
87 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
88 simulcast_enabled_proxy.InitEncode(&codec_settings, kSettings));
89 EXPECT_EQ(kImplementationName,
90 simulcast_enabled_proxy.GetEncoderInfo().implementation_name);
91
92 NiceMock<MockVideoEncoderFactory> nonsimulcast_factory;
93
94 EXPECT_CALL(nonsimulcast_factory, CreateVideoEncoder)
95 .Times(4)
96 .WillOnce([&] {
97 auto mock_encoder = std::make_unique<NiceMock<MockVideoEncoder>>();
98 EXPECT_CALL(*mock_encoder, InitEncode(_, _))
99 .WillOnce(Return(
100 WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED));
101 ON_CALL(*mock_encoder, GetEncoderInfo)
102 .WillByDefault(Return(encoder_info));
103 return mock_encoder;
104 })
105 .WillRepeatedly([&] {
106 auto mock_encoder = std::make_unique<NiceMock<MockVideoEncoder>>();
107 EXPECT_CALL(*mock_encoder, InitEncode(_, _))
108 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
109 ON_CALL(*mock_encoder, GetEncoderInfo)
110 .WillByDefault(Return(encoder_info));
111 return mock_encoder;
112 });
113
114 EncoderSimulcastProxy simulcast_disabled_proxy(&nonsimulcast_factory,
115 SdpVideoFormat("VP8"));
116 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
117 simulcast_disabled_proxy.InitEncode(&codec_settings, kSettings));
118 EXPECT_EQ(kSimulcastAdaptedImplementationName,
119 simulcast_disabled_proxy.GetEncoderInfo().implementation_name);
120
121 // Cleanup.
122 simulcast_enabled_proxy.Release();
123 simulcast_disabled_proxy.Release();
124 }
125
TEST(EncoderSimulcastProxy,ForwardsTrustedSetting)126 TEST(EncoderSimulcastProxy, ForwardsTrustedSetting) {
127 auto mock_encoder_owned = std::make_unique<NiceMock<MockVideoEncoder>>();
128 auto* mock_encoder = mock_encoder_owned.get();
129 NiceMock<MockVideoEncoderFactory> simulcast_factory;
130
131 EXPECT_CALL(*mock_encoder, InitEncode(_, _))
132 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
133
134 EXPECT_CALL(simulcast_factory, CreateVideoEncoder)
135 .Times(1)
136 .WillOnce(Return(ByMove(std::move(mock_encoder_owned))));
137
138 EncoderSimulcastProxy simulcast_enabled_proxy(&simulcast_factory,
139 SdpVideoFormat("VP8"));
140 VideoCodec codec_settings;
141 webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings);
142 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
143 simulcast_enabled_proxy.InitEncode(&codec_settings, kSettings));
144
145 VideoEncoder::EncoderInfo info;
146 info.has_trusted_rate_controller = true;
147 EXPECT_CALL(*mock_encoder, GetEncoderInfo()).WillRepeatedly(Return(info));
148
149 EXPECT_TRUE(
150 simulcast_enabled_proxy.GetEncoderInfo().has_trusted_rate_controller);
151 }
152
TEST(EncoderSimulcastProxy,ForwardsHardwareAccelerated)153 TEST(EncoderSimulcastProxy, ForwardsHardwareAccelerated) {
154 auto mock_encoder_owned = std::make_unique<NiceMock<MockVideoEncoder>>();
155 NiceMock<MockVideoEncoder>* mock_encoder = mock_encoder_owned.get();
156 NiceMock<MockVideoEncoderFactory> simulcast_factory;
157
158 EXPECT_CALL(*mock_encoder, InitEncode(_, _))
159 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
160
161 EXPECT_CALL(simulcast_factory, CreateVideoEncoder)
162 .Times(1)
163 .WillOnce(Return(ByMove(std::move(mock_encoder_owned))));
164
165 EncoderSimulcastProxy simulcast_enabled_proxy(&simulcast_factory,
166 SdpVideoFormat("VP8"));
167 VideoCodec codec_settings;
168 webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings);
169 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
170 simulcast_enabled_proxy.InitEncode(&codec_settings, kSettings));
171
172 VideoEncoder::EncoderInfo info;
173
174 info.is_hardware_accelerated = false;
175 EXPECT_CALL(*mock_encoder, GetEncoderInfo()).WillOnce(Return(info));
176 EXPECT_FALSE(
177 simulcast_enabled_proxy.GetEncoderInfo().is_hardware_accelerated);
178
179 info.is_hardware_accelerated = true;
180 EXPECT_CALL(*mock_encoder, GetEncoderInfo()).WillOnce(Return(info));
181 EXPECT_TRUE(simulcast_enabled_proxy.GetEncoderInfo().is_hardware_accelerated);
182 }
183
TEST(EncoderSimulcastProxy,ForwardsInternalSource)184 TEST(EncoderSimulcastProxy, ForwardsInternalSource) {
185 auto mock_encoder_owned = std::make_unique<NiceMock<MockVideoEncoder>>();
186 NiceMock<MockVideoEncoder>* mock_encoder = mock_encoder_owned.get();
187 NiceMock<MockVideoEncoderFactory> simulcast_factory;
188
189 EXPECT_CALL(*mock_encoder, InitEncode(_, _))
190 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
191
192 EXPECT_CALL(simulcast_factory, CreateVideoEncoder)
193 .Times(1)
194 .WillOnce(Return(ByMove(std::move(mock_encoder_owned))));
195
196 EncoderSimulcastProxy simulcast_enabled_proxy(&simulcast_factory,
197 SdpVideoFormat("VP8"));
198 VideoCodec codec_settings;
199 webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings);
200 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
201 simulcast_enabled_proxy.InitEncode(&codec_settings, kSettings));
202
203 VideoEncoder::EncoderInfo info;
204
205 info.has_internal_source = false;
206 EXPECT_CALL(*mock_encoder, GetEncoderInfo()).WillOnce(Return(info));
207 EXPECT_FALSE(simulcast_enabled_proxy.GetEncoderInfo().has_internal_source);
208
209 info.has_internal_source = true;
210 EXPECT_CALL(*mock_encoder, GetEncoderInfo()).WillOnce(Return(info));
211 EXPECT_TRUE(simulcast_enabled_proxy.GetEncoderInfo().has_internal_source);
212 }
213
214 } // namespace testing
215 } // namespace webrtc
216