• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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