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