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