This CL is to adding feedback of packet loss rate to encoder in voice engine. A direct reason for doing it is to make use of Opus FEC, which can adapt itself to changes in the packet loss rate.

This CL is going to be combined with another CL in ACM, which is to be landed.

TEST=passed_try_bots
BUG=
R=stefan@webrtc.org, xians@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/13449004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@6262 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
minyue@webrtc.org 2014-05-28 09:52:06 +00:00
parent aca5939dfc
commit c1a40a7b68
15 changed files with 196 additions and 47 deletions

View File

@ -89,6 +89,24 @@ class StatisticsProxy : public RtcpStatisticsCallback {
ChannelStatistics stats_; ChannelStatistics stats_;
}; };
class VoEBitrateObserver : public BitrateObserver {
public:
explicit VoEBitrateObserver(Channel* owner)
: owner_(owner) {}
virtual ~VoEBitrateObserver() {}
// Implements BitrateObserver.
virtual void OnNetworkChanged(const uint32_t bitrate_bps,
const uint8_t fraction_lost,
const uint32_t rtt) OVERRIDE {
// |fraction_lost| has a scale of 0 - 255.
owner_->OnNetworkChanged(bitrate_bps, fraction_lost, rtt);
}
private:
Channel* owner_;
};
int32_t int32_t
Channel::SendData(FrameType frameType, Channel::SendData(FrameType frameType,
uint8_t payloadType, uint8_t payloadType,
@ -900,7 +918,13 @@ Channel::Channel(int32_t channelId,
_RxVadDetection(false), _RxVadDetection(false),
_rxAgcIsEnabled(false), _rxAgcIsEnabled(false),
_rxNsIsEnabled(false), _rxNsIsEnabled(false),
restored_packet_in_use_(false) restored_packet_in_use_(false),
bitrate_controller_(
BitrateController::CreateBitrateController(Clock::GetRealTimeClock(),
true)),
rtcp_bandwidth_observer_(
bitrate_controller_->CreateRtcpBandwidthObserver()),
send_bitrate_observer_(new VoEBitrateObserver(this))
{ {
WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,_channelId), WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,_channelId),
"Channel::Channel() - ctor"); "Channel::Channel() - ctor");
@ -915,6 +939,7 @@ Channel::Channel(int32_t channelId,
configuration.rtcp_feedback = this; configuration.rtcp_feedback = this;
configuration.audio_messages = this; configuration.audio_messages = this;
configuration.receive_statistics = rtp_receive_statistics_.get(); configuration.receive_statistics = rtp_receive_statistics_.get();
configuration.bandwidth_callback = rtcp_bandwidth_observer_.get();
_rtpRtcpModule.reset(RtpRtcp::CreateRtpRtcp(configuration)); _rtpRtcpModule.reset(RtpRtcp::CreateRtpRtcp(configuration));
@ -1489,9 +1514,27 @@ Channel::SetSendCodec(const CodecInst& codec)
return -1; return -1;
} }
bitrate_controller_->SetBitrateObserver(send_bitrate_observer_.get(),
codec.rate, 0, 0);
return 0; return 0;
} }
void
Channel::OnNetworkChanged(const uint32_t bitrate_bps,
const uint8_t fraction_lost, // 0 - 255.
const uint32_t rtt) {
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
"Channel::OnNetworkChanged(bitrate_bps=%d, fration_lost=%d, rtt=%d)",
bitrate_bps, fraction_lost, rtt);
// Normalizes rate to 0 - 100.
if (audio_coding_->SetPacketLossRate(100 * fraction_lost / 255) != 0) {
_engineStatisticsPtr->SetLastError(VE_AUDIO_CODING_MODULE_ERROR,
kTraceError, "OnNetworkChanged() failed to set packet loss rate");
assert(false); // This should not happen.
}
}
int32_t int32_t
Channel::SetVADStatus(bool enableVAD, ACMVADMode mode, bool disableDTX) Channel::SetVADStatus(bool enableVAD, ACMVADMode mode, bool disableDTX)
{ {
@ -3508,15 +3551,15 @@ Channel::GetRTPStatistics(CallStatistics& stats)
return 0; return 0;
} }
int Channel::SetFECStatus(bool enable, int redPayloadtype) { int Channel::SetREDStatus(bool enable, int redPayloadtype) {
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
"Channel::SetFECStatus()"); "Channel::SetREDStatus()");
if (enable) { if (enable) {
if (redPayloadtype < 0 || redPayloadtype > 127) { if (redPayloadtype < 0 || redPayloadtype > 127) {
_engineStatisticsPtr->SetLastError( _engineStatisticsPtr->SetLastError(
VE_PLTYPE_ERROR, kTraceError, VE_PLTYPE_ERROR, kTraceError,
"SetFECStatus() invalid RED payload type"); "SetREDStatus() invalid RED payload type");
return -1; return -1;
} }
@ -3538,7 +3581,7 @@ int Channel::SetFECStatus(bool enable, int redPayloadtype) {
} }
int int
Channel::GetFECStatus(bool& enabled, int& redPayloadtype) Channel::GetREDStatus(bool& enabled, int& redPayloadtype)
{ {
enabled = audio_coding_->REDStatus(); enabled = audio_coding_->REDStatus();
if (enabled) if (enabled)
@ -3548,22 +3591,43 @@ Channel::GetFECStatus(bool& enabled, int& redPayloadtype)
{ {
_engineStatisticsPtr->SetLastError( _engineStatisticsPtr->SetLastError(
VE_RTP_RTCP_MODULE_ERROR, kTraceError, VE_RTP_RTCP_MODULE_ERROR, kTraceError,
"GetFECStatus() failed to retrieve RED PT from RTP/RTCP " "GetREDStatus() failed to retrieve RED PT from RTP/RTCP "
"module"); "module");
return -1; return -1;
} }
WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
VoEId(_instanceId, _channelId), VoEId(_instanceId, _channelId),
"GetFECStatus() => enabled=%d, redPayloadtype=%d", "GetREDStatus() => enabled=%d, redPayloadtype=%d",
enabled, redPayloadtype); enabled, redPayloadtype);
return 0; return 0;
} }
WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
VoEId(_instanceId, _channelId), VoEId(_instanceId, _channelId),
"GetFECStatus() => enabled=%d", enabled); "GetREDStatus() => enabled=%d", enabled);
return 0; return 0;
} }
int Channel::SetCodecFECStatus(bool enable) {
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
"Channel::SetCodecFECStatus()");
if (audio_coding_->SetCodecFEC(enable) != 0) {
_engineStatisticsPtr->SetLastError(
VE_AUDIO_CODING_MODULE_ERROR, kTraceError,
"SetCodecFECStatus() failed to set FEC state");
return -1;
}
return 0;
}
bool Channel::GetCodecFECStatus() {
bool enabled = audio_coding_->CodecFEC();
WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
VoEId(_instanceId, _channelId),
"GetCodecFECStatus() => enabled=%d", enabled);
return enabled;
}
void Channel::SetNACKStatus(bool enable, int maxNumberOfPackets) { void Channel::SetNACKStatus(bool enable, int maxNumberOfPackets) {
// None of these functions can fail. // None of these functions can fail.
_rtpRtcpModule->SetStorePacketsStatus(enable, maxNumberOfPackets); _rtpRtcpModule->SetStorePacketsStatus(enable, maxNumberOfPackets);
@ -4501,5 +4565,6 @@ int Channel::SetSendRtpHeaderExtension(bool enable, RTPExtensionType type,
} }
return error; return error;
} }
} // namespace voe } // namespace voe
} // namespace webrtc } // namespace webrtc

