| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 489 } | 489 } |
| 490 | 490 |
| 491 uint32_t ViEChannel::DiscardedPackets() const { | 491 uint32_t ViEChannel::DiscardedPackets() const { |
| 492 return vcm_->DiscardedPackets(); | 492 return vcm_->DiscardedPackets(); |
| 493 } | 493 } |
| 494 | 494 |
| 495 int ViEChannel::ReceiveDelay() const { | 495 int ViEChannel::ReceiveDelay() const { |
| 496 return vcm_->Delay(); | 496 return vcm_->Delay(); |
| 497 } | 497 } |
| 498 | 498 |
| 499 int32_t ViEChannel::SetSignalPacketLossStatus(bool enable, | |
| 500 bool only_key_frames) { | |
| 501 if (enable) { | |
| 502 if (only_key_frames) { | |
| 503 vcm_->SetVideoProtection(kProtectionKeyOnLoss, false); | |
| 504 if (vcm_->SetVideoProtection(kProtectionKeyOnKeyLoss, true) != VCM_OK) { | |
| 505 return -1; | |
| 506 } | |
| 507 } else { | |
| 508 vcm_->SetVideoProtection(kProtectionKeyOnKeyLoss, false); | |
| 509 if (vcm_->SetVideoProtection(kProtectionKeyOnLoss, true) != VCM_OK) { | |
| 510 return -1; | |
| 511 } | |
| 512 } | |
| 513 } else { | |
| 514 vcm_->SetVideoProtection(kProtectionKeyOnLoss, false); | |
| 515 vcm_->SetVideoProtection(kProtectionKeyOnKeyLoss, false); | |
| 516 } | |
| 517 return 0; | |
| 518 } | |
| 519 | |
| 520 void ViEChannel::SetRTCPMode(const RTCPMethod rtcp_mode) { | 499 void ViEChannel::SetRTCPMode(const RTCPMethod rtcp_mode) { |
| 521 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | 500 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) |
| 522 rtp_rtcp->SetRTCPStatus(rtcp_mode); | 501 rtp_rtcp->SetRTCPStatus(rtcp_mode); |
| 523 } | 502 } |
| 524 | 503 |
| 525 int32_t ViEChannel::SetNACKStatus(const bool enable) { | 504 void ViEChannel::SetProtectionMode(bool enable_nack, |
| 526 // Update the decoding VCM. | 505 bool enable_fec, |
| 527 if (vcm_->SetVideoProtection(kProtectionNack, enable) != VCM_OK) { | 506 int payload_type_red, |
| 528 return -1; | 507 int payload_type_fec) { |
| 508 // Validate payload types. |
| 509 if (enable_fec) { |
| 510 DCHECK_GE(payload_type_red, 0); |
| 511 DCHECK_GE(payload_type_fec, 0); |
| 512 DCHECK_LE(payload_type_red, 127); |
| 513 DCHECK_LE(payload_type_fec, 127); |
| 514 } else { |
| 515 DCHECK_EQ(payload_type_red, -1); |
| 516 DCHECK_EQ(payload_type_fec, -1); |
| 517 // Set to valid uint8_ts to be castable later without signed overflows. |
| 518 payload_type_red = 0; |
| 519 payload_type_fec = 0; |
| 529 } | 520 } |
| 530 if (enable) { | 521 |
| 531 // Disable possible FEC. | 522 VCMVideoProtection protection_method; |
| 532 SetFECStatus(false, 0, 0); | 523 if (enable_nack) { |
| 524 protection_method = enable_fec ? kProtectionNackFEC : kProtectionNack; |
| 525 } else { |
| 526 protection_method = kProtectionNone; |
| 533 } | 527 } |
| 534 // Update the decoding VCM. | 528 |
| 535 if (vcm_->SetVideoProtection(kProtectionNack, enable) != VCM_OK) { | 529 vcm_->SetVideoProtection(protection_method, true); |
| 536 return -1; | 530 |
| 531 // Set NACK. |
| 532 ProcessNACKRequest(enable_nack); |
| 533 |
| 534 // Set FEC. |
| 535 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { |
| 536 rtp_rtcp->SetGenericFECStatus(enable_fec, |
| 537 static_cast<uint8_t>(payload_type_red), |
| 538 static_cast<uint8_t>(payload_type_fec)); |
| 537 } | 539 } |
| 538 return ProcessNACKRequest(enable); | |
| 539 } | 540 } |
| 540 | 541 |
| 541 int32_t ViEChannel::ProcessNACKRequest(const bool enable) { | 542 void ViEChannel::ProcessNACKRequest(const bool enable) { |
| 542 if (enable) { | 543 if (enable) { |
| 543 // Turn on NACK. | 544 // Turn on NACK. |
| 544 if (rtp_rtcp_modules_[0]->RTCP() == kRtcpOff) { | 545 if (rtp_rtcp_modules_[0]->RTCP() == kRtcpOff) |
| 545 return -1; | 546 return; |
| 546 } | |
| 547 vie_receiver_.SetNackStatus(true, max_nack_reordering_threshold_); | 547 vie_receiver_.SetNackStatus(true, max_nack_reordering_threshold_); |
| 548 | 548 |
| 549 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | 549 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) |
| 550 rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_); | 550 rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_); |
| 551 | 551 |
| 552 vcm_->RegisterPacketRequestCallback(this); | 552 vcm_->RegisterPacketRequestCallback(this); |
| 553 // Don't introduce errors when NACK is enabled. | 553 // Don't introduce errors when NACK is enabled. |
| 554 vcm_->SetDecodeErrorMode(kNoErrors); | 554 vcm_->SetDecodeErrorMode(kNoErrors); |
| 555 } else { | 555 } else { |
| 556 vcm_->RegisterPacketRequestCallback(NULL); | 556 vcm_->RegisterPacketRequestCallback(NULL); |
| 557 if (paced_sender_ == nullptr) { | 557 if (paced_sender_ == nullptr) { |
| 558 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | 558 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) |
| 559 rtp_rtcp->SetStorePacketsStatus(false, 0); | 559 rtp_rtcp->SetStorePacketsStatus(false, 0); |
| 560 } | 560 } |
| 561 vie_receiver_.SetNackStatus(false, max_nack_reordering_threshold_); | 561 vie_receiver_.SetNackStatus(false, max_nack_reordering_threshold_); |
| 562 // When NACK is off, allow decoding with errors. Otherwise, the video | 562 // When NACK is off, allow decoding with errors. Otherwise, the video |
| 563 // will freeze, and will only recover with a complete key frame. | 563 // will freeze, and will only recover with a complete key frame. |
| 564 vcm_->SetDecodeErrorMode(kWithErrors); | 564 vcm_->SetDecodeErrorMode(kWithErrors); |
| 565 } | 565 } |
| 566 return 0; | |
| 567 } | |
| 568 | |
| 569 int32_t ViEChannel::SetFECStatus(const bool enable, | |
| 570 const unsigned char payload_typeRED, | |
| 571 const unsigned char payload_typeFEC) { | |
| 572 // Disable possible NACK. | |
| 573 if (enable) { | |
| 574 SetNACKStatus(false); | |
| 575 } | |
| 576 | |
| 577 return ProcessFECRequest(enable, payload_typeRED, payload_typeFEC); | |
| 578 } | 566 } |
| 579 | 567 |
| 580 bool ViEChannel::IsSendingFecEnabled() { | 568 bool ViEChannel::IsSendingFecEnabled() { |
| 581 bool fec_enabled = false; | 569 bool fec_enabled = false; |
| 582 uint8_t pltype_red = 0; | 570 uint8_t pltype_red = 0; |
| 583 uint8_t pltype_fec = 0; | 571 uint8_t pltype_fec = 0; |
| 584 | 572 |
| 585 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { | 573 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { |
| 586 rtp_rtcp->GenericFECStatus(fec_enabled, pltype_red, pltype_fec); | 574 rtp_rtcp->GenericFECStatus(fec_enabled, pltype_red, pltype_fec); |
| 587 if (fec_enabled) | 575 if (fec_enabled) |
| 588 return true; | 576 return true; |
| 589 } | 577 } |
| 590 return false; | 578 return false; |
| 591 } | 579 } |
| 592 | 580 |
| 593 int32_t ViEChannel::ProcessFECRequest( | |
| 594 const bool enable, | |
| 595 const unsigned char payload_typeRED, | |
| 596 const unsigned char payload_typeFEC) { | |
| 597 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) | |
| 598 rtp_rtcp->SetGenericFECStatus(enable, payload_typeRED, payload_typeFEC); | |
| 599 return 0; | |
| 600 } | |
| 601 | |
| 602 int32_t ViEChannel::SetHybridNACKFECStatus( | |
| 603 const bool enable, | |
| 604 const unsigned char payload_typeRED, | |
| 605 const unsigned char payload_typeFEC) { | |
| 606 if (vcm_->SetVideoProtection(kProtectionNackFEC, enable) != VCM_OK) { | |
| 607 return -1; | |
| 608 } | |
| 609 | |
| 610 int32_t ret_val = 0; | |
| 611 ret_val = ProcessNACKRequest(enable); | |
| 612 if (ret_val < 0) { | |
| 613 return ret_val; | |
| 614 } | |
| 615 return ProcessFECRequest(enable, payload_typeRED, payload_typeFEC); | |
| 616 } | |
| 617 | |
| 618 int ViEChannel::SetSenderBufferingMode(int target_delay_ms) { | 581 int ViEChannel::SetSenderBufferingMode(int target_delay_ms) { |
| 619 if ((target_delay_ms < 0) || (target_delay_ms > kMaxTargetDelayMs)) { | 582 if ((target_delay_ms < 0) || (target_delay_ms > kMaxTargetDelayMs)) { |
| 620 LOG(LS_ERROR) << "Invalid send buffer value."; | 583 LOG(LS_ERROR) << "Invalid send buffer value."; |
| 621 return -1; | 584 return -1; |
| 622 } | 585 } |
| 623 if (target_delay_ms == 0) { | 586 if (target_delay_ms == 0) { |
| 624 // Real-time mode. | 587 // Real-time mode. |
| 625 nack_history_size_sender_ = kSendSidePacketHistorySize; | 588 nack_history_size_sender_ = kSendSidePacketHistorySize; |
| 626 } else { | 589 } else { |
| 627 nack_history_size_sender_ = GetRequiredNackListSize(target_delay_ms); | 590 nack_history_size_sender_ = GetRequiredNackListSize(target_delay_ms); |
| (...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1305 CriticalSectionScoped cs(crit_.get()); | 1268 CriticalSectionScoped cs(crit_.get()); |
| 1306 vcm_receive_stats_callback_ = receive_statistics_proxy; | 1269 vcm_receive_stats_callback_ = receive_statistics_proxy; |
| 1307 } | 1270 } |
| 1308 | 1271 |
| 1309 void ViEChannel::SetIncomingVideoStream( | 1272 void ViEChannel::SetIncomingVideoStream( |
| 1310 IncomingVideoStream* incoming_video_stream) { | 1273 IncomingVideoStream* incoming_video_stream) { |
| 1311 CriticalSectionScoped cs(crit_.get()); | 1274 CriticalSectionScoped cs(crit_.get()); |
| 1312 incoming_video_stream_ = incoming_video_stream; | 1275 incoming_video_stream_ = incoming_video_stream; |
| 1313 } | 1276 } |
| 1314 } // namespace webrtc | 1277 } // namespace webrtc |
| OLD | NEW |