VAD changes ported to ACM2.

This CL ports the relevant parts of  https://code.google.com/p/webrtc/source/detail?r=4625 to ACM2.

BUG=
R=tina.legrand@webrtc.org

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@4804 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
turaj@webrtc.org 2013-09-20 16:38:26 +00:00
parent 362a55e7b0
commit 10e6cc7e23
4 changed files with 79 additions and 85 deletions

View File

@ -423,7 +423,11 @@ int16_t ACMGenericCodec::ResetEncoderSafe() {
DisableVAD(); DisableVAD();
// Set DTX/VAD. // Set DTX/VAD.
return SetVADSafe(enable_dtx, enable_vad, mode); int status = SetVADSafe(&enable_dtx, &enable_vad, &mode);
dtx_enabled_ = enable_dtx;
vad_enabled_ = enable_vad;
vad_mode_ = mode;
return status;
} }
int16_t ACMGenericCodec::InternalResetEncoder() { int16_t ACMGenericCodec::InternalResetEncoder() {
@ -504,10 +508,8 @@ int16_t ACMGenericCodec::InitEncoderSafe(WebRtcACMCodecParams* codec_params,
memset(in_timestamp_, 0, sizeof(uint32_t) * TIMESTAMP_BUFFER_SIZE_W32); memset(in_timestamp_, 0, sizeof(uint32_t) * TIMESTAMP_BUFFER_SIZE_W32);
} }
} }
status = SetVADSafe(codec_params->enable_dtx, codec_params->enable_vad, return SetVADSafe(&codec_params->enable_dtx, &codec_params->enable_vad,
codec_params->vad_mode); &codec_params->vad_mode);
return status;
} }
void ACMGenericCodec::ResetNoMissedSamples() { void ACMGenericCodec::ResetNoMissedSamples() {
@ -634,70 +636,78 @@ uint32_t ACMGenericCodec::EarliestTimestamp() const {
return in_timestamp_[0]; return in_timestamp_[0];
} }
int16_t ACMGenericCodec::SetVAD(const bool enable_dtx, int16_t ACMGenericCodec::SetVAD(bool* enable_dtx,
const bool enable_vad, bool* enable_vad,
const ACMVADMode mode) { ACMVADMode* mode) {
WriteLockScoped cs(codec_wrapper_lock_); WriteLockScoped cs(codec_wrapper_lock_);
return SetVADSafe(enable_dtx, enable_vad, mode); return SetVADSafe(enable_dtx, enable_vad, mode);
} }
int16_t ACMGenericCodec::SetVADSafe(const bool enable_dtx, int16_t ACMGenericCodec::SetVADSafe(bool* enable_dtx,
const bool enable_vad, bool* enable_vad,
const ACMVADMode mode) { ACMVADMode* mode) {
if (enable_dtx) { if (!STR_CASE_CMP(encoder_params_.codec_inst.plname, "OPUS") ||
encoder_params_.codec_inst.channels == 2 ) {
// VAD/DTX is not supported for Opus (even if sending mono), or other
// stereo codecs.
DisableDTX();
DisableVAD();
*enable_dtx = false;
*enable_vad = false;
return 0;
}
if (*enable_dtx) {
// Make G729 AnnexB a special case. // Make G729 AnnexB a special case.
if (!STR_CASE_CMP(encoder_params_.codec_inst.plname, "G729") if (!STR_CASE_CMP(encoder_params_.codec_inst.plname, "G729")
&& !has_internal_dtx_) { && !has_internal_dtx_) {
if (ACMGenericCodec::EnableDTX() < 0) { if (ACMGenericCodec::EnableDTX() < 0) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_, WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
"SetVADSafe: error in enable DTX"); "SetVADSafe: error in enable DTX");
*enable_dtx = false;
*enable_vad = vad_enabled_;
return -1; return -1;
} }
} else { } else {
if (EnableDTX() < 0) { if (EnableDTX() < 0) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_, WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
"SetVADSafe: error in enable DTX"); "SetVADSafe: error in enable DTX");
*enable_dtx = false;
*enable_vad = vad_enabled_;
return -1; return -1;
} }
} }
if (has_internal_dtx_) { // If codec does not have internal DTX (normal case) enabling DTX requires
// Codec has internal DTX, practically we don't need WebRtc VAD, however, // an active VAD. '*enable_dtx == true' overwrites VAD status.
// we let the user to turn it on if they need call-backs on silence. // If codec has internal DTX, practically we don't need WebRtc VAD, however,
// Store VAD mode for future even if VAD is off. // we let the user to turn it on if they need call-backs on silence.
vad_mode_ = mode; if (!has_internal_dtx_) {
return (enable_vad) ? EnableVAD(mode) : DisableVAD(); // DTX is enabled, and VAD will be activated.
} else { *enable_vad = true;
// Codec does not have internal DTX so enabling DTX requires an active
// VAD. 'enable_dtx == true' overwrites VAD status.
if (EnableVAD(mode) < 0) {
// If we cannot create VAD we have to disable DTX.
if (!vad_enabled_) {
DisableDTX();
}
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
"SetVADSafe: error in enable VAD");
return -1;
}
// Return '1', to let the caller know VAD was turned on, even if the
// function was called with VAD='false'.
if (enable_vad == false) {
return 1;
} else {
return 0;
}
} }
} else { } else {
// Make G729 AnnexB a special case. // Make G729 AnnexB a special case.
if (!STR_CASE_CMP(encoder_params_.codec_inst.plname, "G729") if (!STR_CASE_CMP(encoder_params_.codec_inst.plname, "G729")
&& !has_internal_dtx_) { && !has_internal_dtx_) {
ACMGenericCodec::DisableDTX(); ACMGenericCodec::DisableDTX();
*enable_dtx = false;
} else { } else {
DisableDTX(); DisableDTX();
*enable_dtx = false;
} }
return (enable_vad) ? EnableVAD(mode) : DisableVAD();
} }
int16_t status = (*enable_vad) ? EnableVAD(*mode) : DisableVAD();
if (status < 0) {
// Failed to set VAD, disable DTX.
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
"SetVADSafe: error in enable VAD");
DisableDTX();
*enable_dtx = false;
*enable_vad = false;
}
return status;
} }
int16_t ACMGenericCodec::EnableDTX() { int16_t ACMGenericCodec::EnableDTX() {

View File

@ -231,16 +231,16 @@ class ACMGenericCodec {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// int16_t SetVAD() // int16_t SetVAD()
// This is called to set VAD & DTX. If the codec has internal DTX that will // This is called to set VAD & DTX. If the codec has internal DTX, it will
// be used. If DTX is enabled and the codec does not have internal DTX, // be used. If DTX is enabled and the codec does not have internal DTX,
// WebRtc-VAD will be used to decide if the frame is active. If DTX is // WebRtc-VAD will be used to decide if the frame is active. If DTX is
// disabled but VAD is enabled. The audio is passed through VAD to label it // disabled but VAD is enabled, the audio is passed through VAD to label it
// as active or passive, but the frame is encoded normally. However the // as active or passive, but the frame is encoded normally. However the
// bit-stream is labeled properly so that ACM::Process() can use this // bit-stream is labeled properly so that ACM::Process() can use this
// information. In case of failure, the previous states of the VAD & DTX // information. In case of failure, the previous states of the VAD & DTX
// are kept. // are kept.
// //
// Inputs: // Inputs/Output:
// -enable_dtx : if true DTX will be enabled otherwise the DTX is // -enable_dtx : if true DTX will be enabled otherwise the DTX is
// disabled. If codec has internal DTX that will be // disabled. If codec has internal DTX that will be
// used, otherwise WebRtc-CNG is used. In the latter // used, otherwise WebRtc-CNG is used. In the latter
@ -256,9 +256,7 @@ class ACMGenericCodec {
// -1 if failed to set DTX & VAD as specified, // -1 if failed to set DTX & VAD as specified,
// 0 if succeeded. // 0 if succeeded.
// //
int16_t SetVAD(const bool enable_dtx = true, int16_t SetVAD(bool* enable_dtx, bool* enable_vad, ACMVADMode* mode);
const bool enable_vad = false,
const ACMVADMode mode = VADNormal);
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// int32_t ReplaceInternalDTX() // int32_t ReplaceInternalDTX()
@ -639,9 +637,7 @@ class ACMGenericCodec {
// See SetVAD() for the description of function, input(s)/output(s) and // See SetVAD() for the description of function, input(s)/output(s) and
// return value. // return value.
// //
int16_t SetVADSafe(const bool enable_dtx = true, int16_t SetVADSafe(bool* enable_dtx, bool* enable_vad, ACMVADMode* mode);
const bool enable_vad = false,
const ACMVADMode mode = VADNormal);
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// See ReplaceInternalDTX() for the description of function, input and // See ReplaceInternalDTX() for the description of function, input and

View File

@ -525,7 +525,7 @@ int AudioCodingModuleImpl::ProcessSingleStream() {
} }
case kActiveNormalEncoded: case kActiveNormalEncoded:
case kPassiveNormalEncoded: { case kPassiveNormalEncoded: {
current_payload_type = (uint8_t)send_codec_inst_.pltype; current_payload_type = static_cast<uint8_t>(send_codec_inst_.pltype);
frame_type = kAudioFrameSpeech; frame_type = kAudioFrameSpeech;
break; break;
} }
@ -685,7 +685,7 @@ int AudioCodingModuleImpl::ProcessSingleStream() {
if (vad_callback_ != NULL) { if (vad_callback_ != NULL) {
// Callback with VAD decision. // Callback with VAD decision.
vad_callback_->InFrameType(((int16_t)encoding_type)); vad_callback_->InFrameType(static_cast<int16_t>(encoding_type));
} }
} }
return length_bytes; return length_bytes;
@ -998,7 +998,6 @@ int AudioCodingModuleImpl::RegisterSendCodec(const CodecInst& send_codec) {
} }
ACMGenericCodec* codec_ptr = codecs_[codec_id]; ACMGenericCodec* codec_ptr = codecs_[codec_id];
int status;
WebRtcACMCodecParams codec_params; WebRtcACMCodecParams codec_params;
memcpy(&(codec_params.codec_inst), &send_codec, sizeof(CodecInst)); memcpy(&(codec_params.codec_inst), &send_codec, sizeof(CodecInst));
@ -1006,12 +1005,7 @@ int AudioCodingModuleImpl::RegisterSendCodec(const CodecInst& send_codec) {
codec_params.enable_dtx = dtx_enabled_; codec_params.enable_dtx = dtx_enabled_;
codec_params.vad_mode = vad_mode_; codec_params.vad_mode = vad_mode_;
// Force initialization. // Force initialization.
status = codec_ptr->InitEncoder(&codec_params, true); if (codec_ptr->InitEncoder(&codec_params, true) < 0) {
// Check if VAD was turned on, or if error is reported.
if (status == 1) {
vad_enabled_ = true;
} else if (status < 0) {
// Could not initialize the encoder. // Could not initialize the encoder.
// Check if already have a registered codec. // Check if already have a registered codec.
@ -1028,17 +1022,17 @@ int AudioCodingModuleImpl::RegisterSendCodec(const CodecInst& send_codec) {
return -1; return -1;
} }
// Update states.
dtx_enabled_ = codec_params.enable_dtx;
vad_enabled_ = codec_params.enable_vad;
vad_mode_ = codec_params.vad_mode;
// Everything is fine so we can replace the previous codec with this one. // Everything is fine so we can replace the previous codec with this one.
if (send_codec_registered_) { if (send_codec_registered_) {
// If we change codec we start fresh with FEC. // If we change codec we start fresh with FEC.
// This is not strictly required by the standard. // This is not strictly required by the standard.
is_first_red_ = true; is_first_red_ = true;
codec_ptr->SetVAD(&dtx_enabled_, &vad_enabled_, &vad_mode_);
if (codec_ptr->SetVAD(dtx_enabled_, vad_enabled_, vad_mode_) < 0) {
// SetVAD failed.
vad_enabled_ = false;
dtx_enabled_ = false;
}
} }
current_send_codec_idx_ = codec_id; current_send_codec_idx_ = codec_id;
@ -1450,6 +1444,9 @@ int AudioCodingModuleImpl::SetVADSafe(bool enable_dtx,
if ((enable_dtx || enable_vad) && stereo_send_) { if ((enable_dtx || enable_vad) && stereo_send_) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_, WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
"VAD/DTX not supported for stereo sending"); "VAD/DTX not supported for stereo sending");
dtx_enabled_ = false;
vad_enabled_ = false;
vad_mode_ = mode;
return -1; return -1;
} }
@ -1458,37 +1455,28 @@ int AudioCodingModuleImpl::SetVADSafe(bool enable_dtx,
if ((enable_dtx || enable_vad) && secondary_encoder_.get() != NULL) { if ((enable_dtx || enable_vad) && secondary_encoder_.get() != NULL) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_, WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
"VAD/DTX not supported when dual-streaming is enabled."); "VAD/DTX not supported when dual-streaming is enabled.");
dtx_enabled_ = false;
vad_enabled_ = false;
vad_mode_ = mode;
return -1; return -1;
} }
// If a send codec is registered, set VAD/DTX for the codec. // Store VAD/DTX settings. Values can be changed in the call to "SetVAD"
if (HaveValidEncoder("SetVAD")) { // below.
int status = codecs_[current_send_codec_idx_]->SetVAD(enable_dtx, dtx_enabled_ = enable_dtx;
enable_vad, vad_enabled_ = enable_vad;
mode); vad_mode_ = mode;
if (status == 1) {
// Vad was enabled.
vad_enabled_ = true;
dtx_enabled_ = enable_dtx;
vad_mode_ = mode;
return 0; // If a send codec is registered, set VAD/DTX for the codec.
} else if (status < 0) { if (HaveValidEncoder("SetVAD") && codecs_[current_send_codec_idx_]->SetVAD(
&enable_dtx, &enable_vad, &mode) < 0) {
// SetVAD failed. // SetVAD failed.
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_, WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
"SetVAD failed"); "SetVAD failed");
vad_enabled_ = false; vad_enabled_ = false;
dtx_enabled_ = false; dtx_enabled_ = false;
return -1; return -1;
}
} }
vad_enabled_ = enable_vad;
dtx_enabled_ = enable_dtx;
vad_mode_ = mode;
return 0; return 0;
} }

View File

@ -494,8 +494,8 @@ int16_t ACMGenericCodec::ResetEncoderSafe() {
// Set DTX/VAD. // Set DTX/VAD.
int status = SetVADSafe(&enable_dtx, &enable_vad, &mode); int status = SetVADSafe(&enable_dtx, &enable_vad, &mode);
vad_enabled_ = enable_dtx; dtx_enabled_ = enable_dtx;
dtx_enabled_ = enable_vad; vad_enabled_ = enable_vad;
vad_mode_ = mode; vad_mode_ = mode;
return status; return status;
} }