Supporting Opus DTX in Voice Engine.

Opus DTX is an Opus specific feature. It does not require WebRTC VAD/DTX, therefore is not set by VoECodec::SetVADStatus(), but rather a dedicated API.

BUG=1014
R=henrika@webrtc.org, pbos@webrtc.org

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

Cr-Commit-Position: refs/heads/master@{#8716}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8716 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
minyue@webrtc.org 2015-03-13 09:38:07 +00:00
parent dd0292a774
commit 9b2e1144df
8 changed files with 80 additions and 0 deletions

View File

@ -192,6 +192,7 @@ class FakeWebRtcVoiceEngine
vad(false),
codec_fec(false),
max_encoding_bandwidth(0),
opus_dtx(false),
red(false),
nack(false),
media_processor_registered(false),
@ -222,6 +223,7 @@ class FakeWebRtcVoiceEngine
bool vad;
bool codec_fec;
int max_encoding_bandwidth;
bool opus_dtx;
bool red;
bool nack;
bool media_processor_registered;
@ -664,6 +666,16 @@ class FakeWebRtcVoiceEngine
return 0;
}
WEBRTC_FUNC(SetOpusDtx, (int channel, bool enable_dtx)) {
WEBRTC_CHECK_CHANNEL(channel);
if (_stricmp(channels_[channel]->send_codec.plname, "opus") != 0) {
// Return -1 if current send codec is not Opus.
return -1;
}
channels_[channel]->opus_dtx = enable_dtx;
return 0;
}
// webrtc::VoEDtmf
WEBRTC_FUNC(SendTelephoneEvent, (int channel, int event_code,
bool out_of_band = true, int length_ms = 160, int attenuation_db = 10)) {

View File

@ -1565,6 +1565,19 @@ int Channel::SetOpusMaxPlaybackRate(int frequency_hz) {
return 0;
}
int Channel::SetOpusDtx(bool enable_dtx) {
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
"Channel::SetOpusDtx(%d)", enable_dtx);
int ret = enable_dtx ? audio_coding_->EnableOpusDtx(true)
: audio_coding_->DisableOpusDtx();
if (ret != 0) {
_engineStatisticsPtr->SetLastError(
VE_AUDIO_CODING_MODULE_ERROR, kTraceError, "SetOpusDtx() failed");
return -1;
}
return 0;
}
int32_t Channel::RegisterExternalTransport(Transport& transport)
{
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),

View File

@ -208,6 +208,7 @@ public:
int32_t GetRecPayloadType(CodecInst& codec);
int32_t SetSendCNPayloadType(int type, PayloadFrequencies frequency);
int SetOpusMaxPlaybackRate(int frequency_hz);
int SetOpusDtx(bool enable_dtx);
// VoENetwork
int32_t RegisterExternalTransport(Transport& transport);

View File

@ -117,6 +117,10 @@ public:
return -1;
}
// If send codec is Opus on a specified |channel|, set its DTX. Returns 0 if
// success, and -1 if failed.
virtual int SetOpusDtx(int channel, bool enable_dtx) = 0;
// Don't use. To be removed.
virtual int SetAMREncFormat(int channel, AmrMode mode) { return -1; }
virtual int SetAMRDecFormat(int channel, AmrMode mode) { return -1; }

View File

@ -158,6 +158,30 @@ TEST_F(CodecTest, OpusMaxPlaybackRateCannotBeSetForNonOpus) {
}
}
TEST_F(CodecTest, OpusDtxCanBeSetForOpus) {
for (int i = 0; i < voe_codec_->NumOfCodecs(); ++i) {
voe_codec_->GetCodec(i, codec_instance_);
if (_stricmp("opus", codec_instance_.plname)) {
continue;
}
voe_codec_->SetSendCodec(channel_, codec_instance_);
EXPECT_EQ(0, voe_codec_->SetOpusDtx(channel_, false));
EXPECT_EQ(0, voe_codec_->SetOpusDtx(channel_, true));
}
}
TEST_F(CodecTest, OpusDtxCannotBeSetForNonOpus) {
for (int i = 0; i < voe_codec_->NumOfCodecs(); ++i) {
voe_codec_->GetCodec(i, codec_instance_);
if (!_stricmp("opus", codec_instance_.plname)) {
continue;
}
voe_codec_->SetSendCodec(channel_, codec_instance_);
EXPECT_EQ(-1, voe_codec_->SetOpusDtx(channel_, false));
EXPECT_EQ(-1, voe_codec_->SetOpusDtx(channel_, true));
}
}
// TODO(xians, phoglund): Re-enable when issue 372 is resolved.
TEST_F(CodecTest, DISABLED_ManualVerifySendCodecsForAllPacketSizes) {
for (int i = 0; i < voe_codec_->NumOfCodecs(); ++i) {

View File

@ -232,6 +232,7 @@ void RunTest(std::string out_path) {
bool typing_detection = false;
bool muted = false;
bool opus_stereo = false;
bool opus_dtx = false;
bool experimental_ns_enabled = false;
bool debug_recording_started = false;
@ -447,6 +448,7 @@ void RunTest(std::string out_path) {
printf("%i. Toggle Opus stereo (Opus must be selected again to apply "
"the setting) \n", option_index++);
printf("%i. Set Opus maximum playback rate \n", option_index++);
printf("%i. Toggle Opus DTX \n", option_index++);
printf("%i. Set bit rate (only take effect on codecs that allow the "
"change) \n", option_index++);
printf("%i. Toggle debug recording \n", option_index++);
@ -773,6 +775,11 @@ void RunTest(std::string out_path) {
ASSERT_EQ(1, scanf("%i", &max_playback_rate));
res = codec->SetOpusMaxPlaybackRate(chan, max_playback_rate);
VALIDATE;
} else if (option_selection == option_index++) {
opus_dtx = !opus_dtx;
res = codec->SetOpusDtx(chan, opus_dtx);
VALIDATE;
printf("Opus DTX %s.\n", opus_dtx ? "enabled" : "disabled");
} else if (option_selection == option_index++) {
res = codec->GetSendCodec(chan, cinst);
VALIDATE;

View File

@ -436,6 +436,23 @@ int VoECodecImpl::SetOpusMaxPlaybackRate(int channel, int frequency_hz) {
return channelPtr->SetOpusMaxPlaybackRate(frequency_hz);
}
int VoECodecImpl::SetOpusDtx(int channel, bool enable_dtx) {
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
"SetOpusDtx(channel=%d, enable_dtx=%d)", channel, enable_dtx);
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,
"SetOpusDtx failed to locate channel");
return -1;
}
return channelPtr->SetOpusDtx(enable_dtx);
}
void VoECodecImpl::ACMToExternalCodecRepresentation(CodecInst& toInst,
const CodecInst& fromInst)
{

View File

@ -56,6 +56,8 @@ public:
virtual int SetOpusMaxPlaybackRate(int channel, int frequency_hz);
virtual int SetOpusDtx(int channel, bool enable_dtx);
protected:
VoECodecImpl(voe::SharedData* shared);
virtual ~VoECodecImpl();