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
37namespace webrtc {
38
39const int kMaxDecodeWaitTimeMs = 50;
40const int kInvalidRtpExtensionId = 0;
41static const int kMaxTargetDelayMs = 10000;
42static const float kMaxIncompleteTimeMultiplier = 3.5f;
43
44// Helper class receiving statistics callbacks.
45class ChannelStatsObserver : public CallStatsObserver {
46 public:
47  explicit ChannelStatsObserver(ViEChannel* owner) : owner_(owner) {}
48  virtual ~ChannelStatsObserver() {}
49
50  // Implements StatsObserver.
51  virtual void OnRttUpdate(uint32_t rtt) {
52    owner_->OnRttUpdate(rtt);
53  }
54
55 private:
56  ViEChannel* owner_;
57};
58
59ViEChannel::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
125int32_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
177ViEChannel::~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
202int32_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
403int32_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
419int32_t ViEChannel::GetReceiveCodec(VideoCodec* video_codec) {
420  if (vcm_->ReceiveCodec(video_codec) != 0) {
421    return -1;
422  }
423  return 0;
424}
425
426int32_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
440int32_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
452int32_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
467int32_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
478uint32_t ViEChannel::DiscardedPackets() const {
479  return vcm_->DiscardedPackets();
480}
481
482int ViEChannel::ReceiveDelay() const {
483  return vcm_->Delay();
484}
485
486int32_t ViEChannel::WaitForKeyFrame(bool wait) {
487  wait_for_key_frame_ = wait;
488  return 0;
489}
490
491int32_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
512int32_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
523int32_t ViEChannel::GetRTCPMode(RTCPMethod* rtcp_mode) {
524  *rtcp_mode = rtp_rtcp_->RTCP();
525  return 0;
526}
527
528int32_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
544int32_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
586int32_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
597int32_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
615int32_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
631int 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
652int 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
679int 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
686int32_t ViEChannel::SetKeyFrameRequestMethod(
687    const KeyFrameRequestMethod method) {
688  return rtp_rtcp_->SetKeyFrameRequestMethod(method);
689}
690
691bool ViEChannel::EnableRemb(bool enable) {
692  if (rtp_rtcp_->SetREMBStatus(enable) != 0)
693    return false;
694  return true;
695}
696
697int 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
728int ViEChannel::SetReceiveTimestampOffsetStatus(bool enable, int id) {
729  return vie_receiver_.SetReceiveTimestampOffsetStatus(enable, id) ? 0 : -1;
730}
731
732int 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
763int ViEChannel::SetReceiveAbsoluteSendTimeStatus(bool enable, int id) {
764  return vie_receiver_.SetReceiveAbsoluteSendTimeStatus(enable, id) ? 0 : -1;
765}
766
767void ViEChannel::SetRtcpXrRrtrStatus(bool enable) {
768  CriticalSectionScoped cs(rtp_rtcp_cs_.get());
769  rtp_rtcp_->SetRtcpXrRrtrStatus(enable);
770}
771
772void ViEChannel::SetTransmissionSmoothingStatus(bool enable) {
773  assert(paced_sender_ && "No paced sender registered.");
774  paced_sender_->SetStatus(enable);
775}
776
777int32_t ViEChannel::EnableTMMBR(const bool enable) {
778  return rtp_rtcp_->SetTMMBRStatus(enable);
779}
780
781int32_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
792int32_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
822int32_t ViEChannel::SetRemoteSSRCType(const StreamType usage,
823                                      const uint32_t SSRC) {
824  vie_receiver_.SetRtxSsrc(SSRC);
825  return 0;
826}
827
828int32_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
847int32_t ViEChannel::GetRemoteSSRC(uint32_t* ssrc) {
848  *ssrc = vie_receiver_.GetRemoteSsrc();
849  return 0;
850}
851
852int32_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
863void 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
879int 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
889void 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
905void ViEChannel::SetRtxReceivePayloadType(int payload_type) {
906  vie_receiver_.SetRtxPayloadType(payload_type);
907}
908
909int32_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
916int32_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
923int32_t ViEChannel::GetRTCPCName(char rtcp_cname[]) {
924  return rtp_rtcp_->CNAME(rtcp_cname);
925}
926
927int32_t ViEChannel::GetRemoteRTCPCName(char rtcp_cname[]) {
928  uint32_t remoteSSRC = vie_receiver_.GetRemoteSsrc();
929  return rtp_rtcp_->RemoteCNAME(remoteSSRC, rtcp_cname);
930}
931
932int32_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
946int32_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
960int32_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
989int32_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
1042void 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.
1056int32_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
1081void ViEChannel::RegisterReceiveChannelRtcpStatisticsCallback(
1082    RtcpStatisticsCallback* callback) {
1083  vie_receiver_.GetReceiveStatistics()->RegisterRtcpStatisticsCallback(
1084      callback);
1085}
1086
1087int32_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
1123void 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
1136void ViEChannel::RegisterReceiveChannelRtpStatisticsCallback(
1137    StreamDataCountersCallback* callback) {
1138  vie_receiver_.GetReceiveStatistics()->RegisterRtpStatisticsCallback(callback);
1139}
1140
1141void 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
1165void 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
1187bool 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
1218void 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
1229void ViEChannel::GetReceiveBandwidthEstimatorStats(
1230    ReceiveBandwidthEstimatorStats* output) const {
1231  vie_receiver_.GetReceiveBandwidthEstimatorStats(output);
1232}
1233
1234int32_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
1243int32_t ViEChannel::StopRTPDump(RTPDirections direction) {
1244  if (direction == kRtpIncoming) {
1245    return vie_receiver_.StopRTPDump();
1246  } else {
1247    return vie_sender_.StopRTPDump();
1248  }
1249}
1250
1251int32_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
1276int32_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
1304bool ViEChannel::Sending() {
1305  return rtp_rtcp_->Sending();
1306}
1307
1308int32_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
1318int32_t ViEChannel::StopReceive() {
1319  vie_receiver_.StopReceive();
1320  StopDecodeThread();
1321  vcm_->ResetDecoder();
1322  return 0;
1323}
1324
1325int32_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
1340int32_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
1354int32_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
1367int32_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
1378int32_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
1393uint16_t ViEChannel::MaxDataPayloadLength() const {
1394  return rtp_rtcp_->MaxDataPayloadLength();
1395}
1396
1397int32_t ViEChannel::EnableColorEnhancement(bool enable) {
1398  CriticalSectionScoped cs(callback_cs_.get());
1399  color_enhancement_ = enable;
1400  return 0;
1401}
1402
1403RtpRtcp* ViEChannel::rtp_rtcp() {
1404  return rtp_rtcp_.get();
1405}
1406
1407CallStatsObserver* 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.
1415int32_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
1462int32_t ViEChannel::ReceivedDecodedReferenceFrame(
1463  const uint64_t picture_id) {
1464  return rtp_rtcp_->SendRTCPReferencePictureSelection(picture_id);
1465}
1466
1467void ViEChannel::IncomingCodecChanged(const VideoCodec& codec) {
1468  CriticalSectionScoped cs(callback_cs_.get());
1469  receive_codec_ = codec;
1470}
1471
1472int32_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
1481void 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
1500int32_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
1510int32_t ViEChannel::SliceLossIndicationRequest(
1511  const uint64_t picture_id) {
1512  return rtp_rtcp_->SendRTCPSliceLossIndication((uint8_t) picture_id);
1513}
1514
1515int32_t ViEChannel::ResendPackets(const uint16_t* sequence_numbers,
1516                                        uint16_t length) {
1517  return rtp_rtcp_->SendNACK(sequence_numbers, length);
1518}
1519
1520bool ViEChannel::ChannelDecodeThreadFunction(void* obj) {
1521  return static_cast<ViEChannel*>(obj)->ChannelDecodeProcess();
1522}
1523
1524bool ViEChannel::ChannelDecodeProcess() {
1525  vcm_->Decode(kMaxDecodeWaitTimeMs);
1526  return true;
1527}
1528
1529void ViEChannel::OnRttUpdate(uint32_t rtt) {
1530  vcm_->SetReceiveChannelParameters(rtt);
1531}
1532
1533int32_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
1556int32_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
1571int32_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
1585int32_t ViEChannel::VoiceChannel() {
1586  return vie_sync_.VoiceChannel();
1587}
1588
1589int32_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
1599void ViEChannel::RegisterPreRenderCallback(
1600    I420FrameCallback* pre_render_callback) {
1601  CriticalSectionScoped cs(callback_cs_.get());
1602  pre_render_callback_ = pre_render_callback;
1603}
1604
1605void ViEChannel::RegisterPreDecodeImageCallback(
1606    EncodedImageCallback* pre_decode_callback) {
1607  vcm_->RegisterPreDecodeImageCallback(pre_decode_callback);
1608}
1609
1610void 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
1628int32_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
1644void 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
1656void 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
1668void ViEChannel::ResetStatistics(uint32_t ssrc) {
1669  StreamStatistician* statistician =
1670      vie_receiver_.GetReceiveStatistics()->GetStatistician(ssrc);
1671  if (statistician)
1672    statistician->ResetStatistics();
1673}
1674
1675void 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
1686void 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