summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/audioflinger/AudioMixer.cpp46
-rw-r--r--services/audioflinger/AudioMixer.h6
-rw-r--r--services/audioflinger/BufferProviders.cpp105
-rw-r--r--services/audioflinger/BufferProviders.h21
-rw-r--r--services/audioflinger/Threads.cpp12
-rw-r--r--services/audioflinger/Tracks.cpp8
-rw-r--r--services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp3
-rw-r--r--services/audiopolicy/managerdefault/AudioPolicyManager.cpp30
-rw-r--r--services/audiopolicy/managerdefault/AudioPolicyManager.h16
-rw-r--r--services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp9
10 files changed, 156 insertions, 100 deletions
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index f28c625..7040af4 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -38,7 +38,6 @@
#include <audio_utils/format.h>
#include <common_time/local_clock.h>
#include <common_time/cc_helper.h>
-#include <media/AudioResamplerPublic.h>
#include "AudioMixerOps.h"
#include "AudioMixer.h"
@@ -223,8 +222,7 @@ int AudioMixer::getTrackName(audio_channel_mask_t channelMask,
t->mMixerChannelMask = audio_channel_mask_from_representation_and_bits(
AUDIO_CHANNEL_REPRESENTATION_POSITION, AUDIO_CHANNEL_OUT_STEREO);
t->mMixerChannelCount = audio_channel_count_from_out_mask(t->mMixerChannelMask);
- t->mSpeed = AUDIO_TIMESTRETCH_SPEED_NORMAL;
- t->mPitch = AUDIO_TIMESTRETCH_PITCH_NORMAL;
+ t->mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
// Check the downmixing (or upmixing) requirements.
status_t status = t->prepareForDownmix();
if (status != OK) {
@@ -668,19 +666,25 @@ void AudioMixer::setParameter(int name, int target, int param, void *value)
case TIMESTRETCH:
switch (param) {
case PLAYBACK_RATE: {
- const float speed = reinterpret_cast<float*>(value)[0];
- const float pitch = reinterpret_cast<float*>(value)[1];
- ALOG_ASSERT(AUDIO_TIMESTRETCH_SPEED_MIN <= speed
- && speed <= AUDIO_TIMESTRETCH_SPEED_MAX,
- "bad speed %f", speed);
- ALOG_ASSERT(AUDIO_TIMESTRETCH_PITCH_MIN <= pitch
- && pitch <= AUDIO_TIMESTRETCH_PITCH_MAX,
- "bad pitch %f", pitch);
- if (track.setPlaybackRate(speed, pitch)) {
- ALOGV("setParameter(TIMESTRETCH, PLAYBACK_RATE, %f %f", speed, pitch);
+ const AudioPlaybackRate *playbackRate =
+ reinterpret_cast<AudioPlaybackRate*>(value);
+ ALOG_ASSERT(AUDIO_TIMESTRETCH_SPEED_MIN <= playbackRate->mSpeed
+ && playbackRate->mSpeed <= AUDIO_TIMESTRETCH_SPEED_MAX,
+ "bad speed %f", playbackRate->mSpeed);
+ ALOG_ASSERT(AUDIO_TIMESTRETCH_PITCH_MIN <= playbackRate->mPitch
+ && playbackRate->mPitch <= AUDIO_TIMESTRETCH_PITCH_MAX,
+ "bad pitch %f", playbackRate->mPitch);
+ //TODO: use function from AudioResamplerPublic.h to test validity.
+ if (track.setPlaybackRate(*playbackRate)) {
+ ALOGV("setParameter(TIMESTRETCH, PLAYBACK_RATE, STRETCH_MODE, FALLBACK_MODE "
+ "%f %f %d %d",
+ playbackRate->mSpeed,
+ playbackRate->mPitch,
+ playbackRate->mStretchMode,
+ playbackRate->mFallbackMode);
// invalidateState(1 << name);
}
- } break;
+ } break;
default:
LOG_ALWAYS_FATAL("setParameter timestretch: bad param %d", param);
}
@@ -730,24 +734,26 @@ bool AudioMixer::track_t::setResampler(uint32_t trackSampleRate, uint32_t devSam
return false;
}
-bool AudioMixer::track_t::setPlaybackRate(float speed, float pitch)
+bool AudioMixer::track_t::setPlaybackRate(const AudioPlaybackRate &playbackRate)
{
- if (speed == mSpeed && pitch == mPitch) {
+ if ((mTimestretchBufferProvider == NULL &&
+ fabs(playbackRate.mSpeed - mPlaybackRate.mSpeed) < AUDIO_TIMESTRETCH_SPEED_MIN_DELTA &&
+ fabs(playbackRate.mPitch - mPlaybackRate.mPitch) < AUDIO_TIMESTRETCH_PITCH_MIN_DELTA) ||
+ isAudioPlaybackRateEqual(playbackRate, mPlaybackRate)) {
return false;
}
- mSpeed = speed;
- mPitch = pitch;
+ mPlaybackRate = playbackRate;
if (mTimestretchBufferProvider == NULL) {
// TODO: Remove MONO_HACK. Resampler sees #channels after the downmixer
// but if none exists, it is the channel count (1 for mono).
const int timestretchChannelCount = downmixerBufferProvider != NULL
? mMixerChannelCount : channelCount;
mTimestretchBufferProvider = new TimestretchBufferProvider(timestretchChannelCount,
- mMixerInFormat, sampleRate, speed, pitch);
+ mMixerInFormat, sampleRate, playbackRate);
reconfigureBufferProviders();
} else {
reinterpret_cast<TimestretchBufferProvider*>(mTimestretchBufferProvider)
- ->setPlaybackRate(speed, pitch);
+ ->setPlaybackRate(playbackRate);
}
return true;
}
diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h
index e27a0d1..7165c6c 100644
--- a/services/audioflinger/AudioMixer.h
+++ b/services/audioflinger/AudioMixer.h
@@ -23,6 +23,7 @@
#include <hardware/audio_effect.h>
#include <media/AudioBufferProvider.h>
+#include <media/AudioResamplerPublic.h>
#include <media/nbaio/NBLog.h>
#include <system/audio.h>
#include <utils/Compat.h>
@@ -259,8 +260,7 @@ private:
audio_channel_mask_t mMixerChannelMask;
uint32_t mMixerChannelCount;
- float mSpeed;
- float mPitch;
+ AudioPlaybackRate mPlaybackRate;
bool needsRamp() { return (volumeInc[0] | volumeInc[1] | auxInc) != 0; }
bool setResampler(uint32_t trackSampleRate, uint32_t devSampleRate);
@@ -274,7 +274,7 @@ private:
void unprepareForDownmix();
status_t prepareForReformat();
void unprepareForReformat();
- bool setPlaybackRate(float speed, float pitch);
+ bool setPlaybackRate(const AudioPlaybackRate &playbackRate);
void reconfigureBufferProviders();
};
diff --git a/services/audioflinger/BufferProviders.cpp b/services/audioflinger/BufferProviders.cpp
index dcae5e7..77bf4ac 100644
--- a/services/audioflinger/BufferProviders.cpp
+++ b/services/audioflinger/BufferProviders.cpp
@@ -361,25 +361,25 @@ void ReformatBufferProvider::copyFrames(void *dst, const void *src, size_t frame
}
TimestretchBufferProvider::TimestretchBufferProvider(int32_t channelCount,
- audio_format_t format, uint32_t sampleRate, float speed, float pitch) :
+ audio_format_t format, uint32_t sampleRate, const AudioPlaybackRate &playbackRate) :
mChannelCount(channelCount),
mFormat(format),
mSampleRate(sampleRate),
mFrameSize(channelCount * audio_bytes_per_sample(format)),
- mSpeed(speed),
- mPitch(pitch),
mLocalBufferFrameCount(0),
mLocalBufferData(NULL),
mRemaining(0),
- mSonicStream(sonicCreateStream(sampleRate, mChannelCount))
+ mSonicStream(sonicCreateStream(sampleRate, mChannelCount)),
+ mFallbackFailErrorShown(false)
{
- ALOGV("TimestretchBufferProvider(%p)(%u, %#x, %u %f %f)",
- this, channelCount, format, sampleRate, speed, pitch);
- mBuffer.frameCount = 0;
-
LOG_ALWAYS_FATAL_IF(mSonicStream == NULL,
"TimestretchBufferProvider can't allocate Sonic stream");
- sonicSetSpeed(mSonicStream, speed);
+
+ setPlaybackRate(playbackRate);
+ ALOGV("TimestretchBufferProvider(%p)(%u, %#x, %u %f %f %d %d)",
+ this, channelCount, format, sampleRate, playbackRate.mSpeed,
+ playbackRate.mPitch, playbackRate.mStretchMode, playbackRate.mFallbackMode);
+ mBuffer.frameCount = 0;
}
TimestretchBufferProvider::~TimestretchBufferProvider()
@@ -423,8 +423,8 @@ status_t TimestretchBufferProvider::getNextBuffer(
// need to fetch more data
const size_t outputDesired = pBuffer->frameCount - mRemaining;
- mBuffer.frameCount = mSpeed == AUDIO_TIMESTRETCH_SPEED_NORMAL
- ? outputDesired : outputDesired * mSpeed + 1;
+ mBuffer.frameCount = mPlaybackRate.mSpeed == AUDIO_TIMESTRETCH_SPEED_NORMAL
+ ? outputDesired : outputDesired * mPlaybackRate.mSpeed + 1;
status_t res = mTrackBufferProvider->getNextBuffer(&mBuffer, pts);
@@ -491,13 +491,13 @@ void TimestretchBufferProvider::reset()
mRemaining = 0;
}
-status_t TimestretchBufferProvider::setPlaybackRate(float speed, float pitch)
+status_t TimestretchBufferProvider::setPlaybackRate(const AudioPlaybackRate &playbackRate)
{
- mSpeed = speed;
- mPitch = pitch;
-
- sonicSetSpeed(mSonicStream, speed);
+ mPlaybackRate = playbackRate;
+ mFallbackFailErrorShown = false;
+ sonicSetSpeed(mSonicStream, mPlaybackRate.mSpeed);
//TODO: pitch is ignored for now
+ //TODO: optimize: if parameters are the same, don't do any extra computation.
return OK;
}
@@ -508,33 +508,68 @@ void TimestretchBufferProvider::processFrames(void *dstBuffer, size_t *dstFrames
// Note dstFrames is the required number of frames.
// Ensure consumption from src is as expected.
- const size_t targetSrc = *dstFrames * mSpeed;
+ //TODO: add logic to track "very accurate" consumption related to speed, original sampling
+ //rate, actual frames processed.
+ const size_t targetSrc = *dstFrames * mPlaybackRate.mSpeed;
if (*srcFrames < targetSrc) { // limit dst frames to that possible
- *dstFrames = *srcFrames / mSpeed;
+ *dstFrames = *srcFrames / mPlaybackRate.mSpeed;
} else if (*srcFrames > targetSrc + 1) {
*srcFrames = targetSrc + 1;
}
- switch (mFormat) {
- case AUDIO_FORMAT_PCM_FLOAT:
- if (sonicWriteFloatToStream(mSonicStream, (float*)srcBuffer, *srcFrames) != 1) {
- ALOGE("sonicWriteFloatToStream cannot realloc");
- *srcFrames = 0; // cannot consume all of srcBuffer
+ if (mPlaybackRate.mSpeed< TIMESTRETCH_SONIC_SPEED_MIN ||
+ mPlaybackRate.mSpeed > TIMESTRETCH_SONIC_SPEED_MAX ) {
+ //fallback mode
+ if (*dstFrames > 0) {
+ switch(mPlaybackRate.mFallbackMode) {
+ case AUDIO_TIMESTRETCH_FALLBACK_CUT_REPEAT:
+ if (*dstFrames <= *srcFrames) {
+ size_t copySize = mFrameSize * *dstFrames;
+ memcpy(dstBuffer, srcBuffer, copySize);
+ } else {
+ // cyclically repeat the source.
+ for (size_t count = 0; count < *dstFrames; count += *srcFrames) {
+ size_t remaining = min(*srcFrames, *dstFrames - count);
+ memcpy((uint8_t*)dstBuffer + mFrameSize * count,
+ srcBuffer, mFrameSize * remaining);
+ }
+ }
+ break;
+ case AUDIO_TIMESTRETCH_FALLBACK_DEFAULT:
+ case AUDIO_TIMESTRETCH_FALLBACK_MUTE:
+ memset(dstBuffer,0, mFrameSize * *dstFrames);
+ break;
+ case AUDIO_TIMESTRETCH_FALLBACK_FAIL:
+ default:
+ if(!mFallbackFailErrorShown) {
+ ALOGE("invalid parameters in TimestretchBufferProvider fallbackMode:%d",
+ mPlaybackRate.mFallbackMode);
+ mFallbackFailErrorShown = true;
+ }
+ break;
+ }
}
- *dstFrames = sonicReadFloatFromStream(mSonicStream, (float*)dstBuffer, *dstFrames);
- break;
- case AUDIO_FORMAT_PCM_16_BIT:
- if (sonicWriteShortToStream(mSonicStream, (short*)srcBuffer, *srcFrames) != 1) {
- ALOGE("sonicWriteShortToStream cannot realloc");
- *srcFrames = 0; // cannot consume all of srcBuffer
+ } else {
+ switch (mFormat) {
+ case AUDIO_FORMAT_PCM_FLOAT:
+ if (sonicWriteFloatToStream(mSonicStream, (float*)srcBuffer, *srcFrames) != 1) {
+ ALOGE("sonicWriteFloatToStream cannot realloc");
+ *srcFrames = 0; // cannot consume all of srcBuffer
+ }
+ *dstFrames = sonicReadFloatFromStream(mSonicStream, (float*)dstBuffer, *dstFrames);
+ break;
+ case AUDIO_FORMAT_PCM_16_BIT:
+ if (sonicWriteShortToStream(mSonicStream, (short*)srcBuffer, *srcFrames) != 1) {
+ ALOGE("sonicWriteShortToStream cannot realloc");
+ *srcFrames = 0; // cannot consume all of srcBuffer
+ }
+ *dstFrames = sonicReadShortFromStream(mSonicStream, (short*)dstBuffer, *dstFrames);
+ break;
+ default:
+ // could also be caught on construction
+ LOG_ALWAYS_FATAL("invalid format %#x for TimestretchBufferProvider", mFormat);
}
- *dstFrames = sonicReadShortFromStream(mSonicStream, (short*)dstBuffer, *dstFrames);
- break;
- default:
- // could also be caught on construction
- LOG_ALWAYS_FATAL("invalid format %#x for TimestretchBufferProvider", mFormat);
}
}
-
// ----------------------------------------------------------------------------
} // namespace android
diff --git a/services/audioflinger/BufferProviders.h b/services/audioflinger/BufferProviders.h
index 42030c0..4970b6c 100644
--- a/services/audioflinger/BufferProviders.h
+++ b/services/audioflinger/BufferProviders.h
@@ -151,7 +151,8 @@ protected:
class TimestretchBufferProvider : public PassthruBufferProvider {
public:
TimestretchBufferProvider(int32_t channelCount,
- audio_format_t format, uint32_t sampleRate, float speed, float pitch);
+ audio_format_t format, uint32_t sampleRate,
+ const AudioPlaybackRate &playbackRate);
virtual ~TimestretchBufferProvider();
// Overrides AudioBufferProvider methods
@@ -161,7 +162,7 @@ public:
// Overrides PassthruBufferProvider
virtual void reset();
- virtual status_t setPlaybackRate(float speed, float pitch);
+ virtual status_t setPlaybackRate(const AudioPlaybackRate &playbackRate);
// processes frames
// dstBuffer is where to place the data
@@ -176,15 +177,17 @@ protected:
const audio_format_t mFormat;
const uint32_t mSampleRate; // const for now (TODO change this)
const size_t mFrameSize;
- float mSpeed;
- float mPitch;
+ AudioPlaybackRate mPlaybackRate;
private:
- AudioBufferProvider::Buffer mBuffer;
- size_t mLocalBufferFrameCount;
- void *mLocalBufferData;
- size_t mRemaining;
- sonicStream mSonicStream;
+ AudioBufferProvider::Buffer mBuffer; // for upstream request
+ size_t mLocalBufferFrameCount; // size of local buffer
+ void *mLocalBufferData; // internally allocated buffer for data returned
+ // to caller
+ size_t mRemaining; // remaining data in local buffer
+ sonicStream mSonicStream; // handle to sonic timestretch object
+ //FIXME: this dependency should be abstracted out
+ bool mFallbackFailErrorShown; // log fallback error only once
};
// ----------------------------------------------------------------------------
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 373d643..d3d77cd 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -3599,11 +3599,10 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
// during last round
size_t desiredFrames;
const uint32_t sampleRate = track->mAudioTrackServerProxy->getSampleRate();
- float speed, pitch;
- track->mAudioTrackServerProxy->getPlaybackRate(&speed, &pitch);
+ AudioPlaybackRate playbackRate = track->mAudioTrackServerProxy->getPlaybackRate();
desiredFrames = sourceFramesNeededWithTimestretch(
- sampleRate, mNormalFrameCount, mSampleRate, speed);
+ sampleRate, mNormalFrameCount, mSampleRate, playbackRate.mSpeed);
// TODO: ONLY USED FOR LEGACY RESAMPLERS, remove when they are removed.
// add frames already consumed but not yet released by the resampler
// because mAudioTrackServerProxy->framesReady() will include these frames
@@ -3772,15 +3771,12 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
AudioMixer::SAMPLE_RATE,
(void *)(uintptr_t)reqSampleRate);
- // set the playback rate as an float array {speed, pitch}
- float playbackRate[2];
- track->mAudioTrackServerProxy->getPlaybackRate(
- &playbackRate[0] /*speed*/, &playbackRate[1] /*pitch*/);
+ AudioPlaybackRate playbackRate = track->mAudioTrackServerProxy->getPlaybackRate();
mAudioMixer->setParameter(
name,
AudioMixer::TIMESTRETCH,
AudioMixer::PLAYBACK_RATE,
- playbackRate);
+ &playbackRate);
/*
* Select the appropriate output buffer for the track.
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index da2d634..c6e9745 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -906,11 +906,9 @@ status_t AudioFlinger::PlaybackThread::Track::getTimestamp(AudioTimestamp& times
// FIXME Not accurate under dynamic changes of sample rate and speed.
// Do not use track's mSampleRate as it is not current for mixer tracks.
uint32_t sampleRate = mAudioTrackServerProxy->getSampleRate();
- float speed, pitch;
- mAudioTrackServerProxy->getPlaybackRate(&speed, &pitch);
- uint32_t unpresentedFrames =
- ((double) playbackThread->mLatchQ.mUnpresentedFrames * sampleRate * speed)
- / playbackThread->mSampleRate;
+ AudioPlaybackRate playbackRate = mAudioTrackServerProxy->getPlaybackRate();
+ uint32_t unpresentedFrames = ((double) playbackThread->mLatchQ.mUnpresentedFrames *
+ sampleRate * playbackRate.mSpeed)/ playbackThread->mSampleRate;
// FIXME Since we're using a raw pointer as the key, it is theoretically possible
// for a brand new track to share the same address as a recently destroyed
// track, and thus for us to get the frames released of the wrong track.
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index 9573583..0715eea 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -52,6 +52,9 @@ bool DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const
// - are of the same type (a device type cannot be AUDIO_DEVICE_NONE)
// - have the same address or one device does not specify the address
// - have the same channel mask or one device does not specify the channel mask
+ if (other == 0) {
+ return false;
+ }
return (mDeviceType == other->mDeviceType) &&
(mAddress == "" || other->mAddress == "" || mAddress == other->mAddress) &&
(mChannelMask == 0 || other->mChannelMask == 0 ||
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 3ea6a11..01f2b61 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -969,6 +969,8 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output,
audio_devices_t newDevice;
if (outputDesc->mPolicyMix != NULL) {
newDevice = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
+ } else if (mOutputRoutes.hasRouteChanged(session)) {
+ newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
} else {
newDevice = AUDIO_DEVICE_NONE;
}
@@ -1026,7 +1028,7 @@ status_t AudioPolicyManager::startSource(sp<AudioOutputDescriptor> outputDesc,
// necessary for a correct control of hardware output routing by startOutput() and stopOutput()
outputDesc->changeRefCount(stream, 1);
- if (outputDesc->mRefCount[stream] == 1) {
+ if (outputDesc->mRefCount[stream] == 1 || device != AUDIO_DEVICE_NONE) {
// starting an output being rerouted?
if (device == AUDIO_DEVICE_NONE) {
device = getNewOutputDevice(outputDesc, false /*fromCache*/);
@@ -2462,14 +2464,14 @@ status_t AudioPolicyManager::acquireSoundTriggerSession(audio_session_t *session
return mSoundTriggerSessions.acquireSession(*session, *ioHandle);
}
-status_t AudioPolicyManager::startAudioSource(const struct audio_port_config *source,
- const audio_attributes_t *attributes,
- audio_io_handle_t *handle)
+status_t AudioPolicyManager::startAudioSource(const struct audio_port_config *source __unused,
+ const audio_attributes_t *attributes __unused,
+ audio_io_handle_t *handle __unused)
{
return INVALID_OPERATION;
}
-status_t AudioPolicyManager::stopAudioSource(audio_io_handle_t handle)
+status_t AudioPolicyManager::stopAudioSource(audio_io_handle_t handle __unused)
{
return INVALID_OPERATION;
}
@@ -4511,18 +4513,36 @@ bool AudioPolicyManager::SessionRouteMap::hasRoute(audio_session_t session)
return indexOfKey(session) >= 0 && valueFor(session)->mDeviceDescriptor != 0;
}
+bool AudioPolicyManager::SessionRouteMap::hasRouteChanged(audio_session_t session)
+{
+ if (indexOfKey(session) >= 0) {
+ if (valueFor(session)->mChanged) {
+ valueFor(session)->mChanged = false;
+ return true;
+ }
+ }
+ return false;
+}
+
void AudioPolicyManager::SessionRouteMap::addRoute(audio_session_t session,
audio_stream_type_t streamType,
sp<DeviceDescriptor> deviceDescriptor)
{
sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0;
if (route != NULL) {
+ if ((route->mDeviceDescriptor == 0 && deviceDescriptor != 0) ||
+ (!route->mDeviceDescriptor->equals(deviceDescriptor))) {
+ route->mChanged = true;
+ }
route->mRefCount++;
route->mDeviceDescriptor = deviceDescriptor;
} else {
route = new AudioPolicyManager::SessionRoute(session, streamType, deviceDescriptor);
route->mRefCount++;
add(session, route);
+ if (deviceDescriptor != 0) {
+ route->mChanged = true;
+ }
}
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 146a7af..521f6c4 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -244,7 +244,10 @@ protected:
mStreamType(streamType),
mDeviceDescriptor(deviceDescriptor),
mRefCount(0),
- mActivityCount(0) {}
+ mActivityCount(0),
+ mChanged(false) {}
+
+ void log(const char* prefix);
audio_session_t mSession;
audio_stream_type_t mStreamType;
@@ -252,10 +255,9 @@ protected:
sp<DeviceDescriptor> mDeviceDescriptor;
// "reference" counting
- int mRefCount; // +/- on references
- int mActivityCount; // +/- on start/stop
-
- void log(const char* prefix);
+ int mRefCount; // +/- on references
+ int mActivityCount; // +/- on start/stop
+ bool mChanged;
};
class SessionRouteMap: public KeyedVector<audio_session_t, sp<SessionRoute>>
@@ -268,7 +270,7 @@ protected:
int incRouteActivity(audio_session_t session);
int decRouteActivity(audio_session_t session);
-
+ bool hasRouteChanged(audio_session_t session); // also clears the changed flag
void log(const char* caption);
};
@@ -510,6 +512,8 @@ protected:
void updateCallRouting(audio_devices_t rxDevice, int delayMs = 0);
+ // if argument "device" is different from AUDIO_DEVICE_NONE, startSource() will force
+ // the re-evaluation of the output device.
status_t startSource(sp<AudioOutputDescriptor> outputDesc,
audio_stream_type_t stream,
audio_devices_t device,
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 5f501a5..e764eda 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -546,9 +546,6 @@ status_t AudioPolicyService::listAudioPorts(audio_port_role_t role,
unsigned int *generation)
{
Mutex::Autolock _l(mLock);
- if(!modifyAudioRoutingAllowed()) {
- return PERMISSION_DENIED;
- }
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
@@ -559,9 +556,6 @@ status_t AudioPolicyService::listAudioPorts(audio_port_role_t role,
status_t AudioPolicyService::getAudioPort(struct audio_port *port)
{
Mutex::Autolock _l(mLock);
- if(!modifyAudioRoutingAllowed()) {
- return PERMISSION_DENIED;
- }
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
@@ -602,9 +596,6 @@ status_t AudioPolicyService::listAudioPatches(unsigned int *num_patches,
unsigned int *generation)
{
Mutex::Autolock _l(mLock);
- if(!modifyAudioRoutingAllowed()) {
- return PERMISSION_DENIED;
- }
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}