Merge methods for configuring NACK/FEC/hybrid.

BUG=webrtc:1695
R=stefan@webrtc.org

Review URL: https://codereview.webrtc.org/1226143013

Cr-Commit-Position: refs/heads/master@{#9580}
This commit is contained in:
pbos
2015-07-14 09:36:34 -07:00
committed by Commit bot
parent caa498abbf
commit ba8c15b857
20 changed files with 126 additions and 226 deletions

View File

@ -608,19 +608,15 @@ class RtpRtcp : public Module {
/* /*
* Turn on/off generic FEC * Turn on/off generic FEC
*
* return -1 on failure else 0
*/ */
virtual int32_t SetGenericFECStatus(bool enable, virtual void SetGenericFECStatus(bool enable,
uint8_t payloadTypeRED, uint8_t payload_type_red,
uint8_t payloadTypeFEC) = 0; uint8_t payload_type_fec) = 0;
/* /*
* Get generic FEC setting * Get generic FEC setting
*
* return -1 on failure else 0
*/ */
virtual int32_t GenericFECStatus(bool& enable, virtual void GenericFECStatus(bool& enable,
uint8_t& payloadTypeRED, uint8_t& payloadTypeRED,
uint8_t& payloadTypeFEC) = 0; uint8_t& payloadTypeFEC) = 0;

View File

@ -227,11 +227,13 @@ class MockRtpRtcp : public RtpRtcp {
MOCK_METHOD1(SetTargetSendBitrate, MOCK_METHOD1(SetTargetSendBitrate,
void(uint32_t bitrate_bps)); void(uint32_t bitrate_bps));
MOCK_METHOD3(SetGenericFECStatus, MOCK_METHOD3(SetGenericFECStatus,
int32_t(const bool enable, void(const bool enable,
const uint8_t payloadTypeRED, const uint8_t payload_type_red,
const uint8_t payloadTypeFEC)); const uint8_t payload_type_fec));
MOCK_METHOD3(GenericFECStatus, MOCK_METHOD3(GenericFECStatus,
int32_t(bool& enable, uint8_t& payloadTypeRED, uint8_t& payloadTypeFEC)); void(bool& enable,
uint8_t& payloadTypeRED,
uint8_t& payloadTypeFEC));
MOCK_METHOD2(SetFecParameters, MOCK_METHOD2(SetFecParameters,
int32_t(const FecProtectionParams* delta_params, int32_t(const FecProtectionParams* delta_params,
const FecProtectionParams* key_params)); const FecProtectionParams* key_params));

View File

@ -834,20 +834,17 @@ int32_t ModuleRtpRtcpImpl::SendRTCPSliceLossIndication(
GetFeedbackState(), kRtcpSli, 0, 0, false, picture_id); GetFeedbackState(), kRtcpSli, 0, 0, false, picture_id);
} }
int32_t ModuleRtpRtcpImpl::SetGenericFECStatus( void ModuleRtpRtcpImpl::SetGenericFECStatus(
const bool enable, const bool enable,
const uint8_t payload_type_red, const uint8_t payload_type_red,
const uint8_t payload_type_fec) { const uint8_t payload_type_fec) {
return rtp_sender_.SetGenericFECStatus(enable, rtp_sender_.SetGenericFECStatus(enable, payload_type_red, payload_type_fec);
payload_type_red,
payload_type_fec);
} }
int32_t ModuleRtpRtcpImpl::GenericFECStatus( void ModuleRtpRtcpImpl::GenericFECStatus(bool& enable,
bool& enable, uint8_t& payload_type_red,
uint8_t& payload_type_red, uint8_t& payload_type_fec) {
uint8_t& payload_type_fec) { rtp_sender_.GenericFECStatus(&enable, &payload_type_red,
return rtp_sender_.GenericFECStatus(&enable, &payload_type_red,
&payload_type_fec); &payload_type_fec);
} }

View File