View File

@ -16,6 +16,7 @@
#include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h" #include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h"
#include "webrtc/modules/audio_conference_mixer/interface/audio_conference_mixer_defines.h" #include "webrtc/modules/audio_conference_mixer/interface/audio_conference_mixer_defines.h"
#include "webrtc/modules/audio_processing/rms_level.h" #include "webrtc/modules/audio_processing/rms_level.h"
#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
#include "webrtc/modules/utility/interface/file_player.h" #include "webrtc/modules/utility/interface/file_player.h"
@ -335,8 +336,10 @@ public:
unsigned int& discardedPackets); unsigned int& discardedPackets);
int GetRemoteRTCPReportBlocks(std::vector<ReportBlock>* report_blocks); int GetRemoteRTCPReportBlocks(std::vector<ReportBlock>* report_blocks);
int GetRTPStatistics(CallStatistics& stats); int GetRTPStatistics(CallStatistics& stats);
int SetFECStatus(bool enable, int redPayloadtype); int SetREDStatus(bool enable, int redPayloadtype);
int GetFECStatus(bool& enabled, int& redPayloadtype); int GetREDStatus(bool& enabled, int& redPayloadtype);
int SetCodecFECStatus(bool enable);
bool GetCodecFECStatus();
void SetNACKStatus(bool enable, int maxNumberOfPackets); void SetNACKStatus(bool enable, int maxNumberOfPackets);
int StartRTPDump(const char fileNameUTF8[1024], RTPDirections direction); int StartRTPDump(const char fileNameUTF8[1024], RTPDirections direction);
int StopRTPDump(RTPDirections direction); int StopRTPDump(RTPDirections direction);
@ -471,6 +474,11 @@ public:
uint32_t PrepareEncodeAndSend(int mixingFrequency); uint32_t PrepareEncodeAndSend(int mixingFrequency);
uint32_t EncodeAndSend(); uint32_t EncodeAndSend();
// From BitrateObserver (called by the RTP/RTCP module).
void OnNetworkChanged(const uint32_t bitrate_bps,
const uint8_t fraction_lost, // 0 - 255.
const uint32_t rtt);
private: private:
bool ReceivePacket(const uint8_t* packet, int packet_length, bool ReceivePacket(const uint8_t* packet, int packet_length,
const RTPHeader& header, bool in_order); const RTPHeader& header, bool in_order);
@ -603,6 +611,10 @@ private:
bool _rxAgcIsEnabled; bool _rxAgcIsEnabled;
bool _rxNsIsEnabled; bool _rxNsIsEnabled;
bool restored_packet_in_use_; bool restored_packet_in_use_;
// RtcpBandwidthObserver
scoped_ptr<BitrateController> bitrate_controller_;
scoped_ptr<RtcpBandwidthObserver> rtcp_bandwidth_observer_;
scoped_ptr<BitrateObserver> send_bitrate_observer_;
}; };
} // namespace voe } // namespace voe

