Upstream version 5.34.104.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/trace.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   WEBRTC_TRACE(kTraceApiCall, kTraceVideo, shared_data_.instance_id(),
49                "ViEBase::Release()");
50   (*this)--;  // Decrease ref count.
51
52   int32_t ref_count = GetCount();
53   if (ref_count < 0) {
54     WEBRTC_TRACE(kTraceWarning, kTraceVideo, shared_data_.instance_id(),
55                  "ViEBase release too many times");
56     shared_data_.SetLastError(kViEAPIDoesNotExist);
57     return -1;
58   }
59   WEBRTC_TRACE(kTraceInfo, kTraceVideo, shared_data_.instance_id(),
60                "ViEBase reference count: %d", ref_count);
61   return ref_count;
62 }
63
64 ViEBaseImpl::ViEBaseImpl(const Config& config)
65     : shared_data_(config) {
66   WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_.instance_id(),
67                "ViEBaseImpl::ViEBaseImpl() Ctor");
68 }
69
70 ViEBaseImpl::~ViEBaseImpl() {
71   WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_.instance_id(),
72                "ViEBaseImpl::ViEBaseImpl() Dtor");
73 }
74
75 int ViEBaseImpl::Init() {
76   WEBRTC_TRACE(kTraceApiCall, kTraceVideo, shared_data_.instance_id(),
77                "Init");
78   return 0;
79 }
80
81 int ViEBaseImpl::SetVoiceEngine(VoiceEngine* voice_engine) {
82   WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
83                "%s", __FUNCTION__);
84   if (shared_data_.channel_manager()->SetVoiceEngine(voice_engine) != 0) {
85     shared_data_.SetLastError(kViEBaseVoEFailure);
86     return -1;
87   }
88   return 0;
89 }
90
91 int ViEBaseImpl::RegisterCpuOveruseObserver(int video_channel,
92                                             CpuOveruseObserver* observer) {
93   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
94   ViEChannel* vie_channel = cs.Channel(video_channel);
95   if (!vie_channel) {
96     WEBRTC_TRACE(kTraceError,
97                  kTraceVideo,
98                  ViEId(shared_data_.instance_id()),
99                  "%s: channel %d doesn't exist",
100                  __FUNCTION__,
101                  video_channel);
102     shared_data_.SetLastError(kViEBaseInvalidChannelId);
103     return -1;
104   }
105   ViEEncoder* vie_encoder = cs.Encoder(video_channel);
106   assert(vie_encoder);
107
108   ViEInputManagerScoped is(*(shared_data_.input_manager()));
109   ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
110   if (provider) {
111     ViECapturer* capturer = is.Capture(provider->Id());
112     assert(capturer);
113     capturer->RegisterCpuOveruseObserver(observer);
114   }
115
116   shared_data_.overuse_observers()->insert(
117       std::pair<int, CpuOveruseObserver*>(video_channel, observer));
118   return 0;
119 }
120
121 int ViEBaseImpl::CpuOveruseMeasures(int video_channel,
122                                     int* capture_jitter_ms,
123                                     int* avg_encode_time_ms,
124                                     int* encode_usage_percent,
125                                     int* capture_queue_delay_ms_per_s) {
126   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
127   ViEChannel* vie_channel = cs.Channel(video_channel);
128   if (!vie_channel) {
129     WEBRTC_TRACE(kTraceError,
130                  kTraceVideo,
131                  ViEId(shared_data_.instance_id()),
132                  "%s: channel %d doesn't exist",
133                  __FUNCTION__,
134                  video_channel);
135     shared_data_.SetLastError(kViEBaseInvalidChannelId);
136     return -1;
137   }
138   ViEEncoder* vie_encoder = cs.Encoder(video_channel);
139   assert(vie_encoder);
140
141   ViEInputManagerScoped is(*(shared_data_.input_manager()));
142   ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
143   if (provider) {
144     ViECapturer* capturer = is.Capture(provider->Id());
145     if (capturer) {
146       capturer->CpuOveruseMeasures(capture_jitter_ms,
147                                    avg_encode_time_ms,
148                                    encode_usage_percent,
149                                    capture_queue_delay_ms_per_s);
150       return 0;
151     }
152   }
153   return -1;
154 }
155
156 int ViEBaseImpl::CreateChannel(int& video_channel) {  // NOLINT
157   return CreateChannel(video_channel, static_cast<const Config*>(NULL));
158 }
159
160 int ViEBaseImpl::CreateChannel(int& video_channel,  // NOLINT
161                                const Config* config) {
162   WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
163                "%s", __FUNCTION__);
164   if (shared_data_.channel_manager()->CreateChannel(&video_channel,
165                                                     config) == -1) {
166     WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
167                  "%s: Could not create channel", __FUNCTION__);
168     video_channel = -1;
169     shared_data_.SetLastError(kViEBaseChannelCreationFailed);
170     return -1;
171   }
172   WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(shared_data_.instance_id()),
173                "%s: channel created: %d", __FUNCTION__, video_channel);
174   return 0;
175 }
176
177 int ViEBaseImpl::CreateChannel(int& video_channel,  // NOLINT
178                                int original_channel) {
179   return CreateChannel(video_channel, original_channel, true);
180 }
181
182 int ViEBaseImpl::CreateReceiveChannel(int& video_channel,  // NOLINT
183                                       int original_channel) {
184   return CreateChannel(video_channel, original_channel, false);
185 }
186
187 int ViEBaseImpl::DeleteChannel(const int video_channel) {
188   WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
189                "%s(%d)", __FUNCTION__, video_channel);
190   {
191     ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
192     ViEChannel* vie_channel = cs.Channel(video_channel);
193     if (!vie_channel) {
194       WEBRTC_TRACE(kTraceError, kTraceVideo,
195                    ViEId(shared_data_.instance_id()),
196                    "%s: channel %d doesn't exist", __FUNCTION__, video_channel);
197       shared_data_.SetLastError(kViEBaseInvalidChannelId);
198       return -1;
199     }
200
201     // Deregister the ViEEncoder if no other channel is using it.
202     ViEEncoder* vie_encoder = cs.Encoder(video_channel);
203     if (cs.ChannelUsingViEEncoder(video_channel) == false) {
204       ViEInputManagerScoped is(*(shared_data_.input_manager()));
205       ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
206       if (provider) {
207         provider->DeregisterFrameCallback(vie_encoder);
208       }
209     }
210   }
211
212   if (shared_data_.channel_manager()->DeleteChannel(video_channel) == -1) {
213     WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
214                  "%s: Could not delete channel %d", __FUNCTION__,
215                  video_channel);
216     shared_data_.SetLastError(kViEBaseUnknownError);
217     return -1;
218   }
219   WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(shared_data_.instance_id()),
220                "%s: channel deleted: %d", __FUNCTION__, video_channel);
221   return 0;
222 }
223
224 int ViEBaseImpl::ConnectAudioChannel(const int video_channel,
225                                      const int audio_channel) {
226   WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
227                "%s(%d)", __FUNCTION__, video_channel);
228   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
229   if (!cs.Channel(video_channel)) {
230     WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
231                  "%s: channel %d doesn't exist", __FUNCTION__, video_channel);
232     shared_data_.SetLastError(kViEBaseInvalidChannelId);
233     return -1;
234   }
235
236   if (shared_data_.channel_manager()->ConnectVoiceChannel(video_channel,
237                                                           audio_channel) != 0) {
238     shared_data_.SetLastError(kViEBaseVoEFailure);
239     return -1;
240   }
241   return 0;
242 }
243
244 int ViEBaseImpl::DisconnectAudioChannel(const int video_channel) {
245   WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
246                "%s(%d)", __FUNCTION__, video_channel);
247   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
248   if (!cs.Channel(video_channel)) {
249     WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
250                  "%s: channel %d doesn't exist", __FUNCTION__, video_channel);
251     shared_data_.SetLastError(kViEBaseInvalidChannelId);
252     return -1;
253   }
254
255   if (shared_data_.channel_manager()->DisconnectVoiceChannel(
256       video_channel) != 0) {
257     shared_data_.SetLastError(kViEBaseVoEFailure);
258     return -1;
259   }
260   return 0;
261 }
262
263 int ViEBaseImpl::StartSend(const int video_channel) {
264   WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
265                ViEId(shared_data_.instance_id(), video_channel),
266                "%s(channel: %d)", __FUNCTION__, video_channel);
267
268   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
269   ViEChannel* vie_channel = cs.Channel(video_channel);
270   if (!vie_channel) {
271     WEBRTC_TRACE(kTraceError, kTraceVideo,
272                  ViEId(shared_data_.instance_id(), video_channel),
273                  "%s: Channel %d does not exist", __FUNCTION__, video_channel);
274     shared_data_.SetLastError(kViEBaseInvalidChannelId);
275     return -1;
276   }
277
278   ViEEncoder* vie_encoder = cs.Encoder(video_channel);
279   assert(vie_encoder != NULL);
280   if (vie_encoder->Owner() != video_channel) {
281     WEBRTC_TRACE(kTraceError, kTraceVideo,
282                  ViEId(shared_data_.instance_id(), video_channel),
283                  "Can't start ssend on a receive only channel.");
284     shared_data_.SetLastError(kViEBaseReceiveOnlyChannel);
285     return -1;
286   }
287
288   // Pause and trigger a key frame.
289   vie_encoder->Pause();
290   int32_t error = vie_channel->StartSend();
291   if (error != 0) {
292     vie_encoder->Restart();
293     WEBRTC_TRACE(kTraceError, kTraceVideo,
294                  ViEId(shared_data_.instance_id(), video_channel),
295                  "%s: Could not start sending on channel %d", __FUNCTION__,
296                  video_channel);
297     if (error == kViEBaseAlreadySending) {
298       shared_data_.SetLastError(kViEBaseAlreadySending);
299     }
300     shared_data_.SetLastError(kViEBaseUnknownError);
301     return -1;
302   }
303   vie_encoder->SendKeyFrame();
304   vie_encoder->Restart();
305   return 0;
306 }
307
308 int ViEBaseImpl::StopSend(const int video_channel) {
309   WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
310                ViEId(shared_data_.instance_id(), video_channel),
311                "%s(channel: %d)", __FUNCTION__, video_channel);
312
313   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
314   ViEChannel* vie_channel = cs.Channel(video_channel);
315   if (!vie_channel) {
316     WEBRTC_TRACE(kTraceError, kTraceVideo,
317                  ViEId(shared_data_.instance_id(), video_channel),
318                  "%s: Channel %d does not exist", __FUNCTION__, video_channel);
319     shared_data_.SetLastError(kViEBaseInvalidChannelId);
320     return -1;
321   }
322
323   int32_t error = vie_channel->StopSend();
324   if (error != 0) {
325     WEBRTC_TRACE(kTraceError, kTraceVideo,
326                  ViEId(shared_data_.instance_id(), video_channel),
327                  "%s: Could not stop sending on channel %d", __FUNCTION__,
328                  video_channel);
329     if (error == kViEBaseNotSending) {
330       shared_data_.SetLastError(kViEBaseNotSending);
331     } else {
332       shared_data_.SetLastError(kViEBaseUnknownError);
333     }
334     return -1;
335   }
336   return 0;
337 }
338
339 int ViEBaseImpl::StartReceive(const int video_channel) {
340   WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
341                ViEId(shared_data_.instance_id(), video_channel),
342                "%s(channel: %d)", __FUNCTION__, video_channel);
343
344   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
345   ViEChannel* vie_channel = cs.Channel(video_channel);
346   if (!vie_channel) {
347     WEBRTC_TRACE(kTraceError, kTraceVideo,
348                  ViEId(shared_data_.instance_id(), video_channel),
349                  "%s: Channel %d does not exist", __FUNCTION__, video_channel);
350     shared_data_.SetLastError(kViEBaseInvalidChannelId);
351     return -1;
352   }
353   if (vie_channel->StartReceive() != 0) {
354     shared_data_.SetLastError(kViEBaseUnknownError);
355     return -1;
356   }
357   return 0;
358 }
359
360 int ViEBaseImpl::StopReceive(const int video_channel) {
361   WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
362                ViEId(shared_data_.instance_id(), video_channel),
363                "%s(channel: %d)", __FUNCTION__, video_channel);
364
365   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
366   ViEChannel* vie_channel = cs.Channel(video_channel);
367   if (!vie_channel) {
368     WEBRTC_TRACE(kTraceError, kTraceVideo,
369                  ViEId(shared_data_.instance_id(), video_channel),
370                  "%s: Channel %d does not exist", __FUNCTION__, video_channel);
371     shared_data_.SetLastError(kViEBaseInvalidChannelId);
372     return -1;
373   }
374   if (vie_channel->StopReceive() != 0) {
375     shared_data_.SetLastError(kViEBaseUnknownError);
376     return -1;
377   }
378   return 0;
379 }
380
381 int ViEBaseImpl::GetVersion(char version[1024]) {
382   WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
383                "GetVersion(version=?)");
384   assert(kViEVersionMaxMessageSize == 1024);
385   if (!version) {
386     shared_data_.SetLastError(kViEBaseInvalidArgument);
387     return -1;
388   }
389
390   // Add WebRTC Version.
391   std::stringstream version_stream;
392   version_stream << "VideoEngine 3.49.0" << std::endl;
393
394   // Add build info.
395   version_stream << "Build: " << BUILDINFO << std::endl;
396
397 #ifdef WEBRTC_EXTERNAL_TRANSPORT
398   version_stream << "External transport build" << std::endl;
399 #endif
400   int version_length = version_stream.tellp();
401   assert(version_length < 1024);
402   memcpy(version, version_stream.str().c_str(), version_length);
403   version[version_length] = '\0';
404
405   WEBRTC_TRACE(kTraceStateInfo, kTraceVideo,
406                ViEId(shared_data_.instance_id()), "GetVersion() => %s",
407                version);
408   return 0;
409 }
410
411 int ViEBaseImpl::LastError() {
412   return shared_data_.LastErrorInternal();
413 }
414
415 int ViEBaseImpl::CreateChannel(int& video_channel,  // NOLINT
416                                int original_channel, bool sender) {
417   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
418   if (!cs.Channel(original_channel)) {
419     WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
420                  "%s - original_channel does not exist.", __FUNCTION__,
421                  shared_data_.instance_id());
422     shared_data_.SetLastError(kViEBaseInvalidChannelId);
423     return -1;
424   }
425
426   if (shared_data_.channel_manager()->CreateChannel(&video_channel,
427                                                     original_channel,
428                                                     sender) == -1) {
429     WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
430                  "%s: Could not create channel", __FUNCTION__);
431     video_channel = -1;
432     shared_data_.SetLastError(kViEBaseChannelCreationFailed);
433     return -1;
434   }
435   WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(shared_data_.instance_id()),
436                "%s: channel created: %d", __FUNCTION__, video_channel);
437   return 0;
438 }
439
440 }  // namespace webrtc