• 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 
GetCpuOveruseMetrics(int video_channel,CpuOveruseMetrics * metrics)124 int ViEBaseImpl::GetCpuOveruseMetrics(int video_channel,
125                                       CpuOveruseMetrics* metrics) {
126   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
127   ViEChannel* vie_channel = cs.Channel(video_channel);
128   if (!vie_channel) {
129     shared_data_.SetLastError(kViEBaseInvalidChannelId);
130     return -1;
131   }
132   ViEEncoder* vie_encoder = cs.Encoder(video_channel);
133   assert(vie_encoder);
134 
135   ViEInputManagerScoped is(*(shared_data_.input_manager()));
136   ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
137   if (provider) {
138     ViECapturer* capturer = is.Capture(provider->Id());
139     if (capturer) {
140       capturer->GetCpuOveruseMetrics(metrics);
141       return 0;
142     }
143   }
144   return -1;
145 }
146 
RegisterSendSideDelayObserver(int channel,SendSideDelayObserver * observer)147 void ViEBaseImpl::RegisterSendSideDelayObserver(
148     int channel, SendSideDelayObserver* observer) {
149   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
150   ViEChannel* vie_channel = cs.Channel(channel);
151   assert(vie_channel);
152   vie_channel->RegisterSendSideDelayObserver(observer);
153 }
154 
CreateChannel(int & video_channel)155 int ViEBaseImpl::CreateChannel(int& video_channel) {  // NOLINT
156   return CreateChannel(video_channel, static_cast<const Config*>(NULL));
157 }
158 
CreateChannel(int & video_channel,const Config * config)159 int ViEBaseImpl::CreateChannel(int& video_channel,  // NOLINT
160                                const Config* config) {
161   if (shared_data_.channel_manager()->CreateChannel(&video_channel,
162                                                     config) == -1) {
163     video_channel = -1;
164     shared_data_.SetLastError(kViEBaseChannelCreationFailed);
165     return -1;
166   }
167   LOG(LS_INFO) << "Video channel created: " << video_channel;
168   return 0;
169 }
170 
CreateChannel(int & video_channel,int original_channel)171 int ViEBaseImpl::CreateChannel(int& video_channel,  // NOLINT
172                                int original_channel) {
173   return CreateChannel(video_channel, original_channel, true);
174 }
175 
CreateReceiveChannel(int & video_channel,int original_channel)176 int ViEBaseImpl::CreateReceiveChannel(int& video_channel,  // NOLINT
177                                       int original_channel) {
178   return CreateChannel(video_channel, original_channel, false);
179 }
180 
DeleteChannel(const int video_channel)181 int ViEBaseImpl::DeleteChannel(const int video_channel) {
182   {
183     ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
184     ViEChannel* vie_channel = cs.Channel(video_channel);
185     if (!vie_channel) {
186       shared_data_.SetLastError(kViEBaseInvalidChannelId);
187       return -1;
188     }
189 
190     // Deregister the ViEEncoder if no other channel is using it.
191     ViEEncoder* vie_encoder = cs.Encoder(video_channel);
192     if (cs.ChannelUsingViEEncoder(video_channel) == false) {
193       ViEInputManagerScoped is(*(shared_data_.input_manager()));
194       ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
195       if (provider) {
196         provider->DeregisterFrameCallback(vie_encoder);
197       }
198     }
199   }
200 
201   if (shared_data_.channel_manager()->DeleteChannel(video_channel) == -1) {
202     shared_data_.SetLastError(kViEBaseUnknownError);
203     return -1;
204   }
205   LOG(LS_INFO) << "Channel deleted " << video_channel;
206   return 0;
207 }
208 
ConnectAudioChannel(const int video_channel,const int audio_channel)209 int ViEBaseImpl::ConnectAudioChannel(const int video_channel,
210                                      const int audio_channel) {
211   LOG_F(LS_INFO) << "ConnectAudioChannel, video channel " << video_channel
212                  << ", audio channel " << audio_channel;
213   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
214   if (!cs.Channel(video_channel)) {
215     shared_data_.SetLastError(kViEBaseInvalidChannelId);
216     return -1;
217   }
218 
219   if (shared_data_.channel_manager()->ConnectVoiceChannel(video_channel,
220                                                           audio_channel) != 0) {
221     shared_data_.SetLastError(kViEBaseVoEFailure);
222     return -1;
223   }
224   return 0;
225 }
226 
DisconnectAudioChannel(const int video_channel)227 int ViEBaseImpl::DisconnectAudioChannel(const int video_channel) {
228   LOG_F(LS_INFO) << "DisconnectAudioChannel " << video_channel;
229   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
230   if (!cs.Channel(video_channel)) {
231     shared_data_.SetLastError(kViEBaseInvalidChannelId);
232     return -1;
233   }
234 
235   if (shared_data_.channel_manager()->DisconnectVoiceChannel(
236       video_channel) != 0) {
237     shared_data_.SetLastError(kViEBaseVoEFailure);
238     return -1;
239   }
240   return 0;
241 }
242 
StartSend(const int video_channel)243 int ViEBaseImpl::StartSend(const int video_channel) {
244   LOG_F(LS_INFO) << "StartSend: " << video_channel;
245   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
246   ViEChannel* vie_channel = cs.Channel(video_channel);
247   if (!vie_channel) {
248     shared_data_.SetLastError(kViEBaseInvalidChannelId);
249     return -1;
250   }
251 
252   ViEEncoder* vie_encoder = cs.Encoder(video_channel);
253   assert(vie_encoder != NULL);
254   if (vie_encoder->Owner() != video_channel) {
255     LOG_F(LS_ERROR) <<  "Can't start send on a receive only channel.";
256     shared_data_.SetLastError(kViEBaseReceiveOnlyChannel);
257     return -1;
258   }
259 
260   // Pause and trigger a key frame.
261   vie_encoder->Pause();
262   int32_t error = vie_channel->StartSend();
263   if (error != 0) {
264     vie_encoder->Restart();
265     if (error == kViEBaseAlreadySending) {
266       shared_data_.SetLastError(kViEBaseAlreadySending);
267     }
268     LOG_F(LS_ERROR) << "Could not start sending " << video_channel;
269     shared_data_.SetLastError(kViEBaseUnknownError);
270     return -1;
271   }
272   vie_encoder->SendKeyFrame();
273   vie_encoder->Restart();
274   return 0;
275 }
276 
StopSend(const int video_channel)277 int ViEBaseImpl::StopSend(const int video_channel) {
278   LOG_F(LS_INFO) << "StopSend " << video_channel;
279 
280   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
281   ViEChannel* vie_channel = cs.Channel(video_channel);
282   if (!vie_channel) {
283     shared_data_.SetLastError(kViEBaseInvalidChannelId);
284     return -1;
285   }
286 
287   int32_t error = vie_channel->StopSend();
288   if (error != 0) {
289     if (error == kViEBaseNotSending) {
290       shared_data_.SetLastError(kViEBaseNotSending);
291     } else {
292       LOG_F(LS_ERROR) << "Could not stop sending " << video_channel;
293       shared_data_.SetLastError(kViEBaseUnknownError);
294     }
295     return -1;
296   }
297   return 0;
298 }
299 
StartReceive(const int video_channel)300 int ViEBaseImpl::StartReceive(const int video_channel) {
301   LOG_F(LS_INFO) << "StartReceive " << 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   if (vie_channel->StartReceive() != 0) {
310     shared_data_.SetLastError(kViEBaseUnknownError);
311     return -1;
312   }
313   return 0;
314 }
315 
StopReceive(const int video_channel)316 int ViEBaseImpl::StopReceive(const int video_channel) {
317   LOG_F(LS_INFO) << "StopReceive " << video_channel;
318   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
319   ViEChannel* vie_channel = cs.Channel(video_channel);
320   if (!vie_channel) {
321     shared_data_.SetLastError(kViEBaseInvalidChannelId);
322     return -1;
323   }
324   if (vie_channel->StopReceive() != 0) {
325     shared_data_.SetLastError(kViEBaseUnknownError);
326     return -1;
327   }
328   return 0;
329 }
330 
GetVersion(char version[1024])331 int ViEBaseImpl::GetVersion(char version[1024]) {
332   assert(kViEVersionMaxMessageSize == 1024);
333   if (!version) {
334     shared_data_.SetLastError(kViEBaseInvalidArgument);
335     return -1;
336   }
337 
338   // Add WebRTC Version.
339   std::stringstream version_stream;
340   version_stream << "VideoEngine 38" << std::endl;
341 
342   // Add build info.
343   version_stream << "Build: " << BUILDINFO << std::endl;
344 
345   int version_length = version_stream.tellp();
346   assert(version_length < 1024);
347   memcpy(version, version_stream.str().c_str(), version_length);
348   version[version_length] = '\0';
349   return 0;
350 }
351 
LastError()352 int ViEBaseImpl::LastError() {
353   return shared_data_.LastErrorInternal();
354 }
355 
CreateChannel(int & video_channel,int original_channel,bool sender)356 int ViEBaseImpl::CreateChannel(int& video_channel,  // NOLINT
357                                int original_channel, bool sender) {
358   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
359   if (!cs.Channel(original_channel)) {
360     shared_data_.SetLastError(kViEBaseInvalidChannelId);
361     return -1;
362   }
363 
364   if (shared_data_.channel_manager()->CreateChannel(&video_channel,
365                                                     original_channel,
366                                                     sender) == -1) {
367     video_channel = -1;
368     shared_data_.SetLastError(kViEBaseChannelCreationFailed);
369     return -1;
370   }
371   LOG_F(LS_INFO) << "VideoChannel created: " << video_channel
372                  << ", base channel " << original_channel
373                  << ", is send channel : " << sender;
374   return 0;
375 }
376 
377 }  // namespace webrtc
378