diff options
Diffstat (limited to 'services/audioflinger/Threads.cpp')
-rw-r--r-- | services/audioflinger/Threads.cpp | 336 |
1 files changed, 199 insertions, 137 deletions
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index 594ed05..7809eff 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -356,13 +356,47 @@ String8 devicesToString(audio_devices_t devices) AUDIO_DEVICE_OUT_SPEAKER, "SPEAKER", AUDIO_DEVICE_OUT_WIRED_HEADSET, "WIRED_HEADSET", AUDIO_DEVICE_OUT_WIRED_HEADPHONE, "WIRED_HEADPHONE", + AUDIO_DEVICE_OUT_BLUETOOTH_SCO, "BLUETOOTH_SCO", + AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET, "BLUETOOTH_SCO_HEADSET", + AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT, "BLUETOOTH_SCO_CARKIT", + AUDIO_DEVICE_OUT_BLUETOOTH_A2DP, "BLUETOOTH_A2DP", + AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, "BLUETOOTH_A2DP_HEADPHONES", + AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, "BLUETOOTH_A2DP_SPEAKER", + AUDIO_DEVICE_OUT_AUX_DIGITAL, "AUX_DIGITAL", + AUDIO_DEVICE_OUT_HDMI, "HDMI", + AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET, "ANLG_DOCK_HEADSET", + AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET, "DGTL_DOCK_HEADSET", + AUDIO_DEVICE_OUT_USB_ACCESSORY, "USB_ACCESSORY", + AUDIO_DEVICE_OUT_USB_DEVICE, "USB_DEVICE", AUDIO_DEVICE_OUT_TELEPHONY_TX, "TELEPHONY_TX", + AUDIO_DEVICE_OUT_LINE, "LINE", + AUDIO_DEVICE_OUT_HDMI_ARC, "HDMI_ARC", + AUDIO_DEVICE_OUT_SPDIF, "SPDIF", + AUDIO_DEVICE_OUT_FM, "FM", + AUDIO_DEVICE_OUT_AUX_LINE, "AUX_LINE", + AUDIO_DEVICE_OUT_SPEAKER_SAFE, "SPEAKER_SAFE", AUDIO_DEVICE_NONE, "NONE", // must be last }, mappingsIn[] = { + AUDIO_DEVICE_IN_COMMUNICATION, "COMMUNICATION", + AUDIO_DEVICE_IN_AMBIENT, "AMBIENT", AUDIO_DEVICE_IN_BUILTIN_MIC, "BUILTIN_MIC", + AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, "BLUETOOTH_SCO_HEADSET", AUDIO_DEVICE_IN_WIRED_HEADSET, "WIRED_HEADSET", + AUDIO_DEVICE_IN_AUX_DIGITAL, "AUX_DIGITAL", AUDIO_DEVICE_IN_VOICE_CALL, "VOICE_CALL", + AUDIO_DEVICE_IN_TELEPHONY_RX, "TELEPHONY_RX", + AUDIO_DEVICE_IN_BACK_MIC, "BACK_MIC", AUDIO_DEVICE_IN_REMOTE_SUBMIX, "REMOTE_SUBMIX", + AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET, "ANLG_DOCK_HEADSET", + AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET, "DGTL_DOCK_HEADSET", + AUDIO_DEVICE_IN_USB_ACCESSORY, "USB_ACCESSORY", + AUDIO_DEVICE_IN_USB_DEVICE, "USB_DEVICE", + AUDIO_DEVICE_IN_FM_TUNER, "FM_TUNER", + AUDIO_DEVICE_IN_TV_TUNER, "TV_TUNER", + AUDIO_DEVICE_IN_LINE, "LINE", + AUDIO_DEVICE_IN_SPDIF, "SPDIF", + AUDIO_DEVICE_IN_BLUETOOTH_A2DP, "BLUETOOTH_A2DP", + AUDIO_DEVICE_IN_LOOPBACK, "LOOPBACK", AUDIO_DEVICE_NONE, "NONE", // must be last }; String8 result; @@ -487,7 +521,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 +532,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 +602,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 +638,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 +743,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 +939,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 +953,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 +1394,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 +1417,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), @@ -1366,7 +1438,7 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false), mMixerStatus(MIXER_IDLE), mMixerStatusIgnoringFastTracks(MIXER_IDLE), - standbyDelay(AudioFlinger::mStandbyTimeInNsecs), + mStandbyDelayNs(AudioFlinger::mStandbyTimeInNsecs), mBytesRemaining(0), mCurrentWriteLength(0), mUseAsyncWrite(false), @@ -1572,10 +1644,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 @@ -2418,9 +2492,9 @@ void AudioFlinger::PlaybackThread::threadLoop_exit() /* The derived values that are cached: - mSinkBufferSize from frame count * frame size - - activeSleepTime from activeSleepTimeUs() - - idleSleepTime from idleSleepTimeUs() - - standbyDelay from mActiveSleepTimeUs (DIRECT only) + - mActiveSleepTimeUs from activeSleepTimeUs() + - mIdleSleepTimeUs from idleSleepTimeUs() + - mStandbyDelayNs from mActiveSleepTimeUs (DIRECT only) - maxPeriod from frame count and sample rate (MIXER only) The parameters that affect these derived values are: @@ -2437,8 +2511,8 @@ The parameters that affect these derived values are: void AudioFlinger::PlaybackThread::cacheParameters_l() { mSinkBufferSize = mNormalFrameCount * mFrameSize; - activeSleepTime = activeSleepTimeUs(); - idleSleepTime = idleSleepTimeUs(); + mActiveSleepTimeUs = activeSleepTimeUs(); + mIdleSleepTimeUs = idleSleepTimeUs(); } void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamType) @@ -2605,7 +2679,7 @@ bool AudioFlinger::PlaybackThread::threadLoop() { Vector< sp<Track> > tracksToRemove; - standbyTime = systemTime(); + mStandbyTimeNs = systemTime(); // MIXER nsecs_t lastWarning = 0; @@ -2617,7 +2691,7 @@ bool AudioFlinger::PlaybackThread::threadLoop() int lastGeneration = 0; cacheParameters_l(); - sleepTime = idleSleepTime; + mSleepTimeUs = mIdleSleepTimeUs; if (mType == MIXER) { sleepTimeShift = 0; @@ -2696,12 +2770,12 @@ bool AudioFlinger::PlaybackThread::threadLoop() if (released) { acquireWakeLock_l(); } - standbyTime = systemTime() + standbyDelay; - sleepTime = 0; + mStandbyTimeNs = systemTime() + mStandbyDelayNs; + mSleepTimeUs = 0; continue; } - if ((!mActiveTracks.size() && systemTime() > standbyTime) || + if ((!mActiveTracks.size() && systemTime() > mStandbyTimeNs) || isSuspended()) { // put audio hardware into standby after short delay if (shouldStandby_l()) { @@ -2736,8 +2810,8 @@ bool AudioFlinger::PlaybackThread::threadLoop() mBytesRemaining = 0; checkSilentMode_l(); - standbyTime = systemTime() + standbyDelay; - sleepTime = idleSleepTime; + mStandbyTimeNs = systemTime() + mStandbyDelayNs; + mSleepTimeUs = mIdleSleepTimeUs; if (mType == MIXER) { sleepTimeShift = 0; } @@ -2768,15 +2842,15 @@ bool AudioFlinger::PlaybackThread::threadLoop() threadLoop_mix(); } else if ((mMixerStatus != MIXER_DRAIN_TRACK) && (mMixerStatus != MIXER_DRAIN_ALL)) { - // threadLoop_sleepTime sets sleepTime to 0 if data + // threadLoop_sleepTime sets mSleepTimeUs to 0 if data // must be written to HAL threadLoop_sleepTime(); - if (sleepTime == 0) { + if (mSleepTimeUs == 0) { mCurrentWriteLength = mSinkBufferSize; } } // Either threadLoop_mix() or threadLoop_sleepTime() should have set - // mMixerBuffer with data if mMixerBufferValid is true and sleepTime == 0. + // mMixerBuffer with data if mMixerBufferValid is true and mSleepTimeUs == 0. // Merge mMixerBuffer data into mEffectBuffer (if any effects are valid) // or mSinkBuffer (if there are no effects). // @@ -2784,7 +2858,7 @@ bool AudioFlinger::PlaybackThread::threadLoop() // support higher precision, this needs to move. // // mMixerBufferValid is only set true by MixerThread::prepareTracks_l(). - // TODO use sleepTime == 0 as an additional condition. + // TODO use mSleepTimeUs == 0 as an additional condition. if (mMixerBufferValid) { void *buffer = mEffectBufferValid ? mEffectBuffer : mSinkBuffer; audio_format_t format = mEffectBufferValid ? mEffectBufferFormat : mFormat; @@ -2795,14 +2869,14 @@ bool AudioFlinger::PlaybackThread::threadLoop() mBytesRemaining = mCurrentWriteLength; if (isSuspended()) { - sleepTime = suspendSleepTimeUs(); + mSleepTimeUs = suspendSleepTimeUs(); // simulate write to HAL when suspended mBytesWritten += mSinkBufferSize; mBytesRemaining = 0; } // only process effects if we're going to write - if (sleepTime == 0 && mType != OFFLOAD) { + if (mSleepTimeUs == 0 && mType != OFFLOAD) { for (size_t i = 0; i < effectChains.size(); i ++) { effectChains[i]->process_l(); } @@ -2821,7 +2895,7 @@ bool AudioFlinger::PlaybackThread::threadLoop() // Only if the Effects buffer is enabled and there is data in the // Effects buffer (buffer valid), we need to // copy into the sink buffer. - // TODO use sleepTime == 0 as an additional condition. + // TODO use mSleepTimeUs == 0 as an additional condition. if (mEffectBufferValid) { //ALOGV("writing effect buffer to sink buffer format %#x", mFormat); memcpy_by_audio_format(mSinkBuffer, mFormat, mEffectBuffer, mEffectBufferFormat, @@ -2832,8 +2906,8 @@ bool AudioFlinger::PlaybackThread::threadLoop() unlockEffectChains(effectChains); if (!waitingAsyncCallback()) { - // sleepTime == 0 means we must write to audio hardware - if (sleepTime == 0) { + // mSleepTimeUs == 0 means we must write to audio hardware + if (mSleepTimeUs == 0) { if (mBytesRemaining) { ssize_t ret = threadLoop_write(); if (ret < 0) { @@ -2863,7 +2937,7 @@ bool AudioFlinger::PlaybackThread::threadLoop() } else { ATRACE_BEGIN("sleep"); - usleep(sleepTime); + usleep(mSleepTimeUs); ATRACE_END(); } } @@ -3118,8 +3192,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 +3326,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 +3334,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 } @@ -3467,11 +3533,11 @@ void AudioFlinger::MixerThread::threadLoop_mix() // Only increase sleep time if the mixer is ready for two consecutive times to avoid // that a steady state of alternating ready/not ready conditions keeps the sleep time // such that we would underrun the audio HAL. - if ((sleepTime == 0) && (sleepTimeShift > 0)) { + if ((mSleepTimeUs == 0) && (sleepTimeShift > 0)) { sleepTimeShift--; } - sleepTime = 0; - standbyTime = systemTime() + standbyDelay; + mSleepTimeUs = 0; + mStandbyTimeNs = systemTime() + mStandbyDelayNs; //TODO: delay standby when effects have a tail } @@ -3480,11 +3546,11 @@ void AudioFlinger::MixerThread::threadLoop_sleepTime() { // If no tracks are ready, sleep once for the duration of an output // buffer size, then write 0s to the output - if (sleepTime == 0) { + if (mSleepTimeUs == 0) { if (mMixerStatus == MIXER_TRACKS_ENABLED) { - sleepTime = activeSleepTime >> sleepTimeShift; - if (sleepTime < kMinThreadSleepTimeUs) { - sleepTime = kMinThreadSleepTimeUs; + mSleepTimeUs = mActiveSleepTimeUs >> sleepTimeShift; + if (mSleepTimeUs < kMinThreadSleepTimeUs) { + mSleepTimeUs = kMinThreadSleepTimeUs; } // reduce sleep time in case of consecutive application underruns to avoid // starving the audio HAL. As activeSleepTimeUs() is larger than a buffer @@ -3494,7 +3560,7 @@ void AudioFlinger::MixerThread::threadLoop_sleepTime() sleepTimeShift++; } } else { - sleepTime = idleSleepTime; + mSleepTimeUs = mIdleSleepTimeUs; } } else if (mBytesWritten != 0 || (mMixerStatus == MIXER_TRACKS_ENABLED)) { // clear out mMixerBuffer or mSinkBuffer, to ensure buffers are cleared @@ -3504,7 +3570,7 @@ void AudioFlinger::MixerThread::threadLoop_sleepTime() } else { memset(mSinkBuffer, 0, mSinkBufferSize); } - sleepTime = 0; + mSleepTimeUs = 0; ALOGV_IF(mBytesWritten == 0 && (mMixerStatus == MIXER_TRACKS_ENABLED), "anticipated start"); } @@ -4294,16 +4360,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 { } @@ -4443,7 +4509,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep track->mRetryCount = kMaxTrackRetriesDirect; mActiveTrack = t; mixerStatus = MIXER_TRACKS_READY; - if (usesHwAvSync() && mHwPaused) { + if (mHwPaused) { doHwResume = true; mHwPaused = false; } @@ -4495,7 +4561,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep android_atomic_or(CBLK_DISABLED, &cblk->mFlags); } else if (last) { mixerStatus = MIXER_TRACKS_ENABLED; - if (usesHwAvSync() && !mHwPaused && !mStandby) { + if (mHwSupportsPause && !mHwPaused && !mStandby) { doHwPause = true; mHwPaused = true; } @@ -4553,8 +4619,8 @@ void AudioFlinger::DirectOutputThread::threadLoop_mix() mActiveTrack->releaseBuffer(&buffer); } mCurrentWriteLength = curBuf - (int8_t *)mSinkBuffer; - sleepTime = 0; - standbyTime = systemTime() + standbyDelay; + mSleepTimeUs = 0; + mStandbyTimeNs = systemTime() + mStandbyDelayNs; mActiveTrack.clear(); } @@ -4562,18 +4628,18 @@ void AudioFlinger::DirectOutputThread::threadLoop_sleepTime() { // do not write to HAL when paused if (mHwPaused || (usesHwAvSync() && mStandby)) { - sleepTime = idleSleepTime; + mSleepTimeUs = mIdleSleepTimeUs; return; } - if (sleepTime == 0) { + if (mSleepTimeUs == 0) { if (mMixerStatus == MIXER_TRACKS_ENABLED) { - sleepTime = activeSleepTime; + mSleepTimeUs = mActiveSleepTimeUs; } else { - sleepTime = idleSleepTime; + mSleepTimeUs = mIdleSleepTimeUs; } } else if (mBytesWritten != 0 && audio_is_linear_pcm(mFormat)) { memset(mSinkBuffer, 0, mFrameCount * mFrameSize); - sleepTime = 0; + mSleepTimeUs = 0; } } @@ -4609,7 +4675,7 @@ bool AudioFlinger::DirectOutputThread::shouldStandby_l() mTracks[mTracks.size() - 1]->mState == TrackBase::IDLE; } - return !mStandby && !(trackPaused || (usesHwAvSync() && mHwPaused && !trackStopped)); + return !mStandby && !(trackPaused || (mHwPaused && !trackStopped)); } // getTrackName_l() must be called with ThreadBase::mLock held @@ -4714,11 +4780,11 @@ void AudioFlinger::DirectOutputThread::cacheParameters_l() // hardware resources as soon as possible // no delay on outputs with HW A/V sync if (usesHwAvSync()) { - standbyDelay = 0; - } else if (audio_is_linear_pcm(mFormat)) { - standbyDelay = microseconds(activeSleepTime*2); + mStandbyDelayNs = 0; + } else if ((mType == OFFLOAD) && !audio_is_linear_pcm(mFormat)) { + mStandbyDelayNs = kOffloadStandbyDelayNs; } else { - standbyDelay = kOffloadStandbyDelayNs; + mStandbyDelayNs = microseconds(mActiveSleepTimeUs*2); } } @@ -4832,8 +4898,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 @@ -4898,7 +4964,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr if (track->isPausing()) { track->setPaused(); if (last) { - if (!mHwPaused) { + if (mHwSupportsPause && !mHwPaused) { doHwPause = true; mHwPaused = true; } @@ -4934,7 +5000,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr // resume an interrupted write } // enable write to audio HAL - sleepTime = 0; + mSleepTimeUs = 0; // Do not handle new data in this iteration even if track->framesReady() mixerStatus = MIXER_TRACKS_ENABLED; @@ -4994,8 +5060,8 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr // do not modify drain sequence if we are already draining. This happens // when resuming from pause after drain. if ((mDrainSequence & 1) == 0) { - sleepTime = 0; - standbyTime = systemTime() + standbyDelay; + mSleepTimeUs = 0; + mStandbyTimeNs = systemTime() + mStandbyDelayNs; mixerStatus = MIXER_DRAIN_TRACK; mDrainSequence += 2; } @@ -5110,9 +5176,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); @@ -5137,19 +5203,19 @@ void AudioFlinger::DuplicatingThread::threadLoop_mix() memset(mSinkBuffer, 0, mSinkBufferSize); } } - sleepTime = 0; + mSleepTimeUs = 0; writeFrames = mNormalFrameCount; mCurrentWriteLength = mSinkBufferSize; - standbyTime = systemTime() + standbyDelay; + mStandbyTimeNs = systemTime() + mStandbyDelayNs; } void AudioFlinger::DuplicatingThread::threadLoop_sleepTime() { - if (sleepTime == 0) { + if (mSleepTimeUs == 0) { if (mMixerStatus == MIXER_TRACKS_ENABLED) { - sleepTime = activeSleepTime; + mSleepTimeUs = mActiveSleepTimeUs; } else { - sleepTime = idleSleepTime; + mSleepTimeUs = mIdleSleepTimeUs; } } else if (mBytesWritten != 0) { if (mMixerStatus == MIXER_TRACKS_ENABLED) { @@ -5159,7 +5225,7 @@ void AudioFlinger::DuplicatingThread::threadLoop_sleepTime() // flush remaining overflow buffers in output tracks writeFrames = 0; } - sleepTime = 0; + mSleepTimeUs = 0; } } @@ -5292,12 +5358,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 +5483,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 |