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