View File

@ -102,6 +102,18 @@ public:
virtual int SetSendCNPayloadType( virtual int SetSendCNPayloadType(
int channel, int type, PayloadFrequencies frequency = kFreq16000Hz) = 0; int channel, int type, PayloadFrequencies frequency = kFreq16000Hz) = 0;
// Sets the codec internal FEC (forward error correction) status for a
// specified |channel|. Returns 0 if success, and -1 if failed.
// TODO(minyue): Make SetFECStatus() pure virtual when fakewebrtcvoiceengine
// in talk is ready.
virtual int SetFECStatus(int channel, bool enable) { return -1; }
// Gets the codec internal FEC status for a specified |channel|. Returns 0
// with the status stored in |enabled| if success, and -1 if encountered
// error.
// TODO(minyue): Make GetFECStatus() pure virtual when fakewebrtcvoiceengine
// in talk is ready.
virtual int GetFECStatus(int channel, bool& enabled) { return -1; }
// Sets the VAD/DTX (silence suppression) status and |mode| for a // Sets the VAD/DTX (silence suppression) status and |mode| for a
// specified |channel|. Disabling VAD (through |enable|) will also disable // specified |channel|. Disabling VAD (through |enable|) will also disable

View File

@ -67,7 +67,7 @@
#define VE_SEND_ERROR 8092 #define VE_SEND_ERROR 8092
#define VE_CANNOT_REMOVE_CONF_CHANNEL 8093 #define VE_CANNOT_REMOVE_CONF_CHANNEL 8093
#define VE_PLTYPE_ERROR 8094 #define VE_PLTYPE_ERROR 8094
#define VE_SET_FEC_FAILED 8095 #define VE_SET_RED_FAILED 8095
#define VE_CANNOT_GET_PLAY_DATA 8096 #define VE_CANNOT_GET_PLAY_DATA 8096
#define VE_APM_ERROR 8097 #define VE_APM_ERROR 8097
#define VE_RUNTIME_PLAY_WARNING 8098 #define VE_RUNTIME_PLAY_WARNING 8098

View File

