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