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