@ -15,7 +15,7 @@
// - Transmission of RTCP sender reports. // - Transmission of RTCP sender reports.
// - Obtaining RTCP data from incoming RTCP sender reports. // - Obtaining RTCP data from incoming RTCP sender reports.
// - RTP and RTCP statistics (jitter, packet loss, RTT etc.). // - RTP and RTCP statistics (jitter, packet loss, RTT etc.).
// - Forward Error Correction (FEC). // - Redundant Coding (RED)
// - Writing RTP and RTCP packets to binary files for off-line analysis of // - Writing RTP and RTCP packets to binary files for off-line analysis of
// the call quality. // the call quality.
// //
@ -200,13 +200,33 @@ public:
virtual int GetRemoteRTCPReportBlocks( virtual int GetRemoteRTCPReportBlocks(
int channel, std::vector<ReportBlock>* receive_blocks) = 0; int channel, std::vector<ReportBlock>* receive_blocks) = 0;
// Sets the Redundant Coding (RED) status on a specific |channel|.
// TODO(minyue): Make SetREDStatus() pure virtual when fakewebrtcvoiceengine
// in talk is ready.
virtual int SetREDStatus(
int channel, bool enable, int redPayloadtype = -1) { return -1; }
// Gets the RED status on a specific |channel|.
// TODO(minyue): Make GetREDStatus() pure virtual when fakewebrtcvoiceengine
// in talk is ready.
virtual int GetREDStatus(
int channel, bool& enabled, int& redPayloadtype) { return -1; }
// Sets the Forward Error Correction (FEC) status on a specific |channel|. // Sets the Forward Error Correction (FEC) status on a specific |channel|.
// TODO(minyue): Remove SetFECStatus() when SetFECStatus() is replaced by
// SetREDStatus() in fakewebrtcvoiceengine.
virtual int SetFECStatus( virtual int SetFECStatus(
int channel, bool enable, int redPayloadtype = -1) = 0; int channel, bool enable, int redPayloadtype = -1) {
return SetREDStatus(channel, enable, redPayloadtype);
};
// Gets the FEC status on a specific |channel|. // Gets the FEC status on a specific |channel|.
// TODO(minyue): Remove GetFECStatus() when GetFECStatus() is replaced by
// GetREDStatus() in fakewebrtcvoiceengine.
virtual int GetFECStatus( virtual int GetFECStatus(
int channel, bool& enabled, int& redPayloadtype) = 0; int channel, bool& enabled, int& redPayloadtype) {
return SetREDStatus(channel, enabled, redPayloadtype);
}
// This function enables Negative Acknowledgment (NACK) using RTCP, // This function enables Negative Acknowledgment (NACK) using RTCP,
// implemented based on RFC 4585. NACK retransmits RTP packets if lost on // implemented based on RFC 4585. NACK retransmits RTP packets if lost on

View File

