summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/media/IAudioTrack.h3
-rw-r--r--media/libmedia/AudioTrack.cpp3
-rw-r--r--media/libmedia/IAudioTrack.cpp12
-rw-r--r--services/audioflinger/AudioFlinger.h1
-rw-r--r--services/audioflinger/Effects.cpp22
-rw-r--r--services/audioflinger/PlaybackTracks.h1
-rw-r--r--services/audioflinger/Threads.cpp11
-rw-r--r--services/audioflinger/Tracks.cpp16
8 files changed, 63 insertions, 6 deletions
diff --git a/include/media/IAudioTrack.h b/include/media/IAudioTrack.h
index afac4ae..5c8a484 100644
--- a/include/media/IAudioTrack.h
+++ b/include/media/IAudioTrack.h
@@ -90,6 +90,9 @@ public:
/* Return NO_ERROR if timestamp is valid */
virtual status_t getTimestamp(AudioTimestamp& timestamp) = 0;
+
+ /* Signal the playback thread for a change in control block */
+ virtual void signal() = 0;
};
// ----------------------------------------------------------------------------
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 754a4e3..37d50cf 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -534,6 +534,9 @@ status_t AudioTrack::setVolume(float left, float right)
mProxy->setVolumeLR((uint32_t(uint16_t(right * 0x1000)) << 16) | uint16_t(left * 0x1000));
+ if (isOffloaded()) {
+ mAudioTrack->signal();
+ }
return NO_ERROR;
}
diff --git a/media/libmedia/IAudioTrack.cpp b/media/libmedia/IAudioTrack.cpp
index f0d75ba..3cd9cfd 100644
--- a/media/libmedia/IAudioTrack.cpp
+++ b/media/libmedia/IAudioTrack.cpp
@@ -41,6 +41,7 @@ enum {
SET_MEDIA_TIME_TRANSFORM,
SET_PARAMETERS,
GET_TIMESTAMP,
+ SIGNAL,
};
class BpAudioTrack : public BpInterface<IAudioTrack>
@@ -182,6 +183,12 @@ public:
}
return status;
}
+
+ virtual void signal() {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
+ remote()->transact(SIGNAL, data, &reply);
+ }
};
IMPLEMENT_META_INTERFACE(AudioTrack, "android.media.IAudioTrack");
@@ -269,6 +276,11 @@ status_t BnAudioTrack::onTransact(
}
return NO_ERROR;
} break;
+ case SIGNAL: {
+ CHECK_INTERFACE(IAudioTrack, data, reply);
+ signal();
+ return NO_ERROR;
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 7f2f9ec..d6b10f7 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -412,6 +412,7 @@ private:
int target);
virtual status_t setParameters(const String8& keyValuePairs);
virtual status_t getTimestamp(AudioTimestamp& timestamp);
+ virtual void signal(); // signal playback thread for a change in control block
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 7644de6..bb98a35 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -973,13 +973,20 @@ status_t AudioFlinger::EffectHandle::enable()
}
mEnabled = false;
} else {
- if (thread != 0 && !mEffect->isOffloadable()) {
- if ((thread->type() == ThreadBase::OFFLOAD)) {
+ if (thread != 0) {
+ if (thread->type() == ThreadBase::OFFLOAD) {
PlaybackThread *t = (PlaybackThread *)thread.get();
- t->invalidateTracks(AUDIO_STREAM_MUSIC);
+ Mutex::Autolock _l(t->mLock);
+ t->broadcast_l();
}
- if (mEffect->sessionId() == AUDIO_SESSION_OUTPUT_MIX) {
- thread->mAudioFlinger->onNonOffloadableGlobalEffectEnable();
+ if (!mEffect->isOffloadable()) {
+ if (thread->type() == ThreadBase::OFFLOAD) {
+ PlaybackThread *t = (PlaybackThread *)thread.get();
+ t->invalidateTracks(AUDIO_STREAM_MUSIC);
+ }
+ if (mEffect->sessionId() == AUDIO_SESSION_OUTPUT_MIX) {
+ thread->mAudioFlinger->onNonOffloadableGlobalEffectEnable();
+ }
}
}
}
@@ -1010,6 +1017,11 @@ status_t AudioFlinger::EffectHandle::disable()
sp<ThreadBase> thread = mEffect->thread().promote();
if (thread != 0) {
thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
+ if (thread->type() == ThreadBase::OFFLOAD) {
+ PlaybackThread *t = (PlaybackThread *)thread.get();
+ Mutex::Autolock _l(t->mLock);
+ t->broadcast_l();
+ }
}
return status;
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index be4b811..ae0aba4 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -61,6 +61,7 @@ public:
int16_t *mainBuffer() const { return mMainBuffer; }
int auxEffectId() const { return mAuxEffectId; }
virtual status_t getTimestamp(AudioTimestamp& timestamp);
+ void signal();
// implement FastMixerState::VolumeProvider interface
virtual uint32_t getVolumeLR();
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index e70a09a..9716eb3 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2246,12 +2246,21 @@ bool AudioFlinger::PlaybackThread::threadLoop()
}
// only process effects if we're going to write
- if (sleepTime == 0) {
+ if (sleepTime == 0 && mType != OFFLOAD) {
for (size_t i = 0; i < effectChains.size(); i ++) {
effectChains[i]->process_l();
}
}
}
+ // Process effect chains for offloaded thread even if no audio
+ // was read from audio track: process only updates effect state
+ // and thus does have to be synchronized with audio writes but may have
+ // to be called while waiting for async write callback
+ if (mType == OFFLOAD) {
+ for (size_t i = 0; i < effectChains.size(); i ++) {
+ effectChains[i]->process_l();
+ }
+ }
// enable changes in effect chain
unlockEffectChains(effectChains);
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 9002f9b..3970acd 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -288,6 +288,12 @@ status_t AudioFlinger::TrackHandle::getTimestamp(AudioTimestamp& timestamp)
return mTrack->getTimestamp(timestamp);
}
+
+void AudioFlinger::TrackHandle::signal()
+{
+ return mTrack->signal();
+}
+
status_t AudioFlinger::TrackHandle::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
@@ -935,6 +941,16 @@ void AudioFlinger::PlaybackThread::Track::invalidate()
mIsInvalid = true;
}
+void AudioFlinger::PlaybackThread::Track::signal()
+{
+ sp<ThreadBase> thread = mThread.promote();
+ if (thread != 0) {
+ PlaybackThread *t = (PlaybackThread *)thread.get();
+ Mutex::Autolock _l(t->mLock);
+ t->broadcast_l();
+ }
+}
+
// ----------------------------------------------------------------------------
sp<AudioFlinger::PlaybackThread::TimedTrack>