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
27namespace webrtc {
28
29ViEChannelManager::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
47ViEChannelManager::~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
71void ViEChannelManager::SetModuleProcessThread(
72    ProcessThread* module_process_thread) {
73  assert(!module_process_thread_);
74  module_process_thread_ = module_process_thread;
75}
76
77int 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
135int 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
208int 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
285int 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
312int 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
326int 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
336VoiceEngine* ViEChannelManager::GetVoiceEngine() {
337  CriticalSectionScoped cs(channel_id_critsect_);
338  return voice_engine_;
339}
340
341bool 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
354bool 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
367void 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
388bool 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
399bool 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
410bool 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
425bool 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
468ViEChannel* 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
478ViEEncoder* 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
487int 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
501void 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
508ChannelGroup* 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
518bool 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
540void 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
555ViEChannelManagerScoped::ViEChannelManagerScoped(
556    const ViEChannelManager& vie_channel_manager)
557    : ViEManagerScopedBase(vie_channel_manager) {
558}
559
560ViEChannel* ViEChannelManagerScoped::Channel(int vie_channel_id) const {
561  return static_cast<const ViEChannelManager*>(vie_manager_)->ViEChannelPtr(
562      vie_channel_id);
563}
564ViEEncoder* ViEChannelManagerScoped::Encoder(int vie_channel_id) const {
565  return static_cast<const ViEChannelManager*>(vie_manager_)->ViEEncoderPtr(
566      vie_channel_id);
567}
568
569bool ViEChannelManagerScoped::ChannelUsingViEEncoder(int channel_id) const {
570  return (static_cast<const ViEChannelManager*>(vie_manager_))->
571      ChannelUsingViEEncoder(channel_id);
572}
573
574void 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