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 true};
54 codec_settings.simulcastStream[1] = {test::kTestWidth,
55 test::kTestHeight,
56 test::kTestFrameRate,
57 2,
58 3000,
59 1000,
60 1000,
61 56,
62 true};
63 codec_settings.simulcastStream[2] = {test::kTestWidth,
64 test::kTestHeight,
65 test::kTestFrameRate,
66 2,
67 5000,
68 1000,
69 1000,
70 56,
71 true};
72 codec_settings.numberOfSimulcastStreams = 3;
73
74 auto mock_encoder = std::make_unique<NiceMock<MockVideoEncoder>>();
75 NiceMock<MockVideoEncoderFactory> simulcast_factory;
76
77 EXPECT_CALL(*mock_encoder, InitEncode(_, _))
78 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
79 VideoEncoder::EncoderInfo encoder_info;
80 encoder_info.implementation_name = kImplementationName;
81 EXPECT_CALL(*mock_encoder, GetEncoderInfo())
82 .WillRepeatedly(Return(encoder_info));
83
84 EXPECT_CALL(simulcast_factory, CreateVideoEncoder)
85 .Times(1)
86 .WillOnce(Return(ByMove(std::move(mock_encoder))));
87
88 EncoderSimulcastProxy simulcast_enabled_proxy(&simulcast_factory,
89 SdpVideoFormat("VP8"));
90 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
91 simulcast_enabled_proxy.InitEncode(&codec_settings, kSettings));
92 EXPECT_EQ(kImplementationName,
93 simulcast_enabled_proxy.GetEncoderInfo().implementation_name);
94
95 NiceMock<MockVideoEncoderFactory> nonsimulcast_factory;
96
97 EXPECT_CALL(nonsimulcast_factory, CreateVideoEncoder)
98 .Times(4)
99 .WillOnce([&] {
100 auto mock_encoder = std::make_unique<NiceMock<MockVideoEncoder>>();
101 EXPECT_CALL(*mock_encoder, InitEncode(_, _))
102 .WillOnce(Return(
103 WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED));
104 ON_CALL(*mock_encoder, GetEncoderInfo)
105 .WillByDefault(Return(encoder_info));
106 return mock_encoder;
107 })
108 .WillRepeatedly([&] {
109 auto mock_encoder = std::make_unique<NiceMock<MockVideoEncoder>>();
110 EXPECT_CALL(*mock_encoder, InitEncode(_, _))
111 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
112 ON_CALL(*mock_encoder, GetEncoderInfo)
113 .WillByDefault(Return(encoder_info));
114 return mock_encoder;
115 });
116
117 EncoderSimulcastProxy simulcast_disabled_proxy(&nonsimulcast_factory,
118 SdpVideoFormat("VP8"));
119 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
120 simulcast_disabled_proxy.InitEncode(&codec_settings, kSettings));
121 EXPECT_EQ(kSimulcastAdaptedImplementationName,
122 simulcast_disabled_proxy.GetEncoderInfo().implementation_name);
123
124 // Cleanup.
125 simulcast_enabled_proxy.Release();
126 simulcast_disabled_proxy.Release();
127 }
128
TEST(EncoderSimulcastProxy,ForwardsTrustedSetting)129 TEST(EncoderSimulcastProxy, ForwardsTrustedSetting) {
130 auto mock_encoder_owned = std::make_unique<NiceMock<MockVideoEncoder>>();
131 auto* mock_encoder = mock_encoder_owned.get();
132 NiceMock<MockVideoEncoderFactory> simulcast_factory;
133
134 EXPECT_CALL(*mock_encoder, InitEncode(_, _))
135 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
136
137 EXPECT_CALL(simulcast_factory, CreateVideoEncoder)
138 .Times(1)
139 .WillOnce(Return(ByMove(std::move(mock_encoder_owned))));
140
141 EncoderSimulcastProxy simulcast_enabled_proxy(&simulcast_factory,
142 SdpVideoFormat("VP8"));
143 VideoCodec codec_settings;
144 webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings);
145 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
146 simulcast_enabled_proxy.InitEncode(&codec_settings, kSettings));
147
148 VideoEncoder::EncoderInfo info;
149 info.has_trusted_rate_controller = true;
150 EXPECT_CALL(*mock_encoder, GetEncoderInfo()).WillRepeatedly(Return(info));
151
152 EXPECT_TRUE(
153 simulcast_enabled_proxy.GetEncoderInfo().has_trusted_rate_controller);
154 }
155
TEST(EncoderSimulcastProxy,ForwardsHardwareAccelerated)156 TEST(EncoderSimulcastProxy, ForwardsHardwareAccelerated) {
157 auto mock_encoder_owned = std::make_unique<NiceMock<MockVideoEncoder>>();
158 NiceMock<MockVideoEncoder>* mock_encoder = mock_encoder_owned.get();
159 NiceMock<MockVideoEncoderFactory> simulcast_factory;
160
161 EXPECT_CALL(*mock_encoder, InitEncode(_, _))
162 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
163
164 EXPECT_CALL(simulcast_factory, CreateVideoEncoder)
165 .Times(1)
166 .WillOnce(Return(ByMove(std::move(mock_encoder_owned))));
167
168 EncoderSimulcastProxy simulcast_enabled_proxy(&simulcast_factory,
169 SdpVideoFormat("VP8"));
170 VideoCodec codec_settings;
171 webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings);
172 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
173 simulcast_enabled_proxy.InitEncode(&codec_settings, kSettings));
174
175 VideoEncoder::EncoderInfo info;
176
177 info.is_hardware_accelerated = false;
178 EXPECT_CALL(*mock_encoder, GetEncoderInfo()).WillOnce(Return(info));
179 EXPECT_FALSE(
180 simulcast_enabled_proxy.GetEncoderInfo().is_hardware_accelerated);
181
182 info.is_hardware_accelerated = true;
183 EXPECT_CALL(*mock_encoder, GetEncoderInfo()).WillOnce(Return(info));
184 EXPECT_TRUE(simulcast_enabled_proxy.GetEncoderInfo().is_hardware_accelerated);
185 }
186
TEST(EncoderSimulcastProxy,ForwardsInternalSource)187 TEST(EncoderSimulcastProxy, ForwardsInternalSource) {
188 auto mock_encoder_owned = std::make_unique<NiceMock<MockVideoEncoder>>();
189 NiceMock<MockVideoEncoder>* mock_encoder = mock_encoder_owned.get();
190 NiceMock<MockVideoEncoderFactory> simulcast_factory;
191
192 EXPECT_CALL(*mock_encoder, InitEncode(_, _))
193 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
194
195 EXPECT_CALL(simulcast_factory, CreateVideoEncoder)
196 .Times(1)
197 .WillOnce(Return(ByMove(std::move(mock_encoder_owned))));
198
199 EncoderSimulcastProxy simulcast_enabled_proxy(&simulcast_factory,
200 SdpVideoFormat("VP8"));
201 VideoCodec codec_settings;
202 webrtc::test::CodecSettings(kVideoCodecVP8, &codec_settings);
203 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
204 simulcast_enabled_proxy.InitEncode(&codec_settings, kSettings));
205
206 VideoEncoder::EncoderInfo info;
207
208 info.has_internal_source = false;
209 EXPECT_CALL(*mock_encoder, GetEncoderInfo()).WillOnce(Return(info));
210 EXPECT_FALSE(simulcast_enabled_proxy.GetEncoderInfo().has_internal_source);
211
212 info.has_internal_source = true;
213 EXPECT_CALL(*mock_encoder, GetEncoderInfo()).WillOnce(Return(info));
214 EXPECT_TRUE(simulcast_enabled_proxy.GetEncoderInfo().has_internal_source);
215 }
216
217 } // namespace testing
218 } // namespace webrtc
219