summaryrefslogtreecommitdiffstats
path: root/services/audioflinger/Threads.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/audioflinger/Threads.cpp')
-rw-r--r--services/audioflinger/Threads.cpp190
1 files changed, 109 insertions, 81 deletions
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index d9b4249..721f6af 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -487,7 +487,7 @@ const char *sourceToString(audio_source_t source)
}
AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
- audio_devices_t outDevice, audio_devices_t inDevice, type_t type)
+ audio_devices_t outDevice, audio_devices_t inDevice, type_t type, bool systemReady)
: Thread(false /*canCallJava*/),
mType(type),
mAudioFlinger(audioFlinger),
@@ -498,7 +498,8 @@ AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio
mStandby(false), mOutDevice(outDevice), mInDevice(inDevice),
mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id),
// mName will be set by concrete (non-virtual) subclass
- mDeathRecipient(new PMDeathRecipient(this))
+ mDeathRecipient(new PMDeathRecipient(this)),
+ mSystemReady(systemReady)
{
memset(&mPatch, 0, sizeof(struct audio_patch));
}
@@ -567,6 +568,11 @@ status_t AudioFlinger::ThreadBase::sendConfigEvent_l(sp<ConfigEvent>& event)
{
status_t status = NO_ERROR;
+ if (event->mRequiresSystemReady && !mSystemReady) {
+ event->mWaitStatus = false;
+ mPendingConfigEvents.add(event);
+ return status;
+ }
mConfigEvents.add(event);
ALOGV("sendConfigEvent_l() num events %d event %d", mConfigEvents.size(), event->mType);
mWaitWorkCV.signal();
@@ -598,6 +604,12 @@ void AudioFlinger::ThreadBase::sendIoConfigEvent_l(audio_io_config_event event)
sendConfigEvent_l(configEvent);
}
+void AudioFlinger::ThreadBase::sendPrioConfigEvent(pid_t pid, pid_t tid, int32_t prio)
+{
+ Mutex::Autolock _l(mLock);
+ sendPrioConfigEvent_l(pid, tid, prio);
+}
+
// sendPrioConfigEvent_l() must be called with ThreadBase::mLock held
void AudioFlinger::ThreadBase::sendPrioConfigEvent_l(pid_t pid, pid_t tid, int32_t prio)
{
@@ -697,49 +709,62 @@ void AudioFlinger::ThreadBase::processConfigEvents_l()
String8 channelMaskToString(audio_channel_mask_t mask, bool output) {
String8 s;
- if (output) {
- if (mask & AUDIO_CHANNEL_OUT_FRONT_LEFT) s.append("front-left, ");
- if (mask & AUDIO_CHANNEL_OUT_FRONT_RIGHT) s.append("front-right, ");
- if (mask & AUDIO_CHANNEL_OUT_FRONT_CENTER) s.append("front-center, ");
- if (mask & AUDIO_CHANNEL_OUT_LOW_FREQUENCY) s.append("low freq, ");
- if (mask & AUDIO_CHANNEL_OUT_BACK_LEFT) s.append("back-left, ");
- if (mask & AUDIO_CHANNEL_OUT_BACK_RIGHT) s.append("back-right, ");
- if (mask & AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER) s.append("front-left-of-center, ");
- if (mask & AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER) s.append("front-right-of-center, ");
- if (mask & AUDIO_CHANNEL_OUT_BACK_CENTER) s.append("back-center, ");
- if (mask & AUDIO_CHANNEL_OUT_SIDE_LEFT) s.append("side-left, ");
- if (mask & AUDIO_CHANNEL_OUT_SIDE_RIGHT) s.append("side-right, ");
- if (mask & AUDIO_CHANNEL_OUT_TOP_CENTER) s.append("top-center ,");
- if (mask & AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT) s.append("top-front-left, ");
- if (mask & AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER) s.append("top-front-center, ");
- if (mask & AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT) s.append("top-front-right, ");
- if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_LEFT) s.append("top-back-left, ");
- if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_CENTER) s.append("top-back-center, " );
- if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT) s.append("top-back-right, " );
- if (mask & ~AUDIO_CHANNEL_OUT_ALL) s.append("unknown, ");
- } else {
- if (mask & AUDIO_CHANNEL_IN_LEFT) s.append("left, ");
- if (mask & AUDIO_CHANNEL_IN_RIGHT) s.append("right, ");
- if (mask & AUDIO_CHANNEL_IN_FRONT) s.append("front, ");
- if (mask & AUDIO_CHANNEL_IN_BACK) s.append("back, ");
- if (mask & AUDIO_CHANNEL_IN_LEFT_PROCESSED) s.append("left-processed, ");
- if (mask & AUDIO_CHANNEL_IN_RIGHT_PROCESSED) s.append("right-processed, ");
- if (mask & AUDIO_CHANNEL_IN_FRONT_PROCESSED) s.append("front-processed, ");
- if (mask & AUDIO_CHANNEL_IN_BACK_PROCESSED) s.append("back-processed, ");
- if (mask & AUDIO_CHANNEL_IN_PRESSURE) s.append("pressure, ");
- if (mask & AUDIO_CHANNEL_IN_X_AXIS) s.append("X, ");
- if (mask & AUDIO_CHANNEL_IN_Y_AXIS) s.append("Y, ");
- if (mask & AUDIO_CHANNEL_IN_Z_AXIS) s.append("Z, ");
- if (mask & AUDIO_CHANNEL_IN_VOICE_UPLINK) s.append("voice-uplink, ");
- if (mask & AUDIO_CHANNEL_IN_VOICE_DNLINK) s.append("voice-dnlink, ");
- if (mask & ~AUDIO_CHANNEL_IN_ALL) s.append("unknown, ");
- }
- int len = s.length();
- if (s.length() > 2) {
- char *str = s.lockBuffer(len);
- s.unlockBuffer(len - 2);
- }
- return s;
+ const audio_channel_representation_t representation = audio_channel_mask_get_representation(mask);
+
+ switch (representation) {
+ case AUDIO_CHANNEL_REPRESENTATION_POSITION: {
+ if (output) {
+ if (mask & AUDIO_CHANNEL_OUT_FRONT_LEFT) s.append("front-left, ");
+ if (mask & AUDIO_CHANNEL_OUT_FRONT_RIGHT) s.append("front-right, ");
+ if (mask & AUDIO_CHANNEL_OUT_FRONT_CENTER) s.append("front-center, ");
+ if (mask & AUDIO_CHANNEL_OUT_LOW_FREQUENCY) s.append("low freq, ");
+ if (mask & AUDIO_CHANNEL_OUT_BACK_LEFT) s.append("back-left, ");
+ if (mask & AUDIO_CHANNEL_OUT_BACK_RIGHT) s.append("back-right, ");
+ if (mask & AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER) s.append("front-left-of-center, ");
+ if (mask & AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER) s.append("front-right-of-center, ");
+ if (mask & AUDIO_CHANNEL_OUT_BACK_CENTER) s.append("back-center, ");
+ if (mask & AUDIO_CHANNEL_OUT_SIDE_LEFT) s.append("side-left, ");
+ if (mask & AUDIO_CHANNEL_OUT_SIDE_RIGHT) s.append("side-right, ");
+ if (mask & AUDIO_CHANNEL_OUT_TOP_CENTER) s.append("top-center ,");
+ if (mask & AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT) s.append("top-front-left, ");
+ if (mask & AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER) s.append("top-front-center, ");
+ if (mask & AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT) s.append("top-front-right, ");
+ if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_LEFT) s.append("top-back-left, ");
+ if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_CENTER) s.append("top-back-center, " );
+ if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT) s.append("top-back-right, " );
+ if (mask & ~AUDIO_CHANNEL_OUT_ALL) s.append("unknown, ");
+ } else {
+ if (mask & AUDIO_CHANNEL_IN_LEFT) s.append("left, ");
+ if (mask & AUDIO_CHANNEL_IN_RIGHT) s.append("right, ");
+ if (mask & AUDIO_CHANNEL_IN_FRONT) s.append("front, ");
+ if (mask & AUDIO_CHANNEL_IN_BACK) s.append("back, ");
+ if (mask & AUDIO_CHANNEL_IN_LEFT_PROCESSED) s.append("left-processed, ");
+ if (mask & AUDIO_CHANNEL_IN_RIGHT_PROCESSED) s.append("right-processed, ");
+ if (mask & AUDIO_CHANNEL_IN_FRONT_PROCESSED) s.append("front-processed, ");
+ if (mask & AUDIO_CHANNEL_IN_BACK_PROCESSED) s.append("back-processed, ");
+ if (mask & AUDIO_CHANNEL_IN_PRESSURE) s.append("pressure, ");
+ if (mask & AUDIO_CHANNEL_IN_X_AXIS) s.append("X, ");
+ if (mask & AUDIO_CHANNEL_IN_Y_AXIS) s.append("Y, ");
+ if (mask & AUDIO_CHANNEL_IN_Z_AXIS) s.append("Z, ");
+ if (mask & AUDIO_CHANNEL_IN_VOICE_UPLINK) s.append("voice-uplink, ");
+ if (mask & AUDIO_CHANNEL_IN_VOICE_DNLINK) s.append("voice-dnlink, ");
+ if (mask & ~AUDIO_CHANNEL_IN_ALL) s.append("unknown, ");
+ }
+ const int len = s.length();
+ if (len > 2) {
+ char *str = s.lockBuffer(len); // needed?
+ s.unlockBuffer(len - 2); // remove trailing ", "
+ }
+ return s;
+ }
+ case AUDIO_CHANNEL_REPRESENTATION_INDEX:
+ s.appendFormat("index mask, bits:%#x", audio_channel_mask_get_bits(mask));
+ return s;
+ default:
+ s.appendFormat("unknown mask, representation:%d bits:%#x",
+ representation, audio_channel_mask_get_bits(mask));
+ return s;
+ }
}
void AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args __unused)
@@ -880,8 +905,7 @@ void AudioFlinger::ThreadBase::updateWakeLockUids(const SortedVector<int> &uids)
}
void AudioFlinger::ThreadBase::getPowerManager_l() {
-
- if (mPowerManager == 0) {
+ if (mSystemReady && mPowerManager == 0) {
// use checkService() to avoid blocking if power service is not up yet
sp<IBinder> binder =
defaultServiceManager()->checkService(String16("power"));
@@ -895,7 +919,6 @@ void AudioFlinger::ThreadBase::getPowerManager_l() {
}
void AudioFlinger::ThreadBase::updateWakeLockUids_l(const SortedVector<int> &uids) {
-
getPowerManager_l();
if (mWakeLockToken == NULL) {
ALOGE("no wake lock to update!");
@@ -1337,6 +1360,20 @@ void AudioFlinger::ThreadBase::getAudioPortConfig(struct audio_port_config *conf
AUDIO_PORT_CONFIG_FORMAT;
}
+void AudioFlinger::ThreadBase::systemReady()
+{
+ Mutex::Autolock _l(mLock);
+ if (mSystemReady) {
+ return;
+ }
+ mSystemReady = true;
+
+ for (size_t i = 0; i < mPendingConfigEvents.size(); i++) {
+ sendConfigEvent_l(mPendingConfigEvents.editItemAt(i));
+ }
+ mPendingConfigEvents.clear();
+}
+
// ----------------------------------------------------------------------------
// Playback
@@ -1346,8 +1383,9 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge
AudioStreamOut* output,
audio_io_handle_t id,
audio_devices_t device,
- type_t type)
- : ThreadBase(audioFlinger, id, device, AUDIO_DEVICE_NONE, type),
+ type_t type,
+ bool systemReady)
+ : ThreadBase(audioFlinger, id, device, AUDIO_DEVICE_NONE, type, systemReady),
mNormalFrameCount(0), mSinkBuffer(NULL),
mMixerBufferEnabled(AudioFlinger::kEnableExtendedPrecision),
mMixerBuffer(NULL),
@@ -1572,10 +1610,12 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac
) &&
// PCM data
audio_is_linear_pcm(format) &&
- // identical channel mask to sink, or mono in and stereo sink
+ // TODO: extract as a data library function that checks that a computationally
+ // expensive downmixer is not required: isFastOutputChannelConversion()
(channelMask == mChannelMask ||
- (channelMask == AUDIO_CHANNEL_OUT_MONO &&
- mChannelMask == AUDIO_CHANNEL_OUT_STEREO)) &&
+ mChannelMask != AUDIO_CHANNEL_OUT_STEREO ||
+ (channelMask == AUDIO_CHANNEL_OUT_MONO
+ /* && mChannelMask == AUDIO_CHANNEL_OUT_STEREO */)) &&
// hardware sample rate
(sampleRate == mSampleRate) &&
// normal mixer has an associated fast mixer
@@ -3118,8 +3158,8 @@ void AudioFlinger::PlaybackThread::getAudioPortConfig(struct audio_port_config *
// ----------------------------------------------------------------------------
AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
- audio_io_handle_t id, audio_devices_t device, type_t type)
- : PlaybackThread(audioFlinger, output, id, device, type),
+ audio_io_handle_t id, audio_devices_t device, bool systemReady, type_t type)
+ : PlaybackThread(audioFlinger, output, id, device, type, systemReady),
// mAudioMixer below
// mFastMixer below
mFastMixerFutex(0)
@@ -3252,11 +3292,7 @@ AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, Aud
// start the fast mixer
mFastMixer->run("FastMixer", PRIORITY_URGENT_AUDIO);
pid_t tid = mFastMixer->getTid();
- int err = requestPriority(getpid_cached, tid, kPriorityFastMixer);
- if (err != 0) {
- ALOGW("Policy SCHED_FIFO priority %d is unavailable for pid %d tid %d; error %d",
- kPriorityFastMixer, getpid_cached, tid, err);
- }
+ sendPrioConfigEvent(getpid_cached, tid, kPriorityFastMixer);
#ifdef AUDIO_WATCHDOG
// create and start the watchdog
@@ -3264,11 +3300,7 @@ AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, Aud
mAudioWatchdog->setDump(&mAudioWatchdogDump);
mAudioWatchdog->run("AudioWatchdog", PRIORITY_URGENT_AUDIO);
tid = mAudioWatchdog->getTid();
- err = requestPriority(getpid_cached, tid, kPriorityFastMixer);
- if (err != 0) {
- ALOGW("Policy SCHED_FIFO priority %d is unavailable for pid %d tid %d; error %d",
- kPriorityFastMixer, getpid_cached, tid, err);
- }
+ sendPrioConfigEvent(getpid_cached, tid, kPriorityFastMixer);
#endif
}
@@ -4294,16 +4326,16 @@ void AudioFlinger::MixerThread::cacheParameters_l()
// ----------------------------------------------------------------------------
AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger,
- AudioStreamOut* output, audio_io_handle_t id, audio_devices_t device)
- : PlaybackThread(audioFlinger, output, id, device, DIRECT)
+ AudioStreamOut* output, audio_io_handle_t id, audio_devices_t device, bool systemReady)
+ : PlaybackThread(audioFlinger, output, id, device, DIRECT, systemReady)
// mLeftVolFloat, mRightVolFloat
{
}
AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger,
AudioStreamOut* output, audio_io_handle_t id, uint32_t device,
- ThreadBase::type_t type)
- : PlaybackThread(audioFlinger, output, id, device, type)
+ ThreadBase::type_t type, bool systemReady)
+ : PlaybackThread(audioFlinger, output, id, device, type, systemReady)
// mLeftVolFloat, mRightVolFloat
{
}
@@ -4832,8 +4864,8 @@ void AudioFlinger::AsyncCallbackThread::resetDraining()
// ----------------------------------------------------------------------------
AudioFlinger::OffloadThread::OffloadThread(const sp<AudioFlinger>& audioFlinger,
- AudioStreamOut* output, audio_io_handle_t id, uint32_t device)
- : DirectOutputThread(audioFlinger, output, id, device, OFFLOAD),
+ AudioStreamOut* output, audio_io_handle_t id, uint32_t device, bool systemReady)
+ : DirectOutputThread(audioFlinger, output, id, device, OFFLOAD, systemReady),
mPausedBytesRemaining(0)
{
//FIXME: mStandby should be set to true by ThreadBase constructor
@@ -5110,9 +5142,9 @@ void AudioFlinger::OffloadThread::onAddNewTrack_l()
// ----------------------------------------------------------------------------
AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger,
- AudioFlinger::MixerThread* mainThread, audio_io_handle_t id)
+ AudioFlinger::MixerThread* mainThread, audio_io_handle_t id, bool systemReady)
: MixerThread(audioFlinger, mainThread->getOutput(), id, mainThread->outDevice(),
- DUPLICATING),
+ systemReady, DUPLICATING),
mWaitTimeMs(UINT_MAX)
{
addOutputTrack(mainThread);
@@ -5292,12 +5324,13 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger,
AudioStreamIn *input,
audio_io_handle_t id,
audio_devices_t outDevice,
- audio_devices_t inDevice
+ audio_devices_t inDevice,
+ bool systemReady
#ifdef TEE_SINK
, const sp<NBAIO_Sink>& teeSink
#endif
) :
- ThreadBase(audioFlinger, id, outDevice, inDevice, RECORD),
+ ThreadBase(audioFlinger, id, outDevice, inDevice, RECORD, systemReady),
mInput(input), mActiveTracksGen(0), mRsmpInBuffer(NULL),
// mRsmpInFrames and mRsmpInFramesP2 are set by readInputParameters_l()
mRsmpInRear(0)
@@ -5416,12 +5449,7 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger,
// start the fast capture
mFastCapture->run("FastCapture", ANDROID_PRIORITY_URGENT_AUDIO);
pid_t tid = mFastCapture->getTid();
- int err = requestPriority(getpid_cached, tid, kPriorityFastMixer);
- if (err != 0) {
- ALOGW("Policy SCHED_FIFO priority %d is unavailable for pid %d tid %d; error %d",
- kPriorityFastCapture, getpid_cached, tid, err);
- }
-
+ sendPrioConfigEvent(getpid_cached, tid, kPriorityFastMixer);
#ifdef AUDIO_WATCHDOG
// FIXME
#endif