@ -710,10 +710,10 @@ JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_StartSend(
return -1; return -1;
} */ } */
/* if (veData1.rtp_rtcp->SetFECStatus(channel, 1) != 0) /* if (veData1.rtp_rtcp->SetREDStatus(channel, 1) != 0)
{ {
__android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
"Failed to enable FEC"); "Failed to enable RED");
return -1; return -1;
} */ } */
@ -755,10 +755,10 @@ JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_StopSend(
jobject, jobject,
jint channel) jint channel)
{ {
/* if (veData1.rtp_rtcp->SetFECStatus(channel, 0) != 0) /* if (veData1.rtp_rtcp->SetREDStatus(channel, 0) != 0)
{ {
__android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
"Failed to disable FEC"); "Failed to disable RED");
return -1; return -1;
} */ } */
@ -1142,21 +1142,21 @@ Java_org_webrtc_voiceengine_test_AndroidTest_SetLoudspeakerStatus(
/*VALIDATE_RTP_RTCP_POINTER; /*VALIDATE_RTP_RTCP_POINTER;
if (veData1.rtp_rtcp->SetFECStatus(0, enable, -1) != 0) if (veData1.rtp_rtcp->SetREDStatus(0, enable, -1) != 0)
{ {
__android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
"Could not set FEC"); "Could not set RED");
return -1; return -1;
} }
else if(enable) else if(enable)
{ {
__android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
"Could enable FEC"); "Could enable RED");
} }
else else
{ {
__android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
"Could disable FEC"); "Could disable RED");
}*/ }*/
return 0; return 0;

View File

@ -173,7 +173,7 @@
#define IDC_CHECK_TYPING_DETECTION 1101 #define IDC_CHECK_TYPING_DETECTION 1101
#define IDC_CHECK_START_STOP_MODE2 1102 #define IDC_CHECK_START_STOP_MODE2 1102
#define IDC_CHECK_DIRECT_FEEDBACK 1102 #define IDC_CHECK_DIRECT_FEEDBACK 1102
#define IDC_CHECK_FEC 1102 #define IDC_CHECK_RED 1102
#define IDC_BUTTON_SET_RX_TELEPHONE_PT_TYPE 1103 #define IDC_BUTTON_SET_RX_TELEPHONE_PT_TYPE 1103
#define IDC_BUTTON_SET_RX_TELEPHONE_PT 1103 #define IDC_BUTTON_SET_RX_TELEPHONE_PT 1103
#define IDC_BUTTON_CLEAR_ERROR_CALLBACK 1103 #define IDC_BUTTON_CLEAR_ERROR_CALLBACK 1103

View File

@ -207,7 +207,7 @@ BEGIN
CONTROL "TypingDetect",IDC_CHECK_TYPING_DETECTION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,572,156,60,14,WS_EX_DLGMODALFRAME CONTROL "TypingDetect",IDC_CHECK_TYPING_DETECTION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,572,156,60,14,WS_EX_DLGMODALFRAME
EDITTEXT IDC_EDIT_AUDIO_LAYER,28,224,116,14,ES_AUTOHSCROLL | ES_READONLY EDITTEXT IDC_EDIT_AUDIO_LAYER,28,224,116,14,ES_AUTOHSCROLL | ES_READONLY
EDITTEXT IDC_EDIT_CPU_LOAD,152,224,116,14,ES_AUTOHSCROLL | ES_READONLY EDITTEXT IDC_EDIT_CPU_LOAD,152,224,116,14,ES_AUTOHSCROLL | ES_READONLY
CONTROL "FEC",IDC_CHECK_FEC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,176,55,28,14,WS_EX_DLGMODALFRAME CONTROL "RED",IDC_CHECK_RED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,176,55,28,14,WS_EX_DLGMODALFRAME
LTEXT "=> Callbacks",IDC_STATIC_ERROR_CALLBACK,283,226,43,8 LTEXT "=> Callbacks",IDC_STATIC_ERROR_CALLBACK,283,226,43,8
EDITTEXT IDC_EDIT_ERROR_CALLBACK,328,224,312,14,ES_AUTOHSCROLL EDITTEXT IDC_EDIT_ERROR_CALLBACK,328,224,312,14,ES_AUTOHSCROLL
PUSHBUTTON "Clear",IDC_BUTTON_CLEAR_ERROR_CALLBACK,644,224,24,14 PUSHBUTTON "Clear",IDC_BUTTON_CLEAR_ERROR_CALLBACK,644,224,24,14

View File

@ -1238,7 +1238,7 @@ BEGIN_MESSAGE_MAP(CWinTestDlg, CDialog)
ON_BN_CLICKED(IDC_CHECK_NS_1, &CWinTestDlg::OnBnClickedCheckNs1) ON_BN_CLICKED(IDC_CHECK_NS_1, &CWinTestDlg::OnBnClickedCheckNs1)
ON_BN_CLICKED(IDC_CHECK_REC_CALL, &CWinTestDlg::OnBnClickedCheckRecCall) ON_BN_CLICKED(IDC_CHECK_REC_CALL, &CWinTestDlg::OnBnClickedCheckRecCall)
ON_BN_CLICKED(IDC_CHECK_TYPING_DETECTION, &CWinTestDlg::OnBnClickedCheckTypingDetection) ON_BN_CLICKED(IDC_CHECK_TYPING_DETECTION, &CWinTestDlg::OnBnClickedCheckTypingDetection)
ON_BN_CLICKED(IDC_CHECK_FEC, &CWinTestDlg::OnBnClickedCheckFEC) ON_BN_CLICKED(IDC_CHECK_RED, &CWinTestDlg::OnBnClickedCheckRED)
ON_BN_CLICKED(IDC_BUTTON_CLEAR_ERROR_CALLBACK, &CWinTestDlg::OnBnClickedButtonClearErrorCallback) ON_BN_CLICKED(IDC_BUTTON_CLEAR_ERROR_CALLBACK, &CWinTestDlg::OnBnClickedButtonClearErrorCallback)
END_MESSAGE_MAP() END_MESSAGE_MAP()
@ -1440,7 +1440,7 @@ BOOL CWinTestDlg::OnInitDialog()
GetDlgItem(IDC_CHECK_RXVAD)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK_RXVAD)->EnableWindow(FALSE);
GetDlgItem(IDC_CHECK_AGC_1)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK_AGC_1)->EnableWindow(FALSE);
GetDlgItem(IDC_CHECK_NS_1)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK_NS_1)->EnableWindow(FALSE);
GetDlgItem(IDC_CHECK_FEC)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK_RED)->EnableWindow(FALSE);
CComboBox* comboIP(NULL); CComboBox* comboIP(NULL);
comboIP = (CComboBox*)GetDlgItem(IDC_COMBO_IP_1); comboIP = (CComboBox*)GetDlgItem(IDC_COMBO_IP_1);
@ -1709,7 +1709,7 @@ void CWinTestDlg::OnBnClickedButtonCreate1()
GetDlgItem(IDC_CHECK_RXVAD)->EnableWindow(TRUE); GetDlgItem(IDC_CHECK_RXVAD)->EnableWindow(TRUE);
GetDlgItem(IDC_CHECK_AGC_1)->EnableWindow(TRUE); GetDlgItem(IDC_CHECK_AGC_1)->EnableWindow(TRUE);
GetDlgItem(IDC_CHECK_NS_1)->EnableWindow(TRUE); GetDlgItem(IDC_CHECK_NS_1)->EnableWindow(TRUE);
GetDlgItem(IDC_CHECK_FEC)->EnableWindow(TRUE); GetDlgItem(IDC_CHECK_RED)->EnableWindow(TRUE);
// Always set send codec to default codec <=> index 0. // Always set send codec to default codec <=> index 0.
CodecInst codec; CodecInst codec;
@ -1799,7 +1799,7 @@ void CWinTestDlg::OnBnClickedButtonDelete1()
GetDlgItem(IDC_CHECK_AGC_1)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK_AGC_1)->EnableWindow(FALSE);
GetDlgItem(IDC_CHECK_NS_1)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK_NS_1)->EnableWindow(FALSE);
GetDlgItem(IDC_CHECK_RXVAD)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK_RXVAD)->EnableWindow(FALSE);
GetDlgItem(IDC_CHECK_FEC)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK_RED)->EnableWindow(FALSE);
SetDlgItemText(IDC_EDIT_RXVAD, _T("")); SetDlgItemText(IDC_EDIT_RXVAD, _T(""));
GetDlgItem(IDC_EDIT_RXVAD)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT_RXVAD)->EnableWindow(FALSE);
CButton* button = (CButton*)GetDlgItem(IDC_CHECK_EXT_TRANS_1); CButton* button = (CButton*)GetDlgItem(IDC_CHECK_EXT_TRANS_1);
@ -1834,7 +1834,7 @@ void CWinTestDlg::OnBnClickedButtonDelete1()
button->SetCheck(BST_UNCHECKED); button->SetCheck(BST_UNCHECKED);
button = (CButton*)GetDlgItem(IDC_CHECK_RXVAD); button = (CButton*)GetDlgItem(IDC_CHECK_RXVAD);
button->SetCheck(BST_UNCHECKED); button->SetCheck(BST_UNCHECKED);
button = (CButton*)GetDlgItem(IDC_CHECK_FEC); button = (CButton*)GetDlgItem(IDC_CHECK_RED);
button->SetCheck(BST_UNCHECKED); button->SetCheck(BST_UNCHECKED);
} }
} }
@ -3250,13 +3250,14 @@ void CWinTestDlg::OnBnClickedCheckTypingDetection()
TEST(_veApmPtr->SetTypingDetectionStatus(enable) == 0, _T("SetTypingDetectionStatus(enable=%d)"), enable); TEST(_veApmPtr->SetTypingDetectionStatus(enable) == 0, _T("SetTypingDetectionStatus(enable=%d)"), enable);
} }
void CWinTestDlg::OnBnClickedCheckFEC() void CWinTestDlg::OnBnClickedCheckRED()
{ {
CButton* button = (CButton*)GetDlgItem(IDC_CHECK_FEC); CButton* button = (CButton*)GetDlgItem(IDC_CHECK_RED);
int channel = GetDlgItemInt(IDC_EDIT_1); int channel = GetDlgItemInt(IDC_EDIT_1);
int check = button->GetCheck(); int check = button->GetCheck();
const bool enable = (check == BST_CHECKED); const bool enable = (check == BST_CHECKED);
TEST(_veRtpRtcpPtr->SetFECStatus(channel, enable) == 0, _T("SetFECStatus(enable=%d)"), enable); TEST(_veRtpRtcpPtr->SetREDStatus(channel, enable) == 0,
_T("SetREDStatus(enable=%d)"), enable);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -268,7 +268,7 @@ public:
afx_msg void OnBnClickedCheckNs1(); afx_msg void OnBnClickedCheckNs1();
afx_msg void OnBnClickedCheckRecCall(); afx_msg void OnBnClickedCheckRecCall();
afx_msg void OnBnClickedCheckTypingDetection(); afx_msg void OnBnClickedCheckTypingDetection();
afx_msg void OnBnClickedCheckFEC(); afx_msg void OnBnClickedCheckRED();
afx_msg void OnBnClickedButtonClearErrorCallback(); afx_msg void OnBnClickedButtonClearErrorCallback();
afx_msg void OnBnClickedCheckBwe1(); afx_msg void OnBnClickedCheckBwe1();
}; };

