1 /*
2 * Copyright (c) 2012 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 #include "webrtc/video_engine/vie_base_impl.h"
12
13 #include <sstream>
14 #include <string>
15 #include <utility>
16
17 #include "webrtc/engine_configurations.h"
18 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
19 #include "webrtc/modules/video_coding/main/interface/video_coding.h"
20 #include "webrtc/modules/video_processing/main/interface/video_processing.h"
21 #include "webrtc/modules/video_render/include/video_render.h"
22 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
23 #include "webrtc/system_wrappers/interface/logging.h"
24 #include "webrtc/video_engine/include/vie_errors.h"
25 #include "webrtc/video_engine/vie_capturer.h"
26 #include "webrtc/video_engine/vie_channel.h"
27 #include "webrtc/video_engine/vie_channel_manager.h"
28 #include "webrtc/video_engine/vie_defines.h"
29 #include "webrtc/video_engine/vie_encoder.h"
30 #include "webrtc/video_engine/vie_impl.h"
31 #include "webrtc/video_engine/vie_input_manager.h"
32 #include "webrtc/video_engine/vie_shared_data.h"
33
34 namespace webrtc {
35
GetInterface(VideoEngine * video_engine)36 ViEBase* ViEBase::GetInterface(VideoEngine* video_engine) {
37 if (!video_engine) {
38 return NULL;
39 }
40 VideoEngineImpl* vie_impl = static_cast<VideoEngineImpl*>(video_engine);
41 ViEBaseImpl* vie_base_impl = vie_impl;
42 (*vie_base_impl)++; // Increase ref count.
43
44 return vie_base_impl;
45 }
46
Release()47 int ViEBaseImpl::Release() {
48 (*this)--; // Decrease ref count.
49
50 int32_t ref_count = GetCount();
51 if (ref_count < 0) {
52 LOG(LS_WARNING) << "ViEBase released too many times.";
53 return -1;
54 }
55 return ref_count;
56 }
57
ViEBaseImpl(const Config & config)58 ViEBaseImpl::ViEBaseImpl(const Config& config)
59 : shared_data_(config) {}
60
~ViEBaseImpl()61 ViEBaseImpl::~ViEBaseImpl() {}
62
Init()63 int ViEBaseImpl::Init() {
64 return 0;
65 }
66
SetVoiceEngine(VoiceEngine * voice_engine)67 int ViEBaseImpl::SetVoiceEngine(VoiceEngine* voice_engine) {
68 LOG_F(LS_INFO) << "SetVoiceEngine";
69 if (shared_data_.channel_manager()->SetVoiceEngine(voice_engine) != 0) {
70 shared_data_.SetLastError(kViEBaseVoEFailure);
71 return -1;
72 }
73 return 0;
74 }
75
RegisterCpuOveruseObserver(int video_channel,CpuOveruseObserver * observer)76 int ViEBaseImpl::RegisterCpuOveruseObserver(int video_channel,
77 CpuOveruseObserver* observer) {
78 LOG_F(LS_INFO) << "RegisterCpuOveruseObserver on channel " << video_channel;
79 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
80 ViEChannel* vie_channel = cs.Channel(video_channel);
81 if (!vie_channel) {
82 shared_data_.SetLastError(kViEBaseInvalidChannelId);
83 return -1;
84 }
85 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
86 assert(vie_encoder);
87
88 ViEInputManagerScoped is(*(shared_data_.input_manager()));
89 ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
90 if (provider) {
91 ViECapturer* capturer = is.Capture(provider->Id());
92 assert(capturer);
93 capturer->RegisterCpuOveruseObserver(observer);
94 }
95
96 shared_data_.overuse_observers()->insert(
97 std::pair<int, CpuOveruseObserver*>(video_channel, observer));
98 return 0;
99 }
100
SetCpuOveruseOptions(int video_channel,const CpuOveruseOptions & options)101 int ViEBaseImpl::SetCpuOveruseOptions(int video_channel,
102 const CpuOveruseOptions& options) {
103 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
104 ViEChannel* vie_channel = cs.Channel(video_channel);
105 if (!vie_channel) {
106 shared_data_.SetLastError(kViEBaseInvalidChannelId);
107 return -1;
108 }
109 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
110 assert(vie_encoder);
111
112 ViEInputManagerScoped is(*(shared_data_.input_manager()));
113 ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
114 if (provider) {
115 ViECapturer* capturer = is.Capture(provider->Id());
116 if (capturer) {
117 capturer->SetCpuOveruseOptions(options);
118 return 0;
119 }
120 }
121 return -1;
122 }
123
CpuOveruseMeasures(int video_channel,int * capture_jitter_ms,int * avg_encode_time_ms,int * encode_usage_percent,int * capture_queue_delay_ms_per_s)124 int ViEBaseImpl::CpuOveruseMeasures(int video_channel,
125 int* capture_jitter_ms,
126 int* avg_encode_time_ms,
127 int* encode_usage_percent,
128 int* capture_queue_delay_ms_per_s) {
129 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
130 ViEChannel* vie_channel = cs.Channel(video_channel);
131 if (!vie_channel) {
132 shared_data_.SetLastError(kViEBaseInvalidChannelId);
133 return -1;
134 }
135 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
136 assert(vie_encoder);
137
138 ViEInputManagerScoped is(*(shared_data_.input_manager()));
139 ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
140 if (provider) {
141 ViECapturer* capturer = is.Capture(provider->Id());
142 if (capturer) {
143 CpuOveruseMetrics metrics;
144 capturer->GetCpuOveruseMetrics(&metrics);
145 *capture_jitter_ms = metrics.capture_jitter_ms;
146 *avg_encode_time_ms = metrics.avg_encode_time_ms;
147 *encode_usage_percent = metrics.encode_usage_percent;
148 *capture_queue_delay_ms_per_s = metrics.capture_queue_delay_ms_per_s;
149 return 0;
150 }
151 }
152 return -1;
153 }
154
GetCpuOveruseMetrics(int video_channel,CpuOveruseMetrics * metrics)155 int ViEBaseImpl::GetCpuOveruseMetrics(int video_channel,
156 CpuOveruseMetrics* metrics) {
157 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
158 ViEChannel* vie_channel = cs.Channel(video_channel);
159 if (!vie_channel) {
160 shared_data_.SetLastError(kViEBaseInvalidChannelId);
161 return -1;
162 }
163 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
164 assert(vie_encoder);
165
166 ViEInputManagerScoped is(*(shared_data_.input_manager()));
167 ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
168 if (provider) {
169 ViECapturer* capturer = is.Capture(provider->Id());
170 if (capturer) {
171 capturer->GetCpuOveruseMetrics(metrics);
172 return 0;
173 }
174 }
175 return -1;
176 }
177
CreateChannel(int & video_channel)178 int ViEBaseImpl::CreateChannel(int& video_channel) { // NOLINT
179 return CreateChannel(video_channel, static_cast<const Config*>(NULL));
180 }
181
CreateChannel(int & video_channel,const Config * config)182 int ViEBaseImpl::CreateChannel(int& video_channel, // NOLINT
183 const Config* config) {
184 if (shared_data_.channel_manager()->CreateChannel(&video_channel,
185 config) == -1) {
186 video_channel = -1;
187 shared_data_.SetLastError(kViEBaseChannelCreationFailed);
188 return -1;
189 }
190 LOG(LS_INFO) << "Video channel created: " << video_channel;
191 return 0;
192 }
193
CreateChannel(int & video_channel,int original_channel)194 int ViEBaseImpl::CreateChannel(int& video_channel, // NOLINT
195 int original_channel) {
196 return CreateChannel(video_channel, original_channel, true);
197 }
198
CreateReceiveChannel(int & video_channel,int original_channel)199 int ViEBaseImpl::CreateReceiveChannel(int& video_channel, // NOLINT
200 int original_channel) {
201 return CreateChannel(video_channel, original_channel, false);
202 }
203
DeleteChannel(const int video_channel)204 int ViEBaseImpl::DeleteChannel(const int video_channel) {
205 {
206 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
207 ViEChannel* vie_channel = cs.Channel(video_channel);
208 if (!vie_channel) {
209 shared_data_.SetLastError(kViEBaseInvalidChannelId);
210 return -1;
211 }
212
213 // Deregister the ViEEncoder if no other channel is using it.
214 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
215 if (cs.ChannelUsingViEEncoder(video_channel) == false) {
216 ViEInputManagerScoped is(*(shared_data_.input_manager()));
217 ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
218 if (provider) {
219 provider->DeregisterFrameCallback(vie_encoder);
220 }
221 }
222 }
223
224 if (shared_data_.channel_manager()->DeleteChannel(video_channel) == -1) {
225 shared_data_.SetLastError(kViEBaseUnknownError);
226 return -1;
227 }
228 LOG(LS_INFO) << "Channel deleted " << video_channel;
229 return 0;
230 }
231
ConnectAudioChannel(const int video_channel,const int audio_channel)232 int ViEBaseImpl::ConnectAudioChannel(const int video_channel,
233 const int audio_channel) {
234 LOG_F(LS_INFO) << "ConnectAudioChannel, video channel " << video_channel
235 << ", audio channel " << audio_channel;
236 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
237 if (!cs.Channel(video_channel)) {
238 shared_data_.SetLastError(kViEBaseInvalidChannelId);
239 return -1;
240 }
241
242 if (shared_data_.channel_manager()->ConnectVoiceChannel(video_channel,
243 audio_channel) != 0) {
244 shared_data_.SetLastError(kViEBaseVoEFailure);
245 return -1;
246 }
247 return 0;
248 }
249
DisconnectAudioChannel(const int video_channel)250 int ViEBaseImpl::DisconnectAudioChannel(const int video_channel) {
251 LOG_F(LS_INFO) << "DisconnectAudioChannel " << video_channel;
252 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
253 if (!cs.Channel(video_channel)) {
254 shared_data_.SetLastError(kViEBaseInvalidChannelId);
255 return -1;
256 }
257
258 if (shared_data_.channel_manager()->DisconnectVoiceChannel(
259 video_channel) != 0) {
260 shared_data_.SetLastError(kViEBaseVoEFailure);
261 return -1;
262 }
263 return 0;
264 }
265
StartSend(const int video_channel)266 int ViEBaseImpl::StartSend(const int video_channel) {
267 LOG_F(LS_INFO) << "StartSend: " << video_channel;
268 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
269 ViEChannel* vie_channel = cs.Channel(video_channel);
270 if (!vie_channel) {
271 shared_data_.SetLastError(kViEBaseInvalidChannelId);
272 return -1;
273 }
274
275 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
276 assert(vie_encoder != NULL);
277 if (vie_encoder->Owner() != video_channel) {
278 LOG_F(LS_ERROR) << "Can't start send on a receive only channel.";
279 shared_data_.SetLastError(kViEBaseReceiveOnlyChannel);
280 return -1;
281 }
282
283 // Pause and trigger a key frame.
284 vie_encoder->Pause();
285 int32_t error = vie_channel->StartSend();
286 if (error != 0) {
287 vie_encoder->Restart();
288 if (error == kViEBaseAlreadySending) {
289 shared_data_.SetLastError(kViEBaseAlreadySending);
290 }
291 LOG_F(LS_ERROR) << "Could not start sending " << video_channel;
292 shared_data_.SetLastError(kViEBaseUnknownError);
293 return -1;
294 }
295 vie_encoder->SendKeyFrame();
296 vie_encoder->Restart();
297 return 0;
298 }
299
StopSend(const int video_channel)300 int ViEBaseImpl::StopSend(const int video_channel) {
301 LOG_F(LS_INFO) << "StopSend " << video_channel;
302
303 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
304 ViEChannel* vie_channel = cs.Channel(video_channel);
305 if (!vie_channel) {
306 shared_data_.SetLastError(kViEBaseInvalidChannelId);
307 return -1;
308 }
309
310 int32_t error = vie_channel->StopSend();
311 if (error != 0) {
312 if (error == kViEBaseNotSending) {
313 shared_data_.SetLastError(kViEBaseNotSending);
314 } else {
315 LOG_F(LS_ERROR) << "Could not stop sending " << video_channel;
316 shared_data_.SetLastError(kViEBaseUnknownError);
317 }
318 return -1;
319 }
320 return 0;
321 }
322
StartReceive(const int video_channel)323 int ViEBaseImpl::StartReceive(const int video_channel) {
324 LOG_F(LS_INFO) << "StartReceive " << video_channel;
325
326 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
327 ViEChannel* vie_channel = cs.Channel(video_channel);
328 if (!vie_channel) {
329 shared_data_.SetLastError(kViEBaseInvalidChannelId);
330 return -1;
331 }
332 if (vie_channel->StartReceive() != 0) {
333 shared_data_.SetLastError(kViEBaseUnknownError);
334 return -1;
335 }
336 return 0;
337 }
338
StopReceive(const int video_channel)339 int ViEBaseImpl::StopReceive(const int video_channel) {
340 LOG_F(LS_INFO) << "StopReceive " << video_channel;
341 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
342 ViEChannel* vie_channel = cs.Channel(video_channel);
343 if (!vie_channel) {
344 shared_data_.SetLastError(kViEBaseInvalidChannelId);
345 return -1;
346 }
347 if (vie_channel->StopReceive() != 0) {
348 shared_data_.SetLastError(kViEBaseUnknownError);
349 return -1;
350 }
351 return 0;
352 }
353
GetVersion(char version[1024])354 int ViEBaseImpl::GetVersion(char version[1024]) {
355 assert(kViEVersionMaxMessageSize == 1024);
356 if (!version) {
357 shared_data_.SetLastError(kViEBaseInvalidArgument);
358 return -1;
359 }
360
361 // Add WebRTC Version.
362 std::stringstream version_stream;
363 version_stream << "VideoEngine 3.54.0" << std::endl;
364
365 // Add build info.
366 version_stream << "Build: " << BUILDINFO << std::endl;
367
368 int version_length = version_stream.tellp();
369 assert(version_length < 1024);
370 memcpy(version, version_stream.str().c_str(), version_length);
371 version[version_length] = '\0';
372 return 0;
373 }
374
LastError()375 int ViEBaseImpl::LastError() {
376 return shared_data_.LastErrorInternal();
377 }
378
CreateChannel(int & video_channel,int original_channel,bool sender)379 int ViEBaseImpl::CreateChannel(int& video_channel, // NOLINT
380 int original_channel, bool sender) {
381 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
382 if (!cs.Channel(original_channel)) {
383 shared_data_.SetLastError(kViEBaseInvalidChannelId);
384 return -1;
385 }
386
387 if (shared_data_.channel_manager()->CreateChannel(&video_channel,
388 original_channel,
389 sender) == -1) {
390 video_channel = -1;
391 shared_data_.SetLastError(kViEBaseChannelCreationFailed);
392 return -1;
393 }
394 LOG_F(LS_INFO) << "VideoChannel created: " << video_channel
395 << ", base channel " << original_channel
396 << ", is send channel : " << sender;
397 return 0;
398 }
399
400 } // namespace webrtc
401