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