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_channel_manager.h" 12 13 #include "webrtc/common.h" 14 #include "webrtc/engine_configurations.h" 15 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h" 16 #include "webrtc/modules/utility/interface/process_thread.h" 17 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 18 #include "webrtc/system_wrappers/interface/logging.h" 19 #include "webrtc/video_engine/call_stats.h" 20 #include "webrtc/video_engine/encoder_state_feedback.h" 21 #include "webrtc/video_engine/vie_channel.h" 22 #include "webrtc/video_engine/vie_defines.h" 23 #include "webrtc/video_engine/vie_encoder.h" 24 #include "webrtc/video_engine/vie_remb.h" 25 #include "webrtc/voice_engine/include/voe_video_sync.h" 26 27 namespace webrtc { 28 29 ViEChannelManager::ViEChannelManager( 30 int engine_id, 31 int number_of_cores, 32 const Config& config) 33 : channel_id_critsect_(CriticalSectionWrapper::CreateCriticalSection()), 34 engine_id_(engine_id), 35 number_of_cores_(number_of_cores), 36 free_channel_ids_(new bool[kViEMaxNumberOfChannels]), 37 free_channel_ids_size_(kViEMaxNumberOfChannels), 38 voice_sync_interface_(NULL), 39 voice_engine_(NULL), 40 module_process_thread_(NULL), 41 engine_config_(config) { 42 for (int idx = 0; idx < free_channel_ids_size_; idx++) { 43 free_channel_ids_[idx] = true; 44 } 45 } 46 47 ViEChannelManager::~ViEChannelManager() { 48 while (channel_map_.size() > 0) { 49 ChannelMap::iterator it = channel_map_.begin(); 50 // DeleteChannel will erase this channel from the map and invalidate |it|. 51 DeleteChannel(it->first); 52 } 53 54 if (voice_sync_interface_) { 55 voice_sync_interface_->Release(); 56 } 57 if (channel_id_critsect_) { 58 delete channel_id_critsect_; 59 channel_id_critsect_ = NULL; 60 } 61 if (free_channel_ids_) { 62 delete[] free_channel_ids_; 63 free_channel_ids_ = NULL; 64 free_channel_ids_size_ = 0; 65 } 66 assert(channel_groups_.empty()); 67 assert(channel_map_.empty()); 68 assert(vie_encoder_map_.empty()); 69 } 70 71 void ViEChannelManager::SetModuleProcessThread( 72 ProcessThread* module_process_thread) { 73 assert(!module_process_thread_); 74 module_process_thread_ = module_process_thread; 75 } 76 77 int ViEChannelManager::CreateChannel(int* channel_id, 78 const Config* channel_group_config) { 79 CriticalSectionScoped cs(channel_id_critsect_); 80 81 // Get a new channel id. 82 int new_channel_id = FreeChannelId(); 83 if (new_channel_id == -1) { 84 return -1; 85 } 86 87 // Create a new channel group and add this channel. 88 ChannelGroup* group = new ChannelGroup(engine_id_, module_process_thread_, 89 channel_group_config); 90 BitrateController* bitrate_controller = group->GetBitrateController(); 91 ViEEncoder* vie_encoder = new ViEEncoder(engine_id_, new_channel_id, 92 number_of_cores_, 93 engine_config_, 94 *module_process_thread_, 95 bitrate_controller); 96 97 RtcpBandwidthObserver* bandwidth_observer = 98 bitrate_controller->CreateRtcpBandwidthObserver(); 99 RemoteBitrateEstimator* remote_bitrate_estimator = 100 group->GetRemoteBitrateEstimator(); 101 EncoderStateFeedback* encoder_state_feedback = 102 group->GetEncoderStateFeedback(); 103 RtcpRttStats* rtcp_rtt_stats = 104 group->GetCallStats()->rtcp_rtt_stats(); 105 106 if (!(vie_encoder->Init() && 107 CreateChannelObject(new_channel_id, vie_encoder, bandwidth_observer, 108 remote_bitrate_estimator, rtcp_rtt_stats, 109 encoder_state_feedback->GetRtcpIntraFrameObserver(), 110 true))) { 111 delete vie_encoder; 112 vie_encoder = NULL; 113 ReturnChannelId(new_channel_id); 114 delete group; 115 return -1; 116 } 117 118 // Add ViEEncoder to EncoderFeedBackObserver. 119 unsigned int ssrc = 0; 120 int idx = 0; 121 channel_map_[new_channel_id]->GetLocalSSRC(idx, &ssrc); 122 encoder_state_feedback->AddEncoder(ssrc, vie_encoder); 123 std::list<unsigned int> ssrcs; 124 ssrcs.push_back(ssrc); 125 vie_encoder->SetSsrcs(ssrcs); 126 *channel_id = new_channel_id; 127 group->AddChannel(*channel_id); 128 channel_groups_.push_back(group); 129 // Register the channel to receive stats updates. 130 group->GetCallStats()->RegisterStatsObserver( 131 channel_map_[new_channel_id]->GetStatsObserver()); 132 return 0; 133 } 134 135 int ViEChannelManager::CreateChannel(int* channel_id, 136 int original_channel, 137 bool sender) { 138 CriticalSectionScoped cs(channel_id_critsect_); 139 140 ChannelGroup* channel_group = FindGroup(original_channel); 141 if (!channel_group) { 142 return -1; 143 } 144 int new_channel_id = FreeChannelId(); 145 if (new_channel_id == -1) { 146 return -1; 147 } 148 BitrateController* bitrate_controller = channel_group->GetBitrateController(); 149 RtcpBandwidthObserver* bandwidth_observer = 150 bitrate_controller->CreateRtcpBandwidthObserver(); 151 RemoteBitrateEstimator* remote_bitrate_estimator = 152 channel_group->GetRemoteBitrateEstimator(); 153 EncoderStateFeedback* encoder_state_feedback = 154 channel_group->GetEncoderStateFeedback(); 155 RtcpRttStats* rtcp_rtt_stats = 156 channel_group->GetCallStats()->rtcp_rtt_stats(); 157 158 ViEEncoder* vie_encoder = NULL; 159 if (sender) { 160 // We need to create a new ViEEncoder. 161 vie_encoder = new ViEEncoder(engine_id_, new_channel_id, number_of_cores_, 162 engine_config_, 163 *module_process_thread_, 164 bitrate_controller); 165 if (!(vie_encoder->Init() && 166 CreateChannelObject( 167 new_channel_id, 168 vie_encoder, 169 bandwidth_observer, 170 remote_bitrate_estimator, 171 rtcp_rtt_stats, 172 encoder_state_feedback->GetRtcpIntraFrameObserver(), 173 sender))) { 174 delete vie_encoder; 175 vie_encoder = NULL; 176 } 177 // Register the ViEEncoder to get key frame requests for this channel. 178 unsigned int ssrc = 0; 179 int stream_idx = 0; 180 channel_map_[new_channel_id]->GetLocalSSRC(stream_idx, &ssrc); 181 encoder_state_feedback->AddEncoder(ssrc, vie_encoder); 182 } else { 183 vie_encoder = ViEEncoderPtr(original_channel); 184 assert(vie_encoder); 185 if (!CreateChannelObject( 186 new_channel_id, 187 vie_encoder, 188 bandwidth_observer, 189 remote_bitrate_estimator, 190 rtcp_rtt_stats, 191 encoder_state_feedback->GetRtcpIntraFrameObserver(), 192 sender)) { 193 vie_encoder = NULL; 194 } 195 } 196 if (!vie_encoder) { 197 ReturnChannelId(new_channel_id); 198 return -1; 199 } 200 *channel_id = new_channel_id; 201 channel_group->AddChannel(*channel_id); 202 // Register the channel to receive stats updates. 203 channel_group->GetCallStats()->RegisterStatsObserver( 204 channel_map_[new_channel_id]->GetStatsObserver()); 205 return 0; 206 } 207 208 int ViEChannelManager::DeleteChannel(int channel_id) { 209 ViEChannel* vie_channel = NULL; 210 ViEEncoder* vie_encoder = NULL; 211 ChannelGroup* group = NULL; 212 { 213 // Write lock to make sure no one is using the channel. 214 ViEManagerWriteScoped wl(this); 215 216 // Protect the maps. 217 CriticalSectionScoped cs(channel_id_critsect_); 218 219 ChannelMap::iterator c_it = channel_map_.find(channel_id); 220 if (c_it == channel_map_.end()) { 221 // No such channel. 222 return -1; 223 } 224 vie_channel = c_it->second; 225 channel_map_.erase(c_it); 226 227 ReturnChannelId(channel_id); 228 229 // Find the encoder object. 230 EncoderMap::iterator e_it = vie_encoder_map_.find(channel_id); 231 assert(e_it != vie_encoder_map_.end()); 232 vie_encoder = e_it->second; 233 234 group = FindGroup(channel_id); 235 group->GetCallStats()->DeregisterStatsObserver( 236 vie_channel->GetStatsObserver()); 237 group->SetChannelRembStatus(channel_id, false, false, vie_channel); 238 239 // Remove the feedback if we're owning the encoder. 240 if (vie_encoder->channel_id() == channel_id) { 241 group->GetEncoderStateFeedback()->RemoveEncoder(vie_encoder); 242 } 243 244 unsigned int remote_ssrc = 0; 245 vie_channel->GetRemoteSSRC(&remote_ssrc); 246 group->RemoveChannel(channel_id, remote_ssrc); 247 248 // Check if other channels are using the same encoder. 249 if (ChannelUsingViEEncoder(channel_id)) { 250 vie_encoder = NULL; 251 } else { 252 // Delete later when we've released the critsect. 253 } 254 255 // We can't erase the item before we've checked for other channels using 256 // same ViEEncoder. 257 vie_encoder_map_.erase(e_it); 258 259 if (group->Empty()) { 260 channel_groups_.remove(group); 261 } else { 262 group = NULL; // Prevent group from being deleted. 263 } 264 } 265 delete vie_channel; 266 // Leave the write critsect before deleting the objects. 267 // Deleting a channel can cause other objects, such as renderers, to be 268 // deleted, which might take time. 269 // If statment just to show that this object is not always deleted. 270 if (vie_encoder) { 271 LOG(LS_VERBOSE) << "ViEEncoder deleted for channel " << channel_id; 272 delete vie_encoder; 273 } 274 // If statment just to show that this object is not always deleted. 275 if (group) { 276 // Delete the group if empty last since the encoder holds a pointer to the 277 // BitrateController object that the group owns. 278 LOG(LS_VERBOSE) << "Channel group deleted for channel " << channel_id; 279 delete group; 280 } 281 LOG(LS_VERBOSE) << "Channel deleted " << channel_id; 282 return 0; 283 } 284 285 int ViEChannelManager::SetVoiceEngine(VoiceEngine* voice_engine) { 286 // Write lock to make sure no one is using the channel. 287 ViEManagerWriteScoped wl(this); 288 289 CriticalSectionScoped cs(channel_id_critsect_); 290 291 VoEVideoSync* sync_interface = NULL; 292 if (voice_engine) { 293 // Get new sync interface. 294 sync_interface = VoEVideoSync::GetInterface(voice_engine); 295 if (!sync_interface) { 296 return -1; 297 } 298 } 299 300 for (ChannelMap::iterator it = channel_map_.begin(); it != channel_map_.end(); 301 ++it) { 302 it->second->SetVoiceChannel(-1, sync_interface); 303 } 304 if (voice_sync_interface_) { 305 voice_sync_interface_->Release(); 306 } 307 voice_engine_ = voice_engine; 308 voice_sync_interface_ = sync_interface; 309 return 0; 310 } 311 312 int ViEChannelManager::ConnectVoiceChannel(int channel_id, 313 int audio_channel_id) { 314 CriticalSectionScoped cs(channel_id_critsect_); 315 if (!voice_sync_interface_) { 316 LOG_F(LS_ERROR) << "No VoE set."; 317 return -1; 318 } 319 ViEChannel* channel = ViEChannelPtr(channel_id); 320 if (!channel) { 321 return -1; 322 } 323 return channel->SetVoiceChannel(audio_channel_id, voice_sync_interface_); 324 } 325 326 int ViEChannelManager::DisconnectVoiceChannel(int channel_id) { 327 CriticalSectionScoped cs(channel_id_critsect_); 328 ViEChannel* channel = ViEChannelPtr(channel_id); 329 if (channel) { 330 channel->SetVoiceChannel(-1, NULL); 331 return 0; 332 } 333 return -1; 334 } 335 336 VoiceEngine* ViEChannelManager::GetVoiceEngine() { 337 CriticalSectionScoped cs(channel_id_critsect_); 338 return voice_engine_; 339 } 340 341 bool ViEChannelManager::SetRembStatus(int channel_id, bool sender, 342 bool receiver) { 343 CriticalSectionScoped cs(channel_id_critsect_); 344 ChannelGroup* group = FindGroup(channel_id); 345 if (!group) { 346 return false; 347 } 348 ViEChannel* channel = ViEChannelPtr(channel_id); 349 assert(channel); 350 351 return group->SetChannelRembStatus(channel_id, sender, receiver, channel); 352 } 353 354 bool ViEChannelManager::SetReservedTransmitBitrate( 355 int channel_id, uint32_t reserved_transmit_bitrate_bps) { 356 CriticalSectionScoped cs(channel_id_critsect_); 357 ChannelGroup* group = FindGroup(channel_id); 358 if (!group) { 359 return false; 360 } 361 362 BitrateController* bitrate_controller = group->GetBitrateController(); 363 bitrate_controller->SetReservedBitrate(reserved_transmit_bitrate_bps); 364 return true; 365 } 366 367 void ViEChannelManager::UpdateSsrcs(int channel_id, 368 const std::list<unsigned int>& ssrcs) { 369 CriticalSectionScoped cs(channel_id_critsect_); 370 ChannelGroup* channel_group = FindGroup(channel_id); 371 if (channel_group == NULL) { 372 return; 373 } 374 ViEEncoder* encoder = ViEEncoderPtr(channel_id); 375 assert(encoder); 376 377 EncoderStateFeedback* encoder_state_feedback = 378 channel_group->GetEncoderStateFeedback(); 379 // Remove a possible previous setting for this encoder before adding the new 380 // setting. 381 encoder_state_feedback->RemoveEncoder(encoder); 382 for (std::list<unsigned int>::const_iterator it = ssrcs.begin(); 383 it != ssrcs.end(); ++it) { 384 encoder_state_feedback->AddEncoder(*it, encoder); 385 } 386 } 387 388 bool ViEChannelManager::SetBandwidthEstimationConfig( 389 int channel_id, const webrtc::Config& config) { 390 CriticalSectionScoped cs(channel_id_critsect_); 391 ChannelGroup* group = FindGroup(channel_id); 392 if (!group) { 393 return false; 394 } 395 group->SetBandwidthEstimationConfig(config); 396 return true; 397 } 398 399 bool ViEChannelManager::GetEstimatedSendBandwidth( 400 int channel_id, uint32_t* estimated_bandwidth) const { 401 CriticalSectionScoped cs(channel_id_critsect_); 402 ChannelGroup* group = FindGroup(channel_id); 403 if (!group) { 404 return false; 405 } 406 group->GetBitrateController()->AvailableBandwidth(estimated_bandwidth); 407 return true; 408 } 409 410 bool ViEChannelManager::GetEstimatedReceiveBandwidth( 411 int channel_id, uint32_t* estimated_bandwidth) const { 412 CriticalSectionScoped cs(channel_id_critsect_); 413 ChannelGroup* group = FindGroup(channel_id); 414 if (!group) { 415 return false; 416 } 417 std::vector<unsigned int> ssrcs; 418 if (!group->GetRemoteBitrateEstimator()->LatestEstimate( 419 &ssrcs, estimated_bandwidth) || ssrcs.empty()) { 420 *estimated_bandwidth = 0; 421 } 422 return true; 423 } 424 425 bool ViEChannelManager::CreateChannelObject( 426 int channel_id, 427 ViEEncoder* vie_encoder, 428 RtcpBandwidthObserver* bandwidth_observer, 429 RemoteBitrateEstimator* remote_bitrate_estimator, 430 RtcpRttStats* rtcp_rtt_stats, 431 RtcpIntraFrameObserver* intra_frame_observer, 432 bool sender) { 433 PacedSender* paced_sender = vie_encoder->GetPacedSender(); 434 435 // Register the channel at the encoder. 436 RtpRtcp* send_rtp_rtcp_module = vie_encoder->SendRtpRtcpModule(); 437 438 ViEChannel* vie_channel = new ViEChannel(channel_id, engine_id_, 439 number_of_cores_, 440 engine_config_, 441 *module_process_thread_, 442 intra_frame_observer, 443 bandwidth_observer, 444 remote_bitrate_estimator, 445 rtcp_rtt_stats, 446 paced_sender, 447 send_rtp_rtcp_module, 448 sender); 449 if (vie_channel->Init() != 0) { 450 delete vie_channel; 451 return false; 452 } 453 VideoCodec encoder; 454 if (vie_encoder->GetEncoder(&encoder) != 0) { 455 delete vie_channel; 456 return false; 457 } 458 if (sender && vie_channel->SetSendCodec(encoder) != 0) { 459 delete vie_channel; 460 return false; 461 } 462 // Store the channel, add it to the channel group and save the vie_encoder. 463 channel_map_[channel_id] = vie_channel; 464 vie_encoder_map_[channel_id] = vie_encoder; 465 return true; 466 } 467 468 ViEChannel* ViEChannelManager::ViEChannelPtr(int channel_id) const { 469 CriticalSectionScoped cs(channel_id_critsect_); 470 ChannelMap::const_iterator it = channel_map_.find(channel_id); 471 if (it == channel_map_.end()) { 472 LOG(LS_ERROR) << "Channel doesn't exist " << channel_id; 473 return NULL; 474 } 475 return it->second; 476 } 477 478 ViEEncoder* ViEChannelManager::ViEEncoderPtr(int video_channel_id) const { 479 CriticalSectionScoped cs(channel_id_critsect_); 480 EncoderMap::const_iterator it = vie_encoder_map_.find(video_channel_id); 481 if (it == vie_encoder_map_.end()) { 482 return NULL; 483 } 484 return it->second; 485 } 486 487 int ViEChannelManager::FreeChannelId() { 488 int idx = 0; 489 while (idx < free_channel_ids_size_) { 490 if (free_channel_ids_[idx] == true) { 491 // We've found a free id, allocate it and return. 492 free_channel_ids_[idx] = false; 493 return idx + kViEChannelIdBase; 494 } 495 idx++; 496 } 497 LOG(LS_ERROR) << "Max number of channels reached."; 498 return -1; 499 } 500 501 void ViEChannelManager::ReturnChannelId(int channel_id) { 502 CriticalSectionScoped cs(channel_id_critsect_); 503 assert(channel_id < kViEMaxNumberOfChannels + kViEChannelIdBase && 504 channel_id >= kViEChannelIdBase); 505 free_channel_ids_[channel_id - kViEChannelIdBase] = true; 506 } 507 508 ChannelGroup* ViEChannelManager::FindGroup(int channel_id) const { 509 for (ChannelGroups::const_iterator it = channel_groups_.begin(); 510 it != channel_groups_.end(); ++it) { 511 if ((*it)->HasChannel(channel_id)) { 512 return *it; 513 } 514 } 515 return NULL; 516 } 517 518 bool ViEChannelManager::ChannelUsingViEEncoder(int channel_id) const { 519 CriticalSectionScoped cs(channel_id_critsect_); 520 EncoderMap::const_iterator orig_it = vie_encoder_map_.find(channel_id); 521 if (orig_it == vie_encoder_map_.end()) { 522 // No ViEEncoder for this channel. 523 return false; 524 } 525 526 // Loop through all other channels to see if anyone points at the same 527 // ViEEncoder. 528 for (EncoderMap::const_iterator comp_it = vie_encoder_map_.begin(); 529 comp_it != vie_encoder_map_.end(); ++comp_it) { 530 // Make sure we're not comparing the same channel with itself. 531 if (comp_it->first != channel_id) { 532 if (comp_it->second == orig_it->second) { 533 return true; 534 } 535 } 536 } 537 return false; 538 } 539 540 void ViEChannelManager::ChannelsUsingViEEncoder(int channel_id, 541 ChannelList* channels) const { 542 CriticalSectionScoped cs(channel_id_critsect_); 543 EncoderMap::const_iterator orig_it = vie_encoder_map_.find(channel_id); 544 545 for (ChannelMap::const_iterator c_it = channel_map_.begin(); 546 c_it != channel_map_.end(); ++c_it) { 547 EncoderMap::const_iterator comp_it = vie_encoder_map_.find(c_it->first); 548 assert(comp_it != vie_encoder_map_.end()); 549 if (comp_it->second == orig_it->second) { 550 channels->push_back(c_it->second); 551 } 552 } 553 } 554 555 ViEChannelManagerScoped::ViEChannelManagerScoped( 556 const ViEChannelManager& vie_channel_manager) 557 : ViEManagerScopedBase(vie_channel_manager) { 558 } 559 560 ViEChannel* ViEChannelManagerScoped::Channel(int vie_channel_id) const { 561 return static_cast<const ViEChannelManager*>(vie_manager_)->ViEChannelPtr( 562 vie_channel_id); 563 } 564 ViEEncoder* ViEChannelManagerScoped::Encoder(int vie_channel_id) const { 565 return static_cast<const ViEChannelManager*>(vie_manager_)->ViEEncoderPtr( 566 vie_channel_id); 567 } 568 569 bool ViEChannelManagerScoped::ChannelUsingViEEncoder(int channel_id) const { 570 return (static_cast<const ViEChannelManager*>(vie_manager_))-> 571 ChannelUsingViEEncoder(channel_id); 572 } 573 574 void ViEChannelManagerScoped::ChannelsUsingViEEncoder( 575 int channel_id, ChannelList* channels) const { 576 (static_cast<const ViEChannelManager*>(vie_manager_))-> 577 ChannelsUsingViEEncoder(channel_id, channels); 578 } 579 580 } // namespace webrtc 581