View File

@ -295,6 +295,41 @@ int VoECodecImpl::SetSendCNPayloadType(int channel, int type,
return channelPtr->SetSendCNPayloadType(type, frequency); return channelPtr->SetSendCNPayloadType(type, frequency);
} }
int VoECodecImpl::SetFECStatus(int channel, bool enable) {
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
"SetCodecFECStatus(channel=%d, enable=%d)", channel, enable);
if (!_shared->statistics().Initialized()) {
_shared->SetLastError(VE_NOT_INITED, kTraceError);
return -1;
}
voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
voe::Channel* channelPtr = ch.channel();
if (channelPtr == NULL) {
_shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
"SetCodecFECStatus() failed to locate channel");
return -1;
}
return channelPtr->SetCodecFECStatus(enable);
}
int VoECodecImpl::GetFECStatus(int channel, bool& enabled) {
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
"GetCodecFECStatus(channel=%d)", channel);
if (!_shared->statistics().Initialized()) {
_shared->SetLastError(VE_NOT_INITED, kTraceError);
return -1;
}
voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
voe::Channel* channelPtr = ch.channel();
if (channelPtr == NULL) {
_shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
"GetFECStatus() failed to locate channel");
return -1;
}
enabled = channelPtr->GetCodecFECStatus();
return 0;
}
int VoECodecImpl::SetVADStatus(int channel, bool enable, VadModes mode, int VoECodecImpl::SetVADStatus(int channel, bool enable, VadModes mode,
bool disableDTX) bool disableDTX)
{ {

View File

@ -40,6 +40,10 @@ public:
virtual int GetRecPayloadType(int channel, CodecInst& codec); virtual int GetRecPayloadType(int channel, CodecInst& codec);
virtual int SetFECStatus(int channel, bool enable);
virtual int GetFECStatus(int channel, bool& enabled);
virtual int SetVADStatus(int channel, virtual int SetVADStatus(int channel,
bool enable, bool enable,
VadModes mode = kVadConventional, VadModes mode = kVadConventional,

View File

@ -427,10 +427,10 @@ int VoERTP_RTCPImpl::GetRemoteRTCPReportBlocks(
return channel_ptr->GetRemoteRTCPReportBlocks(report_blocks); return channel_ptr->GetRemoteRTCPReportBlocks(report_blocks);
} }
int VoERTP_RTCPImpl::SetFECStatus(int channel, bool enable, int redPayloadtype) int VoERTP_RTCPImpl::SetREDStatus(int channel, bool enable, int redPayloadtype)
{ {
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
"SetFECStatus(channel=%d, enable=%d, redPayloadtype=%d)", "SetREDStatus(channel=%d, enable=%d, redPayloadtype=%d)",
channel, enable, redPayloadtype); channel, enable, redPayloadtype);
#ifdef WEBRTC_CODEC_RED #ifdef WEBRTC_CODEC_RED
if (!_shared->statistics().Initialized()) if (!_shared->statistics().Initialized())
@ -443,23 +443,23 @@ int VoERTP_RTCPImpl::SetFECStatus(int channel, bool enable, int redPayloadtype)
if (channelPtr == NULL) if (channelPtr == NULL)
{ {
_shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
"SetFECStatus() failed to locate channel"); "SetREDStatus() failed to locate channel");
return -1; return -1;
} }
return channelPtr->SetFECStatus(enable, redPayloadtype); return channelPtr->SetREDStatus(enable, redPayloadtype);
#else #else
_shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError, _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
"SetFECStatus() RED is not supported"); "SetREDStatus() RED is not supported");
return -1; return -1;
#endif #endif
} }
int VoERTP_RTCPImpl::GetFECStatus(int channel, int VoERTP_RTCPImpl::GetREDStatus(int channel,
bool& enabled, bool& enabled,
int& redPayloadtype) int& redPayloadtype)
{ {
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
"GetFECStatus(channel=%d, enabled=?, redPayloadtype=?)", "GetREDStatus(channel=%d, enabled=?, redPayloadtype=?)",
channel); channel);
#ifdef WEBRTC_CODEC_RED #ifdef WEBRTC_CODEC_RED
if (!_shared->statistics().Initialized()) if (!_shared->statistics().Initialized())
@ -472,18 +472,17 @@ int VoERTP_RTCPImpl::GetFECStatus(int channel,
if (channelPtr == NULL) if (channelPtr == NULL)
{ {
_shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
"GetFECStatus() failed to locate channel"); "GetREDStatus() failed to locate channel");
return -1; return -1;
} }
return channelPtr->GetFECStatus(enabled, redPayloadtype); return channelPtr->GetREDStatus(enabled, redPayloadtype);
#else #else
_shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError, _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
"GetFECStatus() RED is not supported"); "GetREDStatus() RED is not supported");
return -1; return -1;
#endif #endif
} }
int VoERTP_RTCPImpl::SetNACKStatus(int channel, int VoERTP_RTCPImpl::SetNACKStatus(int channel,
bool enable, bool enable,
int maxNoPackets) int maxNoPackets)

