• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ViEChannelManager(int engine_id,int number_of_cores,const Config & config)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 
~ViEChannelManager()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 
SetModuleProcessThread(ProcessThread * module_process_thread)71 void ViEChannelManager::SetModuleProcessThread(
72     ProcessThread* module_process_thread) {
73   assert(!module_process_thread_);
74   module_process_thread_ = module_process_thread;
75 }
76 
CreateChannel(int * channel_id,const Config * channel_group_config)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 
CreateChannel(int * channel_id,int original_channel,bool sender)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 
DeleteChannel(int channel_id)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 
SetVoiceEngine(VoiceEngine * voice_engine)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 
ConnectVoiceChannel(int channel_id,int audio_channel_id)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 
DisconnectVoiceChannel(int channel_id)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 
GetVoiceEngine()336 VoiceEngine* ViEChannelManager::GetVoiceEngine() {
337   CriticalSectionScoped cs(channel_id_critsect_);
338   return voice_engine_;
339 }
340 
SetRembStatus(int channel_id,bool sender,bool receiver)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 
SetReservedTransmitBitrate(int channel_id,uint32_t reserved_transmit_bitrate_bps)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 
UpdateSsrcs(int channel_id,const std::list<unsigned int> & ssrcs)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 
SetBandwidthEstimationConfig(int channel_id,const webrtc::Config & config)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 
GetEstimatedSendBandwidth(int channel_id,uint32_t * estimated_bandwidth) const399 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 
GetEstimatedReceiveBandwidth(int channel_id,uint32_t * estimated_bandwidth) const410 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 
CreateChannelObject(int channel_id,ViEEncoder * vie_encoder,RtcpBandwidthObserver * bandwidth_observer,RemoteBitrateEstimator * remote_bitrate_estimator,RtcpRttStats * rtcp_rtt_stats,RtcpIntraFrameObserver * intra_frame_observer,bool sender)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 
ViEChannelPtr(int channel_id) const468 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 
ViEEncoderPtr(int video_channel_id) const478 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 
FreeChannelId()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 
ReturnChannelId(int channel_id)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 
FindGroup(int channel_id) const508 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 
ChannelUsingViEEncoder(int channel_id) const518 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 
ChannelsUsingViEEncoder(int channel_id,ChannelList * channels) const540 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 
ViEChannelManagerScoped(const ViEChannelManager & vie_channel_manager)555 ViEChannelManagerScoped::ViEChannelManagerScoped(
556     const ViEChannelManager& vie_channel_manager)
557     : ViEManagerScopedBase(vie_channel_manager) {
558 }
559 
Channel(int vie_channel_id) const560 ViEChannel* ViEChannelManagerScoped::Channel(int vie_channel_id) const {
561   return static_cast<const ViEChannelManager*>(vie_manager_)->ViEChannelPtr(
562       vie_channel_id);
563 }
Encoder(int vie_channel_id) const564 ViEEncoder* ViEChannelManagerScoped::Encoder(int vie_channel_id) const {
565   return static_cast<const ViEChannelManager*>(vie_manager_)->ViEEncoderPtr(
566       vie_channel_id);
567 }
568 
ChannelUsingViEEncoder(int channel_id) const569 bool ViEChannelManagerScoped::ChannelUsingViEEncoder(int channel_id) const {
570   return (static_cast<const ViEChannelManager*>(vie_manager_))->
571       ChannelUsingViEEncoder(channel_id);
572 }
573 
ChannelsUsingViEEncoder(int channel_id,ChannelList * channels) const574 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