Adding flag to force Opus application and DTX while toggling.

Currently, we only allow Opus DTX in combination with Opus kVoip mode. When one of them is toggled, the other might need to change as well. This CL is to introduce a flag to force a co-config.

BUG=
R=henrik.lundin@webrtc.org, tina.legrand@webrtc.org

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

Cr-Commit-Position: refs/heads/master@{#8698}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8698 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
minyue@webrtc.org
2015-03-12 15:28:41 +00:00
parent 75b7f17c29
commit e16bfde512
10 changed files with 119 additions and 58 deletions

View File

@ -514,14 +514,17 @@ AudioDecoder* ACMGenericCodec::Decoder() {
return decoder_proxy_.IsSet() ? &decoder_proxy_ : nullptr;
}
int ACMGenericCodec::EnableOpusDtx() {
int ACMGenericCodec::EnableOpusDtx(bool force_voip) {
WriteLockScoped wl(codec_wrapper_lock_);
if (!is_opus_)
return -1; // Needed for tests to pass.
if (GetOpusApplication(encoder_->NumChannels(), true) != kVoip) {
// Opus DTX can only be enabled when application mode is KVoip.
return -1;
if (!force_voip &&
GetOpusApplication(encoder_->NumChannels(), true) != kVoip) {
// Opus DTX can only be enabled when application mode is KVoip.
return -1;
}
opus_application_ = kVoip;
opus_application_set_ = true;
opus_dtx_enabled_ = true;
ResetAudioEncoder();
return 0;
@ -547,11 +550,16 @@ int ACMGenericCodec::SetFEC(bool enable_fec) {
return 0;
}
int ACMGenericCodec::SetOpusApplication(OpusApplicationMode application) {
int ACMGenericCodec::SetOpusApplication(OpusApplicationMode application,
bool disable_dtx_if_needed) {
WriteLockScoped wl(codec_wrapper_lock_);
if (opus_dtx_enabled_ && application == kAudio) {
// Opus can only be set to kAudio when DTX is off.
return -1;
if (disable_dtx_if_needed) {
opus_dtx_enabled_ = false;
} else {
// Opus can only be set to kAudio when DTX is off.
return -1;
}
}
opus_application_ = application;
opus_application_set_ = true;

View File

@ -320,18 +320,25 @@ class ACMGenericCodec {
int32_t SetISACMaxRate(const uint32_t max_rate_bps);
///////////////////////////////////////////////////////////////////////////
// int SetOpusApplication()
// int SetOpusApplication(OpusApplicationMode application,
// bool disable_dtx_if_needed)
// Sets the intended application for the Opus encoder. Opus uses this to
// optimize the encoding for applications like VOIP and music.
// optimize the encoding for applications like VOIP and music. Currently, two
// modes are supported: kVoip and kAudio. kAudio is only allowed when Opus
// DTX is switched off. If DTX is on, and |application| == kAudio, a failure
// will be triggered unless |disable_dtx_if_needed| == true, for which, the
// DTX will be forced off.
//
// Input:
// - application : intended application.
// - application : intended application.
// - disable_dtx_if_needed : whether to force Opus DTX to stop when needed.
//
// Return value:
// -1 if failed or on codecs other than Opus.
// 0 if succeeded.
//
int SetOpusApplication(OpusApplicationMode /*application*/);
int SetOpusApplication(OpusApplicationMode application,
bool disable_dtx_if_needed);
///////////////////////////////////////////////////////////////////////////
// int SetOpusMaxPlaybackRate()
@ -344,19 +351,24 @@ class ACMGenericCodec {
// -frequency_hz : maximum playback rate in Hz.
//
// Return value:
// -1 if failed or on codecs other than Opus
// -1 if failed or on codecs other than Opus.
// 0 if succeeded.
//
int SetOpusMaxPlaybackRate(int /* frequency_hz */);
///////////////////////////////////////////////////////////////////////////
// EnableOpusDtx()
// Enable the DTX, if the codec is Opus. If current Opus application mode is
// audio, a failure will be triggered.
// EnableOpusDtx(bool force_voip)
// Enable the DTX, if the codec is Opus. Currently, DTX can only be enabled
// when the application mode is kVoip. If |force_voip| == true, the
// application mode will be forced to kVoip. Otherwise, a failure will be
// triggered if current application mode is kAudio.
// Input:
// - force_voip : whether to force application mode to kVoip.
// Return value:
// -1 if failed or on codecs other than Opus.
// 0 if succeeded.
int EnableOpusDtx();
//
int EnableOpusDtx(bool force_voip);
///////////////////////////////////////////////////////////////////////////
// DisbleOpusDtx()
@ -364,6 +376,7 @@ class ACMGenericCodec {
// Return value:
// -1 if failed or on codecs other than Opus.
// 0 if succeeded.
//
int DisableOpusDtx();
///////////////////////////////////////////////////////////////////////////

View File

@ -67,7 +67,7 @@ TEST_F(AcmGenericCodecOpusTest, ChangeApplicationMode) {
EXPECT_EQ(AudioEncoderOpus::kAudio, opus_ptr->application());
// Change mode.
EXPECT_EQ(0, codec_wrapper_->SetOpusApplication(kVoip));
EXPECT_EQ(0, codec_wrapper_->SetOpusApplication(kVoip, false));
// Verify that the AudioEncoder object was changed.
EXPECT_NE(opus_ptr, GetAudioEncoderOpus());
EXPECT_EQ(AudioEncoderOpus::kVoip, GetAudioEncoderOpus()->application());
@ -89,7 +89,7 @@ TEST_F(AcmGenericCodecOpusTest, ResetWontChangeApplicationMode) {
EXPECT_EQ(AudioEncoderOpus::kAudio, GetAudioEncoderOpus()->application());
// Now change to kVoip.
EXPECT_EQ(0, codec_wrapper_->SetOpusApplication(kVoip));
EXPECT_EQ(0, codec_wrapper_->SetOpusApplication(kVoip, false));
EXPECT_EQ(AudioEncoderOpus::kVoip, GetAudioEncoderOpus()->application());
opus_ptr = GetAudioEncoderOpus();
@ -108,18 +108,36 @@ TEST_F(AcmGenericCodecOpusTest, ToggleDtx) {
// Verify that the mode is still kAudio.
EXPECT_EQ(AudioEncoderOpus::kAudio, GetAudioEncoderOpus()->application());
// DTX is not allowed in audio mode.
EXPECT_EQ(-1, codec_wrapper_->EnableOpusDtx());
// DTX is not allowed in audio mode, if mode forcing flag is false.
EXPECT_EQ(-1, codec_wrapper_->EnableOpusDtx(false));
EXPECT_EQ(AudioEncoderOpus::kAudio, GetAudioEncoderOpus()->application());
EXPECT_EQ(0, codec_wrapper_->SetOpusApplication(kVoip));
EXPECT_EQ(0, codec_wrapper_->EnableOpusDtx());
// Audio mode is not allowed when DTX is on.
EXPECT_EQ(-1, codec_wrapper_->SetOpusApplication(kAudio));
// DTX will be on, if mode forcing flag is true. Then application mode is
// switched to kVoip.
EXPECT_EQ(0, codec_wrapper_->EnableOpusDtx(true));
EXPECT_EQ(AudioEncoderOpus::kVoip, GetAudioEncoderOpus()->application());
// Audio mode is not allowed when DTX is on, and DTX forcing flag is false.
EXPECT_EQ(-1, codec_wrapper_->SetOpusApplication(kAudio, false));
EXPECT_EQ(true, GetAudioEncoderOpus()->dtx_enabled());
// Audio mode will be set, if DTX forcing flag is true. Then DTX is switched
// off.
EXPECT_EQ(0, codec_wrapper_->SetOpusApplication(kAudio, true));
EXPECT_EQ(false, GetAudioEncoderOpus()->dtx_enabled());
// Now we set VOIP mode. The DTX forcing flag has no effect.
EXPECT_EQ(0, codec_wrapper_->SetOpusApplication(kVoip, true));
EXPECT_EQ(false, GetAudioEncoderOpus()->dtx_enabled());
// In VOIP mode, we can enable DTX with mode forcing flag being false.
EXPECT_EQ(0, codec_wrapper_->EnableOpusDtx(false));
// Turn off DTX.
EXPECT_EQ(0, codec_wrapper_->DisableOpusDtx());
EXPECT_EQ(0, codec_wrapper_->SetOpusApplication(kAudio));
// When DTX is off, we can set Audio mode with DTX forcing flag being false.
EXPECT_EQ(0, codec_wrapper_->SetOpusApplication(kAudio, false));
}
#endif // WEBRTC_CODEC_OPUS

View File

@ -1327,12 +1327,14 @@ int AudioCodingModuleImpl::ConfigISACBandwidthEstimator(
// frame_size_ms, rate_bit_per_sec, enforce_frame_size);
}
int AudioCodingModuleImpl::SetOpusApplication(OpusApplicationMode application) {
int AudioCodingModuleImpl::SetOpusApplication(OpusApplicationMode application,
bool disable_dtx_if_needed) {
CriticalSectionScoped lock(acm_crit_sect_);
if (!HaveValidEncoder("SetOpusApplication")) {
return -1;
}
return codecs_[current_send_codec_idx_]->SetOpusApplication(application);
return codecs_[current_send_codec_idx_]->SetOpusApplication(
application, disable_dtx_if_needed);
}
// Informs Opus encoder of the maximum playback rate the receiver will render.
@ -1344,12 +1346,12 @@ int AudioCodingModuleImpl::SetOpusMaxPlaybackRate(int frequency_hz) {
return codecs_[current_send_codec_idx_]->SetOpusMaxPlaybackRate(frequency_hz);
}
int AudioCodingModuleImpl::EnableOpusDtx() {
int AudioCodingModuleImpl::EnableOpusDtx(bool force_voip) {
CriticalSectionScoped lock(acm_crit_sect_);
if (!HaveValidEncoder("EnableOpusDtx")) {
return -1;
}
return codecs_[current_send_codec_idx_]->EnableOpusDtx();
return codecs_[current_send_codec_idx_]->EnableOpusDtx(force_voip);
}
int AudioCodingModuleImpl::DisableOpusDtx() {

View File

@ -214,13 +214,14 @@ class AudioCodingModuleImpl : public AudioCodingModule {
int rate_bit_per_sec,
bool enforce_frame_size = false) override;
int SetOpusApplication(OpusApplicationMode application) override;
int SetOpusApplication(OpusApplicationMode application,
bool disable_dtx_if_needed) override;
// If current send codec is Opus, informs it about the maximum playback rate
// the receiver will render.
int SetOpusMaxPlaybackRate(int frequency_hz) override;
int EnableOpusDtx() override;
int EnableOpusDtx(bool force_voip) override;
int DisableOpusDtx() override;

View File

@ -1117,7 +1117,7 @@ TEST_F(AcmSenderBitExactnessOldApi, MAYBE_Opus_stereo_20ms) {
TEST_F(AcmSenderBitExactnessOldApi, MAYBE_Opus_stereo_20ms_voip) {
ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 2, 120, 960, 960));
// If not set, default will be kAudio in case of stereo.
send_test_->acm()->SetOpusApplication(kVoip);
EXPECT_EQ(0, send_test_->acm()->SetOpusApplication(kVoip, false));
Run(AcmReceiverBitExactnessOldApi::PlatformChecksum(
"9b9e12bc3cc793740966e11cbfa8b35b",
"57412a4b5771d19ff03ec35deffe7067",