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