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 |