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] = {.width = test::kTestWidth,
46 .height = test::kTestHeight,
47 .maxFramerate = test::kTestFrameRate,
48 .numberOfTemporalLayers = 2,
49 .maxBitrate = 2000,
50 .targetBitrate = 1000,
51 .minBitrate = 1000,
52 .qpMax = 56,
53 .active = true};
54 codec_settings.simulcastStream[1] = {.width = test::kTestWidth,
55 .height = test::kTestHeight,
56 .maxFramerate = test::kTestFrameRate,
57 .numberOfTemporalLayers = 2,
58 .maxBitrate = 3000,
59 .targetBitrate = 1000,
60 .minBitrate = 1000,
61 .qpMax = 56,
62 .active = true};
63 codec_settings.simulcastStream[2] = {.width = test::kTestWidth,
64 .height = test::kTestHeight,
65 .maxFramerate = test::kTestFrameRate,
66 .numberOfTemporalLayers = 2,
67 .maxBitrate = 5000,
68 .targetBitrate = 1000,
69 .minBitrate = 1000,
70 .qpMax = 56,
71 .active = 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
187 } // namespace testing
188 } // namespace webrtc
189