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-Original-Commit-Position: refs/heads/master@{#8716}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: 9b2e1144df6e3622354caca00baf4a7462a0809c
diff --git a/voice_engine/channel.cc b/voice_engine/channel.cc
index 2df3a71..719cc35 100644
--- a/voice_engine/channel.cc
+++ b/voice_engine/channel.cc
@@ -1565,6 +1565,19 @@
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),
diff --git a/voice_engine/channel.h b/voice_engine/channel.h
index cd1469f..e197af8 100644
--- a/voice_engine/channel.h
+++ b/voice_engine/channel.h
@@ -208,6 +208,7 @@
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);
diff --git a/voice_engine/include/voe_codec.h b/voice_engine/include/voe_codec.h
index a61b49b..4b9f939 100644
--- a/voice_engine/include/voe_codec.h
+++ b/voice_engine/include/voe_codec.h
@@ -117,6 +117,10 @@
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; }
diff --git a/voice_engine/test/auto_test/standard/codec_test.cc b/voice_engine/test/auto_test/standard/codec_test.cc
index 3460f0a..bfc2a30 100644
--- a/voice_engine/test/auto_test/standard/codec_test.cc
+++ b/voice_engine/test/auto_test/standard/codec_test.cc
@@ -158,6 +158,30 @@
}
}
+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) {
diff --git a/voice_engine/test/cmd_test/voe_cmd_test.cc b/voice_engine/test/cmd_test/voe_cmd_test.cc
index f0c3471..419ba55 100644
--- a/voice_engine/test/cmd_test/voe_cmd_test.cc
+++ b/voice_engine/test/cmd_test/voe_cmd_test.cc
@@ -232,6 +232,7 @@
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 @@
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++);
@@ -774,6 +776,11 @@
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;
printf("Current bit rate is %i bps, set to: ", cinst.rate);
diff --git a/voice_engine/voe_codec_impl.cc b/voice_engine/voe_codec_impl.cc
index aa54a1f..2b0141f 100644
--- a/voice_engine/voe_codec_impl.cc
+++ b/voice_engine/voe_codec_impl.cc
@@ -436,6 +436,23 @@
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)
{
diff --git a/voice_engine/voe_codec_impl.h b/voice_engine/voe_codec_impl.h
index ab26adc..dad808d 100644
--- a/voice_engine/voe_codec_impl.h
+++ b/voice_engine/voe_codec_impl.h
@@ -56,6 +56,8 @@
virtual int SetOpusMaxPlaybackRate(int channel, int frequency_hz);
+ virtual int SetOpusDtx(int channel, bool enable_dtx);
+
protected:
VoECodecImpl(voe::SharedData* shared);
virtual ~VoECodecImpl();