Home | History | Annotate | Download | only in video_engine
      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