@ -280,13 +280,13 @@ class ModuleRtpRtcpImpl : public RtpRtcp {
void SetTargetSendBitrate(uint32_t bitrate_bps) override; void SetTargetSendBitrate(uint32_t bitrate_bps) override;
int32_t SetGenericFECStatus(bool enable, void SetGenericFECStatus(bool enable,
uint8_t payload_type_red, uint8_t payload_type_red,
uint8_t payload_type_fec) override; uint8_t payload_type_fec) override;
int32_t GenericFECStatus(bool& enable, void GenericFECStatus(bool& enable,
uint8_t& payload_type_red, uint8_t& payload_type_red,
uint8_t& payload_type_fec) override; uint8_t& payload_type_fec) override;
int32_t SetFecParameters(const FecProtectionParams* delta_params, int32_t SetFecParameters(const FecProtectionParams* delta_params,
const FecProtectionParams* key_params) override; const FecProtectionParams* key_params) override;

View File

@ -1736,24 +1736,18 @@ int32_t RTPSender::SendRTPIntraRequest() {
return video_->SendRTPIntraRequest(); return video_->SendRTPIntraRequest();
} }
int32_t RTPSender::SetGenericFECStatus(bool enable, void RTPSender::SetGenericFECStatus(bool enable,
uint8_t payload_type_red, uint8_t payload_type_red,
uint8_t payload_type_fec) { uint8_t payload_type_fec) {
if (audio_configured_) { DCHECK(!audio_configured_);
return -1;
}
video_->SetGenericFECStatus(enable, payload_type_red, payload_type_fec); video_->SetGenericFECStatus(enable, payload_type_red, payload_type_fec);
return 0;
} }
int32_t RTPSender::GenericFECStatus(bool* enable, void RTPSender::GenericFECStatus(bool* enable,
uint8_t* payload_type_red, uint8_t* payload_type_red,
uint8_t* payload_type_fec) const { uint8_t* payload_type_fec) const {
if (audio_configured_) { DCHECK(!audio_configured_);
return -1;
}
video_->GenericFECStatus(*enable, *payload_type_red, *payload_type_fec); video_->GenericFECStatus(*enable, *payload_type_red, *payload_type_fec);
return 0;
} }
int32_t RTPSender::SetFecParameters( int32_t RTPSender::SetFecParameters(

View File

@ -263,12 +263,13 @@ class RTPSender : public RTPSenderInterface {
int32_t SendRTPIntraRequest(); int32_t SendRTPIntraRequest();
// FEC. // FEC.
int32_t SetGenericFECStatus(bool enable, void SetGenericFECStatus(bool enable,
uint8_t payload_type_red, uint8_t payload_type_red,
uint8_t payload_type_fec); uint8_t payload_type_fec);
int32_t GenericFECStatus(bool *enable, uint8_t *payload_type_red, void GenericFECStatus(bool* enable,
uint8_t *payload_type_fec) const; uint8_t* payload_type_red,
uint8_t* payload_type_fec) const;
int32_t SetFecParameters(const FecProtectionParams *delta_params, int32_t SetFecParameters(const FecProtectionParams *delta_params,
const FecProtectionParams *key_params); const FecProtectionParams *key_params);

View File

@ -41,8 +41,6 @@ enum { kDefaultStartBitrateKbps = 300 };
enum VCMVideoProtection { enum VCMVideoProtection {
kProtectionNone, kProtectionNone,
kProtectionNack, // Both send-side and receive-side kProtectionNack, // Both send-side and receive-side
kProtectionNackSender, // Send-side only
kProtectionNackReceiver, // Receive-side only
kProtectionFEC, kProtectionFEC,
kProtectionNackFEC, kProtectionNackFEC,
kProtectionKeyOnLoss, kProtectionKeyOnLoss,

View File

@ -519,7 +519,6 @@ VCMFecMethod::UpdateParameters(const VCMProtectionParameters* parameters)
return true; return true;
} }
VCMLossProtectionLogic::VCMLossProtectionLogic(int64_t nowMs): VCMLossProtectionLogic::VCMLossProtectionLogic(int64_t nowMs):
_selectedMethod(NULL),
_currentParameters(), _currentParameters(),
_rtt(0), _rtt(0),
_lossPr(0.0f), _lossPr(0.0f),
@ -548,25 +547,21 @@ VCMLossProtectionLogic::~VCMLossProtectionLogic()
void VCMLossProtectionLogic::SetMethod( void VCMLossProtectionLogic::SetMethod(
enum VCMProtectionMethodEnum newMethodType) { enum VCMProtectionMethodEnum newMethodType) {
if (_selectedMethod != nullptr) { if (_selectedMethod && _selectedMethod->Type() == newMethodType)
if (_selectedMethod->Type() == newMethodType) return;
return;
// Remove old method.
delete _selectedMethod;
}
switch(newMethodType) { switch(newMethodType) {
case kNack: case kNack:
_selectedMethod = new VCMNackMethod(); _selectedMethod.reset(new VCMNackMethod());
break; break;
case kFec: case kFec:
_selectedMethod = new VCMFecMethod(); _selectedMethod.reset(new VCMFecMethod());
break; break;
case kNackFec: case kNackFec:
_selectedMethod = new VCMNackFecMethod(kLowRttNackMs, -1); _selectedMethod.reset(new VCMNackFecMethod(kLowRttNackMs, -1));
break; break;
case kNone: case kNone:
_selectedMethod = nullptr; _selectedMethod.reset();
break; break;
} }
UpdateMethod(); UpdateMethod();
@ -726,10 +721,8 @@ void VCMLossProtectionLogic::UpdateNumLayers(int numLayers) {
bool bool
VCMLossProtectionLogic::UpdateMethod() VCMLossProtectionLogic::UpdateMethod()
{ {
if (_selectedMethod == NULL) if (!_selectedMethod)
{ return false;
return false;
}
_currentParameters.rtt = _rtt; _currentParameters.rtt = _rtt;
_currentParameters.lossPr = _lossPr; _currentParameters.lossPr = _lossPr;
_currentParameters.bitRate = _bitRate; _currentParameters.bitRate = _bitRate;
@ -748,11 +741,11 @@ VCMLossProtectionLogic::UpdateMethod()
VCMProtectionMethod* VCMProtectionMethod*
VCMLossProtectionLogic::SelectedMethod() const VCMLossProtectionLogic::SelectedMethod() const
{ {
return _selectedMethod; return _selectedMethod.get();
} }
VCMProtectionMethodEnum VCMLossProtectionLogic::SelectedType() const { VCMProtectionMethodEnum VCMLossProtectionLogic::SelectedType() const {
return _selectedMethod == nullptr ? kNone : _selectedMethod->Type(); return _selectedMethod ? _selectedMethod->Type() : kNone;
} }
void void
@ -773,11 +766,8 @@ VCMLossProtectionLogic::Reset(int64_t nowMs)
Release(); Release();
} }
void void VCMLossProtectionLogic::Release() {
VCMLossProtectionLogic::Release() _selectedMethod.reset();
{
delete _selectedMethod;
_selectedMethod = NULL;
} }
} // namespace media_optimization } // namespace media_optimization

View File

@ -15,6 +15,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "webrtc/base/exp_filter.h" #include "webrtc/base/exp_filter.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/modules/video_coding/main/source/internal_defines.h" #include "webrtc/modules/video_coding/main/source/internal_defines.h"
#include "webrtc/modules/video_coding/main/source/qm_select.h" #include "webrtc/modules/video_coding/main/source/qm_select.h"
#include "webrtc/system_wrappers/interface/trace.h" #include "webrtc/system_wrappers/interface/trace.h"
@ -335,7 +336,7 @@ private:
// Sets the available loss protection methods. // Sets the available loss protection methods.
void UpdateMaxLossHistory(uint8_t lossPr255, int64_t now); void UpdateMaxLossHistory(uint8_t lossPr255, int64_t now);
uint8_t MaxFilteredLossPr(int64_t nowMs) const; uint8_t MaxFilteredLossPr(int64_t nowMs) const;
VCMProtectionMethod* _selectedMethod; rtc::scoped_ptr<VCMProtectionMethod> _selectedMethod;
VCMProtectionParameters _currentParameters; VCMProtectionParameters _currentParameters;
int64_t _rtt; int64_t _rtt;
float _lossPr; float _lossPr;

View File

@ -317,13 +317,8 @@ uint32_t MediaOptimization::SetTargetRates(
return target_bit_rate_; return target_bit_rate_;
} }
void MediaOptimization::EnableProtectionMethod(bool enable, void MediaOptimization::SetProtectionMethod(VCMProtectionMethodEnum method) {
VCMProtectionMethodEnum method) {
CriticalSectionScoped lock(crit_sect_.get()); CriticalSectionScoped lock(crit_sect_.get());
if (!enable && loss_prot_logic_->SelectedType() != method)
return;
if (!enable)
method = kNone;
loss_prot_logic_->SetMethod(method); loss_prot_logic_->SetMethod(method);
} }

View File

@ -62,7 +62,7 @@ class MediaOptimization {
VCMProtectionCallback* protection_callback, VCMProtectionCallback* protection_callback,
VCMQMSettingsCallback* qmsettings_callback); VCMQMSettingsCallback* qmsettings_callback);
void EnableProtectionMethod(bool enable, VCMProtectionMethodEnum method); void SetProtectionMethod(VCMProtectionMethodEnum method);
void EnableQM(bool enable); void EnableQM(bool enable);
void EnableFrameDropper(bool enable); void EnableFrameDropper(bool enable);

View File

@ -168,7 +168,9 @@ class VideoCodingModuleImpl : public VideoCodingModule {
int32_t SetVideoProtection(VCMVideoProtection videoProtection, int32_t SetVideoProtection(VCMVideoProtection videoProtection,
bool enable) override { bool enable) override {
sender_->SetVideoProtection(enable, videoProtection); // TODO(pbos): Remove enable from receive-side protection modes as well.
if (enable)
sender_->SetVideoProtection(videoProtection);
return receiver_->SetVideoProtection(videoProtection, enable); return receiver_->SetVideoProtection(videoProtection, enable);
} }

View File

@ -98,7 +98,7 @@ class VideoSender {
int32_t RegisterTransportCallback(VCMPacketizationCallback* transport); int32_t RegisterTransportCallback(VCMPacketizationCallback* transport);
int32_t RegisterSendStatisticsCallback(VCMSendStatisticsCallback* sendStats); int32_t RegisterSendStatisticsCallback(VCMSendStatisticsCallback* sendStats);
int32_t RegisterProtectionCallback(VCMProtectionCallback* protection); int32_t RegisterProtectionCallback(VCMProtectionCallback* protection);
void SetVideoProtection(bool enable, VCMVideoProtection videoProtection); void SetVideoProtection(VCMVideoProtection videoProtection);
int32_t AddVideoFrame(const VideoFrame& videoFrame, int32_t AddVideoFrame(const VideoFrame& videoFrame,
const VideoContentMetrics* _contentMetrics, const VideoContentMetrics* _contentMetrics,

View File

@ -8,6 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "webrtc/base/checks.h"
#include "webrtc/common_types.h" #include "webrtc/common_types.h"
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h" #include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
@ -187,15 +188,9 @@ int32_t VideoReceiver::SetVideoProtection(VCMVideoProtection videoProtection,
// By default, do not decode with errors. // By default, do not decode with errors.
_receiver.SetDecodeErrorMode(kNoErrors); _receiver.SetDecodeErrorMode(kNoErrors);
switch (videoProtection) { switch (videoProtection) {
case kProtectionNack: case kProtectionNack: {
case kProtectionNackReceiver: { DCHECK(enable);
CriticalSectionScoped cs(_receiveCritSect); _receiver.SetNackMode(kNack, -1, -1);
if (enable) {
// Enable NACK and always wait for retransmits.
_receiver.SetNackMode(kNack, -1, -1);
} else {
_receiver.SetNackMode(kNoNack, -1, -1);
}
break; break;
} }
@ -226,25 +221,17 @@ int32_t VideoReceiver::SetVideoProtection(VCMVideoProtection videoProtection,
case kProtectionNackFEC: { case kProtectionNackFEC: {
CriticalSectionScoped cs(_receiveCritSect); CriticalSectionScoped cs(_receiveCritSect);
if (enable) { DCHECK(enable);
// Enable hybrid NACK/FEC. Always wait for retransmissions _receiver.SetNackMode(kNack, media_optimization::kLowRttNackMs, -1);
// and don't add extra delay when RTT is above _receiver.SetDecodeErrorMode(kNoErrors);
// kLowRttNackMs.
_receiver.SetNackMode(kNack, media_optimization::kLowRttNackMs, -1);
_receiver.SetDecodeErrorMode(kNoErrors);
_receiver.SetDecodeErrorMode(kNoErrors);
} else {
_receiver.SetNackMode(kNoNack, -1, -1);
}
break; break;
} }
case kProtectionNackSender:
case kProtectionFEC: case kProtectionFEC:
// Ignore encoder modes.
return VCM_OK;
case kProtectionNone: case kProtectionNone:
// TODO(pbos): Implement like sender and remove enable parameter. Ignored // No receiver-side protection.
// for now. DCHECK(enable);
_receiver.SetNackMode(kNoNack, -1, -1);
_receiver.SetDecodeErrorMode(kWithErrors);
break; break;
} }
return VCM_OK; return VCM_OK;

View File

@ -296,24 +296,21 @@ int32_t VideoSender::RegisterProtectionCallback(
} }
// Enable or disable a video protection method. // Enable or disable a video protection method.
void VideoSender::SetVideoProtection(bool enable, void VideoSender::SetVideoProtection(VCMVideoProtection videoProtection) {
VCMVideoProtection videoProtection) {
CriticalSectionScoped cs(_sendCritSect); CriticalSectionScoped cs(_sendCritSect);
switch (videoProtection) { switch (videoProtection) {
case kProtectionNone: case kProtectionNone:
_mediaOpt.EnableProtectionMethod(enable, media_optimization::kNone); _mediaOpt.SetProtectionMethod(media_optimization::kNone);
break; break;
case kProtectionNack: case kProtectionNack:
case kProtectionNackSender: _mediaOpt.SetProtectionMethod(media_optimization::kNack);
_mediaOpt.EnableProtectionMethod(enable, media_optimization::kNack);
break; break;
case kProtectionNackFEC: case kProtectionNackFEC:
_mediaOpt.EnableProtectionMethod(enable, media_optimization::kNackFec); _mediaOpt.SetProtectionMethod(media_optimization::kNackFec);
break; break;
case kProtectionFEC: case kProtectionFEC:
_mediaOpt.EnableProtectionMethod(enable, media_optimization::kFec); _mediaOpt.SetProtectionMethod(media_optimization::kFec);
break; break;
case kProtectionNackReceiver:
case kProtectionKeyOnLoss: case kProtectionKeyOnLoss:
case kProtectionKeyOnKeyLoss: case kProtectionKeyOnKeyLoss:
// Ignore receiver modes. // Ignore receiver modes.

View File

@ -144,7 +144,8 @@ VideoReceiveStream::VideoReceiveStream(int num_cpu_cores,
vie_channel_ = channel_group_->GetChannel(channel_id_); vie_channel_ = channel_group_->GetChannel(channel_id_);
// TODO(pbos): This is not fine grained enough... // TODO(pbos): This is not fine grained enough...
vie_channel_->SetNACKStatus(config_.rtp.nack.rtp_history_ms > 0); vie_channel_->SetProtectionMode(config_.rtp.nack.rtp_history_ms > 0, false,
-1, -1);
vie_channel_->SetKeyFrameRequestMethod(kKeyFrameReqPliRtcp); vie_channel_->SetKeyFrameRequestMethod(kKeyFrameReqPliRtcp);
SetRtcpMode(config_.rtp.rtcp_mode); SetRtcpMode(config_.rtp.rtcp_mode);

View File

@ -147,28 +147,14 @@ VideoSendStream::VideoSendStream(
channel_group_->SetChannelRembStatus(true, false, vie_channel_); channel_group_->SetChannelRembStatus(true, false, vie_channel_);
// Enable NACK, FEC or both. // Enable NACK, FEC or both.
bool enable_protection_nack = false; const bool enable_protection_nack = config_.rtp.nack.rtp_history_ms > 0;
bool enable_protection_fec = false; const bool enable_protection_fec = config_.rtp.fec.red_payload_type != -1;
if (config_.rtp.fec.red_payload_type != -1) { // TODO(changbin): Should set RTX for RED mapping in RTP sender in future.
enable_protection_fec = true; vie_channel_->SetProtectionMode(enable_protection_nack, enable_protection_fec,
DCHECK(config_.rtp.fec.ulpfec_payload_type != -1); config_.rtp.fec.red_payload_type,
if (config_.rtp.nack.rtp_history_ms > 0) { config_.rtp.fec.ulpfec_payload_type);
enable_protection_nack = true;
vie_channel_->SetHybridNACKFECStatus(
true, static_cast<unsigned char>(config_.rtp.fec.red_payload_type),
static_cast<unsigned char>(config_.rtp.fec.ulpfec_payload_type));
} else {
vie_channel_->SetFECStatus(
true, static_cast<unsigned char>(config_.rtp.fec.red_payload_type),
static_cast<unsigned char>(config_.rtp.fec.ulpfec_payload_type));
}
// TODO(changbin): Should set RTX for RED mapping in RTP sender in future.
} else {
enable_protection_nack = config_.rtp.nack.rtp_history_ms > 0;
vie_channel_->SetNACKStatus(config_.rtp.nack.rtp_history_ms > 0);
}
vie_encoder_->UpdateProtectionMethod(enable_protection_nack, vie_encoder_->UpdateProtectionMethod(enable_protection_nack,
enable_protection_fec); enable_protection_fec);
ConfigureSsrcs(); ConfigureSsrcs();

View File

@ -496,54 +496,54 @@ int ViEChannel::ReceiveDelay() const {
return vcm_->Delay(); return vcm_->Delay();
} }
int32_t ViEChannel::SetSignalPacketLossStatus(bool enable,
bool only_key_frames) {
if (enable) {
if (only_key_frames) {
vcm_->SetVideoProtection(kProtectionKeyOnLoss, false);
if (vcm_->SetVideoProtection(kProtectionKeyOnKeyLoss, true) != VCM_OK) {
return -1;
}
} else {
vcm_->SetVideoProtection(kProtectionKeyOnKeyLoss, false);
if (vcm_->SetVideoProtection(kProtectionKeyOnLoss, true) != VCM_OK) {
return -1;
}
}
} else {
vcm_->SetVideoProtection(kProtectionKeyOnLoss, false);
vcm_->SetVideoProtection(kProtectionKeyOnKeyLoss, false);
}
return 0;
}
void ViEChannel::SetRTCPMode(const RTCPMethod rtcp_mode) { void ViEChannel::SetRTCPMode(const RTCPMethod rtcp_mode) {
for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
rtp_rtcp->SetRTCPStatus(rtcp_mode); rtp_rtcp->SetRTCPStatus(rtcp_mode);
} }
int32_t ViEChannel::SetNACKStatus(const bool enable) { void ViEChannel::SetProtectionMode(bool enable_nack,
// Update the decoding VCM. bool enable_fec,
if (vcm_->SetVideoProtection(kProtectionNack, enable) != VCM_OK) { int payload_type_red,
return -1; int payload_type_fec) {
// Validate payload types.
if (enable_fec) {
DCHECK_GE(payload_type_red, 0);
DCHECK_GE(payload_type_fec, 0);
DCHECK_LE(payload_type_red, 127);
DCHECK_LE(payload_type_fec, 127);
} else {
DCHECK_EQ(payload_type_red, -1);
DCHECK_EQ(payload_type_fec, -1);
// Set to valid uint8_ts to be castable later without signed overflows.
payload_type_red = 0;
payload_type_fec = 0;
} }
if (enable) {
// Disable possible FEC. VCMVideoProtection protection_method;
SetFECStatus(false, 0, 0); if (enable_nack) {
protection_method = enable_fec ? kProtectionNackFEC : kProtectionNack;
} else {
protection_method = kProtectionNone;
} }
// Update the decoding VCM.
if (vcm_->SetVideoProtection(kProtectionNack, enable) != VCM_OK) { vcm_->SetVideoProtection(protection_method, true);
return -1;
// Set NACK.
ProcessNACKRequest(enable_nack);
// Set FEC.
for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
rtp_rtcp->SetGenericFECStatus(enable_fec,
static_cast<uint8_t>(payload_type_red),
static_cast<uint8_t>(payload_type_fec));
} }
return ProcessNACKRequest(enable);
} }
int32_t ViEChannel::ProcessNACKRequest(const bool enable) { void ViEChannel::ProcessNACKRequest(const bool enable) {
if (enable) { if (enable) {
// Turn on NACK. // Turn on NACK.
if (rtp_rtcp_modules_[0]->RTCP() == kRtcpOff) { if (rtp_rtcp_modules_[0]->RTCP() == kRtcpOff)
return -1; return;
}
vie_receiver_.SetNackStatus(true, max_nack_reordering_threshold_); vie_receiver_.SetNackStatus(true, max_nack_reordering_threshold_);
for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
@ -563,18 +563,6 @@ int32_t ViEChannel::ProcessNACKRequest(const bool enable) {
// will freeze, and will only recover with a complete key frame. // will freeze, and will only recover with a complete key frame.
vcm_->SetDecodeErrorMode(kWithErrors); vcm_->SetDecodeErrorMode(kWithErrors);
} }
return 0;
}
int32_t ViEChannel::SetFECStatus(const bool enable,
const unsigned char payload_typeRED,
const unsigned char payload_typeFEC) {
// Disable possible NACK.
if (enable) {
SetNACKStatus(false);
}
return ProcessFECRequest(enable, payload_typeRED, payload_typeFEC);
} }
bool ViEChannel::IsSendingFecEnabled() { bool ViEChannel::IsSendingFecEnabled() {
@ -590,31 +578,6 @@ bool ViEChannel::IsSendingFecEnabled() {
return false; return false;
} }
int32_t ViEChannel::ProcessFECRequest(
const bool enable,
const unsigned char payload_typeRED,
const unsigned char payload_typeFEC) {
for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
rtp_rtcp->SetGenericFECStatus(enable, payload_typeRED, payload_typeFEC);
return 0;
}
int32_t ViEChannel::SetHybridNACKFECStatus(
const bool enable,
const unsigned char payload_typeRED,
const unsigned char payload_typeFEC) {
if (vcm_->SetVideoProtection(kProtectionNackFEC, enable) != VCM_OK) {
return -1;
}
int32_t ret_val = 0;
ret_val = ProcessNACKRequest(enable);
if (ret_val < 0) {
return ret_val;
}
return ProcessFECRequest(enable, payload_typeRED, payload_typeFEC);
}
int ViEChannel::SetSenderBufferingMode(int target_delay_ms) { int ViEChannel::SetSenderBufferingMode(int target_delay_ms) {
if ((target_delay_ms < 0) || (target_delay_ms > kMaxTargetDelayMs)) { if ((target_delay_ms < 0) || (target_delay_ms > kMaxTargetDelayMs)) {
LOG(LS_ERROR) << "Invalid send buffer value."; LOG(LS_ERROR) << "Invalid send buffer value.";

View File

@ -136,19 +136,11 @@ class ViEChannel : public VCMFrameTypeCallback,
// Returns the estimated delay in milliseconds. // Returns the estimated delay in milliseconds.
int ReceiveDelay() const; int ReceiveDelay() const;
// If enabled, a key frame request will be sent as soon as there are lost
// packets. If |only_key_frames| are set, requests are only sent for loss in
// key frames.
int32_t SetSignalPacketLossStatus(bool enable, bool only_key_frames);
void SetRTCPMode(const RTCPMethod rtcp_mode); void SetRTCPMode(const RTCPMethod rtcp_mode);
int32_t SetNACKStatus(const bool enable); void SetProtectionMode(bool enable_nack,
int32_t SetFECStatus(const bool enable, bool enable_fec,
const unsigned char payload_typeRED, int payload_type_red,
const unsigned char payload_typeFEC); int payload_type_fec);
int32_t SetHybridNACKFECStatus(const bool enable,
const unsigned char payload_typeRED,
const unsigned char payload_typeFEC);
bool IsSendingFecEnabled(); bool IsSendingFecEnabled();
int SetSenderBufferingMode(int target_delay_ms); int SetSenderBufferingMode(int target_delay_ms);
int SetReceiverBufferingMode(int target_delay_ms); int SetReceiverBufferingMode(int target_delay_ms);
@ -354,10 +346,7 @@ class ViEChannel : public VCMFrameTypeCallback,
void StartDecodeThread(); void StartDecodeThread();
void StopDecodeThread(); void StopDecodeThread();
int32_t ProcessNACKRequest(const bool enable); void ProcessNACKRequest(const bool enable);
int32_t ProcessFECRequest(const bool enable,
const unsigned char payload_typeRED,
const unsigned char payload_typeFEC);
// Compute NACK list parameters for the buffering mode. // Compute NACK list parameters for the buffering mode.
int GetRequiredNackListSize(int target_delay_ms); int GetRequiredNackListSize(int target_delay_ms);
void SetRtxSendStatus(bool enable); void SetRtxSendStatus(bool enable);

View File

@ -612,13 +612,14 @@ int32_t ViEEncoder::UpdateProtectionMethod(bool nack, bool fec) {
nack_enabled_ = nack; nack_enabled_ = nack;
// Set Video Protection for VCM. // Set Video Protection for VCM.
if (fec_enabled_ && nack_enabled_) { VCMVideoProtection protection_mode;
vcm_->SetVideoProtection(webrtc::kProtectionNackFEC, true); if (fec_enabled_) {
protection_mode =
nack_enabled_ ? webrtc::kProtectionNackFEC : kProtectionFEC;
} else { } else {
vcm_->SetVideoProtection(webrtc::kProtectionFEC, fec_enabled_); protection_mode = nack_enabled_ ? kProtectionNack : kProtectionNone;
vcm_->SetVideoProtection(webrtc::kProtectionNackSender, nack_enabled_);
vcm_->SetVideoProtection(webrtc::kProtectionNackFEC, false);
} }
vcm_->SetVideoProtection(protection_mode, true);
if (fec_enabled_ || nack_enabled_) { if (fec_enabled_ || nack_enabled_) {
// The send codec must be registered to set correct MTU. // The send codec must be registered to set correct MTU.