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.cpp336
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