blob: a1f3fc2631b9e6dfb92e778c02f910679e2d5f3f [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
pbos@webrtc.orgf5d4cb12013-05-17 13:44:48 +000011#include "webrtc/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>
mflodman@webrtc.orgf3973e82013-12-13 09:40:45 +000015#include <utility>
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +000016
pbos@webrtc.orgf5d4cb12013-05-17 13:44:48 +000017#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"
andrew@webrtc.org9841d922012-10-31 05:22:11 +000021#include "webrtc/modules/video_render/include/video_render.h"
pbos@webrtc.orgf5d4cb12013-05-17 13:44:48 +000022#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"
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +000025#include "webrtc/video_engine/vie_capturer.h"
pbos@webrtc.orgf5d4cb12013-05-17 13:44:48 +000026#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"
niklase@google.com470e71d2011-07-07 08:21:25 +000033
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000034namespace webrtc {
niklase@google.com470e71d2011-07-07 08:21:25 +000035
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000036ViEBase* ViEBase::GetInterface(VideoEngine* video_engine) {
37 if (!video_engine) {
38 return NULL;
39 }
andrew@webrtc.orgd72262d2013-05-09 02:12:07 +000040 VideoEngineImpl* vie_impl = static_cast<VideoEngineImpl*>(video_engine);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000041 ViEBaseImpl* vie_base_impl = vie_impl;
42 (*vie_base_impl)++; // Increase ref count.
niklase@google.com470e71d2011-07-07 08:21:25 +000043
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000044 return vie_base_impl;
niklase@google.com470e71d2011-07-07 08:21:25 +000045}
46
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000047int ViEBaseImpl::Release() {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000048 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, shared_data_.instance_id(),
niklase@google.com470e71d2011-07-07 08:21:25 +000049 "ViEBase::Release()");
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000050 (*this)--; // Decrease ref count.
niklase@google.com470e71d2011-07-07 08:21:25 +000051
pbos@webrtc.orgb238d122013-04-09 13:41:51 +000052 int32_t ref_count = GetCount();
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000053 if (ref_count < 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000054 WEBRTC_TRACE(kTraceWarning, kTraceVideo, shared_data_.instance_id(),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000055 "ViEBase release too many times");
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000056 shared_data_.SetLastError(kViEAPIDoesNotExist);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000057 return -1;
58 }
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000059 WEBRTC_TRACE(kTraceInfo, kTraceVideo, shared_data_.instance_id(),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000060 "ViEBase reference count: %d", ref_count);
61 return ref_count;
niklase@google.com470e71d2011-07-07 08:21:25 +000062}
63
andresp@webrtc.org7707d062013-05-13 10:50:50 +000064ViEBaseImpl::ViEBaseImpl(const Config& config)
65 : shared_data_(config) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000066 WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_.instance_id(),
niklase@google.com470e71d2011-07-07 08:21:25 +000067 "ViEBaseImpl::ViEBaseImpl() Ctor");
68}
69
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000070ViEBaseImpl::~ViEBaseImpl() {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000071 WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_.instance_id(),
niklase@google.com470e71d2011-07-07 08:21:25 +000072 "ViEBaseImpl::ViEBaseImpl() Dtor");
niklase@google.com470e71d2011-07-07 08:21:25 +000073}
74
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000075int ViEBaseImpl::Init() {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000076 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, shared_data_.instance_id(),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000077 "Init");
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000078 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +000079}
80
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000081int ViEBaseImpl::SetVoiceEngine(VoiceEngine* voice_engine) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000082 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000083 "%s", __FUNCTION__);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000084 if (shared_data_.channel_manager()->SetVoiceEngine(voice_engine) != 0) {
85 shared_data_.SetLastError(kViEBaseVoEFailure);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +000086 return -1;
87 }
88 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +000089}
90
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +000091int 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
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000121int ViEBaseImpl::SetCpuOveruseOptions(int video_channel,
122 const CpuOveruseOptions& options) {
123 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
124 ViEChannel* vie_channel = cs.Channel(video_channel);
125 if (!vie_channel) {
126 WEBRTC_TRACE(kTraceError,
127 kTraceVideo,
128 ViEId(shared_data_.instance_id()),
129 "%s: channel %d doesn't exist",
130 __FUNCTION__,
131 video_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->SetCpuOveruseOptions(options);
144 return 0;
145 }
146 }
147 return -1;
148}
149
asapersson@webrtc.orgc7ff8f92013-11-26 11:12:33 +0000150int ViEBaseImpl::CpuOveruseMeasures(int video_channel,
151 int* capture_jitter_ms,
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000152 int* avg_encode_time_ms,
153 int* encode_usage_percent,
154 int* capture_queue_delay_ms_per_s) {
asapersson@webrtc.orgb24d3352013-11-20 13:51:40 +0000155 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
156 ViEChannel* vie_channel = cs.Channel(video_channel);
157 if (!vie_channel) {
158 WEBRTC_TRACE(kTraceError,
159 kTraceVideo,
160 ViEId(shared_data_.instance_id()),
161 "%s: channel %d doesn't exist",
162 __FUNCTION__,
163 video_channel);
164 shared_data_.SetLastError(kViEBaseInvalidChannelId);
165 return -1;
166 }
167 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
168 assert(vie_encoder);
169
170 ViEInputManagerScoped is(*(shared_data_.input_manager()));
171 ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
172 if (provider) {
173 ViECapturer* capturer = is.Capture(provider->Id());
174 if (capturer) {
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000175 capturer->CpuOveruseMeasures(capture_jitter_ms,
176 avg_encode_time_ms,
177 encode_usage_percent,
178 capture_queue_delay_ms_per_s);
asapersson@webrtc.orgb24d3352013-11-20 13:51:40 +0000179 return 0;
180 }
181 }
182 return -1;
183}
184
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000185int ViEBaseImpl::CreateChannel(int& video_channel) { // NOLINT
henrik.lundin@webrtc.org41907742014-01-29 08:47:15 +0000186 return CreateChannel(video_channel, static_cast<const Config*>(NULL));
187}
188
189int ViEBaseImpl::CreateChannel(int& video_channel, // NOLINT
190 const Config* config) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000191 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000192 "%s", __FUNCTION__);
henrik.lundin@webrtc.org41907742014-01-29 08:47:15 +0000193 if (shared_data_.channel_manager()->CreateChannel(&video_channel,
194 config) == -1) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000195 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000196 "%s: Could not create channel", __FUNCTION__);
197 video_channel = -1;
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000198 shared_data_.SetLastError(kViEBaseChannelCreationFailed);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000199 return -1;
200 }
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000201 WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000202 "%s: channel created: %d", __FUNCTION__, video_channel);
203 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000204}
205
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000206int ViEBaseImpl::CreateChannel(int& video_channel, // NOLINT
207 int original_channel) {
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000208 return CreateChannel(video_channel, original_channel, true);
209}
niklase@google.com470e71d2011-07-07 08:21:25 +0000210
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000211int ViEBaseImpl::CreateReceiveChannel(int& video_channel, // NOLINT
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000212 int original_channel) {
213 return CreateChannel(video_channel, original_channel, false);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000214}
niklase@google.com470e71d2011-07-07 08:21:25 +0000215
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000216int ViEBaseImpl::DeleteChannel(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000217 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000218 "%s(%d)", __FUNCTION__, video_channel);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000219 {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000220 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000221 ViEChannel* vie_channel = cs.Channel(video_channel);
222 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000223 WEBRTC_TRACE(kTraceError, kTraceVideo,
224 ViEId(shared_data_.instance_id()),
225 "%s: channel %d doesn't exist", __FUNCTION__, video_channel);
226 shared_data_.SetLastError(kViEBaseInvalidChannelId);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000227 return -1;
228 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000229
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000230 // Deregister the ViEEncoder if no other channel is using it.
231 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
232 if (cs.ChannelUsingViEEncoder(video_channel) == false) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000233 ViEInputManagerScoped is(*(shared_data_.input_manager()));
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000234 ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
235 if (provider) {
236 provider->DeregisterFrameCallback(vie_encoder);
237 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000238 }
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000239 }
240
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000241 if (shared_data_.channel_manager()->DeleteChannel(video_channel) == -1) {
242 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000243 "%s: Could not delete channel %d", __FUNCTION__,
244 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000245 shared_data_.SetLastError(kViEBaseUnknownError);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000246 return -1;
247 }
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000248 WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000249 "%s: channel deleted: %d", __FUNCTION__, video_channel);
250 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000251}
252
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000253int ViEBaseImpl::ConnectAudioChannel(const int video_channel,
254 const int audio_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000255 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000256 "%s(%d)", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000257 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000258 if (!cs.Channel(video_channel)) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000259 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000260 "%s: channel %d doesn't exist", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000261 shared_data_.SetLastError(kViEBaseInvalidChannelId);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000262 return -1;
263 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000264
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000265 if (shared_data_.channel_manager()->ConnectVoiceChannel(video_channel,
266 audio_channel) != 0) {
267 shared_data_.SetLastError(kViEBaseVoEFailure);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000268 return -1;
269 }
270 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000271}
272
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000273int ViEBaseImpl::DisconnectAudioChannel(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000274 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000275 "%s(%d)", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000276 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000277 if (!cs.Channel(video_channel)) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000278 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000279 "%s: channel %d doesn't exist", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000280 shared_data_.SetLastError(kViEBaseInvalidChannelId);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000281 return -1;
282 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000283
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000284 if (shared_data_.channel_manager()->DisconnectVoiceChannel(
285 video_channel) != 0) {
286 shared_data_.SetLastError(kViEBaseVoEFailure);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000287 return -1;
288 }
289 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000290}
291
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000292int ViEBaseImpl::StartSend(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000293 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
294 ViEId(shared_data_.instance_id(), video_channel),
295 "%s(channel: %d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000296
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000297 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000298 ViEChannel* vie_channel = cs.Channel(video_channel);
299 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000300 WEBRTC_TRACE(kTraceError, kTraceVideo,
301 ViEId(shared_data_.instance_id(), video_channel),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000302 "%s: Channel %d does not exist", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000303 shared_data_.SetLastError(kViEBaseInvalidChannelId);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000304 return -1;
305 }
mflodman@webrtc.org1a739ba2012-02-28 16:11:33 +0000306
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000307 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000308 assert(vie_encoder != NULL);
309 if (vie_encoder->Owner() != video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000310 WEBRTC_TRACE(kTraceError, kTraceVideo,
311 ViEId(shared_data_.instance_id(), video_channel),
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000312 "Can't start ssend on a receive only channel.");
313 shared_data_.SetLastError(kViEBaseReceiveOnlyChannel);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000314 return -1;
315 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000316
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000317 // Pause and trigger a key frame.
318 vie_encoder->Pause();
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000319 int32_t error = vie_channel->StartSend();
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000320 if (error != 0) {
321 vie_encoder->Restart();
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000322 WEBRTC_TRACE(kTraceError, kTraceVideo,
323 ViEId(shared_data_.instance_id(), video_channel),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000324 "%s: Could not start sending on channel %d", __FUNCTION__,
325 video_channel);
326 if (error == kViEBaseAlreadySending) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000327 shared_data_.SetLastError(kViEBaseAlreadySending);
niklase@google.com470e71d2011-07-07 08:21:25 +0000328 }
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000329 shared_data_.SetLastError(kViEBaseUnknownError);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000330 return -1;
331 }
332 vie_encoder->SendKeyFrame();
333 vie_encoder->Restart();
334 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000335}
336
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000337int ViEBaseImpl::StopSend(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000338 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
339 ViEId(shared_data_.instance_id(), video_channel),
340 "%s(channel: %d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000341
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000342 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000343 ViEChannel* vie_channel = cs.Channel(video_channel);
344 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000345 WEBRTC_TRACE(kTraceError, kTraceVideo,
346 ViEId(shared_data_.instance_id(), video_channel),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000347 "%s: Channel %d does not exist", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000348 shared_data_.SetLastError(kViEBaseInvalidChannelId);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000349 return -1;
350 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000351
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000352 int32_t error = vie_channel->StopSend();
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000353 if (error != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000354 WEBRTC_TRACE(kTraceError, kTraceVideo,
355 ViEId(shared_data_.instance_id(), video_channel),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000356 "%s: Could not stop sending on channel %d", __FUNCTION__,
357 video_channel);
358 if (error == kViEBaseNotSending) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000359 shared_data_.SetLastError(kViEBaseNotSending);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000360 } else {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000361 shared_data_.SetLastError(kViEBaseUnknownError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000362 }
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000363 return -1;
364 }
365 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000366}
367
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000368int ViEBaseImpl::StartReceive(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000369 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
370 ViEId(shared_data_.instance_id(), video_channel),
371 "%s(channel: %d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000372
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000373 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000374 ViEChannel* vie_channel = cs.Channel(video_channel);
375 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000376 WEBRTC_TRACE(kTraceError, kTraceVideo,
377 ViEId(shared_data_.instance_id(), video_channel),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000378 "%s: Channel %d does not exist", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000379 shared_data_.SetLastError(kViEBaseInvalidChannelId);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000380 return -1;
381 }
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000382 if (vie_channel->StartReceive() != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000383 shared_data_.SetLastError(kViEBaseUnknownError);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000384 return -1;
385 }
386 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000387}
388
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000389int ViEBaseImpl::StopReceive(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000390 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
391 ViEId(shared_data_.instance_id(), video_channel),
392 "%s(channel: %d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000393
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000394 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000395 ViEChannel* vie_channel = cs.Channel(video_channel);
396 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000397 WEBRTC_TRACE(kTraceError, kTraceVideo,
398 ViEId(shared_data_.instance_id(), video_channel),
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000399 "%s: Channel %d does not exist", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000400 shared_data_.SetLastError(kViEBaseInvalidChannelId);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000401 return -1;
402 }
403 if (vie_channel->StopReceive() != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000404 shared_data_.SetLastError(kViEBaseUnknownError);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000405 return -1;
406 }
407 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000408}
409
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000410int ViEBaseImpl::GetVersion(char version[1024]) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000411 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_.instance_id()),
niklase@google.com470e71d2011-07-07 08:21:25 +0000412 "GetVersion(version=?)");
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000413 assert(kViEVersionMaxMessageSize == 1024);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000414 if (!version) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000415 shared_data_.SetLastError(kViEBaseInvalidArgument);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000416 return -1;
417 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000418
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000419 // Add WebRTC Version.
420 std::stringstream version_stream;
elham@webrtc.org39f8dda2014-03-25 18:41:14 +0000421 version_stream << "VideoEngine 3.51.0" << std::endl;
niklase@google.com470e71d2011-07-07 08:21:25 +0000422
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000423 // Add build info.
andrew@webrtc.org3054ba62013-12-04 17:00:44 +0000424 version_stream << "Build: " << BUILDINFO << std::endl;
niklase@google.com470e71d2011-07-07 08:21:25 +0000425
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000426#ifdef WEBRTC_EXTERNAL_TRANSPORT
427 version_stream << "External transport build" << std::endl;
428#endif
429 int version_length = version_stream.tellp();
430 assert(version_length < 1024);
431 memcpy(version, version_stream.str().c_str(), version_length);
leozwang@webrtc.org6c08f262012-07-13 22:00:16 +0000432 version[version_length] = '\0';
niklase@google.com470e71d2011-07-07 08:21:25 +0000433
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000434 WEBRTC_TRACE(kTraceStateInfo, kTraceVideo,
435 ViEId(shared_data_.instance_id()), "GetVersion() => %s",
436 version);
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000437 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000438}
439
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000440int ViEBaseImpl::LastError() {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000441 return shared_data_.LastErrorInternal();
niklase@google.com470e71d2011-07-07 08:21:25 +0000442}
443
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000444int ViEBaseImpl::CreateChannel(int& video_channel, // NOLINT
445 int original_channel, bool sender) {
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000446 ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
447 if (!cs.Channel(original_channel)) {
448 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
449 "%s - original_channel does not exist.", __FUNCTION__,
450 shared_data_.instance_id());
451 shared_data_.SetLastError(kViEBaseInvalidChannelId);
452 return -1;
453 }
454
mflodman@webrtc.orgab2610f2012-06-29 10:05:28 +0000455 if (shared_data_.channel_manager()->CreateChannel(&video_channel,
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000456 original_channel,
457 sender) == -1) {
458 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_.instance_id()),
459 "%s: Could not create channel", __FUNCTION__);
460 video_channel = -1;
461 shared_data_.SetLastError(kViEBaseChannelCreationFailed);
462 return -1;
463 }
464 WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(shared_data_.instance_id()),
465 "%s: channel created: %d", __FUNCTION__, video_channel);
466 return 0;
467}
468
mflodman@webrtc.org27a82a62011-11-30 18:04:26 +0000469} // namespace webrtc