View File

@ -73,12 +73,12 @@ public:
virtual int GetRemoteRTCPReportBlocks( virtual int GetRemoteRTCPReportBlocks(
int channel, std::vector<ReportBlock>* report_blocks); int channel, std::vector<ReportBlock>* report_blocks);
// FEC // RED
virtual int SetFECStatus(int channel, virtual int SetREDStatus(int channel,
bool enable, bool enable,
int redPayloadtype = -1); int redPayloadtype = -1);
virtual int GetFECStatus(int channel, bool& enabled, int& redPayloadtype); virtual int GetREDStatus(int channel, bool& enabled, int& redPayloadtype);
//NACK //NACK
virtual int SetNACKStatus(int channel, virtual int SetNACKStatus(int channel,

View File

@ -20,6 +20,7 @@
'<(webrtc_root)/modules/modules.gyp:audio_conference_mixer', '<(webrtc_root)/modules/modules.gyp:audio_conference_mixer',
'<(webrtc_root)/modules/modules.gyp:audio_device', '<(webrtc_root)/modules/modules.gyp:audio_device',
'<(webrtc_root)/modules/modules.gyp:audio_processing', '<(webrtc_root)/modules/modules.gyp:audio_processing',
'<(webrtc_root)/modules/modules.gyp:bitrate_controller',
'<(webrtc_root)/modules/modules.gyp:media_file', '<(webrtc_root)/modules/modules.gyp:media_file',
'<(webrtc_root)/modules/modules.gyp:rtp_rtcp', '<(webrtc_root)/modules/modules.gyp:rtp_rtcp',
'<(webrtc_root)/modules/modules.gyp:webrtc_utility', '<(webrtc_root)/modules/modules.gyp:webrtc_utility',