Skip to content
Permalink
Browse files

audio/msm7630: Fix for back to back VOIP calls failure

- Back to back VOIP calls fail.
- MVS driver is not closed in HAL at the end of VOIP call
  due to wrong book keeping of VOIP in and out streams.
  This prevents back to back VOIP calls.
- Enhance bookkeeping code and close driver at end of VOIP call

(cherry picked from commit 2884ae26b9b65f49acee44a49efbc6196ab6d15f)

Change-Id: I4aa578442c24949b56586a5260fefd5e73c9292a
  • Loading branch information...
Sunil Joseph authored and Kali- committed Oct 26, 2012
1 parent 07e24e8 commit 672734efc42c82ad75794020368ca14efbbed24c
Showing with 82 additions and 43 deletions.
  1. +71 −31 msm7x30/AudioHardware.cpp
  2. +4 −1 msm7x30/AudioHardware.h
  3. +2 −6 msm7x30/AudioPolicyManager.cpp
  4. +1 −1 msm7x30/audio_hw_hal.cpp
  5. +4 −4 msm7x30/audio_policy_hal.cpp
@@ -496,7 +496,7 @@ AudioHardware::AudioHardware() :
mInit(false), mMicMute(true), mBluetoothNrec(true), mBluetoothId(0),
mOutput(0),mBluetoothVGS(false),
mCurSndDevice(-1),mTtyMode(TTY_OFF), mDualMicEnabled(false), mFmFd(-1),
mVoipFd(-1), mNumVoipStreams(0), mDirectOutput(0)
mVoipFd(-1), mVoipInActive(false), mVoipOutActive(false), mDirectOutput(0)
{

int control;
@@ -2059,7 +2059,7 @@ status_t AudioHardware::AudioStreamOutDirect::set(
uint32_t lChannels = pChannels ? *pChannels : 0;
uint32_t lRate = pRate ? *pRate : 0;

ALOGE("set1 lFormat = %d lChannels= %u lRate = %u\n", lFormat, lChannels, lRate );
ALOGV("AudioStreamOutDirect::set lFormat = %d lChannels= %u lRate = %u\n", lFormat, lChannels, lRate );
mHardware = hw;

// fix up defaults
@@ -2085,7 +2085,6 @@ status_t AudioHardware::AudioStreamOutDirect::set(
mDevices = devices;
mChannels = lChannels;
mSampleRate = lRate;
mHardware->mNumVoipStreams++;

if(mSampleRate == AUDIO_HW_VOIP_SAMPLERATE_8K) {
mBufferSize = AUDIO_HW_VOIP_BUFFERSIZE_8K;
@@ -2096,15 +2095,19 @@ status_t AudioHardware::AudioStreamOutDirect::set(
return BAD_VALUE;
}

mHardware->mVoipOutActive = true;

if (mHardware->mVoipInActive)
mHardware->setupDeviceforVoipCall(true);

return NO_ERROR;
}

AudioHardware::AudioStreamOutDirect::~AudioStreamOutDirect()
{
ALOGV("AudioStreamOutDirect destructor");
mHardware->mVoipOutActive = false;
standby();
if (mHardware->mNumVoipStreams)
mHardware->mNumVoipStreams--;
}

ssize_t AudioHardware::AudioStreamOutDirect::write(const void* buffer, size_t bytes)
@@ -2113,12 +2116,18 @@ ssize_t AudioHardware::AudioStreamOutDirect::write(const void* buffer, size_t by
size_t count = bytes;
const uint8_t* p = static_cast<const uint8_t*>(buffer);
unsigned short dec_id = INVALID_DEVICE;
ALOGV("AudioStreamOutDirect::write(%p, %ld)", buffer, bytes);

if (mStandby) {
if(mHardware->mVoipFd >= 0) {
mFd = mHardware->mVoipFd;
}
else {

mHardware->mVoipOutActive = true;
if (mHardware->mVoipInActive)
mHardware->setupDeviceforVoipCall(true);

mStandby = false;
} else {
//Routing Voice
if ( (cur_rx != INVALID_DEVICE) && (cur_tx != INVALID_DEVICE))
{
@@ -2182,6 +2191,10 @@ ssize_t AudioHardware::AudioStreamOutDirect::write(const void* buffer, size_t by
goto Error;
}

mHardware->mVoipOutActive = true;
if (mHardware->mVoipInActive)
mHardware->setupDeviceforVoipCall(true);

// fill 2 buffers before AUDIO_START
mStartCount = AUDIO_HW_NUM_OUT_BUF;
mStandby = false;
@@ -2240,10 +2253,12 @@ status_t AudioHardware::AudioStreamOutDirect::standby()
{
Routing_table* temp = NULL;
ALOGD("AudioStreamOutDirect::standby()");
Mutex::Autolock lock(mHardware->mVoipLock);
status_t status = NO_ERROR;

ALOGV(" AudioStreamOutDirect::standby mHardware->mNumVoipStreams = %d mFd = %d\n", mHardware->mNumVoipStreams, mFd);
if (mFd >= 0 && (mHardware->mNumVoipStreams == 1)) {
ALOGD("Voipin %d driver fd %d", mHardware->mVoipInActive, mHardware->mVoipFd);
mHardware->mVoipOutActive = false;
if (mHardware->mVoipFd >= 0 && !mHardware->mVoipInActive) {
ALOGE("mute and disbale device ***\n");
//Mute and disable the device.
int ret = msm_set_voice_rx_vol(0);
@@ -2258,15 +2273,18 @@ status_t AudioHardware::AudioStreamOutDirect::standby()
if (ret < 0)
ALOGE("Error %d ending voice\n", ret);

if (mFd >= 0) {
ret = ioctl(mFd, AUDIO_STOP, NULL);
if (mHardware->mVoipFd >= 0) {
ret = ioctl(mHardware->mVoipFd, AUDIO_STOP, NULL);
ALOGE("MVS stop returned %d \n", ret);
::close(mFd);
mFd = mHardware->mVoipFd = -1;
ALOGV("driver closed");
mHardware->setupDeviceforVoipCall(false);
ALOGD("MVS driver closed %d mFd %d", __LINE__, mHardware->mVoipFd);
}
//mHardware->checkMicMute();
}
else
ALOGE("Not closing MVS driver");
mStandby = true;
return status;
}
@@ -3962,6 +3980,27 @@ status_t AudioHardware::AudioSessionOutLPA::getRenderPosition(uint32_t *dspFrame
//TODO: enable when supported by driver
return INVALID_OPERATION;
}

status_t AudioHardware::setupDeviceforVoipCall(bool value)
{

int mode = (value ? AudioSystem::MODE_IN_COMMUNICATION : AudioSystem::MODE_NORMAL);
if (setMode(mode) != NO_ERROR) {
ALOGV("setMode fails");
return UNKNOWN_ERROR;
}

if (setMicMute(!value) != NO_ERROR) {
ALOGV("MicMute fails");
return UNKNOWN_ERROR;
}

ALOGD("Device setup sucess for VOIP call");

return NO_ERROR;
}


status_t AudioHardware::AudioSessionOutLPA::getBufferInfo(buf_info **buf) {

buf_info *tempbuf = (buf_info *)malloc(sizeof(buf_info) + mInputBufferCount*sizeof(int *));
@@ -4056,11 +4095,6 @@ status_t AudioHardware::AudioStreamInVoip::set(
ALOGV("Check if driver is open");
if(mHardware->mVoipFd >= 0) {
mFd = mHardware->mVoipFd;
// Increment voip stream count
mHardware->mNumVoipStreams++;
ALOGV("MVS driver is already opened, mHardware->mNumVoipStreams = %d \n",
mHardware->mNumVoipStreams);

}
else {

@@ -4103,10 +4137,6 @@ status_t AudioHardware::AudioStreamInVoip::set(

mFd = status;
ALOGE("VOPIstreamin : Save the fd \n");
mHardware->mVoipFd = mFd;
// Increment voip stream count
mHardware->mNumVoipStreams++;
ALOGV(" input stream set mHardware->mNumVoipStreams = %d \n", mHardware->mNumVoipStreams);

// configuration
ALOGV("get mvs config");
@@ -4150,6 +4180,13 @@ status_t AudioHardware::AudioStreamInVoip::set(
ALOGV(" Set state AUDIO_INPUT_OPENED\n");
mState = AUDIO_INPUT_OPENED;

ALOGV(" Set mVoipFd now\n");
mHardware->mVoipFd = mFd;
mHardware->mVoipInActive = true;

if (mHardware->mVoipOutActive)
mHardware->setupDeviceforVoipCall(true);

if (!acoustic)
return NO_ERROR;

@@ -4168,9 +4205,8 @@ status_t AudioHardware::AudioStreamInVoip::set(
AudioHardware::AudioStreamInVoip::~AudioStreamInVoip()
{
ALOGV("AudioStreamInVoip destructor");
mHardware->mVoipInActive = false;
standby();
if (mHardware->mNumVoipStreams)
mHardware->mNumVoipStreams--;
}

ssize_t AudioHardware::AudioStreamInVoip::read( void* buffer, ssize_t bytes)
@@ -4233,11 +4269,13 @@ ssize_t AudioHardware::AudioStreamInVoip::read( void* buffer, ssize_t bytes)

status_t AudioHardware::AudioStreamInVoip::standby()
{
bool isDriverClosed = false;
Routing_table* temp = NULL;
ALOGD("AudioStreamInVoip::standby");
Mutex::Autolock lock(mHardware->mVoipLock);
if (!mHardware) return -1;
ALOGV(" AudioStreamInVoip::standby = %d \n", mHardware->mNumVoipStreams);
if (mState > AUDIO_INPUT_CLOSED && (mHardware->mNumVoipStreams == 1)) {
ALOGE("VoipOut %d driver fd %d", mHardware->mVoipOutActive, mHardware->mVoipFd);
mHardware->mVoipInActive = false;
if (mState > AUDIO_INPUT_CLOSED && !mHardware->mVoipOutActive) {
ALOGE(" closing mvs driver\n");
//Mute and disable the device.
int ret = msm_set_voice_rx_vol(0);
@@ -4251,16 +4289,18 @@ status_t AudioHardware::AudioStreamInVoip::standby()
ALOGE("Error %d ending voice\n", ret);
if (ret < 0)
ALOGE("Error %d closing mixer\n", ret);
if (mFd >= 0) {
ret = ioctl(mFd, AUDIO_STOP, NULL);
ALOGE("MVS stop returned %d \n", ret);
if (mHardware->mVoipFd >= 0) {
ret = ioctl(mHardware->mVoipFd, AUDIO_STOP, NULL);
ALOGD("MVS stop returned %d %d %d\n", ret, __LINE__, mHardware->mVoipFd);
::close(mFd);
mFd = mHardware->mVoipFd = -1;
ALOGV("driver closed");
isDriverClosed = true;
mHardware->setupDeviceforVoipCall(false);
ALOGD("MVS driver closed %d mFd %d", __LINE__, mHardware->mVoipFd);
}
mState = AUDIO_INPUT_CLOSED;
}
else
ALOGE("Not closing MVS driver");
return NO_ERROR;
}

@@ -326,6 +326,7 @@ class AudioHardware : public AudioHardwareBase

protected:
virtual status_t dump(int fd, const Vector<String16>& args);
status_t setupDeviceforVoipCall(bool value);

private:

@@ -662,7 +663,9 @@ class AudioHardware : public AudioHardwareBase
friend class AudioStreamInMSM72xx;
Mutex mLock;
int mVoipFd;
int mNumVoipStreams;
bool mVoipInActive;
bool mVoipOutActive;
Mutex mVoipLock;
int mVoipSession;

};
@@ -598,10 +598,6 @@ AudioPolicyManagerBase::IOProfile *AudioPolicyManager::getProfileForDirectOutput
uint32_t channelMask,
audio_output_flags_t flags)
{
if( !((flags & AUDIO_OUTPUT_FLAG_LPA) ||
(flags & AUDIO_OUTPUT_FLAG_TUNNEL)||
(flags & AUDIO_OUTPUT_FLAG_VOIP_RX)) )
flags = AUDIO_OUTPUT_FLAG_DIRECT;

for (size_t i = 0; i < mHwModules.size(); i++) {
if (mHwModules[i]->mHandle == 0) {
@@ -611,7 +607,7 @@ AudioPolicyManagerBase::IOProfile *AudioPolicyManager::getProfileForDirectOutput
AudioPolicyManagerBase::IOProfile *profile = mHwModules[i]->mOutputProfiles[j];
if (isCompatibleProfile(profile, device, samplingRate, format,
channelMask,
flags)) {
(audio_output_flags_t)(flags|AUDIO_OUTPUT_FLAG_DIRECT))) {
if (mAvailableOutputDevices & profile->mSupportedDevices) {
return mHwModules[i]->mOutputProfiles[j];
}
@@ -1298,7 +1294,7 @@ audio_devices_t AudioPolicyManager::getDeviceForInputSource(int inputSource)
}
break;
case AUDIO_SOURCE_VOICE_COMMUNICATION:
device = AudioSystem::DEVICE_IN_COMMUNICATION;
device = AUDIO_DEVICE_IN_COMMUNICATION;
break;

case AUDIO_SOURCE_CAMCORDER:
@@ -619,7 +619,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
if (!in)
return -ENOMEM;

devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0);
devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0);
in->qcom_in = qadev->hwif->openInputStream(devices, (int *)&config->format,
&config->channel_mask,
&config->sample_rate,
@@ -72,7 +72,7 @@ static int ap_set_device_connection_state(struct audio_policy *pol,
{
struct qcom_audio_policy *qap = to_qap(pol);
return qap->apm->setDeviceConnectionState(
(AudioSystem::audio_devices)device,
device,
(AudioSystem::device_connection_state)state,
device_address);
}
@@ -84,7 +84,7 @@ static audio_policy_dev_state_t ap_get_device_connection_state(
{
const struct qcom_audio_policy *qap = to_cqap(pol);
return (audio_policy_dev_state_t)qap->apm->getDeviceConnectionState(
(AudioSystem::audio_devices)device,
device,
device_address);
}

@@ -185,7 +185,7 @@ static audio_io_handle_t ap_get_output(struct audio_policy *pol,

ALOGV("%s: tid %d", __func__, gettid());
return qap->apm->getOutput((AudioSystem::stream_type)stream,
sampling_rate,(int) format, channelMask,
sampling_rate,(int) format, channelMask,
(AudioSystem::output_flags)flags);
}

@@ -296,7 +296,7 @@ static int ap_get_stream_volume_index_for_device(const struct audio_policy *pol,
const struct qcom_audio_policy *qap = to_cqap(pol);
return qap->apm->getStreamVolumeIndex((AudioSystem::stream_type)stream,
index,
device);
AUDIO_DEVICE_OUT_DEFAULT);
}

static audio_devices_t ap_get_devices_for_stream(const struct audio_policy *pol,

0 comments on commit 672734e

Please sign in to comment.
You can’t perform that action at this time.