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