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