2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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.
11 #include "webrtc/video_engine/vie_channel.h"
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/metrics.h"
29 #include "webrtc/system_wrappers/interface/thread_wrapper.h"
30 #include "webrtc/video_engine/call_stats.h"
31 #include "webrtc/video_engine/include/vie_codec.h"
32 #include "webrtc/video_engine/include/vie_errors.h"
33 #include "webrtc/video_engine/include/vie_image_process.h"
34 #include "webrtc/video_engine/include/vie_rtp_rtcp.h"
35 #include "webrtc/frame_callback.h"
36 #include "webrtc/video_engine/vie_defines.h"
40 const int kMaxDecodeWaitTimeMs = 50;
41 const int kInvalidRtpExtensionId = 0;
42 static const int kMaxTargetDelayMs = 10000;
43 static const float kMaxIncompleteTimeMultiplier = 3.5f;
47 RTCPReportBlock AggregateReportBlocks(
48 const std::vector<RTCPReportBlock>& report_blocks,
49 std::map<uint32_t, RTCPReportBlock>* prev_report_blocks) {
50 int fraction_lost_sum = 0;
51 int fl_seq_num_sum = 0;
53 int number_of_report_blocks = 0;
54 RTCPReportBlock aggregate;
55 std::vector<RTCPReportBlock>::const_iterator report_block =
56 report_blocks.begin();
57 for (; report_block != report_blocks.end(); ++report_block) {
58 aggregate.cumulativeLost += report_block->cumulativeLost;
59 std::map<uint32_t, RTCPReportBlock>::iterator prev_report_block =
60 prev_report_blocks->find(report_block->sourceSSRC);
61 if (prev_report_block != prev_report_blocks->end()) {
62 // Skip the first report block since we won't be able to get a correct
64 int seq_num_diff = report_block->extendedHighSeqNum -
65 prev_report_block->second.extendedHighSeqNum;
66 if (seq_num_diff > 0) {
67 fraction_lost_sum += report_block->fractionLost * seq_num_diff;
68 fl_seq_num_sum += seq_num_diff;
71 jitter_sum += report_block->jitter;
72 ++number_of_report_blocks;
73 (*prev_report_blocks)[report_block->sourceSSRC] = *report_block;
75 if (fl_seq_num_sum > 0) {
76 aggregate.fractionLost =
77 (fraction_lost_sum + fl_seq_num_sum / 2) / fl_seq_num_sum;
79 if (number_of_report_blocks > 0) {
81 (jitter_sum + number_of_report_blocks / 2) / number_of_report_blocks;
83 // Not well defined for aggregated report blocks.
84 aggregate.extendedHighSeqNum = 0;
89 // Helper class receiving statistics callbacks.
90 class ChannelStatsObserver : public CallStatsObserver {
92 explicit ChannelStatsObserver(ViEChannel* owner) : owner_(owner) {}
93 virtual ~ChannelStatsObserver() {}
95 // Implements StatsObserver.
96 virtual void OnRttUpdate(uint32_t rtt) {
97 owner_->OnRttUpdate(rtt);
104 ViEChannel::ViEChannel(int32_t channel_id,
106 uint32_t number_of_cores,
107 const Config& config,
108 ProcessThread& module_process_thread,
109 RtcpIntraFrameObserver* intra_frame_observer,
110 RtcpBandwidthObserver* bandwidth_observer,
111 RemoteBitrateEstimator* remote_bitrate_estimator,
112 RtcpRttStats* rtt_stats,
113 PacedSender* paced_sender,
114 RtpRtcp* default_rtp_rtcp,
116 : ViEFrameProviderBase(channel_id, engine_id),
117 channel_id_(channel_id),
118 engine_id_(engine_id),
119 number_of_cores_(number_of_cores),
120 num_socket_threads_(kViESocketThreads),
121 callback_cs_(CriticalSectionWrapper::CreateCriticalSection()),
122 rtp_rtcp_cs_(CriticalSectionWrapper::CreateCriticalSection()),
123 default_rtp_rtcp_(default_rtp_rtcp),
124 vcm_(VideoCodingModule::Create()),
125 vie_receiver_(channel_id, vcm_, remote_bitrate_estimator, this),
126 vie_sender_(channel_id),
127 vie_sync_(vcm_, this),
128 stats_observer_(new ChannelStatsObserver(this)),
129 module_process_thread_(module_process_thread),
130 codec_observer_(NULL),
131 do_key_frame_callbackRequest_(false),
133 rtcp_observer_(NULL),
134 intra_frame_observer_(intra_frame_observer),
135 rtt_stats_(rtt_stats),
136 paced_sender_(paced_sender),
137 pad_with_redundant_payloads_(false),
138 bandwidth_observer_(bandwidth_observer),
139 send_timestamp_extension_id_(kInvalidRtpExtensionId),
140 absolute_send_time_extension_id_(kInvalidRtpExtensionId),
141 external_transport_(NULL),
142 decoder_reset_(true),
143 wait_for_key_frame_(false),
144 decode_thread_(NULL),
145 effect_filter_(NULL),
146 color_enhancement_(false),
149 nack_history_size_sender_(kSendSidePacketHistorySize),
150 max_nack_reordering_threshold_(kMaxPacketAgeToNack),
151 pre_render_callback_(NULL),
152 start_ms_(Clock::GetRealTimeClock()->TimeInMilliseconds()) {
153 RtpRtcp::Configuration configuration;
154 configuration.id = ViEModuleId(engine_id, channel_id);
155 configuration.audio = false;
156 configuration.default_module = default_rtp_rtcp;
157 configuration.outgoing_transport = &vie_sender_;
158 configuration.rtcp_feedback = this;
159 configuration.intra_frame_callback = intra_frame_observer;
160 configuration.bandwidth_callback = bandwidth_observer;
161 configuration.rtt_stats = rtt_stats;
162 configuration.remote_bitrate_estimator = remote_bitrate_estimator;
163 configuration.paced_sender = paced_sender;
164 configuration.receive_statistics = vie_receiver_.GetReceiveStatistics();
165 configuration.send_bitrate_observer = &send_bitrate_observer_;
166 configuration.send_frame_count_observer = &send_frame_count_observer_;
167 configuration.send_side_delay_observer = &send_side_delay_observer_;
169 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(configuration));
170 vie_receiver_.SetRtpRtcpModule(rtp_rtcp_.get());
171 vcm_->SetNackSettings(kMaxNackListSize, max_nack_reordering_threshold_, 0);
174 int32_t ViEChannel::Init() {
175 if (module_process_thread_.RegisterModule(
176 vie_receiver_.GetReceiveStatistics()) != 0) {
179 // RTP/RTCP initialization.
180 if (rtp_rtcp_->SetSendingMediaStatus(false) != 0) {
183 if (module_process_thread_.RegisterModule(rtp_rtcp_.get()) != 0) {
186 rtp_rtcp_->SetKeyFrameRequestMethod(kKeyFrameReqFirRtp);
187 rtp_rtcp_->SetRTCPStatus(kRtcpCompound);
189 rtp_rtcp_->SetStorePacketsStatus(true, nack_history_size_sender_);
191 if (vcm_->InitializeReceiver() != 0) {
194 if (vcm_->SetVideoProtection(kProtectionKeyOnLoss, true)) {
197 if (vcm_->RegisterReceiveCallback(this) != 0) {
200 vcm_->RegisterFrameTypeCallback(this);
201 vcm_->RegisterReceiveStatisticsCallback(this);
202 vcm_->RegisterDecoderTimingCallback(this);
203 vcm_->SetRenderDelay(kViEDefaultRenderDelayMs);
204 if (module_process_thread_.RegisterModule(vcm_) != 0) {
207 #ifdef VIDEOCODEC_VP8
208 VideoCodec video_codec;
209 if (vcm_->Codec(kVideoCodecVP8, &video_codec) == VCM_OK) {
210 rtp_rtcp_->RegisterSendPayload(video_codec);
211 // TODO(holmer): Can we call SetReceiveCodec() here instead?
212 if (!vie_receiver_.RegisterPayload(video_codec)) {
215 vcm_->RegisterReceiveCodec(&video_codec, number_of_cores_);
216 vcm_->RegisterSendCodec(&video_codec, number_of_cores_,
217 rtp_rtcp_->MaxDataPayloadLength());
226 ViEChannel::~ViEChannel() {
228 // Make sure we don't get more callbacks from the RTP module.
229 module_process_thread_.DeRegisterModule(vie_receiver_.GetReceiveStatistics());
230 module_process_thread_.DeRegisterModule(rtp_rtcp_.get());
231 module_process_thread_.DeRegisterModule(vcm_);
232 module_process_thread_.DeRegisterModule(&vie_sync_);
233 while (simulcast_rtp_rtcp_.size() > 0) {
234 std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
235 RtpRtcp* rtp_rtcp = *it;
236 module_process_thread_.DeRegisterModule(rtp_rtcp);
238 simulcast_rtp_rtcp_.erase(it);
240 while (removed_rtp_rtcp_.size() > 0) {
241 std::list<RtpRtcp*>::iterator it = removed_rtp_rtcp_.begin();
243 removed_rtp_rtcp_.erase(it);
245 if (decode_thread_) {
249 VideoCodingModule::Destroy(vcm_);
252 void ViEChannel::UpdateHistograms() {
253 const float kMinCallLengthInMinutes = 0.5f;
254 float elapsed_minutes =
255 (Clock::GetRealTimeClock()->TimeInMilliseconds() - start_ms_) / 60000.0f;
256 if (elapsed_minutes < kMinCallLengthInMinutes) {
259 RtcpPacketTypeCounter rtcp_sent;
260 RtcpPacketTypeCounter rtcp_received;
261 GetRtcpPacketTypeCounters(&rtcp_sent, &rtcp_received);
264 if (rtcp_received.nack_requests > 0) {
265 RTC_HISTOGRAM_PERCENTAGE(
266 "WebRTC.Video.UniqueNackRequestsReceivedInPercent",
267 rtcp_received.UniqueNackRequestsInPercent());
269 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.NackPacketsReceivedPerMinute",
270 rtcp_received.nack_packets / elapsed_minutes);
271 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.FirPacketsReceivedPerMinute",
272 rtcp_received.fir_packets / elapsed_minutes);
273 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.PliPacketsReceivedPerMinute",
274 rtcp_received.pli_packets / elapsed_minutes);
275 } else if (vie_receiver_.GetRemoteSsrc() > 0) {
276 // Get receive stats if we are receiving packets, i.e. there is a remote
278 if (rtcp_sent.nack_requests > 0) {
279 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.UniqueNackRequestsSentInPercent",
280 rtcp_sent.UniqueNackRequestsInPercent());
282 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.NackPacketsSentPerMinute",
283 rtcp_sent.nack_packets / elapsed_minutes);
284 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.FirPacketsSentPerMinute",
285 rtcp_sent.fir_packets / elapsed_minutes);
286 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.PliPacketsSentPerMinute",
287 rtcp_sent.pli_packets / elapsed_minutes);
289 webrtc::VCMFrameCount frames;
290 if (vcm_->ReceivedFrameCount(frames) == VCM_OK) {
291 uint32_t total_frames = frames.numKeyFrames + frames.numDeltaFrames;
292 if (total_frames > 0) {
293 RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.KeyFramesReceivedInPermille",
294 static_cast<int>((frames.numKeyFrames * 1000.0f / total_frames) +
301 int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
306 if (video_codec.codecType == kVideoCodecRED ||
307 video_codec.codecType == kVideoCodecULPFEC) {
308 LOG_F(LS_ERROR) << "Not a valid send codec " << video_codec.codecType;
311 if (kMaxSimulcastStreams < video_codec.numberOfSimulcastStreams) {
312 LOG_F(LS_ERROR) << "Incorrect config "
313 << video_codec.numberOfSimulcastStreams;
316 // Update the RTP module with the settings.
317 // Stop and Start the RTP module -> trigger new SSRC, if an SSRC hasn't been
319 bool restart_rtp = false;
320 if (rtp_rtcp_->Sending() && new_stream) {
322 rtp_rtcp_->SetSendingStatus(false);
323 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
324 it != simulcast_rtp_rtcp_.end(); ++it) {
325 (*it)->SetSendingStatus(false);
326 (*it)->SetSendingMediaStatus(false);
330 bool fec_enabled = false;
331 uint8_t payload_type_red;
332 uint8_t payload_type_fec;
333 rtp_rtcp_->GenericFECStatus(fec_enabled, payload_type_red, payload_type_fec);
335 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
337 if (video_codec.numberOfSimulcastStreams > 0) {
338 // Set correct bitrate to base layer.
339 // Create our simulcast RTP modules.
340 int num_modules_to_add = video_codec.numberOfSimulcastStreams -
341 simulcast_rtp_rtcp_.size() - 1;
342 if (num_modules_to_add < 0) {
343 num_modules_to_add = 0;
346 // Add back removed rtp modules. Order is important (allocate from front of
347 // removed modules) to preserve RTP settings such as SSRCs for simulcast
349 std::list<RtpRtcp*> new_rtp_modules;
350 for (; removed_rtp_rtcp_.size() > 0 && num_modules_to_add > 0;
351 --num_modules_to_add) {
352 new_rtp_modules.push_back(removed_rtp_rtcp_.front());
353 removed_rtp_rtcp_.pop_front();
356 for (int i = 0; i < num_modules_to_add; ++i)
357 new_rtp_modules.push_back(CreateRtpRtcpModule());
359 // Initialize newly added modules.
360 for (std::list<RtpRtcp*>::iterator it = new_rtp_modules.begin();
361 it != new_rtp_modules.end();
363 RtpRtcp* rtp_rtcp = *it;
365 rtp_rtcp->SetRTCPStatus(rtp_rtcp_->RTCP());
367 if (rtp_rtcp_->StorePackets()) {
368 rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
369 } else if (paced_sender_) {
370 rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
374 rtp_rtcp->SetGenericFECStatus(
375 fec_enabled, payload_type_red, payload_type_fec);
377 rtp_rtcp->SetSendingStatus(rtp_rtcp_->Sending());
378 rtp_rtcp->SetSendingMediaStatus(rtp_rtcp_->SendingMedia());
383 rtp_rtcp_->RTXSendStatus(&mode, &ssrc, &payload_type);
384 rtp_rtcp->SetRTXSendStatus(mode);
385 simulcast_rtp_rtcp_.push_back(rtp_rtcp);
387 // Silently ignore error.
388 module_process_thread_.RegisterModule(rtp_rtcp);
391 // Remove last in list if we have too many.
392 for (int j = simulcast_rtp_rtcp_.size();
393 j > (video_codec.numberOfSimulcastStreams - 1);
395 RtpRtcp* rtp_rtcp = simulcast_rtp_rtcp_.back();
396 module_process_thread_.DeRegisterModule(rtp_rtcp);
397 rtp_rtcp->SetSendingStatus(false);
398 rtp_rtcp->SetSendingMediaStatus(false);
399 rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback(NULL);
400 rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL);
401 simulcast_rtp_rtcp_.pop_back();
402 removed_rtp_rtcp_.push_front(rtp_rtcp);
405 // Configure all simulcast modules.
406 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
407 it != simulcast_rtp_rtcp_.end();
410 RtpRtcp* rtp_rtcp = *it;
411 rtp_rtcp->DeRegisterSendPayload(video_codec.plType);
412 if (rtp_rtcp->RegisterSendPayload(video_codec) != 0) {
416 rtp_rtcp->SetMaxTransferUnit(mtu_);
419 rtp_rtcp->SetSendingStatus(true);
420 rtp_rtcp->SetSendingMediaStatus(true);
422 if (send_timestamp_extension_id_ != kInvalidRtpExtensionId) {
423 // Deregister in case the extension was previously enabled.
424 rtp_rtcp->DeregisterSendRtpHeaderExtension(
425 kRtpExtensionTransmissionTimeOffset);
426 if (rtp_rtcp->RegisterSendRtpHeaderExtension(
427 kRtpExtensionTransmissionTimeOffset,
428 send_timestamp_extension_id_) != 0) {
431 rtp_rtcp->DeregisterSendRtpHeaderExtension(
432 kRtpExtensionTransmissionTimeOffset);
434 if (absolute_send_time_extension_id_ != kInvalidRtpExtensionId) {
435 // Deregister in case the extension was previously enabled.
436 rtp_rtcp->DeregisterSendRtpHeaderExtension(
437 kRtpExtensionAbsoluteSendTime);
438 if (rtp_rtcp->RegisterSendRtpHeaderExtension(
439 kRtpExtensionAbsoluteSendTime,
440 absolute_send_time_extension_id_) != 0) {
443 rtp_rtcp->DeregisterSendRtpHeaderExtension(
444 kRtpExtensionAbsoluteSendTime);
446 rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback(
447 rtp_rtcp_->GetSendChannelRtcpStatisticsCallback());
448 rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(
449 rtp_rtcp_->GetSendChannelRtpStatisticsCallback());
451 // |RegisterSimulcastRtpRtcpModules| resets all old weak pointers and old
452 // modules can be deleted after this step.
453 vie_receiver_.RegisterSimulcastRtpRtcpModules(simulcast_rtp_rtcp_);
455 while (!simulcast_rtp_rtcp_.empty()) {
456 RtpRtcp* rtp_rtcp = simulcast_rtp_rtcp_.back();
457 module_process_thread_.DeRegisterModule(rtp_rtcp);
458 rtp_rtcp->SetSendingStatus(false);
459 rtp_rtcp->SetSendingMediaStatus(false);
460 rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback(NULL);
461 rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL);
462 simulcast_rtp_rtcp_.pop_back();
463 removed_rtp_rtcp_.push_front(rtp_rtcp);
465 // Clear any previous modules.
466 vie_receiver_.RegisterSimulcastRtpRtcpModules(simulcast_rtp_rtcp_);
469 // Don't log this error, no way to check in advance if this pl_type is
470 // registered or not...
471 rtp_rtcp_->DeRegisterSendPayload(video_codec.plType);
472 if (rtp_rtcp_->RegisterSendPayload(video_codec) != 0) {
476 rtp_rtcp_->SetSendingStatus(true);
477 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
478 it != simulcast_rtp_rtcp_.end(); ++it) {
479 (*it)->SetSendingStatus(true);
480 (*it)->SetSendingMediaStatus(true);
486 int32_t ViEChannel::SetReceiveCodec(const VideoCodec& video_codec) {
487 if (!vie_receiver_.SetReceiveCodec(video_codec)) {
491 if (video_codec.codecType != kVideoCodecRED &&
492 video_codec.codecType != kVideoCodecULPFEC) {
493 // Register codec type with VCM, but do not register RED or ULPFEC.
494 if (vcm_->RegisterReceiveCodec(&video_codec, number_of_cores_,
495 wait_for_key_frame_) != VCM_OK) {
502 int32_t ViEChannel::GetReceiveCodec(VideoCodec* video_codec) {
503 if (vcm_->ReceiveCodec(video_codec) != 0) {
509 int32_t ViEChannel::RegisterCodecObserver(ViEDecoderObserver* observer) {
510 CriticalSectionScoped cs(callback_cs_.get());
512 if (codec_observer_) {
513 LOG_F(LS_ERROR) << "Observer already registered.";
516 codec_observer_ = observer;
518 codec_observer_ = NULL;
523 int32_t ViEChannel::RegisterExternalDecoder(const uint8_t pl_type,
524 VideoDecoder* decoder,
525 bool buffered_rendering,
526 int32_t render_delay) {
528 result = vcm_->RegisterExternalDecoder(decoder, pl_type, buffered_rendering);
529 if (result != VCM_OK) {
532 return vcm_->SetRenderDelay(render_delay);
535 int32_t ViEChannel::DeRegisterExternalDecoder(const uint8_t pl_type) {
536 VideoCodec current_receive_codec;
538 result = vcm_->ReceiveCodec(¤t_receive_codec);
539 if (vcm_->RegisterExternalDecoder(NULL, pl_type, false) != VCM_OK) {
543 if (result == 0 && current_receive_codec.plType == pl_type) {
544 result = vcm_->RegisterReceiveCodec(
545 ¤t_receive_codec, number_of_cores_, wait_for_key_frame_);
550 int32_t ViEChannel::ReceiveCodecStatistics(uint32_t* num_key_frames,
551 uint32_t* num_delta_frames) {
552 VCMFrameCount received_frames;
553 if (vcm_->ReceivedFrameCount(received_frames) != VCM_OK) {
556 *num_key_frames = received_frames.numKeyFrames;
557 *num_delta_frames = received_frames.numDeltaFrames;
561 uint32_t ViEChannel::DiscardedPackets() const {
562 return vcm_->DiscardedPackets();
565 int ViEChannel::ReceiveDelay() const {
566 return vcm_->Delay();
569 int32_t ViEChannel::WaitForKeyFrame(bool wait) {
570 wait_for_key_frame_ = wait;
574 int32_t ViEChannel::SetSignalPacketLossStatus(bool enable,
575 bool only_key_frames) {
577 if (only_key_frames) {
578 vcm_->SetVideoProtection(kProtectionKeyOnLoss, false);
579 if (vcm_->SetVideoProtection(kProtectionKeyOnKeyLoss, true) != VCM_OK) {
583 vcm_->SetVideoProtection(kProtectionKeyOnKeyLoss, false);
584 if (vcm_->SetVideoProtection(kProtectionKeyOnLoss, true) != VCM_OK) {
589 vcm_->SetVideoProtection(kProtectionKeyOnLoss, false);
590 vcm_->SetVideoProtection(kProtectionKeyOnKeyLoss, false);
595 int32_t ViEChannel::SetRTCPMode(const RTCPMethod rtcp_mode) {
596 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
597 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
598 it != simulcast_rtp_rtcp_.end();
600 RtpRtcp* rtp_rtcp = *it;
601 rtp_rtcp->SetRTCPStatus(rtcp_mode);
603 return rtp_rtcp_->SetRTCPStatus(rtcp_mode);
606 int32_t ViEChannel::GetRTCPMode(RTCPMethod* rtcp_mode) {
607 *rtcp_mode = rtp_rtcp_->RTCP();
611 int32_t ViEChannel::SetNACKStatus(const bool enable) {
612 // Update the decoding VCM.
613 if (vcm_->SetVideoProtection(kProtectionNack, enable) != VCM_OK) {
617 // Disable possible FEC.
618 SetFECStatus(false, 0, 0);
620 // Update the decoding VCM.
621 if (vcm_->SetVideoProtection(kProtectionNack, enable) != VCM_OK) {
624 return ProcessNACKRequest(enable);
627 int32_t ViEChannel::ProcessNACKRequest(const bool enable) {
630 if (rtp_rtcp_->RTCP() == kRtcpOff) {
633 vie_receiver_.SetNackStatus(true, max_nack_reordering_threshold_);
634 rtp_rtcp_->SetStorePacketsStatus(true, nack_history_size_sender_);
635 vcm_->RegisterPacketRequestCallback(this);
637 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
639 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
640 it != simulcast_rtp_rtcp_.end();
642 RtpRtcp* rtp_rtcp = *it;
643 rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
645 // Don't introduce errors when NACK is enabled.
646 vcm_->SetDecodeErrorMode(kNoErrors);
648 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
649 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
650 it != simulcast_rtp_rtcp_.end();
652 RtpRtcp* rtp_rtcp = *it;
653 if (paced_sender_ == NULL) {
654 rtp_rtcp->SetStorePacketsStatus(false, 0);
657 vcm_->RegisterPacketRequestCallback(NULL);
658 if (paced_sender_ == NULL) {
659 rtp_rtcp_->SetStorePacketsStatus(false, 0);
661 vie_receiver_.SetNackStatus(false, max_nack_reordering_threshold_);
662 // When NACK is off, allow decoding with errors. Otherwise, the video
663 // will freeze, and will only recover with a complete key frame.
664 vcm_->SetDecodeErrorMode(kWithErrors);
669 int32_t ViEChannel::SetFECStatus(const bool enable,
670 const unsigned char payload_typeRED,
671 const unsigned char payload_typeFEC) {
672 // Disable possible NACK.
674 SetNACKStatus(false);
677 return ProcessFECRequest(enable, payload_typeRED, payload_typeFEC);
680 int32_t ViEChannel::ProcessFECRequest(
682 const unsigned char payload_typeRED,
683 const unsigned char payload_typeFEC) {
684 if (rtp_rtcp_->SetGenericFECStatus(enable, payload_typeRED,
685 payload_typeFEC) != 0) {
688 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
689 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
690 it != simulcast_rtp_rtcp_.end();
692 RtpRtcp* rtp_rtcp = *it;
693 rtp_rtcp->SetGenericFECStatus(enable, payload_typeRED, payload_typeFEC);
698 int32_t ViEChannel::SetHybridNACKFECStatus(
700 const unsigned char payload_typeRED,
701 const unsigned char payload_typeFEC) {
702 if (vcm_->SetVideoProtection(kProtectionNackFEC, enable) != VCM_OK) {
707 ret_val = ProcessNACKRequest(enable);
711 return ProcessFECRequest(enable, payload_typeRED, payload_typeFEC);
714 int ViEChannel::SetSenderBufferingMode(int target_delay_ms) {
715 if ((target_delay_ms < 0) || (target_delay_ms > kMaxTargetDelayMs)) {
716 LOG(LS_ERROR) << "Invalid send buffer value.";
719 if (target_delay_ms == 0) {
721 nack_history_size_sender_ = kSendSidePacketHistorySize;
723 nack_history_size_sender_ = GetRequiredNackListSize(target_delay_ms);
724 // Don't allow a number lower than the default value.
725 if (nack_history_size_sender_ < kSendSidePacketHistorySize) {
726 nack_history_size_sender_ = kSendSidePacketHistorySize;
729 if (rtp_rtcp_->SetStorePacketsStatus(true, nack_history_size_sender_) != 0) {
735 int ViEChannel::SetReceiverBufferingMode(int target_delay_ms) {
736 if ((target_delay_ms < 0) || (target_delay_ms > kMaxTargetDelayMs)) {
737 LOG(LS_ERROR) << "Invalid receive buffer delay value.";
740 int max_nack_list_size;
741 int max_incomplete_time_ms;
742 if (target_delay_ms == 0) {
743 // Real-time mode - restore default settings.
744 max_nack_reordering_threshold_ = kMaxPacketAgeToNack;
745 max_nack_list_size = kMaxNackListSize;
746 max_incomplete_time_ms = 0;
748 max_nack_list_size = 3 * GetRequiredNackListSize(target_delay_ms) / 4;
749 max_nack_reordering_threshold_ = max_nack_list_size;
750 // Calculate the max incomplete time and round to int.
751 max_incomplete_time_ms = static_cast<int>(kMaxIncompleteTimeMultiplier *
752 target_delay_ms + 0.5f);
754 vcm_->SetNackSettings(max_nack_list_size, max_nack_reordering_threshold_,
755 max_incomplete_time_ms);
756 vcm_->SetMinReceiverDelay(target_delay_ms);
757 if (vie_sync_.SetTargetBufferingDelay(target_delay_ms) < 0)
762 int ViEChannel::GetRequiredNackListSize(int target_delay_ms) {
763 // The max size of the nack list should be large enough to accommodate the
764 // the number of packets (frames) resulting from the increased delay.
765 // Roughly estimating for ~40 packets per frame @ 30fps.
766 return target_delay_ms * 40 * 30 / 1000;
769 int32_t ViEChannel::SetKeyFrameRequestMethod(
770 const KeyFrameRequestMethod method) {
771 return rtp_rtcp_->SetKeyFrameRequestMethod(method);
774 bool ViEChannel::EnableRemb(bool enable) {
775 if (rtp_rtcp_->SetREMBStatus(enable) != 0)
780 int ViEChannel::SetSendTimestampOffsetStatus(bool enable, int id) {
781 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
784 // Enable the extension, but disable possible old id to avoid errors.
785 send_timestamp_extension_id_ = id;
786 rtp_rtcp_->DeregisterSendRtpHeaderExtension(
787 kRtpExtensionTransmissionTimeOffset);
788 error = rtp_rtcp_->RegisterSendRtpHeaderExtension(
789 kRtpExtensionTransmissionTimeOffset, id);
790 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
791 it != simulcast_rtp_rtcp_.end(); it++) {
792 (*it)->DeregisterSendRtpHeaderExtension(
793 kRtpExtensionTransmissionTimeOffset);
794 error |= (*it)->RegisterSendRtpHeaderExtension(
795 kRtpExtensionTransmissionTimeOffset, id);
798 // Disable the extension.
799 send_timestamp_extension_id_ = kInvalidRtpExtensionId;
800 rtp_rtcp_->DeregisterSendRtpHeaderExtension(
801 kRtpExtensionTransmissionTimeOffset);
802 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
803 it != simulcast_rtp_rtcp_.end(); it++) {
804 (*it)->DeregisterSendRtpHeaderExtension(
805 kRtpExtensionTransmissionTimeOffset);
811 int ViEChannel::SetReceiveTimestampOffsetStatus(bool enable, int id) {
812 return vie_receiver_.SetReceiveTimestampOffsetStatus(enable, id) ? 0 : -1;
815 int ViEChannel::SetSendAbsoluteSendTimeStatus(bool enable, int id) {
816 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
819 // Enable the extension, but disable possible old id to avoid errors.
820 absolute_send_time_extension_id_ = id;
821 rtp_rtcp_->DeregisterSendRtpHeaderExtension(
822 kRtpExtensionAbsoluteSendTime);
823 error = rtp_rtcp_->RegisterSendRtpHeaderExtension(
824 kRtpExtensionAbsoluteSendTime, id);
825 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
826 it != simulcast_rtp_rtcp_.end(); it++) {
827 (*it)->DeregisterSendRtpHeaderExtension(
828 kRtpExtensionAbsoluteSendTime);
829 error |= (*it)->RegisterSendRtpHeaderExtension(
830 kRtpExtensionAbsoluteSendTime, id);
833 // Disable the extension.
834 absolute_send_time_extension_id_ = kInvalidRtpExtensionId;
835 rtp_rtcp_->DeregisterSendRtpHeaderExtension(
836 kRtpExtensionAbsoluteSendTime);
837 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
838 it != simulcast_rtp_rtcp_.end(); it++) {
839 (*it)->DeregisterSendRtpHeaderExtension(
840 kRtpExtensionAbsoluteSendTime);
846 int ViEChannel::SetReceiveAbsoluteSendTimeStatus(bool enable, int id) {
847 return vie_receiver_.SetReceiveAbsoluteSendTimeStatus(enable, id) ? 0 : -1;
850 void ViEChannel::SetRtcpXrRrtrStatus(bool enable) {
851 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
852 rtp_rtcp_->SetRtcpXrRrtrStatus(enable);
855 void ViEChannel::SetTransmissionSmoothingStatus(bool enable) {
856 assert(paced_sender_ && "No paced sender registered.");
857 paced_sender_->SetStatus(enable);
860 int32_t ViEChannel::EnableTMMBR(const bool enable) {
861 return rtp_rtcp_->SetTMMBRStatus(enable);
864 int32_t ViEChannel::EnableKeyFrameRequestCallback(const bool enable) {
866 CriticalSectionScoped cs(callback_cs_.get());
867 if (enable && !codec_observer_) {
868 LOG(LS_ERROR) << "No ViECodecObserver set.";
871 do_key_frame_callbackRequest_ = enable;
875 int32_t ViEChannel::SetSSRC(const uint32_t SSRC,
876 const StreamType usage,
877 const uint8_t simulcast_idx) {
878 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
879 ReserveRtpRtcpModules(simulcast_idx + 1);
880 RtpRtcp* rtp_rtcp = GetRtpRtcpModule(simulcast_idx);
881 if (rtp_rtcp == NULL)
883 if (usage == kViEStreamTypeRtx) {
884 rtp_rtcp->SetRtxSsrc(SSRC);
886 rtp_rtcp->SetSSRC(SSRC);
891 int32_t ViEChannel::SetRemoteSSRCType(const StreamType usage,
892 const uint32_t SSRC) {
893 vie_receiver_.SetRtxSsrc(SSRC);
897 int32_t ViEChannel::GetLocalSSRC(uint8_t idx, unsigned int* ssrc) {
898 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
899 RtpRtcp* rtp_rtcp = GetRtpRtcpModule(idx);
900 if (rtp_rtcp == NULL)
902 *ssrc = rtp_rtcp->SSRC();
906 int32_t ViEChannel::GetRemoteSSRC(uint32_t* ssrc) {
907 *ssrc = vie_receiver_.GetRemoteSsrc();
911 int32_t ViEChannel::GetRemoteCSRC(uint32_t CSRCs[kRtpCsrcSize]) {
912 uint32_t arrayCSRC[kRtpCsrcSize];
913 memset(arrayCSRC, 0, sizeof(arrayCSRC));
915 int num_csrcs = vie_receiver_.GetCsrcs(arrayCSRC);
917 memcpy(CSRCs, arrayCSRC, num_csrcs * sizeof(uint32_t));
922 void ViEChannel::SetPadWithRedundantPayloads(bool enable) {
924 CriticalSectionScoped cs(callback_cs_.get());
925 pad_with_redundant_payloads_ = enable;
930 rtp_rtcp_->RTXSendStatus(&mode, &ssrc, &payload_type);
931 if (mode != kRtxOff) {
932 // Since RTX was already enabled we have to reset it with payload-based
934 SetRtxSendStatus(true);
938 int ViEChannel::SetRtxSendPayloadType(int payload_type) {
939 rtp_rtcp_->SetRtxSendPayloadType(payload_type);
940 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
941 it != simulcast_rtp_rtcp_.end(); it++) {
942 (*it)->SetRtxSendPayloadType(payload_type);
944 SetRtxSendStatus(true);
948 void ViEChannel::SetRtxSendStatus(bool enable) {
949 int rtx_settings = kRtxOff;
951 CriticalSectionScoped cs(callback_cs_.get());
952 rtx_settings = kRtxRetransmitted;
953 if (pad_with_redundant_payloads_)
954 rtx_settings |= kRtxRedundantPayloads;
956 rtp_rtcp_->SetRTXSendStatus(rtx_settings);
957 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
958 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
959 it != simulcast_rtp_rtcp_.end(); it++) {
960 (*it)->SetRTXSendStatus(rtx_settings);
964 void ViEChannel::SetRtxReceivePayloadType(int payload_type) {
965 vie_receiver_.SetRtxPayloadType(payload_type);
968 int32_t ViEChannel::SetStartSequenceNumber(uint16_t sequence_number) {
969 if (rtp_rtcp_->Sending()) {
972 return rtp_rtcp_->SetSequenceNumber(sequence_number);
975 void ViEChannel::SetRtpStateForSsrc(uint32_t ssrc, const RtpState& rtp_state) {
976 assert(!rtp_rtcp_->Sending());
977 default_rtp_rtcp_->SetRtpStateForSsrc(ssrc, rtp_state);
980 RtpState ViEChannel::GetRtpStateForSsrc(uint32_t ssrc) {
981 assert(!rtp_rtcp_->Sending());
984 if (!default_rtp_rtcp_->GetRtpStateForSsrc(ssrc, &rtp_state)) {
985 LOG(LS_ERROR) << "Couldn't get RTP state for ssrc: " << ssrc;
990 int32_t ViEChannel::SetRTCPCName(const char rtcp_cname[]) {
991 if (rtp_rtcp_->Sending()) {
994 return rtp_rtcp_->SetCNAME(rtcp_cname);
997 int32_t ViEChannel::GetRemoteRTCPCName(char rtcp_cname[]) {
998 uint32_t remoteSSRC = vie_receiver_.GetRemoteSsrc();
999 return rtp_rtcp_->RemoteCNAME(remoteSSRC, rtcp_cname);
1002 int32_t ViEChannel::RegisterRtpObserver(ViERTPObserver* observer) {
1003 CriticalSectionScoped cs(callback_cs_.get());
1005 if (rtp_observer_) {
1006 LOG_F(LS_ERROR) << "Observer already registered.";
1009 rtp_observer_ = observer;
1011 rtp_observer_ = NULL;
1016 int32_t ViEChannel::RegisterRtcpObserver(ViERTCPObserver* observer) {
1017 CriticalSectionScoped cs(callback_cs_.get());
1019 if (rtcp_observer_) {
1020 LOG_F(LS_ERROR) << "Observer already registered.";
1023 rtcp_observer_ = observer;
1025 rtcp_observer_ = NULL;
1030 int32_t ViEChannel::SendApplicationDefinedRTCPPacket(
1031 const uint8_t sub_type,
1033 const uint8_t* data,
1034 uint16_t data_length_in_bytes) {
1035 if (!rtp_rtcp_->Sending()) {
1039 LOG_F(LS_ERROR) << "Invalid input.";
1042 if (data_length_in_bytes % 4 != 0) {
1043 LOG(LS_ERROR) << "Invalid input length.";
1046 RTCPMethod rtcp_method = rtp_rtcp_->RTCP();
1047 if (rtcp_method == kRtcpOff) {
1048 LOG_F(LS_ERROR) << "RTCP not enable.";
1051 // Create and send packet.
1052 if (rtp_rtcp_->SetRTCPApplicationSpecificData(sub_type, name, data,
1053 data_length_in_bytes) != 0) {
1059 int32_t ViEChannel::GetSendRtcpStatistics(uint16_t* fraction_lost,
1060 uint32_t* cumulative_lost,
1061 uint32_t* extended_max,
1062 uint32_t* jitter_samples,
1064 // Aggregate the report blocks associated with streams sent on this channel.
1065 std::vector<RTCPReportBlock> report_blocks;
1066 rtp_rtcp_->RemoteRTCPStat(&report_blocks);
1068 CriticalSectionScoped lock(rtp_rtcp_cs_.get());
1069 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
1070 it != simulcast_rtp_rtcp_.end();
1072 (*it)->RemoteRTCPStat(&report_blocks);
1076 if (report_blocks.empty())
1079 uint32_t remote_ssrc = vie_receiver_.GetRemoteSsrc();
1080 std::vector<RTCPReportBlock>::const_iterator it = report_blocks.begin();
1081 for (; it != report_blocks.end(); ++it) {
1082 if (it->remoteSSRC == remote_ssrc)
1085 if (it == report_blocks.end()) {
1086 // We have not received packets with an SSRC matching the report blocks. To
1087 // have a chance of calculating an RTT we will try with the SSRC of the
1088 // first report block received.
1089 // This is very important for send-only channels where we don't know the
1090 // SSRC of the other end.
1091 remote_ssrc = report_blocks[0].remoteSSRC;
1094 RTCPReportBlock report;
1095 if (report_blocks.size() > 1)
1096 report = AggregateReportBlocks(report_blocks, &prev_report_blocks_);
1098 report = report_blocks[0];
1100 *fraction_lost = report.fractionLost;
1101 *cumulative_lost = report.cumulativeLost;
1102 *extended_max = report.extendedHighSeqNum;
1103 *jitter_samples = report.jitter;
1107 if (rtp_rtcp_->RTT(remote_ssrc, &rtt, &dummy, &dummy, &dummy) != 0) {
1114 void ViEChannel::RegisterSendChannelRtcpStatisticsCallback(
1115 RtcpStatisticsCallback* callback) {
1116 rtp_rtcp_->RegisterSendChannelRtcpStatisticsCallback(callback);
1117 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1118 for (std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
1119 it != simulcast_rtp_rtcp_.end();
1121 (*it)->RegisterSendChannelRtcpStatisticsCallback(callback);
1125 // TODO(holmer): This is a bad function name as it implies that it returns the
1126 // received RTCP, while it actually returns the statistics which will be sent
1128 int32_t ViEChannel::GetReceivedRtcpStatistics(uint16_t* fraction_lost,
1129 uint32_t* cumulative_lost,
1130 uint32_t* extended_max,
1131 uint32_t* jitter_samples,
1133 uint32_t remote_ssrc = vie_receiver_.GetRemoteSsrc();
1134 StreamStatistician* statistician =
1135 vie_receiver_.GetReceiveStatistics()->GetStatistician(remote_ssrc);
1136 RtcpStatistics receive_stats;
1137 if (!statistician || !statistician->GetStatistics(
1138 &receive_stats, rtp_rtcp_->RTCP() == kRtcpOff)) {
1141 *fraction_lost = receive_stats.fraction_lost;
1142 *cumulative_lost = receive_stats.cumulative_lost;
1143 *extended_max = receive_stats.extended_max_sequence_number;
1144 *jitter_samples = receive_stats.jitter;
1148 rtp_rtcp_->RTT(remote_ssrc, &rtt, &dummy, &dummy, &dummy);
1153 void ViEChannel::RegisterReceiveChannelRtcpStatisticsCallback(
1154 RtcpStatisticsCallback* callback) {
1155 vie_receiver_.GetReceiveStatistics()->RegisterRtcpStatisticsCallback(
1159 int32_t ViEChannel::GetRtpStatistics(uint32_t* bytes_sent,
1160 uint32_t* packets_sent,
1161 uint32_t* bytes_received,
1162 uint32_t* packets_received) const {
1163 StreamStatistician* statistician = vie_receiver_.GetReceiveStatistics()->
1164 GetStatistician(vie_receiver_.GetRemoteSsrc());
1165 *bytes_received = 0;
1166 *packets_received = 0;
1168 statistician->GetDataCounters(bytes_received, packets_received);
1169 if (rtp_rtcp_->DataCountersRTP(bytes_sent, packets_sent) != 0) {
1172 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1173 for (std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
1174 it != simulcast_rtp_rtcp_.end();
1176 uint32_t bytes_sent_temp = 0;
1177 uint32_t packets_sent_temp = 0;
1178 RtpRtcp* rtp_rtcp = *it;
1179 rtp_rtcp->DataCountersRTP(&bytes_sent_temp, &packets_sent_temp);
1180 *bytes_sent += bytes_sent_temp;
1181 *packets_sent += packets_sent_temp;
1183 for (std::list<RtpRtcp*>::const_iterator it = removed_rtp_rtcp_.begin();
1184 it != removed_rtp_rtcp_.end(); ++it) {
1185 uint32_t bytes_sent_temp = 0;
1186 uint32_t packets_sent_temp = 0;
1187 RtpRtcp* rtp_rtcp = *it;
1188 rtp_rtcp->DataCountersRTP(&bytes_sent_temp, &packets_sent_temp);
1189 *bytes_sent += bytes_sent_temp;
1190 *packets_sent += packets_sent_temp;
1195 void ViEChannel::RegisterSendChannelRtpStatisticsCallback(
1196 StreamDataCountersCallback* callback) {
1197 rtp_rtcp_->RegisterSendChannelRtpStatisticsCallback(callback);
1199 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1200 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
1201 it != simulcast_rtp_rtcp_.end();
1203 (*it)->RegisterSendChannelRtpStatisticsCallback(callback);
1208 void ViEChannel::RegisterReceiveChannelRtpStatisticsCallback(
1209 StreamDataCountersCallback* callback) {
1210 vie_receiver_.GetReceiveStatistics()->RegisterRtpStatisticsCallback(callback);
1213 void ViEChannel::GetRtcpPacketTypeCounters(
1214 RtcpPacketTypeCounter* packets_sent,
1215 RtcpPacketTypeCounter* packets_received) const {
1216 rtp_rtcp_->GetRtcpPacketTypeCounters(packets_sent, packets_received);
1218 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1219 for (std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
1220 it != simulcast_rtp_rtcp_.end(); ++it) {
1221 RtcpPacketTypeCounter sent;
1222 RtcpPacketTypeCounter received;
1223 (*it)->GetRtcpPacketTypeCounters(&sent, &received);
1224 packets_sent->Add(sent);
1225 packets_received->Add(received);
1227 for (std::list<RtpRtcp*>::const_iterator it = removed_rtp_rtcp_.begin();
1228 it != removed_rtp_rtcp_.end(); ++it) {
1229 RtcpPacketTypeCounter sent;
1230 RtcpPacketTypeCounter received;
1231 (*it)->GetRtcpPacketTypeCounters(&sent, &received);
1232 packets_sent->Add(sent);
1233 packets_received->Add(received);
1237 void ViEChannel::GetBandwidthUsage(uint32_t* total_bitrate_sent,
1238 uint32_t* video_bitrate_sent,
1239 uint32_t* fec_bitrate_sent,
1240 uint32_t* nackBitrateSent) const {
1241 rtp_rtcp_->BitrateSent(total_bitrate_sent, video_bitrate_sent,
1242 fec_bitrate_sent, nackBitrateSent);
1243 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1244 for (std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
1245 it != simulcast_rtp_rtcp_.end(); it++) {
1246 uint32_t stream_rate = 0;
1247 uint32_t video_rate = 0;
1248 uint32_t fec_rate = 0;
1249 uint32_t nackRate = 0;
1250 RtpRtcp* rtp_rtcp = *it;
1251 rtp_rtcp->BitrateSent(&stream_rate, &video_rate, &fec_rate, &nackRate);
1252 *total_bitrate_sent += stream_rate;
1253 *video_bitrate_sent += video_rate;
1254 *fec_bitrate_sent += fec_rate;
1255 *nackBitrateSent += nackRate;
1259 bool ViEChannel::GetSendSideDelay(int* avg_send_delay,
1260 int* max_send_delay) const {
1261 *avg_send_delay = 0;
1262 *max_send_delay = 0;
1263 bool valid_estimate = false;
1264 int num_send_delays = 0;
1265 if (rtp_rtcp_->GetSendSideDelay(avg_send_delay, max_send_delay)) {
1267 valid_estimate = true;
1269 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1270 for (std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
1271 it != simulcast_rtp_rtcp_.end(); it++) {
1272 RtpRtcp* rtp_rtcp = *it;
1273 int sub_stream_avg_delay = 0;
1274 int sub_stream_max_delay = 0;
1275 if (rtp_rtcp->GetSendSideDelay(&sub_stream_avg_delay,
1276 &sub_stream_max_delay)) {
1277 *avg_send_delay += sub_stream_avg_delay;
1278 *max_send_delay = std::max(*max_send_delay, sub_stream_max_delay);
1282 if (num_send_delays > 0) {
1283 valid_estimate = true;
1284 *avg_send_delay = *avg_send_delay / num_send_delays;
1285 *avg_send_delay = (*avg_send_delay + num_send_delays / 2) / num_send_delays;
1287 return valid_estimate;
1290 void ViEChannel::RegisterSendSideDelayObserver(
1291 SendSideDelayObserver* observer) {
1292 send_side_delay_observer_.Set(observer);
1295 void ViEChannel::RegisterSendBitrateObserver(
1296 BitrateStatisticsObserver* observer) {
1297 send_bitrate_observer_.Set(observer);
1300 void ViEChannel::GetReceiveBandwidthEstimatorStats(
1301 ReceiveBandwidthEstimatorStats* output) const {
1302 vie_receiver_.GetReceiveBandwidthEstimatorStats(output);
1305 int32_t ViEChannel::StartRTPDump(const char file_nameUTF8[1024],
1306 RTPDirections direction) {
1307 if (direction == kRtpIncoming) {
1308 return vie_receiver_.StartRTPDump(file_nameUTF8);
1310 return vie_sender_.StartRTPDump(file_nameUTF8);
1314 int32_t ViEChannel::StopRTPDump(RTPDirections direction) {
1315 if (direction == kRtpIncoming) {
1316 return vie_receiver_.StopRTPDump();
1318 return vie_sender_.StopRTPDump();
1322 int32_t ViEChannel::StartSend() {
1323 CriticalSectionScoped cs(callback_cs_.get());
1324 if (!external_transport_) {
1325 LOG(LS_ERROR) << "No transport set.";
1328 rtp_rtcp_->SetSendingMediaStatus(true);
1330 if (rtp_rtcp_->Sending()) {
1331 return kViEBaseAlreadySending;
1333 if (rtp_rtcp_->SetSendingStatus(true) != 0) {
1336 CriticalSectionScoped cs_rtp(rtp_rtcp_cs_.get());
1337 for (std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
1338 it != simulcast_rtp_rtcp_.end();
1340 RtpRtcp* rtp_rtcp = *it;
1341 rtp_rtcp->SetSendingMediaStatus(true);
1342 rtp_rtcp->SetSendingStatus(true);
1347 int32_t ViEChannel::StopSend() {
1348 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1349 rtp_rtcp_->SetSendingMediaStatus(false);
1350 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
1351 it != simulcast_rtp_rtcp_.end();
1353 RtpRtcp* rtp_rtcp = *it;
1354 rtp_rtcp->SetSendingMediaStatus(false);
1356 if (!rtp_rtcp_->Sending()) {
1357 return kViEBaseNotSending;
1361 rtp_rtcp_->ResetSendDataCountersRTP();
1362 if (rtp_rtcp_->SetSendingStatus(false) != 0) {
1365 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
1366 it != simulcast_rtp_rtcp_.end();
1368 RtpRtcp* rtp_rtcp = *it;
1369 rtp_rtcp->ResetSendDataCountersRTP();
1370 rtp_rtcp->SetSendingStatus(false);
1375 bool ViEChannel::Sending() {
1376 return rtp_rtcp_->Sending();
1379 int32_t ViEChannel::StartReceive() {
1380 CriticalSectionScoped cs(callback_cs_.get());
1381 if (StartDecodeThread() != 0) {
1382 vie_receiver_.StopReceive();
1385 vie_receiver_.StartReceive();
1389 int32_t ViEChannel::StopReceive() {
1390 vie_receiver_.StopReceive();
1392 vcm_->ResetDecoder();
1396 int32_t ViEChannel::RegisterSendTransport(Transport* transport) {
1397 if (rtp_rtcp_->Sending()) {
1401 CriticalSectionScoped cs(callback_cs_.get());
1402 if (external_transport_) {
1403 LOG_F(LS_ERROR) << "Transport already registered.";
1406 external_transport_ = transport;
1407 vie_sender_.RegisterSendTransport(transport);
1411 int32_t ViEChannel::DeregisterSendTransport() {
1412 CriticalSectionScoped cs(callback_cs_.get());
1413 if (!external_transport_) {
1416 if (rtp_rtcp_->Sending()) {
1417 LOG_F(LS_ERROR) << "Can't deregister transport when sending.";
1420 external_transport_ = NULL;
1421 vie_sender_.DeregisterSendTransport();
1425 int32_t ViEChannel::ReceivedRTPPacket(
1426 const void* rtp_packet, const int32_t rtp_packet_length,
1427 const PacketTime& packet_time) {
1429 CriticalSectionScoped cs(callback_cs_.get());
1430 if (!external_transport_) {
1434 return vie_receiver_.ReceivedRTPPacket(
1435 rtp_packet, rtp_packet_length, packet_time);
1438 int32_t ViEChannel::ReceivedRTCPPacket(
1439 const void* rtcp_packet, const int32_t rtcp_packet_length) {
1441 CriticalSectionScoped cs(callback_cs_.get());
1442 if (!external_transport_) {
1446 return vie_receiver_.ReceivedRTCPPacket(rtcp_packet, rtcp_packet_length);
1449 int32_t ViEChannel::SetMTU(uint16_t mtu) {
1450 if (rtp_rtcp_->SetMaxTransferUnit(mtu) != 0) {
1453 CriticalSectionScoped cs(rtp_rtcp_cs_.get());
1454 for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
1455 it != simulcast_rtp_rtcp_.end();
1457 RtpRtcp* rtp_rtcp = *it;
1458 rtp_rtcp->SetMaxTransferUnit(mtu);
1464 uint16_t ViEChannel::MaxDataPayloadLength() const {
1465 return rtp_rtcp_->MaxDataPayloadLength();
1468 int32_t ViEChannel::EnableColorEnhancement(bool enable) {
1469 CriticalSectionScoped cs(callback_cs_.get());
1470 color_enhancement_ = enable;
1474 RtpRtcp* ViEChannel::rtp_rtcp() {
1475 return rtp_rtcp_.get();
1478 CallStatsObserver* ViEChannel::GetStatsObserver() {
1479 return stats_observer_.get();
1482 // Do not acquire the lock of |vcm_| in this function. Decode callback won't
1483 // necessarily be called from the decoding thread. The decoding thread may have
1484 // held the lock when calling VideoDecoder::Decode, Reset, or Release. Acquiring
1485 // the same lock in the path of decode callback can deadlock.
1486 int32_t ViEChannel::FrameToRender(
1487 I420VideoFrame& video_frame) { // NOLINT
1488 CriticalSectionScoped cs(callback_cs_.get());
1490 if (decoder_reset_) {
1491 // Trigger a callback to the user if the incoming codec has changed.
1492 if (codec_observer_) {
1493 // The codec set by RegisterReceiveCodec might not be the size we're
1494 // actually decoding.
1495 receive_codec_.width = static_cast<uint16_t>(video_frame.width());
1496 receive_codec_.height = static_cast<uint16_t>(video_frame.height());
1497 codec_observer_->IncomingCodecChanged(channel_id_, receive_codec_);
1499 decoder_reset_ = false;
1501 // Post processing is not supported if the frame is backed by a texture.
1502 if (video_frame.native_handle() == NULL) {
1503 if (pre_render_callback_ != NULL)
1504 pre_render_callback_->FrameCallback(&video_frame);
1505 if (effect_filter_) {
1506 unsigned int length = CalcBufferSize(kI420,
1507 video_frame.width(),
1508 video_frame.height());
1509 scoped_ptr<uint8_t[]> video_buffer(new uint8_t[length]);
1510 ExtractBuffer(video_frame, length, video_buffer.get());
1511 effect_filter_->Transform(length,
1513 video_frame.ntp_time_ms(),
1514 video_frame.timestamp(),
1515 video_frame.width(),
1516 video_frame.height());
1518 if (color_enhancement_) {
1519 VideoProcessingModule::ColorEnhancement(&video_frame);
1523 uint32_t arr_ofCSRC[kRtpCsrcSize];
1524 int32_t no_of_csrcs = vie_receiver_.GetCsrcs(arr_ofCSRC);
1525 if (no_of_csrcs <= 0) {
1526 arr_ofCSRC[0] = vie_receiver_.GetRemoteSsrc();
1529 DeliverFrame(&video_frame, no_of_csrcs, arr_ofCSRC);
1533 int32_t ViEChannel::ReceivedDecodedReferenceFrame(
1534 const uint64_t picture_id) {
1535 return rtp_rtcp_->SendRTCPReferencePictureSelection(picture_id);
1538 void ViEChannel::IncomingCodecChanged(const VideoCodec& codec) {
1539 CriticalSectionScoped cs(callback_cs_.get());
1540 receive_codec_ = codec;
1543 int32_t ViEChannel::OnReceiveStatisticsUpdate(const uint32_t bit_rate,
1544 const uint32_t frame_rate) {
1545 CriticalSectionScoped cs(callback_cs_.get());
1546 if (codec_observer_) {
1547 codec_observer_->IncomingRate(channel_id_, frame_rate, bit_rate);
1552 void ViEChannel::OnDecoderTiming(int decode_ms,
1554 int current_delay_ms,
1555 int target_delay_ms,
1556 int jitter_buffer_ms,
1557 int min_playout_delay_ms,
1558 int render_delay_ms) {
1559 CriticalSectionScoped cs(callback_cs_.get());
1560 if (!codec_observer_)
1562 codec_observer_->DecoderTiming(decode_ms,
1567 min_playout_delay_ms,
1571 int32_t ViEChannel::RequestKeyFrame() {
1573 CriticalSectionScoped cs(callback_cs_.get());
1574 if (codec_observer_ && do_key_frame_callbackRequest_) {
1575 codec_observer_->RequestNewKeyFrame(channel_id_);
1578 return rtp_rtcp_->RequestKeyFrame();
1581 int32_t ViEChannel::SliceLossIndicationRequest(
1582 const uint64_t picture_id) {
1583 return rtp_rtcp_->SendRTCPSliceLossIndication((uint8_t) picture_id);
1586 int32_t ViEChannel::ResendPackets(const uint16_t* sequence_numbers,
1588 return rtp_rtcp_->SendNACK(sequence_numbers, length);
1591 bool ViEChannel::ChannelDecodeThreadFunction(void* obj) {
1592 return static_cast<ViEChannel*>(obj)->ChannelDecodeProcess();
1595 bool ViEChannel::ChannelDecodeProcess() {
1596 vcm_->Decode(kMaxDecodeWaitTimeMs);
1600 void ViEChannel::OnRttUpdate(uint32_t rtt) {
1601 vcm_->SetReceiveChannelParameters(rtt);
1604 void ViEChannel::ReserveRtpRtcpModules(size_t num_modules) {
1605 for (size_t total_modules =
1606 1 + simulcast_rtp_rtcp_.size() + removed_rtp_rtcp_.size();
1607 total_modules < num_modules;
1609 RtpRtcp* rtp_rtcp = CreateRtpRtcpModule();
1610 rtp_rtcp->SetSendingStatus(false);
1611 rtp_rtcp->SetSendingMediaStatus(false);
1612 rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback(NULL);
1613 rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL);
1614 removed_rtp_rtcp_.push_back(rtp_rtcp);
1618 RtpRtcp* ViEChannel::GetRtpRtcpModule(size_t index) const {
1620 return rtp_rtcp_.get();
1621 if (index <= simulcast_rtp_rtcp_.size()) {
1622 std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
1623 for (size_t i = 1; i < index; ++i) {
1629 // If the requested module exists it must be in the removed list. Index
1630 // translation to this list must remove the default module as well as all
1631 // active simulcast modules.
1632 size_t removed_idx = index - simulcast_rtp_rtcp_.size() - 1;
1633 if (removed_idx >= removed_rtp_rtcp_.size())
1636 std::list<RtpRtcp*>::const_iterator it = removed_rtp_rtcp_.begin();
1637 while (removed_idx-- > 0)
1643 RtpRtcp* ViEChannel::CreateRtpRtcpModule() {
1644 RtpRtcp::Configuration configuration;
1645 configuration.id = ViEModuleId(engine_id_, channel_id_);
1646 configuration.audio = false; // Video.
1647 configuration.default_module = default_rtp_rtcp_;
1648 configuration.outgoing_transport = &vie_sender_;
1649 configuration.intra_frame_callback = intra_frame_observer_;
1650 configuration.bandwidth_callback = bandwidth_observer_.get();
1651 configuration.rtt_stats = rtt_stats_;
1652 configuration.paced_sender = paced_sender_;
1653 configuration.send_side_delay_observer = &send_side_delay_observer_;
1655 return RtpRtcp::CreateRtpRtcp(configuration);
1658 int32_t ViEChannel::StartDecodeThread() {
1659 // Start the decode thread
1660 if (decode_thread_) {
1664 decode_thread_ = ThreadWrapper::CreateThread(ChannelDecodeThreadFunction,
1665 this, kHighestPriority,
1667 if (!decode_thread_) {
1671 unsigned int thread_id;
1672 if (decode_thread_->Start(thread_id) == false) {
1673 delete decode_thread_;
1674 decode_thread_ = NULL;
1675 LOG(LS_ERROR) << "Could not start decode thread.";
1681 int32_t ViEChannel::StopDecodeThread() {
1682 if (!decode_thread_) {
1686 decode_thread_->SetNotAlive();
1687 if (decode_thread_->Stop()) {
1688 delete decode_thread_;
1690 assert(false && "could not stop decode thread");
1692 decode_thread_ = NULL;
1696 int32_t ViEChannel::SetVoiceChannel(int32_t ve_channel_id,
1697 VoEVideoSync* ve_sync_interface) {
1698 if (ve_sync_interface) {
1699 // Register lip sync
1700 module_process_thread_.RegisterModule(&vie_sync_);
1702 module_process_thread_.DeRegisterModule(&vie_sync_);
1704 return vie_sync_.ConfigureSync(ve_channel_id,
1707 vie_receiver_.GetRtpReceiver());
1710 int32_t ViEChannel::VoiceChannel() {
1711 return vie_sync_.VoiceChannel();
1714 int32_t ViEChannel::RegisterEffectFilter(ViEEffectFilter* effect_filter) {
1715 CriticalSectionScoped cs(callback_cs_.get());
1716 if (effect_filter && effect_filter_) {
1717 LOG(LS_ERROR) << "Effect filter already registered.";
1720 effect_filter_ = effect_filter;
1724 void ViEChannel::RegisterPreRenderCallback(
1725 I420FrameCallback* pre_render_callback) {
1726 CriticalSectionScoped cs(callback_cs_.get());
1727 pre_render_callback_ = pre_render_callback;
1730 void ViEChannel::RegisterPreDecodeImageCallback(
1731 EncodedImageCallback* pre_decode_callback) {
1732 vcm_->RegisterPreDecodeImageCallback(pre_decode_callback);
1735 void ViEChannel::OnApplicationDataReceived(const int32_t id,
1736 const uint8_t sub_type,
1737 const uint32_t name,
1738 const uint16_t length,
1739 const uint8_t* data) {
1740 if (channel_id_ != ChannelId(id)) {
1743 CriticalSectionScoped cs(callback_cs_.get());
1745 if (rtcp_observer_) {
1746 rtcp_observer_->OnApplicationDataReceived(
1747 channel_id_, sub_type, name, reinterpret_cast<const char*>(data),
1753 int32_t ViEChannel::OnInitializeDecoder(
1755 const int8_t payload_type,
1756 const char payload_name[RTP_PAYLOAD_NAME_SIZE],
1757 const int frequency,
1758 const uint8_t channels,
1759 const uint32_t rate) {
1760 LOG(LS_INFO) << "OnInitializeDecoder " << payload_type << " "
1762 vcm_->ResetDecoder();
1764 CriticalSectionScoped cs(callback_cs_.get());
1765 decoder_reset_ = true;
1769 void ViEChannel::OnIncomingSSRCChanged(const int32_t id, const uint32_t ssrc) {
1770 assert(channel_id_ == ChannelId(id));
1771 rtp_rtcp_->SetRemoteSSRC(ssrc);
1773 CriticalSectionScoped cs(callback_cs_.get());
1775 if (rtp_observer_) {
1776 rtp_observer_->IncomingSSRCChanged(channel_id_, ssrc);
1781 void ViEChannel::OnIncomingCSRCChanged(const int32_t id,
1782 const uint32_t CSRC,
1784 assert(channel_id_ == ChannelId(id));
1785 CriticalSectionScoped cs(callback_cs_.get());
1787 if (rtp_observer_) {
1788 rtp_observer_->IncomingCSRCChanged(channel_id_, CSRC, added);
1793 void ViEChannel::ResetStatistics(uint32_t ssrc) {
1794 StreamStatistician* statistician =
1795 vie_receiver_.GetReceiveStatistics()->GetStatistician(ssrc);
1797 statistician->ResetStatistics();
1800 void ViEChannel::RegisterSendFrameCountObserver(
1801 FrameCountObserver* observer) {
1802 send_frame_count_observer_.Set(observer);
1805 void ViEChannel::ReceivedBWEPacket(int64_t arrival_time_ms,
1806 int payload_size, const RTPHeader& header) {
1807 vie_receiver_.ReceivedBWEPacket(arrival_time_ms, payload_size, header);
1809 } // namespace webrtc