2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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.
11 #include "webrtc/video_engine/vie_base_impl.h"
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"
36 ViEBase* ViEBase::GetInterface(VideoEngine* video_engine) {
40 VideoEngineImpl* vie_impl = static_cast<VideoEngineImpl*>(video_engine);
41 ViEBaseImpl* vie_base_impl = vie_impl;
42 (*vie_base_impl)++; // Increase ref count.
47 int ViEBaseImpl::Release() {
48 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, shared_data_.instance_id(),
49 "ViEBase::Release()");
50 (*this)--; // Decrease ref count.
52 int32_t ref_count = GetCount();
54 WEBRTC_TRACE(kTraceWarning, kTraceVideo, shared_data_.instance_id(),
55 "ViEBase release too many times");
56 shared_data_.SetLastError(kViEAPIDoesNotExist);
59 WEBRTC_TRACE(kTraceInfo, kTraceVideo, shared_data_.instance_id(),
60 "ViEBase reference count: %d", ref_count);
64 ViEBaseImpl::ViEBaseImpl(const Config& config)
65 : shared_data_(config) {
66 WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_.instance_id(),
67 "ViEBaseImpl::ViEBaseImpl() Ctor");
70 ViEBaseImpl::~ViEBaseImpl() {
71 WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_.instance_id(),
72 "ViEBaseImpl::ViEBaseImpl() Dtor");
75 int ViEBaseImpl::Init() {
76 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, shared_data_.instance_id(),
81 int ViEBaseImpl::SetVoiceEngine(VoiceEngine* voice_engine) {
82 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
84 if (shared_data_.channel_manager()->SetVoiceEngine(voice_engine) != 0) {
85 shared_data_.SetLastError(kViEBaseVoEFailure);
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);
96 WEBRTC_TRACE(kTraceError,
98 ViEId(shared_data_.instance_id()),
99 "%s: channel %d doesn't exist",
102 shared_data_.SetLastError(kViEBaseInvalidChannelId);
105 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
108 ViEInputManagerScoped is(*(shared_data_.input_manager()));
109 ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
111 ViECapturer* capturer = is.Capture(provider->Id());
113 capturer->RegisterCpuOveruseObserver(observer);
116 shared_data_.overuse_observers()->insert(
117 std::pair<int, CpuOveruseObserver*>(video_channel, observer));
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);
129 WEBRTC_TRACE(kTraceError,
131 ViEId(shared_data_.instance_id()),
132 "%s: channel %d doesn't exist",
135 shared_data_.SetLastError(kViEBaseInvalidChannelId);
138 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
141 ViEInputManagerScoped is(*(shared_data_.input_manager()));
142 ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
144 ViECapturer* capturer = is.Capture(provider->Id());
146 capturer->CpuOveruseMeasures(capture_jitter_ms,
148 encode_usage_percent,
149 capture_queue_delay_ms_per_s);
156 int ViEBaseImpl::CreateChannel(int& video_channel) { // NOLINT
157 return CreateChannel(video_channel, static_cast<const Config*>(NULL));
160 int ViEBaseImpl::CreateChannel(int& video_channel, // NOLINT
161 const Config* config) {
162 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
164 if (shared_data_.channel_manager()->CreateChannel(&video_channel,
166 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
167 "%s: Could not create channel", __FUNCTION__);
169 shared_data_.SetLastError(kViEBaseChannelCreationFailed);
172 WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(shared_data_.instance_id()),
173 "%s: channel created: %d", __FUNCTION__, video_channel);
177 int ViEBaseImpl::CreateChannel(int& video_channel, // NOLINT
178 int original_channel) {
179 return CreateChannel(video_channel, original_channel, true);
182 int ViEBaseImpl::CreateReceiveChannel(int& video_channel, // NOLINT
183 int original_channel) {
184 return CreateChannel(video_channel, original_channel, false);
187 int ViEBaseImpl::DeleteChannel(const int video_channel) {
188 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
189 "%s(%d)", __FUNCTION__, video_channel);
191 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
192 ViEChannel* vie_channel = cs.Channel(video_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);
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);
207 provider->DeregisterFrameCallback(vie_encoder);
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__,
216 shared_data_.SetLastError(kViEBaseUnknownError);
219 WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(shared_data_.instance_id()),
220 "%s: channel deleted: %d", __FUNCTION__, video_channel);
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);
236 if (shared_data_.channel_manager()->ConnectVoiceChannel(video_channel,
237 audio_channel) != 0) {
238 shared_data_.SetLastError(kViEBaseVoEFailure);
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);
255 if (shared_data_.channel_manager()->DisconnectVoiceChannel(
256 video_channel) != 0) {
257 shared_data_.SetLastError(kViEBaseVoEFailure);
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);
268 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
269 ViEChannel* vie_channel = cs.Channel(video_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);
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);
288 // Pause and trigger a key frame.
289 vie_encoder->Pause();
290 int32_t error = vie_channel->StartSend();
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__,
297 if (error == kViEBaseAlreadySending) {
298 shared_data_.SetLastError(kViEBaseAlreadySending);
300 shared_data_.SetLastError(kViEBaseUnknownError);
303 vie_encoder->SendKeyFrame();
304 vie_encoder->Restart();
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);
313 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
314 ViEChannel* vie_channel = cs.Channel(video_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);
323 int32_t error = vie_channel->StopSend();
325 WEBRTC_TRACE(kTraceError, kTraceVideo,
326 ViEId(shared_data_.instance_id(), video_channel),
327 "%s: Could not stop sending on channel %d", __FUNCTION__,
329 if (error == kViEBaseNotSending) {
330 shared_data_.SetLastError(kViEBaseNotSending);
332 shared_data_.SetLastError(kViEBaseUnknownError);
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);
344 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
345 ViEChannel* vie_channel = cs.Channel(video_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);
353 if (vie_channel->StartReceive() != 0) {
354 shared_data_.SetLastError(kViEBaseUnknownError);
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);
365 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
366 ViEChannel* vie_channel = cs.Channel(video_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);
374 if (vie_channel->StopReceive() != 0) {
375 shared_data_.SetLastError(kViEBaseUnknownError);
381 int ViEBaseImpl::GetVersion(char version[1024]) {
382 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
383 "GetVersion(version=?)");
384 assert(kViEVersionMaxMessageSize == 1024);
386 shared_data_.SetLastError(kViEBaseInvalidArgument);
390 // Add WebRTC Version.
391 std::stringstream version_stream;
392 version_stream << "VideoEngine 3.49.0" << std::endl;
395 version_stream << "Build: " << BUILDINFO << std::endl;
397 #ifdef WEBRTC_EXTERNAL_TRANSPORT
398 version_stream << "External transport build" << std::endl;
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';
405 WEBRTC_TRACE(kTraceStateInfo, kTraceVideo,
406 ViEId(shared_data_.instance_id()), "GetVersion() => %s",
411 int ViEBaseImpl::LastError() {
412 return shared_data_.LastErrorInternal();
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);
426 if (shared_data_.channel_manager()->CreateChannel(&video_channel,
429 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
430 "%s: Could not create channel", __FUNCTION__);
432 shared_data_.SetLastError(kViEBaseChannelCreationFailed);
435 WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(shared_data_.instance_id()),
436 "%s: channel created: %d", __FUNCTION__, video_channel);
440 } // namespace webrtc