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