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