blob: 744e9a1beab0667b582ef6785164a5eb71925c1a [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
mflodman@webrtc.org1a739ba2012-02-28 16:11:33 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +000011#include "video_engine/vie_base_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +000013#include <sstream>
14#include <string>
15
16#include "engine_configurations.h" // NOLINT
17#include "system_wrappers/interface/critical_section_wrapper.h"
18#include "modules/rtp_rtcp/interface/rtp_rtcp.h"
19#include "modules/video_coding/main/interface/video_coding.h"
20#include "modules/video_processing/main/interface/video_processing.h"
21#include "modules/video_render/main/interface/video_render.h"
22#include "system_wrappers/interface/trace.h"
23#include "video_engine/vie_channel.h"
24#include "video_engine/vie_channel_manager.h"
25#include "video_engine/vie_defines.h"
26#include "video_engine/vie_encoder.h"
27#include "video_engine/include/vie_errors.h"
28#include "video_engine/vie_impl.h"
29#include "video_engine/vie_input_manager.h"
30#include "video_engine/vie_performance_monitor.h"
31#include "video_engine/vie_shared_data.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000032
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000033namespace webrtc {
niklase@google.com470e71d2011-07-07 08:21:25 +000034
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000035ViEBase* ViEBase::GetInterface(VideoEngine* video_engine) {
36 if (!video_engine) {
37 return NULL;
38 }
39 VideoEngineImpl* vie_impl = reinterpret_cast<VideoEngineImpl*>(video_engine);
40 ViEBaseImpl* vie_base_impl = vie_impl;
41 (*vie_base_impl)++; // Increase ref count.
niklase@google.com470e71d2011-07-07 08:21:25 +000042
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000043 return vie_base_impl;
niklase@google.com470e71d2011-07-07 08:21:25 +000044}
45
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000046int ViEBaseImpl::Release() {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000047 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, shared_data_.instance_id(),
niklase@google.com470e71d2011-07-07 08:21:25 +000048 "ViEBase::Release()");
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000049 (*this)--; // Decrease ref count.
niklase@google.com470e71d2011-07-07 08:21:25 +000050
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000051 WebRtc_Word32 ref_count = GetCount();
52 if (ref_count < 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000053 WEBRTC_TRACE(kTraceWarning, kTraceVideo, shared_data_.instance_id(),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000054 "ViEBase release too many times");
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000055 shared_data_.SetLastError(kViEAPIDoesNotExist);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000056 return -1;
57 }
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000058 WEBRTC_TRACE(kTraceInfo, kTraceVideo, shared_data_.instance_id(),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000059 "ViEBase reference count: %d", ref_count);
60 return ref_count;
niklase@google.com470e71d2011-07-07 08:21:25 +000061}
62
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000063ViEBaseImpl::ViEBaseImpl() {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000064 WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_.instance_id(),
niklase@google.com470e71d2011-07-07 08:21:25 +000065 "ViEBaseImpl::ViEBaseImpl() Ctor");
66}
67
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000068ViEBaseImpl::~ViEBaseImpl() {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000069 WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_.instance_id(),
niklase@google.com470e71d2011-07-07 08:21:25 +000070 "ViEBaseImpl::ViEBaseImpl() Dtor");
niklase@google.com470e71d2011-07-07 08:21:25 +000071}
72
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000073int ViEBaseImpl::Init() {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000074 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, shared_data_.instance_id(),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000075 "Init");
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000076 if (shared_data_.Initialized()) {
77 WEBRTC_TRACE(kTraceWarning, kTraceVideo, shared_data_.instance_id(),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000078 "Init called twice");
niklase@google.com470e71d2011-07-07 08:21:25 +000079 return 0;
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000080 }
81
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000082 shared_data_.SetInitialized();
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000083 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +000084}
85
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000086int ViEBaseImpl::SetVoiceEngine(VoiceEngine* voice_engine) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000087 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000088 "%s", __FUNCTION__);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000089 if (!(shared_data_.Initialized())) {
90 shared_data_.SetLastError(kViENotInitialized);
91 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000092 "%s - ViE instance %d not initialized", __FUNCTION__,
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000093 shared_data_.instance_id());
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000094 return -1;
95 }
niklase@google.com470e71d2011-07-07 08:21:25 +000096
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000097 if (shared_data_.channel_manager()->SetVoiceEngine(voice_engine) != 0) {
98 shared_data_.SetLastError(kViEBaseVoEFailure);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000099 return -1;
100 }
101 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000102}
103
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000104int ViEBaseImpl::CreateChannel(int& video_channel) { // NOLINT
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000105 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000106 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000107
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000108 if (!(shared_data_.Initialized())) {
109 shared_data_.SetLastError(kViENotInitialized);
110 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000111 "%s - ViE instance %d not initialized", __FUNCTION__,
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000112 shared_data_.instance_id());
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000113 return -1;
114 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000115
mflodman@webrtc.orgab2610f2012-06-29 10:05:28 +0000116 if (shared_data_.channel_manager()->CreateChannel(&video_channel) == -1) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000117 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000118 "%s: Could not create channel", __FUNCTION__);
119 video_channel = -1;
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000120 shared_data_.SetLastError(kViEBaseChannelCreationFailed);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000121 return -1;
122 }
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000123 WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000124 "%s: channel created: %d", __FUNCTION__, video_channel);
125 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000126}
127
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000128int ViEBaseImpl::CreateChannel(int& video_channel, // NOLINT
129 int original_channel) {
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000130 return CreateChannel(video_channel, original_channel, true);
131}
niklase@google.com470e71d2011-07-07 08:21:25 +0000132
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000133int ViEBaseImpl::CreateReceiveChannel(int& video_channel, // NOLINT
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000134 int original_channel) {
135 return CreateChannel(video_channel, original_channel, false);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000136}
niklase@google.com470e71d2011-07-07 08:21:25 +0000137
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000138int ViEBaseImpl::DeleteChannel(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000139 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000140 "%s(%d)", __FUNCTION__, video_channel);
141
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000142 if (!(shared_data_.Initialized())) {
143 shared_data_.SetLastError(kViENotInitialized);
144 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000145 "%s - ViE instance %d not initialized", __FUNCTION__,
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000146 shared_data_.instance_id());
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000147 return -1;
148 }
149
150 {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000151 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000152 ViEChannel* vie_channel = cs.Channel(video_channel);
153 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000154 WEBRTC_TRACE(kTraceError, kTraceVideo,
155 ViEId(shared_data_.instance_id()),
156 "%s: channel %d doesn't exist", __FUNCTION__, video_channel);
157 shared_data_.SetLastError(kViEBaseInvalidChannelId);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000158 return -1;
159 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000160
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000161 // Deregister the ViEEncoder if no other channel is using it.
162 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
163 if (cs.ChannelUsingViEEncoder(video_channel) == false) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000164 ViEInputManagerScoped is(*(shared_data_.input_manager()));
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000165 ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
166 if (provider) {
167 provider->DeregisterFrameCallback(vie_encoder);
168 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000169 }
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000170 }
171
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000172 if (shared_data_.channel_manager()->DeleteChannel(video_channel) == -1) {
173 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000174 "%s: Could not delete channel %d", __FUNCTION__,
175 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000176 shared_data_.SetLastError(kViEBaseUnknownError);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000177 return -1;
178 }
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000179 WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000180 "%s: channel deleted: %d", __FUNCTION__, video_channel);
181 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000182}
183
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000184int ViEBaseImpl::ConnectAudioChannel(const int video_channel,
185 const int audio_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000186 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000187 "%s(%d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000188
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000189 if (!(shared_data_.Initialized())) {
190 shared_data_.SetLastError(kViENotInitialized);
191 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000192 "%s - ViE instance %d not initialized", __FUNCTION__,
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000193 shared_data_.instance_id());
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000194 return -1;
195 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000196
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000197 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000198 if (!cs.Channel(video_channel)) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000199 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000200 "%s: channel %d doesn't exist", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000201 shared_data_.SetLastError(kViEBaseInvalidChannelId);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000202 return -1;
203 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000204
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000205 if (shared_data_.channel_manager()->ConnectVoiceChannel(video_channel,
206 audio_channel) != 0) {
207 shared_data_.SetLastError(kViEBaseVoEFailure);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000208 return -1;
209 }
210 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000211}
212
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000213int ViEBaseImpl::DisconnectAudioChannel(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000214 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000215 "%s(%d)", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000216 if (!(shared_data_.Initialized())) {
217 shared_data_.SetLastError(kViENotInitialized);
218 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000219 "%s - ViE instance %d not initialized", __FUNCTION__,
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000220 shared_data_.instance_id());
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000221 return -1;
222 }
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000223 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000224 if (!cs.Channel(video_channel)) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000225 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000226 "%s: channel %d doesn't exist", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000227 shared_data_.SetLastError(kViEBaseInvalidChannelId);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000228 return -1;
229 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000230
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000231 if (shared_data_.channel_manager()->DisconnectVoiceChannel(
232 video_channel) != 0) {
233 shared_data_.SetLastError(kViEBaseVoEFailure);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000234 return -1;
235 }
236 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000237}
238
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000239int ViEBaseImpl::StartSend(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000240 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
241 ViEId(shared_data_.instance_id(), video_channel),
242 "%s(channel: %d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000243
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000244 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000245 ViEChannel* vie_channel = cs.Channel(video_channel);
246 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000247 WEBRTC_TRACE(kTraceError, kTraceVideo,
248 ViEId(shared_data_.instance_id(), video_channel),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000249 "%s: Channel %d does not exist", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000250 shared_data_.SetLastError(kViEBaseInvalidChannelId);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000251 return -1;
252 }
mflodman@webrtc.org1a739ba2012-02-28 16:11:33 +0000253
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000254 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000255 assert(vie_encoder != NULL);
256 if (vie_encoder->Owner() != video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000257 WEBRTC_TRACE(kTraceError, kTraceVideo,
258 ViEId(shared_data_.instance_id(), video_channel),
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000259 "Can't start ssend on a receive only channel.");
260 shared_data_.SetLastError(kViEBaseReceiveOnlyChannel);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000261 return -1;
262 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000263
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000264 // Pause and trigger a key frame.
265 vie_encoder->Pause();
266 WebRtc_Word32 error = vie_channel->StartSend();
267 if (error != 0) {
268 vie_encoder->Restart();
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000269 WEBRTC_TRACE(kTraceError, kTraceVideo,
270 ViEId(shared_data_.instance_id(), video_channel),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000271 "%s: Could not start sending on channel %d", __FUNCTION__,
272 video_channel);
273 if (error == kViEBaseAlreadySending) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000274 shared_data_.SetLastError(kViEBaseAlreadySending);
niklase@google.com470e71d2011-07-07 08:21:25 +0000275 }
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000276 shared_data_.SetLastError(kViEBaseUnknownError);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000277 return -1;
278 }
279 vie_encoder->SendKeyFrame();
280 vie_encoder->Restart();
281 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000282}
283
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000284int ViEBaseImpl::StopSend(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000285 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
286 ViEId(shared_data_.instance_id(), video_channel),
287 "%s(channel: %d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000288
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000289 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000290 ViEChannel* vie_channel = cs.Channel(video_channel);
291 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000292 WEBRTC_TRACE(kTraceError, kTraceVideo,
293 ViEId(shared_data_.instance_id(), video_channel),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000294 "%s: Channel %d does not exist", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000295 shared_data_.SetLastError(kViEBaseInvalidChannelId);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000296 return -1;
297 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000298
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000299 WebRtc_Word32 error = vie_channel->StopSend();
300 if (error != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000301 WEBRTC_TRACE(kTraceError, kTraceVideo,
302 ViEId(shared_data_.instance_id(), video_channel),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000303 "%s: Could not stop sending on channel %d", __FUNCTION__,
304 video_channel);
305 if (error == kViEBaseNotSending) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000306 shared_data_.SetLastError(kViEBaseNotSending);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000307 } else {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000308 shared_data_.SetLastError(kViEBaseUnknownError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000309 }
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000310 return -1;
311 }
312 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000313}
314
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000315int ViEBaseImpl::StartReceive(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000316 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
317 ViEId(shared_data_.instance_id(), video_channel),
318 "%s(channel: %d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000319
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000320 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000321 ViEChannel* vie_channel = cs.Channel(video_channel);
322 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000323 WEBRTC_TRACE(kTraceError, kTraceVideo,
324 ViEId(shared_data_.instance_id(), video_channel),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000325 "%s: Channel %d does not exist", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000326 shared_data_.SetLastError(kViEBaseInvalidChannelId);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000327 return -1;
328 }
329 if (vie_channel->Receiving()) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000330 WEBRTC_TRACE(kTraceError, kTraceVideo,
331 ViEId(shared_data_.instance_id(), video_channel),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000332 "%s: Channel %d already receive.", __FUNCTION__,
333 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000334 shared_data_.SetLastError(kViEBaseAlreadyReceiving);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000335 return -1;
336 }
337 if (vie_channel->StartReceive() != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000338 shared_data_.SetLastError(kViEBaseUnknownError);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000339 return -1;
340 }
341 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000342}
343
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000344int ViEBaseImpl::StopReceive(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000345 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
346 ViEId(shared_data_.instance_id(), video_channel),
347 "%s(channel: %d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000348
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000349 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000350 ViEChannel* vie_channel = cs.Channel(video_channel);
351 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000352 WEBRTC_TRACE(kTraceError, kTraceVideo,
353 ViEId(shared_data_.instance_id(), video_channel),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000354 "%s: Channel %d does not exist", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000355 shared_data_.SetLastError(kViEBaseInvalidChannelId);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000356 return -1;
357 }
358 if (vie_channel->StopReceive() != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000359 shared_data_.SetLastError(kViEBaseUnknownError);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000360 return -1;
361 }
362 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000363}
364
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000365int ViEBaseImpl::RegisterObserver(ViEBaseObserver& observer) { // NOLINT
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000366 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000367 "%s", __FUNCTION__);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000368 if (shared_data_.vie_performance_monitor()->ViEBaseObserverRegistered()) {
369 shared_data_.SetLastError(kViEBaseObserverAlreadyRegistered);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000370 return -1;
371 }
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000372 return shared_data_.vie_performance_monitor()->Init(&observer);
niklase@google.com470e71d2011-07-07 08:21:25 +0000373}
374
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000375int ViEBaseImpl::DeregisterObserver() {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000376 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000377 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000378
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000379 if (!shared_data_.vie_performance_monitor()->ViEBaseObserverRegistered()) {
380 shared_data_.SetLastError(kViEBaseObserverNotRegistered);
381 WEBRTC_TRACE(kTraceError, kTraceVideo, shared_data_.instance_id(),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000382 "%s No observer registered.", __FUNCTION__);
383 return -1;
384 }
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000385 shared_data_.vie_performance_monitor()->Terminate();
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000386 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000387}
388
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000389int ViEBaseImpl::GetVersion(char version[1024]) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000390 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
niklase@google.com470e71d2011-07-07 08:21:25 +0000391 "GetVersion(version=?)");
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000392 assert(kViEVersionMaxMessageSize == 1024);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000393 if (!version) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000394 shared_data_.SetLastError(kViEBaseInvalidArgument);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000395 return -1;
396 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000397
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000398 // Add WebRTC Version.
399 std::stringstream version_stream;
400 version_stream << "VideoEngine 3.8.0" << std::endl;
niklase@google.com470e71d2011-07-07 08:21:25 +0000401
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000402 // Add build info.
403 version_stream << "Build: svn:" << WEBRTC_SVNREVISION << " " << BUILDINFO
404 << std::endl;
niklase@google.com470e71d2011-07-07 08:21:25 +0000405
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000406#ifdef WEBRTC_EXTERNAL_TRANSPORT
407 version_stream << "External transport build" << std::endl;
408#endif
409 int version_length = version_stream.tellp();
410 assert(version_length < 1024);
411 memcpy(version, version_stream.str().c_str(), version_length);
niklase@google.com470e71d2011-07-07 08:21:25 +0000412
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000413 WEBRTC_TRACE(kTraceStateInfo, kTraceVideo,
414 ViEId(shared_data_.instance_id()), "GetVersion() => %s",
415 version);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000416 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000417}
418
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000419int ViEBaseImpl::LastError() {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000420 return shared_data_.LastErrorInternal();
niklase@google.com470e71d2011-07-07 08:21:25 +0000421}
422
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000423int ViEBaseImpl::CreateChannel(int& video_channel, // NOLINT
424 int original_channel, bool sender) {
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000425 if (!(shared_data_.Initialized())) {
426 shared_data_.SetLastError(kViENotInitialized);
427 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
428 "%s - ViE instance %d not initialized", __FUNCTION__,
429 shared_data_.instance_id());
430 return -1;
431 }
432
433 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
434 if (!cs.Channel(original_channel)) {
435 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
436 "%s - original_channel does not exist.", __FUNCTION__,
437 shared_data_.instance_id());
438 shared_data_.SetLastError(kViEBaseInvalidChannelId);
439 return -1;
440 }
441
mflodman@webrtc.orgab2610f2012-06-29 10:05:28 +0000442 if (shared_data_.channel_manager()->CreateChannel(&video_channel,
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000443 original_channel,
444 sender) == -1) {
445 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
446 "%s: Could not create channel", __FUNCTION__);
447 video_channel = -1;
448 shared_data_.SetLastError(kViEBaseChannelCreationFailed);
449 return -1;
450 }
451 WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(shared_data_.instance_id()),
452 "%s: channel created: %d", __FUNCTION__, video_channel);
453 return 0;
454}
455
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000456} // namespace webrtc