• 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.h"
12 
13 #include <algorithm>
14 #include <vector>
15 
16 #include "webrtc/common.h"
17 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
18 #include "webrtc/experiments.h"
19 #include "webrtc/modules/pacing/include/paced_sender.h"
20 #include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
21 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
22 #include "webrtc/modules/utility/interface/process_thread.h"
23 #include "webrtc/modules/video_coding/main/interface/video_coding.h"
24 #include "webrtc/modules/video_processing/main/interface/video_processing.h"
25 #include "webrtc/modules/video_render/include/video_render_defines.h"
26 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
27 #include "webrtc/system_wrappers/interface/logging.h"
28 #include "webrtc/system_wrappers/interface/thread_wrapper.h"
29 #include "webrtc/video_engine/call_stats.h"
30 #include "webrtc/video_engine/include/vie_codec.h"
31 #include "webrtc/video_engine/include/vie_errors.h"
32 #include "webrtc/video_engine/include/vie_image_process.h"
33 #include "webrtc/video_engine/include/vie_rtp_rtcp.h"
34 #include "webrtc/frame_callback.h"
35 #include "webrtc/video_engine/vie_defines.h"
36 
37 namespace webrtc {
38 
39 const int kMaxDecodeWaitTimeMs = 50;
40 const int kInvalidRtpExtensionId = 0;
41 static const int kMaxTargetDelayMs = 10000;
42 static const float kMaxIncompleteTimeMultiplier = 3.5f;
43 
44 namespace {
45 
AggregateReportBlocks(const std::vector<RTCPReportBlock> & report_blocks,std::map<uint32_t,RTCPReportBlock> * prev_report_blocks)46 RTCPReportBlock AggregateReportBlocks(
47     const std::vector<RTCPReportBlock>& report_blocks,
48     std::map<uint32_t, RTCPReportBlock>* prev_report_blocks) {
49   int fraction_lost_sum = 0;
50   int fl_seq_num_sum = 0;
51   int jitter_sum = 0;
52   int number_of_report_blocks = 0;
53   RTCPReportBlock aggregate;
54   std::vector<RTCPReportBlock>::const_iterator report_block =
55       report_blocks.begin();
56   for (; report_block != report_blocks.end(); ++report_block) {
57     aggregate.cumulativeLost += report_block->cumulativeLost;
58     std::map<uint32_t, RTCPReportBlock>::iterator prev_report_block =
59         prev_report_blocks->find(report_block->sourceSSRC);
60     if (prev_report_block != prev_report_blocks->end()) {
61       // Skip the first report block since we won't be able to get a correct
62       // weight for it.
63       int seq_num_diff = report_block->extendedHighSeqNum -
64                          prev_report_block->second.extendedHighSeqNum;
65       if (seq_num_diff > 0) {
66         fraction_lost_sum += report_block->fractionLost * seq_num_diff;
67         fl_seq_num_sum += seq_num_diff;
68       }
69     }
70     jitter_sum += report_block->jitter;
71     ++number_of_report_blocks;
72     (*prev_report_blocks)[report_block->sourceSSRC] = *report_block;
73   }
74   if (fl_seq_num_sum > 0) {
75     aggregate.fractionLost =
76         (fraction_lost_sum + fl_seq_num_sum / 2) / fl_seq_num_sum;
77   }
78   if (number_of_report_blocks > 0) {
79     aggregate.jitter =
80         (jitter_sum + number_of_report_blocks / 2) / number_of_report_blocks;
81   }
82   // Not well defined for aggregated report blocks.
83   aggregate.extendedHighSeqNum = 0;
84   return aggregate;
85 }
86 }  // namespace
87 
88 // Helper class receiving statistics callbacks.
89 class ChannelStatsObserver : public CallStatsObserver {
90  public:
ChannelStatsObserver(ViEChannel * owner)91   explicit ChannelStatsObserver(ViEChannel* owner) : owner_(owner) {}
~ChannelStatsObserver()92   virtual ~ChannelStatsObserver() {}
93 
94   // Implements StatsObserver.
OnRttUpdate(uint32_t rtt)95   virtual void OnRttUpdate(uint32_t rtt) {
96     owner_->OnRttUpdate(rtt);
97   }
98 
99  private:
100   ViEChannel* owner_;
101 };
102 
ViEChannel(int32_t channel_id,int32_t engine_id,uint32_t number_of_cores,const Config & config,ProcessThread & module_process_thread,RtcpIntraFrameObserver * intra_frame_observer,RtcpBandwidthObserver * bandwidth_observer,RemoteBitrateEstimator * remote_bitrate_estimator,RtcpRttStats * rtt_stats,PacedSender * paced_sender,RtpRtcp * default_rtp_rtcp,bool sender)103 ViEChannel::ViEChannel(int32_t channel_id,
104                        int32_t engine_id,
105                        uint32_t number_of_cores,
106                        const Config& config,
107                        ProcessThread& module_process_thread,
108                        RtcpIntraFrameObserver* intra_frame_observer,
109                        RtcpBandwidthObserver* bandwidth_observer,
110                        RemoteBitrateEstimator* remote_bitrate_estimator,
111                        RtcpRttStats* rtt_stats,
112                        PacedSender* paced_sender,
113                        RtpRtcp* default_rtp_rtcp,
114                        bool sender)
115     : ViEFrameProviderBase(channel_id, engine_id),
116       channel_id_(channel_id),
117       engine_id_(engine_id),
118       number_of_cores_(number_of_cores),
119       num_socket_threads_(kViESocketThreads),
120       callback_cs_(CriticalSectionWrapper::CreateCriticalSection()),
121       rtp_rtcp_cs_(CriticalSectionWrapper::CreateCriticalSection()),
122       default_rtp_rtcp_(default_rtp_rtcp),
123       vcm_(VideoCodingModule::Create()),
124       vie_receiver_(channel_id, vcm_, remote_bitrate_estimator, this),
125       vie_sender_(channel_id),
126       vie_sync_(vcm_, this),
127       stats_observer_(new ChannelStatsObserver(this)),
128       module_process_thread_(module_process_thread),
129       codec_observer_(NULL),
130       do_key_frame_callbackRequest_(false),
131       rtp_observer_(NULL),
132       rtcp_observer_(NULL),
133       intra_frame_observer_(intra_frame_observer),
134       rtt_stats_(rtt_stats),
135       paced_sender_(paced_sender),
136       pad_with_redundant_payloads_(false),
137       bandwidth_observer_(bandwidth_observer),
138       send_timestamp_extension_id_(kInvalidRtpExtensionId),
139       absolute_send_time_extension_id_(kInvalidRtpExtensionId),
140       external_transport_(NULL),
141       decoder_reset_(true),
142       wait_for_key_frame_(false),
143       decode_thread_(NULL),
144       effect_filter_(NULL),
145       color_enhancement_(false),
146       mtu_(0),
147       sender_(sender),
148       nack_history_size_sender_(kSendSidePacketHistorySize),
149       max_nack_reordering_threshold_(kMaxPacketAgeToNack),
150       pre_render_callback_(NULL) {
151   RtpRtcp::Configuration configuration;
152   configuration.id = ViEModuleId(engine_id, channel_id);
153   configuration.audio = false;
154   configuration.default_module = default_rtp_rtcp;
155   configuration.outgoing_transport = &vie_sender_;
156   configuration.rtcp_feedback = this;
157   configuration.intra_frame_callback = intra_frame_observer;
158   configuration.bandwidth_callback = bandwidth_observer;
159   configuration.rtt_stats = rtt_stats;
160   configuration.remote_bitrate_estimator = remote_bitrate_estimator;
161   configuration.paced_sender = paced_sender;
162   configuration.receive_statistics = vie_receiver_.GetReceiveStatistics();
163   configuration.send_bitrate_observer = &send_bitrate_observer_;
164   configuration.send_frame_count_observer = &send_frame_count_observer_;
165   configuration.send_side_delay_observer = &send_side_delay_observer_;
166 
167   rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(configuration));
168   vie_receiver_.SetRtpRtcpModule(rtp_rtcp_.get());
169   vcm_->SetNackSettings(kMaxNackListSize, max_nack_reordering_threshold_, 0);
170 }
171 
Init()172 int32_t ViEChannel::Init() {
173   if (module_process_thread_.RegisterModule(
174       vie_receiver_.GetReceiveStatistics()) != 0) {
175     return -1;
176   }
177   // RTP/RTCP initialization.
178   if (rtp_rtcp_->SetSendingMediaStatus(false) != 0) {
179     return -1;
180   }
181   if (module_process_thread_.RegisterModule(rtp_rtcp_.get()) != 0) {
182     return -1;
183   }
184   rtp_rtcp_->SetKeyFrameRequestMethod(kKeyFrameReqFirRtp);
185   rtp_rtcp_->SetRTCPStatus(kRtcpCompound);
186   if (paced_sender_) {
187     rtp_rtcp_->SetStorePacketsStatus(true, nack_history_size_sender_);
188   }
189   if (vcm_->InitializeReceiver() != 0) {
190     return -1;
191   }
192   if (vcm_->SetVideoProtection(kProtectionKeyOnLoss, true)) {
193     return -1;
194   }
195   if (vcm_->RegisterReceiveCallback(this) != 0) {
196     return -1;
197   }
198   vcm_->RegisterFrameTypeCallback(this);
199   vcm_->RegisterReceiveStatisticsCallback(this);
200   vcm_->RegisterDecoderTimingCallback(this);
201   vcm_->SetRenderDelay(kViEDefaultRenderDelayMs);
202   if (module_process_thread_.RegisterModule(vcm_) != 0) {
203     return -1;
204   }
205 #ifdef VIDEOCODEC_VP8
206   VideoCodec video_codec;
207   if (vcm_->Codec(kVideoCodecVP8, &video_codec) == VCM_OK) {
208     rtp_rtcp_->RegisterSendPayload(video_codec);
209     // TODO(holmer): Can we call SetReceiveCodec() here instead?
210     if (!vie_receiver_.RegisterPayload(video_codec)) {
211       return -1;
212     }
213     vcm_->RegisterReceiveCodec(&video_codec, number_of_cores_);
214     vcm_->RegisterSendCodec(&video_codec, number_of_cores_,
215                            rtp_rtcp_->MaxDataPayloadLength());
216   } else {
217     assert(false);
218   }
219 #endif
220 
221   return 0;
222 }
223 
~ViEChannel()224 ViEChannel::~ViEChannel() {
225   // Make sure we don't get more callbacks from the RTP module.
226   module_process_thread_.DeRegisterModule(vie_receiver_.GetReceiveStatistics());
227   module_process_thread_.DeRegisterModule(rtp_rtcp_.get());
228   module_process_thread_.DeRegisterModule(vcm_);
229   module_process_thread_.DeRegisterModule(&vie_sync_);
230   while (simulcast_rtp_rtcp_.size() > 0) {
231     std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
232     RtpRtcp* rtp_rtcp = *it;
233     module_process_thread_.DeRegisterModule(rtp_rtcp);
234     delete rtp_rtcp;
235     simulcast_rtp_rtcp_.erase(it);
236   }
237   while (removed_rtp_rtcp_.size() > 0) {
238     std::list<RtpRtcp*>::iterator it = removed_rtp_rtcp_.begin();
239     delete *it;
240     removed_rtp_rtcp_.erase(it);
241   }
242   if (decode_thread_) {
243     StopDecodeThread();
244   }
245   // Release modules.
246   VideoCodingModule::Destroy(vcm_);
247 }
248 
SetSendCodec(const VideoCodec & video_codec,bool new_stream)249 int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
250                                  bool new_stream) {
251   if (!sender_) {
252     return 0;
253   }
254   if (video_codec.codecType == kVideoCodecRED ||
255       video_codec.codecType == kVideoCodecULPFEC) {
256     LOG_F(LS_ERROR) << "Not a valid send codec " << video_codec.codecType;
257     return -1;
258   }
259   if (kMaxSimulcastStreams < video_codec.numberOfSimulcastStreams) {
260     LOG_F(LS_ERROR) << "Incorrect config "
261                     << video_codec.numberOfSimulcastStreams;
262     return -1;
263   }
264   // Update the RTP module with the settings.
265   // Stop and Start the RTP module -> trigger new SSRC, if an SSRC hasn't been
266   // set explicitly.
267   bool restart_rtp = false;
268   if (rtp_rtcp_->Sending() && new_stream) {
269     restart_rtp = true;
270     rtp_rtcp_->SetSendingStatus(false);
271     for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
272          it != simulcast_rtp_rtcp_.end(); ++it) {
273       (*it)->SetSendingStatus(false);
274       (*it)->SetSendingMediaStatus(false);
275     }
276   }
277 
278   bool fec_enabled = false;
279   uint8_t payload_type_red;
280   uint8_t payload_type_fec;
281   rtp_rtcp_->GenericFECStatus(fec_enabled, payload_type_red, payload_type_fec);
282 
283   CriticalSectionScoped cs(rtp_rtcp_cs_.get());
284 
285   if (video_codec.numberOfSimulcastStreams > 0) {
286     // Set correct bitrate to base layer.
287     // Create our simulcast RTP modules.
288     int num_modules_to_add = video_codec.numberOfSimulcastStreams -
289         simulcast_rtp_rtcp_.size() - 1;
290     if (num_modules_to_add < 0) {
291       num_modules_to_add = 0;
292     }
293 
294     // Add back removed rtp modules. Order is important (allocate from front of
295     // removed modules) to preserve RTP settings such as SSRCs for simulcast
296     // streams.
297     std::list<RtpRtcp*> new_rtp_modules;
298     for (; removed_rtp_rtcp_.size() > 0 && num_modules_to_add > 0;
299          --num_modules_to_add) {
300       new_rtp_modules.push_back(removed_rtp_rtcp_.front());
301       removed_rtp_rtcp_.pop_front();
302     }
303 
304     for (int i = 0; i < num_modules_to_add; ++i)
305       new_rtp_modules.push_back(CreateRtpRtcpModule());
306 
307     // Initialize newly added modules.
308     for (std::list<RtpRtcp*>::iterator it = new_rtp_modules.begin();
309          it != new_rtp_modules.end();
310          ++it) {
311       RtpRtcp* rtp_rtcp = *it;
312 
313       rtp_rtcp->SetRTCPStatus(rtp_rtcp_->RTCP());
314 
315       if (rtp_rtcp_->StorePackets()) {
316         rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
317       } else if (paced_sender_) {
318         rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
319       }
320 
321       if (fec_enabled) {
322         rtp_rtcp->SetGenericFECStatus(
323             fec_enabled, payload_type_red, payload_type_fec);
324       }
325       rtp_rtcp->SetSendingStatus(rtp_rtcp_->Sending());
326       rtp_rtcp->SetSendingMediaStatus(rtp_rtcp_->SendingMedia());
327 
328       int mode;
329       uint32_t ssrc;
330       int payload_type;
331       rtp_rtcp_->RTXSendStatus(&mode, &ssrc, &payload_type);
332       rtp_rtcp->SetRTXSendStatus(mode);
333       simulcast_rtp_rtcp_.push_back(rtp_rtcp);
334 
335       // Silently ignore error.
336       module_process_thread_.RegisterModule(rtp_rtcp);
337     }
338 
339     // Remove last in list if we have too many.
340     for (int j = simulcast_rtp_rtcp_.size();
341          j > (video_codec.numberOfSimulcastStreams - 1);
342          j--) {
343       RtpRtcp* rtp_rtcp = simulcast_rtp_rtcp_.back();
344       module_process_thread_.DeRegisterModule(rtp_rtcp);
345       rtp_rtcp->SetSendingStatus(false);
346       rtp_rtcp->SetSendingMediaStatus(false);
347       rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback(NULL);
348       rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL);
349       simulcast_rtp_rtcp_.pop_back();
350       removed_rtp_rtcp_.push_front(rtp_rtcp);
351     }
352     uint8_t idx = 0;
353     // Configure all simulcast modules.
354     for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
355          it != simulcast_rtp_rtcp_.end();
356          it++) {
357       idx++;
358       RtpRtcp* rtp_rtcp = *it;
359       rtp_rtcp->DeRegisterSendPayload(video_codec.plType);
360       if (rtp_rtcp->RegisterSendPayload(video_codec) != 0) {
361         return -1;
362       }
363       if (mtu_ != 0) {
364         rtp_rtcp->SetMaxTransferUnit(mtu_);
365       }
366       if (restart_rtp) {
367         rtp_rtcp->SetSendingStatus(true);
368         rtp_rtcp->SetSendingMediaStatus(true);
369       }
370       if (send_timestamp_extension_id_ != kInvalidRtpExtensionId) {
371         // Deregister in case the extension was previously enabled.
372         rtp_rtcp->DeregisterSendRtpHeaderExtension(
373             kRtpExtensionTransmissionTimeOffset);
374         if (rtp_rtcp->RegisterSendRtpHeaderExtension(
375             kRtpExtensionTransmissionTimeOffset,
376             send_timestamp_extension_id_) != 0) {
377         }
378       } else {
379         rtp_rtcp->DeregisterSendRtpHeaderExtension(
380             kRtpExtensionTransmissionTimeOffset);
381       }
382       if (absolute_send_time_extension_id_ != kInvalidRtpExtensionId) {
383         // Deregister in case the extension was previously enabled.
384         rtp_rtcp->DeregisterSendRtpHeaderExtension(
385             kRtpExtensionAbsoluteSendTime);
386         if (rtp_rtcp->RegisterSendRtpHeaderExtension(
387             kRtpExtensionAbsoluteSendTime,
388             absolute_send_time_extension_id_) != 0) {
389         }
390       } else {
391         rtp_rtcp->DeregisterSendRtpHeaderExtension(
392             kRtpExtensionAbsoluteSendTime);
393       }
394       rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback(
395           rtp_rtcp_->GetSendChannelRtcpStatisticsCallback());
396       rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(
397           rtp_rtcp_->GetSendChannelRtpStatisticsCallback());
398     }
399     // |RegisterSimulcastRtpRtcpModules| resets all old weak pointers and old
400     // modules can be deleted after this step.
401     vie_receiver_.RegisterSimulcastRtpRtcpModules(simulcast_rtp_rtcp_);
402   } else {
403     while (!simulcast_rtp_rtcp_.empty()) {
404       RtpRtcp* rtp_rtcp = simulcast_rtp_rtcp_.back();
405       module_process_thread_.DeRegisterModule(rtp_rtcp);
406       rtp_rtcp->SetSendingStatus(false);
407       rtp_rtcp->SetSendingMediaStatus(false);
408       rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback(NULL);
409       rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL);
410       simulcast_rtp_rtcp_.pop_back();
411       removed_rtp_rtcp_.push_front(rtp_rtcp);
412     }
413     // Clear any previous modules.
414     vie_receiver_.RegisterSimulcastRtpRtcpModules(simulcast_rtp_rtcp_);
415   }
416 
417   // Don't log this error, no way to check in advance if this pl_type is
418   // registered or not...
419   rtp_rtcp_->DeRegisterSendPayload(video_codec.plType);
420   if (rtp_rtcp_->RegisterSendPayload(video_codec) != 0) {
421     return -1;
422   }
423   if (restart_rtp) {
424     rtp_rtcp_->SetSendingStatus(true);
425     for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
426          it != simulcast_rtp_rtcp_.end(); ++it) {
427       (*it)->SetSendingStatus(true);
428       (*it)->SetSendingMediaStatus(true);
429     }
430   }
431   return 0;
432 }
433 
SetReceiveCodec(const VideoCodec & video_codec)434 int32_t ViEChannel::SetReceiveCodec(const VideoCodec& video_codec) {
435   if (!vie_receiver_.SetReceiveCodec(video_codec)) {
436     return -1;
437   }
438 
439   if (video_codec.codecType != kVideoCodecRED &&
440       video_codec.codecType != kVideoCodecULPFEC) {
441     // Register codec type with VCM, but do not register RED or ULPFEC.
442     if (vcm_->RegisterReceiveCodec(&video_codec, number_of_cores_,
443                                   wait_for_key_frame_) != VCM_OK) {
444       return -1;
445     }
446   }
447   return 0;
448 }
449 
GetReceiveCodec(VideoCodec * video_codec)450 int32_t ViEChannel::GetReceiveCodec(VideoCodec* video_codec) {
451   if (vcm_->ReceiveCodec(video_codec) != 0) {
452     return -1;
453   }
454   return 0;
455 }
456 
RegisterCodecObserver(ViEDecoderObserver * observer)457 int32_t ViEChannel::RegisterCodecObserver(ViEDecoderObserver* observer) {
458   CriticalSectionScoped cs(callback_cs_.get());
459   if (observer) {
460     if (codec_observer_) {
461       LOG_F(LS_ERROR) << "Observer already registered.";
462       return -1;
463     }
464     codec_observer_ = observer;
465   } else {
466     codec_observer_ = NULL;
467   }
468   return 0;
469 }
470 
RegisterExternalDecoder(const uint8_t pl_type,VideoDecoder * decoder,bool buffered_rendering,int32_t render_delay)471 int32_t ViEChannel::RegisterExternalDecoder(const uint8_t pl_type,
472                                             VideoDecoder* decoder,
473                                             bool buffered_rendering,
474                                             int32_t render_delay) {
475   int32_t result;
476   result = vcm_->RegisterExternalDecoder(decoder, pl_type, buffered_rendering);
477   if (result != VCM_OK) {
478     return result;
479   }
480   return vcm_->SetRenderDelay(render_delay);
481 }
482 
DeRegisterExternalDecoder(const uint8_t pl_type)483 int32_t ViEChannel::DeRegisterExternalDecoder(const uint8_t pl_type) {
484   VideoCodec current_receive_codec;
485   int32_t result = 0;
486   result = vcm_->ReceiveCodec(&current_receive_codec);
487   if (vcm_->RegisterExternalDecoder(NULL, pl_type, false) != VCM_OK) {
488     return -1;
489   }
490 
491   if (result == 0 && current_receive_codec.plType == pl_type) {
492     result = vcm_->RegisterReceiveCodec(
493         &current_receive_codec, number_of_cores_, wait_for_key_frame_);
494   }
495   return result;
496 }
497 
ReceiveCodecStatistics(uint32_t * num_key_frames,uint32_t * num_delta_frames)498 int32_t ViEChannel::ReceiveCodecStatistics(uint32_t* num_key_frames,
499                                            uint32_t* num_delta_frames) {
500   VCMFrameCount received_frames;
501   if (vcm_->ReceivedFrameCount(received_frames) != VCM_OK) {
502     return -1;
503   }
504   *num_key_frames = received_frames.numKeyFrames;
505   *num_delta_frames = received_frames.numDeltaFrames;
506   return 0;
507 }
508 
DiscardedPackets() const509 uint32_t ViEChannel::DiscardedPackets() const {
510   return vcm_->DiscardedPackets();
511 }
512 
ReceiveDelay() const513 int ViEChannel::ReceiveDelay() const {
514   return vcm_->Delay();
515 }
516 
WaitForKeyFrame(bool wait)517 int32_t ViEChannel::WaitForKeyFrame(bool wait) {
518   wait_for_key_frame_ = wait;
519   return 0;
520 }
521 
SetSignalPacketLossStatus(bool enable,bool only_key_frames)522 int32_t ViEChannel::SetSignalPacketLossStatus(bool enable,
523                                               bool only_key_frames) {
524   if (enable) {
525     if (only_key_frames) {
526       vcm_->SetVideoProtection(kProtectionKeyOnLoss, false);
527       if (vcm_->SetVideoProtection(kProtectionKeyOnKeyLoss, true) != VCM_OK) {
528         return -1;
529       }
530     } else {
531       vcm_->SetVideoProtection(kProtectionKeyOnKeyLoss, false);
532       if (vcm_->SetVideoProtection(kProtectionKeyOnLoss, true) != VCM_OK) {
533         return -1;
534       }
535     }
536   } else {
537     vcm_->SetVideoProtection(kProtectionKeyOnLoss, false);
538     vcm_->SetVideoProtection(kProtectionKeyOnKeyLoss, false);
539   }
540   return 0;
541 }
542 
SetRTCPMode(const RTCPMethod rtcp_mode)543 int32_t ViEChannel::SetRTCPMode(const RTCPMethod rtcp_mode) {
544   CriticalSectionScoped cs(rtp_rtcp_cs_.get());
545   for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
546        it != simulcast_rtp_rtcp_.end();
547        it++) {
548     RtpRtcp* rtp_rtcp = *it;
549     rtp_rtcp->SetRTCPStatus(rtcp_mode);
550   }
551   return rtp_rtcp_->SetRTCPStatus(rtcp_mode);
552 }
553 
GetRTCPMode(RTCPMethod * rtcp_mode)554 int32_t ViEChannel::GetRTCPMode(RTCPMethod* rtcp_mode) {
555   *rtcp_mode = rtp_rtcp_->RTCP();
556   return 0;
557 }
558 
SetNACKStatus(const bool enable)559 int32_t ViEChannel::SetNACKStatus(const bool enable) {
560   // Update the decoding VCM.
561   if (vcm_->SetVideoProtection(kProtectionNack, enable) != VCM_OK) {
562     return -1;
563   }
564   if (enable) {
565     // Disable possible FEC.
566     SetFECStatus(false, 0, 0);
567   }
568   // Update the decoding VCM.
569   if (vcm_->SetVideoProtection(kProtectionNack, enable) != VCM_OK) {
570     return -1;
571   }
572   return ProcessNACKRequest(enable);
573 }
574 
ProcessNACKRequest(const bool enable)575 int32_t ViEChannel::ProcessNACKRequest(const bool enable) {
576   if (enable) {
577     // Turn on NACK.
578     if (rtp_rtcp_->RTCP() == kRtcpOff) {
579       return -1;
580     }
581     vie_receiver_.SetNackStatus(true, max_nack_reordering_threshold_);
582     rtp_rtcp_->SetStorePacketsStatus(true, nack_history_size_sender_);
583     vcm_->RegisterPacketRequestCallback(this);
584 
585     CriticalSectionScoped cs(rtp_rtcp_cs_.get());
586 
587     for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
588          it != simulcast_rtp_rtcp_.end();
589          it++) {
590       RtpRtcp* rtp_rtcp = *it;
591       rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
592     }
593     // Don't introduce errors when NACK is enabled.
594     vcm_->SetDecodeErrorMode(kNoErrors);
595   } else {
596     CriticalSectionScoped cs(rtp_rtcp_cs_.get());
597     for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
598          it != simulcast_rtp_rtcp_.end();
599          it++) {
600       RtpRtcp* rtp_rtcp = *it;
601       if (paced_sender_ == NULL) {
602         rtp_rtcp->SetStorePacketsStatus(false, 0);
603       }
604     }
605     vcm_->RegisterPacketRequestCallback(NULL);
606     if (paced_sender_ == NULL) {
607       rtp_rtcp_->SetStorePacketsStatus(false, 0);
608     }
609     vie_receiver_.SetNackStatus(false, max_nack_reordering_threshold_);
610     // When NACK is off, allow decoding with errors. Otherwise, the video
611     // will freeze, and will only recover with a complete key frame.
612     vcm_->SetDecodeErrorMode(kWithErrors);
613   }
614   return 0;
615 }
616 
SetFECStatus(const bool enable,const unsigned char payload_typeRED,const unsigned char payload_typeFEC)617 int32_t ViEChannel::SetFECStatus(const bool enable,
618                                        const unsigned char payload_typeRED,
619                                        const unsigned char payload_typeFEC) {
620   // Disable possible NACK.
621   if (enable) {
622     SetNACKStatus(false);
623   }
624 
625   return ProcessFECRequest(enable, payload_typeRED, payload_typeFEC);
626 }
627 
ProcessFECRequest(const bool enable,const unsigned char payload_typeRED,const unsigned char payload_typeFEC)628 int32_t ViEChannel::ProcessFECRequest(
629     const bool enable,
630     const unsigned char payload_typeRED,
631     const unsigned char payload_typeFEC) {
632   if (rtp_rtcp_->SetGenericFECStatus(enable, payload_typeRED,
633                                     payload_typeFEC) != 0) {
634     return -1;
635   }
636   CriticalSectionScoped cs(rtp_rtcp_cs_.get());
637   for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
638        it != simulcast_rtp_rtcp_.end();
639        it++) {
640     RtpRtcp* rtp_rtcp = *it;
641     rtp_rtcp->SetGenericFECStatus(enable, payload_typeRED, payload_typeFEC);
642   }
643   return 0;
644 }
645 
SetHybridNACKFECStatus(const bool enable,const unsigned char payload_typeRED,const unsigned char payload_typeFEC)646 int32_t ViEChannel::SetHybridNACKFECStatus(
647     const bool enable,
648     const unsigned char payload_typeRED,
649     const unsigned char payload_typeFEC) {
650   if (vcm_->SetVideoProtection(kProtectionNackFEC, enable) != VCM_OK) {
651     return -1;
652   }
653 
654   int32_t ret_val = 0;
655   ret_val = ProcessNACKRequest(enable);
656   if (ret_val < 0) {
657     return ret_val;
658   }
659   return ProcessFECRequest(enable, payload_typeRED, payload_typeFEC);
660 }
661 
SetSenderBufferingMode(int target_delay_ms)662 int ViEChannel::SetSenderBufferingMode(int target_delay_ms) {
663   if ((target_delay_ms < 0) || (target_delay_ms > kMaxTargetDelayMs)) {
664     LOG(LS_ERROR) << "Invalid send buffer value.";
665     return -1;
666   }
667   if (target_delay_ms == 0) {
668     // Real-time mode.
669     nack_history_size_sender_ = kSendSidePacketHistorySize;
670   } else {
671     nack_history_size_sender_ = GetRequiredNackListSize(target_delay_ms);
672     // Don't allow a number lower than the default value.
673     if (nack_history_size_sender_ < kSendSidePacketHistorySize) {
674       nack_history_size_sender_ = kSendSidePacketHistorySize;
675     }
676   }
677   if (rtp_rtcp_->SetStorePacketsStatus(true, nack_history_size_sender_) != 0) {
678     return -1;
679   }
680   return 0;
681 }
682 
SetReceiverBufferingMode(int target_delay_ms)683 int ViEChannel::SetReceiverBufferingMode(int target_delay_ms) {
684   if ((target_delay_ms < 0) || (target_delay_ms > kMaxTargetDelayMs)) {
685     LOG(LS_ERROR) << "Invalid receive buffer delay value.";
686     return -1;
687   }
688   int max_nack_list_size;
689   int max_incomplete_time_ms;
690   if (target_delay_ms == 0) {
691     // Real-time mode - restore default settings.
692     max_nack_reordering_threshold_ = kMaxPacketAgeToNack;
693     max_nack_list_size = kMaxNackListSize;
694     max_incomplete_time_ms = 0;
695   } else {
696     max_nack_list_size =  3 * GetRequiredNackListSize(target_delay_ms) / 4;
697     max_nack_reordering_threshold_ = max_nack_list_size;
698     // Calculate the max incomplete time and round to int.
699     max_incomplete_time_ms = static_cast<int>(kMaxIncompleteTimeMultiplier *
700         target_delay_ms + 0.5f);
701   }
702   vcm_->SetNackSettings(max_nack_list_size, max_nack_reordering_threshold_,
703                        max_incomplete_time_ms);
704   vcm_->SetMinReceiverDelay(target_delay_ms);
705   if (vie_sync_.SetTargetBufferingDelay(target_delay_ms) < 0)
706     return -1;
707   return 0;
708 }
709 
GetRequiredNackListSize(int target_delay_ms)710 int ViEChannel::GetRequiredNackListSize(int target_delay_ms) {
711   // The max size of the nack list should be large enough to accommodate the
712   // the number of packets (frames) resulting from the increased delay.
713   // Roughly estimating for ~40 packets per frame @ 30fps.
714   return target_delay_ms * 40 * 30 / 1000;
715 }
716 
SetKeyFrameRequestMethod(const KeyFrameRequestMethod method)717 int32_t ViEChannel::SetKeyFrameRequestMethod(
718     const KeyFrameRequestMethod method) {
719   return rtp_rtcp_->SetKeyFrameRequestMethod(method);
720 }
721 
EnableRemb(bool enable)722 bool ViEChannel::EnableRemb(bool enable) {
723   if (rtp_rtcp_->SetREMBStatus(enable) != 0)
724     return false;
725   return true;
726 }
727 
SetSendTimestampOffsetStatus(bool enable,int id)728 int ViEChannel::SetSendTimestampOffsetStatus(bool enable, int id) {
729   CriticalSectionScoped cs(rtp_rtcp_cs_.get());
730   int error = 0;
731   if (enable) {
732     // Enable the extension, but disable possible old id to avoid errors.
733     send_timestamp_extension_id_ = id;
734     rtp_rtcp_->DeregisterSendRtpHeaderExtension(
735         kRtpExtensionTransmissionTimeOffset);
736     error = rtp_rtcp_->RegisterSendRtpHeaderExtension(
737         kRtpExtensionTransmissionTimeOffset, id);
738     for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
739          it != simulcast_rtp_rtcp_.end(); it++) {
740       (*it)->DeregisterSendRtpHeaderExtension(
741           kRtpExtensionTransmissionTimeOffset);
742       error |= (*it)->RegisterSendRtpHeaderExtension(
743           kRtpExtensionTransmissionTimeOffset, id);
744     }
745   } else {
746     // Disable the extension.
747     send_timestamp_extension_id_ = kInvalidRtpExtensionId;
748     rtp_rtcp_->DeregisterSendRtpHeaderExtension(
749         kRtpExtensionTransmissionTimeOffset);
750     for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
751          it != simulcast_rtp_rtcp_.end(); it++) {
752       (*it)->DeregisterSendRtpHeaderExtension(
753           kRtpExtensionTransmissionTimeOffset);
754     }
755   }
756   return error;
757 }
758 
SetReceiveTimestampOffsetStatus(bool enable,int id)759 int ViEChannel::SetReceiveTimestampOffsetStatus(bool enable, int id) {
760   return vie_receiver_.SetReceiveTimestampOffsetStatus(enable, id) ? 0 : -1;
761 }
762 
SetSendAbsoluteSendTimeStatus(bool enable,int id)763 int ViEChannel::SetSendAbsoluteSendTimeStatus(bool enable, int id) {
764   CriticalSectionScoped cs(rtp_rtcp_cs_.get());
765   int error = 0;
766   if (enable) {
767     // Enable the extension, but disable possible old id to avoid errors.
768     absolute_send_time_extension_id_ = id;
769     rtp_rtcp_->DeregisterSendRtpHeaderExtension(
770         kRtpExtensionAbsoluteSendTime);
771     error = rtp_rtcp_->RegisterSendRtpHeaderExtension(
772         kRtpExtensionAbsoluteSendTime, id);
773     for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
774          it != simulcast_rtp_rtcp_.end(); it++) {
775       (*it)->DeregisterSendRtpHeaderExtension(
776           kRtpExtensionAbsoluteSendTime);
777       error |= (*it)->RegisterSendRtpHeaderExtension(
778           kRtpExtensionAbsoluteSendTime, id);
779     }
780   } else {
781     // Disable the extension.
782     absolute_send_time_extension_id_ = kInvalidRtpExtensionId;
783     rtp_rtcp_->DeregisterSendRtpHeaderExtension(
784         kRtpExtensionAbsoluteSendTime);
785     for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
786          it != simulcast_rtp_rtcp_.end(); it++) {
787       (*it)->DeregisterSendRtpHeaderExtension(
788           kRtpExtensionAbsoluteSendTime);
789     }
790   }
791   return error;
792 }
793 
SetReceiveAbsoluteSendTimeStatus(bool enable,int id)794 int ViEChannel::SetReceiveAbsoluteSendTimeStatus(bool enable, int id) {
795   return vie_receiver_.SetReceiveAbsoluteSendTimeStatus(enable, id) ? 0 : -1;
796 }
797 
SetRtcpXrRrtrStatus(bool enable)798 void ViEChannel::SetRtcpXrRrtrStatus(bool enable) {
799   CriticalSectionScoped cs(rtp_rtcp_cs_.get());
800   rtp_rtcp_->SetRtcpXrRrtrStatus(enable);
801 }
802 
SetTransmissionSmoothingStatus(bool enable)803 void ViEChannel::SetTransmissionSmoothingStatus(bool enable) {
804   assert(paced_sender_ && "No paced sender registered.");
805   paced_sender_->SetStatus(enable);
806 }
807 
EnableTMMBR(const bool enable)808 int32_t ViEChannel::EnableTMMBR(const bool enable) {
809   return rtp_rtcp_->SetTMMBRStatus(enable);
810 }
811 
EnableKeyFrameRequestCallback(const bool enable)812 int32_t ViEChannel::EnableKeyFrameRequestCallback(const bool enable) {
813 
814   CriticalSectionScoped cs(callback_cs_.get());
815   if (enable && !codec_observer_) {
816     LOG(LS_ERROR) << "No ViECodecObserver set.";
817     return -1;
818   }
819   do_key_frame_callbackRequest_ = enable;
820   return 0;
821 }
822 
SetSSRC(const uint32_t SSRC,const StreamType usage,const uint8_t simulcast_idx)823 int32_t ViEChannel::SetSSRC(const uint32_t SSRC,
824                             const StreamType usage,
825                             const uint8_t simulcast_idx) {
826   CriticalSectionScoped cs(rtp_rtcp_cs_.get());
827   ReserveRtpRtcpModules(simulcast_idx + 1);
828   RtpRtcp* rtp_rtcp = GetRtpRtcpModule(simulcast_idx);
829   if (rtp_rtcp == NULL)
830     return -1;
831   if (usage == kViEStreamTypeRtx) {
832     rtp_rtcp->SetRtxSsrc(SSRC);
833   } else {
834     rtp_rtcp->SetSSRC(SSRC);
835   }
836   return 0;
837 }
838 
SetRemoteSSRCType(const StreamType usage,const uint32_t SSRC)839 int32_t ViEChannel::SetRemoteSSRCType(const StreamType usage,
840                                       const uint32_t SSRC) {
841   vie_receiver_.SetRtxSsrc(SSRC);
842   return 0;
843 }
844 
GetLocalSSRC(uint8_t idx,unsigned int * ssrc)845 int32_t ViEChannel::GetLocalSSRC(uint8_t idx, unsigned int* ssrc) {
846   CriticalSectionScoped cs(rtp_rtcp_cs_.get());
847   RtpRtcp* rtp_rtcp = GetRtpRtcpModule(idx);
848   if (rtp_rtcp == NULL)
849     return -1;
850   *ssrc = rtp_rtcp->SSRC();
851   return 0;
852 }
853 
GetRemoteSSRC(uint32_t * ssrc)854 int32_t ViEChannel::GetRemoteSSRC(uint32_t* ssrc) {
855   *ssrc = vie_receiver_.GetRemoteSsrc();
856   return 0;
857 }
858 
GetRemoteCSRC(uint32_t CSRCs[kRtpCsrcSize])859 int32_t ViEChannel::GetRemoteCSRC(uint32_t CSRCs[kRtpCsrcSize]) {
860   uint32_t arrayCSRC[kRtpCsrcSize];
861   memset(arrayCSRC, 0, sizeof(arrayCSRC));
862 
863   int num_csrcs = vie_receiver_.GetCsrcs(arrayCSRC);
864   if (num_csrcs > 0) {
865     memcpy(CSRCs, arrayCSRC, num_csrcs * sizeof(uint32_t));
866   }
867   return 0;
868 }
869 
SetPadWithRedundantPayloads(bool enable)870 void ViEChannel::SetPadWithRedundantPayloads(bool enable) {
871   {
872     CriticalSectionScoped cs(callback_cs_.get());
873     pad_with_redundant_payloads_ = enable;
874   }
875   int mode;
876   uint32_t ssrc;
877   int payload_type;
878   rtp_rtcp_->RTXSendStatus(&mode, &ssrc, &payload_type);
879   if (mode != kRtxOff) {
880     // Since RTX was already enabled we have to reset it with payload-based
881     // padding on.
882     SetRtxSendStatus(true);
883   }
884 }
885 
SetRtxSendPayloadType(int payload_type)886 int ViEChannel::SetRtxSendPayloadType(int payload_type) {
887   rtp_rtcp_->SetRtxSendPayloadType(payload_type);
888   for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
889        it != simulcast_rtp_rtcp_.end(); it++) {
890     (*it)->SetRtxSendPayloadType(payload_type);
891   }
892   SetRtxSendStatus(true);
893   return 0;
894 }
895 
SetRtxSendStatus(bool enable)896 void ViEChannel::SetRtxSendStatus(bool enable) {
897   int rtx_settings = kRtxOff;
898   if (enable) {
899     CriticalSectionScoped cs(callback_cs_.get());
900     rtx_settings = kRtxRetransmitted;
901     if (pad_with_redundant_payloads_)
902       rtx_settings |= kRtxRedundantPayloads;
903   }
904   rtp_rtcp_->SetRTXSendStatus(rtx_settings);
905   CriticalSectionScoped cs(rtp_rtcp_cs_.get());
906   for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
907        it != simulcast_rtp_rtcp_.end(); it++) {
908     (*it)->SetRTXSendStatus(rtx_settings);
909   }
910 }
911 
SetRtxReceivePayloadType(int payload_type)912 void ViEChannel::SetRtxReceivePayloadType(int payload_type) {
913   vie_receiver_.SetRtxPayloadType(payload_type);
914 }
915 
SetStartSequenceNumber(uint16_t sequence_number)916 int32_t ViEChannel::SetStartSequenceNumber(uint16_t sequence_number) {
917   if (rtp_rtcp_->Sending()) {
918     return -1;
919   }
920   return rtp_rtcp_->SetSequenceNumber(sequence_number);
921 }
922 
SetRtpStateForSsrc(uint32_t ssrc,const RtpState & rtp_state)923 void ViEChannel::SetRtpStateForSsrc(uint32_t ssrc, const RtpState& rtp_state) {
924   assert(!rtp_rtcp_->Sending());
925   default_rtp_rtcp_->SetRtpStateForSsrc(ssrc, rtp_state);
926 }
927 
GetRtpStateForSsrc(uint32_t ssrc)928 RtpState ViEChannel::GetRtpStateForSsrc(uint32_t ssrc) {
929   assert(!rtp_rtcp_->Sending());
930 
931   RtpState rtp_state;
932   if (!default_rtp_rtcp_->GetRtpStateForSsrc(ssrc, &rtp_state)) {
933     LOG(LS_ERROR) << "Couldn't get RTP state for ssrc: " << ssrc;
934   }
935   return rtp_state;
936 }
937 
SetRTCPCName(const char rtcp_cname[])938 int32_t ViEChannel::SetRTCPCName(const char rtcp_cname[]) {
939   if (rtp_rtcp_->Sending()) {
940     return -1;
941   }
942   return rtp_rtcp_->SetCNAME(rtcp_cname);
943 }
944 
GetRemoteRTCPCName(char rtcp_cname[])945 int32_t ViEChannel::GetRemoteRTCPCName(char rtcp_cname[]) {
946   uint32_t remoteSSRC = vie_receiver_.GetRemoteSsrc();
947   return rtp_rtcp_->RemoteCNAME(remoteSSRC, rtcp_cname);
948 }
949 
RegisterRtpObserver(ViERTPObserver * observer)950 int32_t ViEChannel::RegisterRtpObserver(ViERTPObserver* observer) {
951   CriticalSectionScoped cs(callback_cs_.get());
952   if (observer) {
953     if (rtp_observer_) {
954       LOG_F(LS_ERROR) << "Observer already registered.";
955       return -1;
956     }
957     rtp_observer_ = observer;
958   } else {
959     rtp_observer_ = NULL;
960   }
961   return 0;
962 }
963 
RegisterRtcpObserver(ViERTCPObserver * observer)964 int32_t ViEChannel::RegisterRtcpObserver(ViERTCPObserver* observer) {
965   CriticalSectionScoped cs(callback_cs_.get());
966   if (observer) {
967     if (rtcp_observer_) {
968       LOG_F(LS_ERROR) << "Observer already registered.";
969       return -1;
970     }
971     rtcp_observer_ = observer;
972   } else {
973     rtcp_observer_ = NULL;
974   }
975   return 0;
976 }
977 
SendApplicationDefinedRTCPPacket(const uint8_t sub_type,uint32_t name,const uint8_t * data,uint16_t data_length_in_bytes)978 int32_t ViEChannel::SendApplicationDefinedRTCPPacket(
979     const uint8_t sub_type,
980     uint32_t name,
981     const uint8_t* data,
982     uint16_t data_length_in_bytes) {
983   if (!rtp_rtcp_->Sending()) {
984     return -1;
985   }
986   if (!data) {
987     LOG_F(LS_ERROR) << "Invalid input.";
988     return -1;
989   }
990   if (data_length_in_bytes % 4 != 0) {
991     LOG(LS_ERROR) << "Invalid input length.";
992     return -1;
993   }
994   RTCPMethod rtcp_method = rtp_rtcp_->RTCP();
995   if (rtcp_method == kRtcpOff) {
996     LOG_F(LS_ERROR) << "RTCP not enable.";
997     return -1;
998   }
999   // Create and send packet.
1000   if (rtp_rtcp_->SetRTCPApplicationSpecificData(sub_type, name, data,
1001                                                data_length_in_bytes) != 0) {
1002     return -1;
1003   }
1004   return 0;
1005 }
1006 
GetSendRtcpStatistics(uint16_t * fraction_lost,uint32_t * cumulative_lost,uint32_t * extended_max,uint32_t * jitter_samples,int32_t * rtt_ms)1007 int32_t ViEChannel::GetSendRtcpStatistics(uint16_t* fraction_lost,
1008                                           uint32_t* cumulative_lost,
1009                                           uint32_t* extended_max,
1010                                           uint32_t* jitter_samples,
1011                                           int32_t* rtt_ms) {
1012   // Aggregate the report blocks associated with streams sent on this channel.
1013   std::vector<RTCPReportBlock> report_blocks;
1014   rtp_rtcp_->RemoteRTCPStat(&report_blocks);
1015   {
1016     CriticalSectionScoped lock(rtp_rtcp_cs_.get());
1017     for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
1018         it != simulcast_rtp_rtcp_.end();
1019         ++it) {
1020       (*it)->RemoteRTCPStat(&report_blocks);
1021     }
1022   }
1023 
1024   if (report_blocks.empty())
1025     return -1;
1026 
1027   uint32_t remote_ssrc = vie_receiver_.GetRemoteSsrc();
1028   std::vector<RTCPReportBlock>::const_iterator it = report_blocks.begin();
1029   for (; it != report_blocks.end(); ++it) {
1030     if (it->remoteSSRC == remote_ssrc)
1031       break;
1032   }
1033   if (it == report_blocks.end()) {
1034     // We have not received packets with an SSRC matching the report blocks. To
1035     // have a chance of calculating an RTT we will try with the SSRC of the
1036     // first report block received.
1037     // This is very important for send-only channels where we don't know the
1038     // SSRC of the other end.
1039     remote_ssrc = report_blocks[0].remoteSSRC;
1040   }
1041 
1042   RTCPReportBlock report;
1043   if (report_blocks.size() > 1)
1044     report = AggregateReportBlocks(report_blocks, &prev_report_blocks_);
1045   else
1046     report = report_blocks[0];
1047 
1048   *fraction_lost = report.fractionLost;
1049   *cumulative_lost = report.cumulativeLost;
1050   *extended_max = report.extendedHighSeqNum;
1051   *jitter_samples = report.jitter;
1052 
1053   uint16_t dummy;
1054   uint16_t rtt = 0;
1055   if (rtp_rtcp_->RTT(remote_ssrc, &rtt, &dummy, &dummy, &dummy) != 0) {
1056     return -1;
1057   }
1058   *rtt_ms = rtt;
1059   return 0;
1060 }
1061 
RegisterSendChannelRtcpStatisticsCallback(RtcpStatisticsCallback * callback)1062 void ViEChannel::RegisterSendChannelRtcpStatisticsCallback(
1063     RtcpStatisticsCallback* callback) {
1064   rtp_rtcp_->RegisterSendChannelRtcpStatisticsCallback(callback);
1065   CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1066   for (std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
1067        it != simulcast_rtp_rtcp_.end();
1068        ++it) {
1069     (*it)->RegisterSendChannelRtcpStatisticsCallback(callback);
1070   }
1071 }
1072 
1073 // TODO(holmer): This is a bad function name as it implies that it returns the
1074 // received RTCP, while it actually returns the statistics which will be sent
1075 // in the RTCP.
GetReceivedRtcpStatistics(uint16_t * fraction_lost,uint32_t * cumulative_lost,uint32_t * extended_max,uint32_t * jitter_samples,int32_t * rtt_ms)1076 int32_t ViEChannel::GetReceivedRtcpStatistics(uint16_t* fraction_lost,
1077                                               uint32_t* cumulative_lost,
1078                                               uint32_t* extended_max,
1079                                               uint32_t* jitter_samples,
1080                                               int32_t* rtt_ms) {
1081   uint32_t remote_ssrc = vie_receiver_.GetRemoteSsrc();
1082   StreamStatistician* statistician =
1083       vie_receiver_.GetReceiveStatistics()->GetStatistician(remote_ssrc);
1084   RtcpStatistics receive_stats;
1085   if (!statistician || !statistician->GetStatistics(
1086       &receive_stats, rtp_rtcp_->RTCP() == kRtcpOff)) {
1087     return -1;
1088   }
1089   *fraction_lost = receive_stats.fraction_lost;
1090   *cumulative_lost = receive_stats.cumulative_lost;
1091   *extended_max = receive_stats.extended_max_sequence_number;
1092   *jitter_samples = receive_stats.jitter;
1093 
1094   uint16_t dummy = 0;
1095   uint16_t rtt = 0;
1096   rtp_rtcp_->RTT(remote_ssrc, &rtt, &dummy, &dummy, &dummy);
1097   *rtt_ms = rtt;
1098   return 0;
1099 }
1100 
RegisterReceiveChannelRtcpStatisticsCallback(RtcpStatisticsCallback * callback)1101 void ViEChannel::RegisterReceiveChannelRtcpStatisticsCallback(
1102     RtcpStatisticsCallback* callback) {
1103   vie_receiver_.GetReceiveStatistics()->RegisterRtcpStatisticsCallback(
1104       callback);
1105 }
1106 
GetRtpStatistics(uint32_t * bytes_sent,uint32_t * packets_sent,uint32_t * bytes_received,uint32_t * packets_received) const1107 int32_t ViEChannel::GetRtpStatistics(uint32_t* bytes_sent,
1108                                      uint32_t* packets_sent,
1109                                      uint32_t* bytes_received,
1110                                      uint32_t* packets_received) const {
1111   StreamStatistician* statistician = vie_receiver_.GetReceiveStatistics()->
1112       GetStatistician(vie_receiver_.GetRemoteSsrc());
1113   *bytes_received = 0;
1114   *packets_received = 0;
1115   if (statistician)
1116     statistician->GetDataCounters(bytes_received, packets_received);
1117   if (rtp_rtcp_->DataCountersRTP(bytes_sent, packets_sent) != 0) {
1118     return -1;
1119   }
1120   CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1121   for (std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
1122        it != simulcast_rtp_rtcp_.end();
1123        it++) {
1124     uint32_t bytes_sent_temp = 0;
1125     uint32_t packets_sent_temp = 0;
1126     RtpRtcp* rtp_rtcp = *it;
1127     rtp_rtcp->DataCountersRTP(&bytes_sent_temp, &packets_sent_temp);
1128     *bytes_sent += bytes_sent_temp;
1129     *packets_sent += packets_sent_temp;
1130   }
1131   for (std::list<RtpRtcp*>::const_iterator it = removed_rtp_rtcp_.begin();
1132        it != removed_rtp_rtcp_.end(); ++it) {
1133     uint32_t bytes_sent_temp = 0;
1134     uint32_t packets_sent_temp = 0;
1135     RtpRtcp* rtp_rtcp = *it;
1136     rtp_rtcp->DataCountersRTP(&bytes_sent_temp, &packets_sent_temp);
1137     *bytes_sent += bytes_sent_temp;
1138     *packets_sent += packets_sent_temp;
1139   }
1140   return 0;
1141 }
1142 
RegisterSendChannelRtpStatisticsCallback(StreamDataCountersCallback * callback)1143 void ViEChannel::RegisterSendChannelRtpStatisticsCallback(
1144       StreamDataCountersCallback* callback) {
1145   rtp_rtcp_->RegisterSendChannelRtpStatisticsCallback(callback);
1146   {
1147     CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1148     for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
1149          it != simulcast_rtp_rtcp_.end();
1150          it++) {
1151       (*it)->RegisterSendChannelRtpStatisticsCallback(callback);
1152     }
1153   }
1154 }
1155 
RegisterReceiveChannelRtpStatisticsCallback(StreamDataCountersCallback * callback)1156 void ViEChannel::RegisterReceiveChannelRtpStatisticsCallback(
1157     StreamDataCountersCallback* callback) {
1158   vie_receiver_.GetReceiveStatistics()->RegisterRtpStatisticsCallback(callback);
1159 }
1160 
GetRtcpPacketTypeCounters(RtcpPacketTypeCounter * packets_sent,RtcpPacketTypeCounter * packets_received) const1161 void ViEChannel::GetRtcpPacketTypeCounters(
1162     RtcpPacketTypeCounter* packets_sent,
1163     RtcpPacketTypeCounter* packets_received) const {
1164   rtp_rtcp_->GetRtcpPacketTypeCounters(packets_sent, packets_received);
1165 
1166   CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1167   for (std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
1168        it != simulcast_rtp_rtcp_.end(); ++it) {
1169     RtcpPacketTypeCounter sent;
1170     RtcpPacketTypeCounter received;
1171     (*it)->GetRtcpPacketTypeCounters(&sent, &received);
1172     packets_sent->Add(sent);
1173     packets_received->Add(received);
1174   }
1175   for (std::list<RtpRtcp*>::const_iterator it = removed_rtp_rtcp_.begin();
1176        it != removed_rtp_rtcp_.end(); ++it) {
1177     RtcpPacketTypeCounter sent;
1178     RtcpPacketTypeCounter received;
1179     (*it)->GetRtcpPacketTypeCounters(&sent, &received);
1180     packets_sent->Add(sent);
1181     packets_received->Add(received);
1182   }
1183 }
1184 
GetBandwidthUsage(uint32_t * total_bitrate_sent,uint32_t * video_bitrate_sent,uint32_t * fec_bitrate_sent,uint32_t * nackBitrateSent) const1185 void ViEChannel::GetBandwidthUsage(uint32_t* total_bitrate_sent,
1186                                    uint32_t* video_bitrate_sent,
1187                                    uint32_t* fec_bitrate_sent,
1188                                    uint32_t* nackBitrateSent) const {
1189   rtp_rtcp_->BitrateSent(total_bitrate_sent, video_bitrate_sent,
1190                          fec_bitrate_sent, nackBitrateSent);
1191   CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1192   for (std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
1193        it != simulcast_rtp_rtcp_.end(); it++) {
1194     uint32_t stream_rate = 0;
1195     uint32_t video_rate = 0;
1196     uint32_t fec_rate = 0;
1197     uint32_t nackRate = 0;
1198     RtpRtcp* rtp_rtcp = *it;
1199     rtp_rtcp->BitrateSent(&stream_rate, &video_rate, &fec_rate, &nackRate);
1200     *total_bitrate_sent += stream_rate;
1201     *video_bitrate_sent += video_rate;
1202     *fec_bitrate_sent += fec_rate;
1203     *nackBitrateSent += nackRate;
1204   }
1205 }
1206 
GetSendSideDelay(int * avg_send_delay,int * max_send_delay) const1207 bool ViEChannel::GetSendSideDelay(int* avg_send_delay,
1208                                   int* max_send_delay) const {
1209   *avg_send_delay = 0;
1210   *max_send_delay = 0;
1211   bool valid_estimate = false;
1212   int num_send_delays = 0;
1213   if (rtp_rtcp_->GetSendSideDelay(avg_send_delay, max_send_delay)) {
1214     ++num_send_delays;
1215     valid_estimate = true;
1216   }
1217   CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1218   for (std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
1219        it != simulcast_rtp_rtcp_.end(); it++) {
1220     RtpRtcp* rtp_rtcp = *it;
1221     int sub_stream_avg_delay = 0;
1222     int sub_stream_max_delay = 0;
1223     if (rtp_rtcp->GetSendSideDelay(&sub_stream_avg_delay,
1224                                    &sub_stream_max_delay)) {
1225       *avg_send_delay += sub_stream_avg_delay;
1226       *max_send_delay = std::max(*max_send_delay, sub_stream_max_delay);
1227       ++num_send_delays;
1228     }
1229   }
1230   if (num_send_delays > 0) {
1231     valid_estimate = true;
1232     *avg_send_delay = *avg_send_delay / num_send_delays;
1233     *avg_send_delay = (*avg_send_delay + num_send_delays / 2) / num_send_delays;
1234   }
1235   return valid_estimate;
1236 }
1237 
RegisterSendSideDelayObserver(SendSideDelayObserver * observer)1238 void ViEChannel::RegisterSendSideDelayObserver(
1239     SendSideDelayObserver* observer) {
1240   send_side_delay_observer_.Set(observer);
1241 }
1242 
RegisterSendBitrateObserver(BitrateStatisticsObserver * observer)1243 void ViEChannel::RegisterSendBitrateObserver(
1244     BitrateStatisticsObserver* observer) {
1245   send_bitrate_observer_.Set(observer);
1246 }
1247 
GetReceiveBandwidthEstimatorStats(ReceiveBandwidthEstimatorStats * output) const1248 void ViEChannel::GetReceiveBandwidthEstimatorStats(
1249     ReceiveBandwidthEstimatorStats* output) const {
1250   vie_receiver_.GetReceiveBandwidthEstimatorStats(output);
1251 }
1252 
StartRTPDump(const char file_nameUTF8[1024],RTPDirections direction)1253 int32_t ViEChannel::StartRTPDump(const char file_nameUTF8[1024],
1254                                  RTPDirections direction) {
1255   if (direction == kRtpIncoming) {
1256     return vie_receiver_.StartRTPDump(file_nameUTF8);
1257   } else {
1258     return vie_sender_.StartRTPDump(file_nameUTF8);
1259   }
1260 }
1261 
StopRTPDump(RTPDirections direction)1262 int32_t ViEChannel::StopRTPDump(RTPDirections direction) {
1263   if (direction == kRtpIncoming) {
1264     return vie_receiver_.StopRTPDump();
1265   } else {
1266     return vie_sender_.StopRTPDump();
1267   }
1268 }
1269 
StartSend()1270 int32_t ViEChannel::StartSend() {
1271   CriticalSectionScoped cs(callback_cs_.get());
1272   if (!external_transport_) {
1273     LOG(LS_ERROR) << "No transport set.";
1274     return -1;
1275   }
1276   rtp_rtcp_->SetSendingMediaStatus(true);
1277 
1278   if (rtp_rtcp_->Sending()) {
1279     return kViEBaseAlreadySending;
1280   }
1281   if (rtp_rtcp_->SetSendingStatus(true) != 0) {
1282     return -1;
1283   }
1284   CriticalSectionScoped cs_rtp(rtp_rtcp_cs_.get());
1285   for (std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
1286        it != simulcast_rtp_rtcp_.end();
1287        it++) {
1288     RtpRtcp* rtp_rtcp = *it;
1289     rtp_rtcp->SetSendingMediaStatus(true);
1290     rtp_rtcp->SetSendingStatus(true);
1291   }
1292   return 0;
1293 }
1294 
StopSend()1295 int32_t ViEChannel::StopSend() {
1296   CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1297   rtp_rtcp_->SetSendingMediaStatus(false);
1298   for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
1299        it != simulcast_rtp_rtcp_.end();
1300        it++) {
1301     RtpRtcp* rtp_rtcp = *it;
1302     rtp_rtcp->SetSendingMediaStatus(false);
1303   }
1304   if (!rtp_rtcp_->Sending()) {
1305     return kViEBaseNotSending;
1306   }
1307 
1308   // Reset.
1309   rtp_rtcp_->ResetSendDataCountersRTP();
1310   if (rtp_rtcp_->SetSendingStatus(false) != 0) {
1311     return -1;
1312   }
1313   for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
1314        it != simulcast_rtp_rtcp_.end();
1315        it++) {
1316     RtpRtcp* rtp_rtcp = *it;
1317     rtp_rtcp->ResetSendDataCountersRTP();
1318     rtp_rtcp->SetSendingStatus(false);
1319   }
1320   return 0;
1321 }
1322 
Sending()1323 bool ViEChannel::Sending() {
1324   return rtp_rtcp_->Sending();
1325 }
1326 
StartReceive()1327 int32_t ViEChannel::StartReceive() {
1328   CriticalSectionScoped cs(callback_cs_.get());
1329   if (StartDecodeThread() != 0) {
1330     vie_receiver_.StopReceive();
1331     return -1;
1332   }
1333   vie_receiver_.StartReceive();
1334   return 0;
1335 }
1336 
StopReceive()1337 int32_t ViEChannel::StopReceive() {
1338   vie_receiver_.StopReceive();
1339   StopDecodeThread();
1340   vcm_->ResetDecoder();
1341   return 0;
1342 }
1343 
RegisterSendTransport(Transport * transport)1344 int32_t ViEChannel::RegisterSendTransport(Transport* transport) {
1345   if (rtp_rtcp_->Sending()) {
1346     return -1;
1347   }
1348 
1349   CriticalSectionScoped cs(callback_cs_.get());
1350   if (external_transport_) {
1351     LOG_F(LS_ERROR) << "Transport already registered.";
1352     return -1;
1353   }
1354   external_transport_ = transport;
1355   vie_sender_.RegisterSendTransport(transport);
1356   return 0;
1357 }
1358 
DeregisterSendTransport()1359 int32_t ViEChannel::DeregisterSendTransport() {
1360   CriticalSectionScoped cs(callback_cs_.get());
1361   if (!external_transport_) {
1362     return 0;
1363   }
1364   if (rtp_rtcp_->Sending()) {
1365     LOG_F(LS_ERROR) << "Can't deregister transport when sending.";
1366     return -1;
1367   }
1368   external_transport_ = NULL;
1369   vie_sender_.DeregisterSendTransport();
1370   return 0;
1371 }
1372 
ReceivedRTPPacket(const void * rtp_packet,const int32_t rtp_packet_length,const PacketTime & packet_time)1373 int32_t ViEChannel::ReceivedRTPPacket(
1374     const void* rtp_packet, const int32_t rtp_packet_length,
1375     const PacketTime& packet_time) {
1376   {
1377     CriticalSectionScoped cs(callback_cs_.get());
1378     if (!external_transport_) {
1379       return -1;
1380     }
1381   }
1382   return vie_receiver_.ReceivedRTPPacket(
1383       rtp_packet, rtp_packet_length, packet_time);
1384 }
1385 
ReceivedRTCPPacket(const void * rtcp_packet,const int32_t rtcp_packet_length)1386 int32_t ViEChannel::ReceivedRTCPPacket(
1387   const void* rtcp_packet, const int32_t rtcp_packet_length) {
1388   {
1389     CriticalSectionScoped cs(callback_cs_.get());
1390     if (!external_transport_) {
1391       return -1;
1392     }
1393   }
1394   return vie_receiver_.ReceivedRTCPPacket(rtcp_packet, rtcp_packet_length);
1395 }
1396 
SetMTU(uint16_t mtu)1397 int32_t ViEChannel::SetMTU(uint16_t mtu) {
1398   if (rtp_rtcp_->SetMaxTransferUnit(mtu) != 0) {
1399     return -1;
1400   }
1401   CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1402   for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
1403        it != simulcast_rtp_rtcp_.end();
1404        it++) {
1405     RtpRtcp* rtp_rtcp = *it;
1406     rtp_rtcp->SetMaxTransferUnit(mtu);
1407   }
1408   mtu_ = mtu;
1409   return 0;
1410 }
1411 
MaxDataPayloadLength() const1412 uint16_t ViEChannel::MaxDataPayloadLength() const {
1413   return rtp_rtcp_->MaxDataPayloadLength();
1414 }
1415 
EnableColorEnhancement(bool enable)1416 int32_t ViEChannel::EnableColorEnhancement(bool enable) {
1417   CriticalSectionScoped cs(callback_cs_.get());
1418   color_enhancement_ = enable;
1419   return 0;
1420 }
1421 
rtp_rtcp()1422 RtpRtcp* ViEChannel::rtp_rtcp() {
1423   return rtp_rtcp_.get();
1424 }
1425 
GetStatsObserver()1426 CallStatsObserver* ViEChannel::GetStatsObserver() {
1427   return stats_observer_.get();
1428 }
1429 
1430 // Do not acquire the lock of |vcm_| in this function. Decode callback won't
1431 // necessarily be called from the decoding thread. The decoding thread may have
1432 // held the lock when calling VideoDecoder::Decode, Reset, or Release. Acquiring
1433 // the same lock in the path of decode callback can deadlock.
FrameToRender(I420VideoFrame & video_frame)1434 int32_t ViEChannel::FrameToRender(
1435     I420VideoFrame& video_frame) {  // NOLINT
1436   CriticalSectionScoped cs(callback_cs_.get());
1437 
1438   if (decoder_reset_) {
1439     // Trigger a callback to the user if the incoming codec has changed.
1440     if (codec_observer_) {
1441       // The codec set by RegisterReceiveCodec might not be the size we're
1442       // actually decoding.
1443       receive_codec_.width = static_cast<uint16_t>(video_frame.width());
1444       receive_codec_.height = static_cast<uint16_t>(video_frame.height());
1445       codec_observer_->IncomingCodecChanged(channel_id_, receive_codec_);
1446     }
1447     decoder_reset_ = false;
1448   }
1449   // Post processing is not supported if the frame is backed by a texture.
1450   if (video_frame.native_handle() == NULL) {
1451     if (pre_render_callback_ != NULL)
1452       pre_render_callback_->FrameCallback(&video_frame);
1453     if (effect_filter_) {
1454       unsigned int length = CalcBufferSize(kI420,
1455                                            video_frame.width(),
1456                                            video_frame.height());
1457       scoped_ptr<uint8_t[]> video_buffer(new uint8_t[length]);
1458       ExtractBuffer(video_frame, length, video_buffer.get());
1459       effect_filter_->Transform(length,
1460                                 video_buffer.get(),
1461                                 video_frame.ntp_time_ms(),
1462                                 video_frame.timestamp(),
1463                                 video_frame.width(),
1464                                 video_frame.height());
1465     }
1466     if (color_enhancement_) {
1467       VideoProcessingModule::ColorEnhancement(&video_frame);
1468     }
1469   }
1470 
1471   uint32_t arr_ofCSRC[kRtpCsrcSize];
1472   int32_t no_of_csrcs = vie_receiver_.GetCsrcs(arr_ofCSRC);
1473   if (no_of_csrcs <= 0) {
1474     arr_ofCSRC[0] = vie_receiver_.GetRemoteSsrc();
1475     no_of_csrcs = 1;
1476   }
1477   DeliverFrame(&video_frame, no_of_csrcs, arr_ofCSRC);
1478   return 0;
1479 }
1480 
ReceivedDecodedReferenceFrame(const uint64_t picture_id)1481 int32_t ViEChannel::ReceivedDecodedReferenceFrame(
1482   const uint64_t picture_id) {
1483   return rtp_rtcp_->SendRTCPReferencePictureSelection(picture_id);
1484 }
1485 
IncomingCodecChanged(const VideoCodec & codec)1486 void ViEChannel::IncomingCodecChanged(const VideoCodec& codec) {
1487   CriticalSectionScoped cs(callback_cs_.get());
1488   receive_codec_ = codec;
1489 }
1490 
OnReceiveStatisticsUpdate(const uint32_t bit_rate,const uint32_t frame_rate)1491 int32_t ViEChannel::OnReceiveStatisticsUpdate(const uint32_t bit_rate,
1492                                               const uint32_t frame_rate) {
1493   CriticalSectionScoped cs(callback_cs_.get());
1494   if (codec_observer_) {
1495     codec_observer_->IncomingRate(channel_id_, frame_rate, bit_rate);
1496   }
1497   return 0;
1498 }
1499 
OnDecoderTiming(int decode_ms,int max_decode_ms,int current_delay_ms,int target_delay_ms,int jitter_buffer_ms,int min_playout_delay_ms,int render_delay_ms)1500 void ViEChannel::OnDecoderTiming(int decode_ms,
1501                                  int max_decode_ms,
1502                                  int current_delay_ms,
1503                                  int target_delay_ms,
1504                                  int jitter_buffer_ms,
1505                                  int min_playout_delay_ms,
1506                                  int render_delay_ms) {
1507   CriticalSectionScoped cs(callback_cs_.get());
1508   if (!codec_observer_)
1509     return;
1510   codec_observer_->DecoderTiming(decode_ms,
1511                                  max_decode_ms,
1512                                  current_delay_ms,
1513                                  target_delay_ms,
1514                                  jitter_buffer_ms,
1515                                  min_playout_delay_ms,
1516                                  render_delay_ms);
1517 }
1518 
RequestKeyFrame()1519 int32_t ViEChannel::RequestKeyFrame() {
1520   {
1521     CriticalSectionScoped cs(callback_cs_.get());
1522     if (codec_observer_ && do_key_frame_callbackRequest_) {
1523       codec_observer_->RequestNewKeyFrame(channel_id_);
1524     }
1525   }
1526   return rtp_rtcp_->RequestKeyFrame();
1527 }
1528 
SliceLossIndicationRequest(const uint64_t picture_id)1529 int32_t ViEChannel::SliceLossIndicationRequest(
1530   const uint64_t picture_id) {
1531   return rtp_rtcp_->SendRTCPSliceLossIndication((uint8_t) picture_id);
1532 }
1533 
ResendPackets(const uint16_t * sequence_numbers,uint16_t length)1534 int32_t ViEChannel::ResendPackets(const uint16_t* sequence_numbers,
1535                                         uint16_t length) {
1536   return rtp_rtcp_->SendNACK(sequence_numbers, length);
1537 }
1538 
ChannelDecodeThreadFunction(void * obj)1539 bool ViEChannel::ChannelDecodeThreadFunction(void* obj) {
1540   return static_cast<ViEChannel*>(obj)->ChannelDecodeProcess();
1541 }
1542 
ChannelDecodeProcess()1543 bool ViEChannel::ChannelDecodeProcess() {
1544   vcm_->Decode(kMaxDecodeWaitTimeMs);
1545   return true;
1546 }
1547 
OnRttUpdate(uint32_t rtt)1548 void ViEChannel::OnRttUpdate(uint32_t rtt) {
1549   vcm_->SetReceiveChannelParameters(rtt);
1550 }
1551 
ReserveRtpRtcpModules(size_t num_modules)1552 void ViEChannel::ReserveRtpRtcpModules(size_t num_modules) {
1553   for (size_t total_modules =
1554            1 + simulcast_rtp_rtcp_.size() + removed_rtp_rtcp_.size();
1555        total_modules < num_modules;
1556        ++total_modules) {
1557     RtpRtcp* rtp_rtcp = CreateRtpRtcpModule();
1558     rtp_rtcp->SetSendingStatus(false);
1559     rtp_rtcp->SetSendingMediaStatus(false);
1560     rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback(NULL);
1561     rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL);
1562     removed_rtp_rtcp_.push_back(rtp_rtcp);
1563   }
1564 }
1565 
GetRtpRtcpModule(size_t index) const1566 RtpRtcp* ViEChannel::GetRtpRtcpModule(size_t index) const {
1567   if (index == 0)
1568     return rtp_rtcp_.get();
1569   if (index <= simulcast_rtp_rtcp_.size()) {
1570     std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
1571     for (size_t i = 1; i < index; ++i) {
1572       ++it;
1573     }
1574     return *it;
1575   }
1576 
1577   // If the requested module exists it must be in the removed list. Index
1578   // translation to this list must remove the default module as well as all
1579   // active simulcast modules.
1580   size_t removed_idx = index - simulcast_rtp_rtcp_.size() - 1;
1581   if (removed_idx >= removed_rtp_rtcp_.size())
1582     return NULL;
1583 
1584   std::list<RtpRtcp*>::const_iterator it = removed_rtp_rtcp_.begin();
1585   while (removed_idx-- > 0)
1586     ++it;
1587 
1588   return *it;
1589 }
1590 
CreateRtpRtcpModule()1591 RtpRtcp* ViEChannel::CreateRtpRtcpModule() {
1592   RtpRtcp::Configuration configuration;
1593   configuration.id = ViEModuleId(engine_id_, channel_id_);
1594   configuration.audio = false;  // Video.
1595   configuration.default_module = default_rtp_rtcp_;
1596   configuration.outgoing_transport = &vie_sender_;
1597   configuration.intra_frame_callback = intra_frame_observer_;
1598   configuration.bandwidth_callback = bandwidth_observer_.get();
1599   configuration.rtt_stats = rtt_stats_;
1600   configuration.paced_sender = paced_sender_;
1601   configuration.send_side_delay_observer = &send_side_delay_observer_;
1602 
1603   return RtpRtcp::CreateRtpRtcp(configuration);
1604 }
1605 
StartDecodeThread()1606 int32_t ViEChannel::StartDecodeThread() {
1607   // Start the decode thread
1608   if (decode_thread_) {
1609     // Already started.
1610     return 0;
1611   }
1612   decode_thread_ = ThreadWrapper::CreateThread(ChannelDecodeThreadFunction,
1613                                                    this, kHighestPriority,
1614                                                    "DecodingThread");
1615   if (!decode_thread_) {
1616     return -1;
1617   }
1618 
1619   unsigned int thread_id;
1620   if (decode_thread_->Start(thread_id) == false) {
1621     delete decode_thread_;
1622     decode_thread_ = NULL;
1623     LOG(LS_ERROR) << "Could not start decode thread.";
1624     return -1;
1625   }
1626   return 0;
1627 }
1628 
StopDecodeThread()1629 int32_t ViEChannel::StopDecodeThread() {
1630   if (!decode_thread_) {
1631     return 0;
1632   }
1633 
1634   decode_thread_->SetNotAlive();
1635   if (decode_thread_->Stop()) {
1636     delete decode_thread_;
1637   } else {
1638     assert(false && "could not stop decode thread");
1639   }
1640   decode_thread_ = NULL;
1641   return 0;
1642 }
1643 
SetVoiceChannel(int32_t ve_channel_id,VoEVideoSync * ve_sync_interface)1644 int32_t ViEChannel::SetVoiceChannel(int32_t ve_channel_id,
1645                                           VoEVideoSync* ve_sync_interface) {
1646   if (ve_sync_interface) {
1647     // Register lip sync
1648     module_process_thread_.RegisterModule(&vie_sync_);
1649   } else {
1650     module_process_thread_.DeRegisterModule(&vie_sync_);
1651   }
1652   return vie_sync_.ConfigureSync(ve_channel_id,
1653                                  ve_sync_interface,
1654                                  rtp_rtcp_.get(),
1655                                  vie_receiver_.GetRtpReceiver());
1656 }
1657 
VoiceChannel()1658 int32_t ViEChannel::VoiceChannel() {
1659   return vie_sync_.VoiceChannel();
1660 }
1661 
RegisterEffectFilter(ViEEffectFilter * effect_filter)1662 int32_t ViEChannel::RegisterEffectFilter(ViEEffectFilter* effect_filter) {
1663   CriticalSectionScoped cs(callback_cs_.get());
1664   if (effect_filter && effect_filter_) {
1665     LOG(LS_ERROR) << "Effect filter already registered.";
1666     return -1;
1667   }
1668   effect_filter_ = effect_filter;
1669   return 0;
1670 }
1671 
RegisterPreRenderCallback(I420FrameCallback * pre_render_callback)1672 void ViEChannel::RegisterPreRenderCallback(
1673     I420FrameCallback* pre_render_callback) {
1674   CriticalSectionScoped cs(callback_cs_.get());
1675   pre_render_callback_ = pre_render_callback;
1676 }
1677 
RegisterPreDecodeImageCallback(EncodedImageCallback * pre_decode_callback)1678 void ViEChannel::RegisterPreDecodeImageCallback(
1679     EncodedImageCallback* pre_decode_callback) {
1680   vcm_->RegisterPreDecodeImageCallback(pre_decode_callback);
1681 }
1682 
OnApplicationDataReceived(const int32_t id,const uint8_t sub_type,const uint32_t name,const uint16_t length,const uint8_t * data)1683 void ViEChannel::OnApplicationDataReceived(const int32_t id,
1684                                            const uint8_t sub_type,
1685                                            const uint32_t name,
1686                                            const uint16_t length,
1687                                            const uint8_t* data) {
1688   if (channel_id_ != ChannelId(id)) {
1689     return;
1690   }
1691   CriticalSectionScoped cs(callback_cs_.get());
1692   {
1693     if (rtcp_observer_) {
1694       rtcp_observer_->OnApplicationDataReceived(
1695           channel_id_, sub_type, name, reinterpret_cast<const char*>(data),
1696           length);
1697     }
1698   }
1699 }
1700 
OnInitializeDecoder(const int32_t id,const int8_t payload_type,const char payload_name[RTP_PAYLOAD_NAME_SIZE],const int frequency,const uint8_t channels,const uint32_t rate)1701 int32_t ViEChannel::OnInitializeDecoder(
1702     const int32_t id,
1703     const int8_t payload_type,
1704     const char payload_name[RTP_PAYLOAD_NAME_SIZE],
1705     const int frequency,
1706     const uint8_t channels,
1707     const uint32_t rate) {
1708   LOG(LS_INFO) << "OnInitializeDecoder " << payload_type << " "
1709                << payload_name;
1710   vcm_->ResetDecoder();
1711 
1712   CriticalSectionScoped cs(callback_cs_.get());
1713   decoder_reset_ = true;
1714   return 0;
1715 }
1716 
OnIncomingSSRCChanged(const int32_t id,const uint32_t ssrc)1717 void ViEChannel::OnIncomingSSRCChanged(const int32_t id, const uint32_t ssrc) {
1718   assert(channel_id_ == ChannelId(id));
1719   rtp_rtcp_->SetRemoteSSRC(ssrc);
1720 
1721   CriticalSectionScoped cs(callback_cs_.get());
1722   {
1723     if (rtp_observer_) {
1724       rtp_observer_->IncomingSSRCChanged(channel_id_, ssrc);
1725     }
1726   }
1727 }
1728 
OnIncomingCSRCChanged(const int32_t id,const uint32_t CSRC,const bool added)1729 void ViEChannel::OnIncomingCSRCChanged(const int32_t id,
1730                                        const uint32_t CSRC,
1731                                        const bool added) {
1732   assert(channel_id_ == ChannelId(id));
1733   CriticalSectionScoped cs(callback_cs_.get());
1734   {
1735     if (rtp_observer_) {
1736       rtp_observer_->IncomingCSRCChanged(channel_id_, CSRC, added);
1737     }
1738   }
1739 }
1740 
ResetStatistics(uint32_t ssrc)1741 void ViEChannel::ResetStatistics(uint32_t ssrc) {
1742   StreamStatistician* statistician =
1743       vie_receiver_.GetReceiveStatistics()->GetStatistician(ssrc);
1744   if (statistician)
1745     statistician->ResetStatistics();
1746 }
1747 
RegisterSendFrameCountObserver(FrameCountObserver * observer)1748 void ViEChannel::RegisterSendFrameCountObserver(
1749     FrameCountObserver* observer) {
1750   send_frame_count_observer_.Set(observer);
1751 }
1752 
ReceivedBWEPacket(int64_t arrival_time_ms,int payload_size,const RTPHeader & header)1753 void ViEChannel::ReceivedBWEPacket(int64_t arrival_time_ms,
1754     int payload_size, const RTPHeader& header) {
1755   vie_receiver_.ReceivedBWEPacket(arrival_time_ms, payload_size, header);
1756 }
1757 }  // namespace webrtc
1758