Call AudioMixer only from MixerThread threadLoop.
As part of change:
Remove track name offset by TRACK0.
Move track name management to the Tracks class.
Sync mixer track name to FastMixer track index.
Fixes regression introduced by commit 8ed196a.
Test: SoundPool, AudioTrack CTS, Usability
Bug: 72937362
Bug: 73004420
Change-Id: I2f1a33f6f0da66bcd7aa91e2a4b663ff822df645
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index ace586c..ef466a2 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -79,7 +79,6 @@
unsigned i;
for (i = 0; i < FastMixerState::sMaxFastTracks; ++i) {
- mFastTrackNames[i] = -1;
mGenerations[i] = 0;
}
#ifdef FAST_THREAD_STATISTICS
@@ -190,7 +189,7 @@
// FIXME new may block for unbounded time at internal mutex of the heap
// implementation; it would be better to have normal mixer allocate for us
// to avoid blocking here and to prevent possible priority inversion
- mMixer = new AudioMixer(frameCount, mSampleRate, FastMixerState::sMaxFastTracks);
+ mMixer = new AudioMixer(frameCount, mSampleRate);
// FIXME See the other FIXME at FastMixer::setNBLogWriter()
const size_t mixerFrameSize = mSinkChannelCount
* audio_bytes_per_sample(mMixerBufferFormat);
@@ -235,7 +234,6 @@
dumpState->mTrackMask = currentTrackMask;
if (current->mFastTracksGen != mFastTracksGen) {
ALOG_ASSERT(mMixerBuffer != NULL);
- int name;
// process removed tracks first to avoid running out of track names
unsigned removedTracks = previousTrackMask & ~currentTrackMask;
@@ -245,9 +243,7 @@
const FastTrack* fastTrack = ¤t->mFastTracks[i];
ALOG_ASSERT(fastTrack->mBufferProvider == NULL);
if (mMixer != NULL) {
- name = mFastTrackNames[i];
- ALOG_ASSERT(name >= 0);
- mMixer->deleteTrackName(name);
+ mMixer->destroy(i);
}
#if !LOG_NDEBUG
mFastTrackNames[i] = -1;
@@ -265,10 +261,16 @@
AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
ALOG_ASSERT(bufferProvider != NULL && mFastTrackNames[i] == -1);
if (mMixer != NULL) {
- name = mMixer->getTrackName(fastTrack->mChannelMask,
+ const int name = i; // for clarity, choose name as fast track index.
+ status_t status = mMixer->create(
+ name,
+ fastTrack->mChannelMask,
fastTrack->mFormat, AUDIO_SESSION_OUTPUT_MIX);
- ALOG_ASSERT(name >= 0);
- mFastTrackNames[i] = name;
+ LOG_ALWAYS_FATAL_IF(status != NO_ERROR,
+ "%s: cannot create track name"
+ " %d, mask %#x, format %#x, sessionId %d in AudioMixer",
+ __func__, name,
+ fastTrack->mChannelMask, fastTrack->mFormat, AUDIO_SESSION_OUTPUT_MIX);
mMixer->setBufferProvider(name, bufferProvider);
mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER,
(void *)mMixerBuffer);
@@ -300,8 +302,7 @@
AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
ALOG_ASSERT(bufferProvider != NULL);
if (mMixer != NULL) {
- name = mFastTrackNames[i];
- ALOG_ASSERT(name >= 0);
+ const int name = i;
mMixer->setBufferProvider(name, bufferProvider);
if (fastTrack->mVolumeProvider == NULL) {
float f = AudioMixer::UNITY_GAIN_FLOAT;
@@ -378,8 +379,7 @@
perTrackTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] = trackFramesWritten;
fastTrack->mBufferProvider->onTimestamp(perTrackTimestamp);
- int name = mFastTrackNames[i];
- ALOG_ASSERT(name >= 0);
+ const int name = i;
if (fastTrack->mVolumeProvider != NULL) {
gain_minifloat_packed_t vlr = fastTrack->mVolumeProvider->getVolumeLR();
float vlf = float_from_gain(gain_minifloat_unpack_left(vlr));
diff --git a/services/audioflinger/FastMixer.h b/services/audioflinger/FastMixer.h
index 930fa8d..235d23f 100644
--- a/services/audioflinger/FastMixer.h
+++ b/services/audioflinger/FastMixer.h
@@ -57,8 +57,6 @@
static const FastMixerState sInitial;
FastMixerState mPreIdle; // copy of state before we went into idle
- int mFastTrackNames[FastMixerState::kMaxFastTracks];
- // handles used by mixer to identify tracks
int mGenerations[FastMixerState::kMaxFastTracks];
// last observed mFastTracks[i].mGeneration
NBAIO_Sink* mOutputSink;
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 27c6d35..e5cb8a2 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -497,9 +497,6 @@
patch->mPatchRecord->buffer(),
patch->mPatchRecord->bufferSize(),
AUDIO_OUTPUT_FLAG_NONE);
- if (patch->mPatchTrack == 0) {
- return NO_MEMORY;
- }
status = patch->mPatchTrack->initCheck();
if (status != NO_ERROR) {
return status;
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index e97bb06..6454be5 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -51,6 +51,11 @@
void flush();
void destroy();
int name() const { return mName; }
+ void setName(int name) {
+ LOG_ALWAYS_FATAL_IF(mName >= 0 && name >= 0,
+ "%s both old name %d and new name %d are valid", __func__, mName, name);
+ mName = name;
+ }
virtual uint32_t sampleRate() const;
@@ -146,10 +151,7 @@
bool mResetDone;
const audio_stream_type_t mStreamType;
- int mName; // track name on the normal mixer,
- // allocated statically at track creation time,
- // and is even allocated (though unused) for fast tracks
- // FIXME don't allocate track name for fast tracks
+ int mName;
effect_buffer_t *mMainBuffer;
int32_t *mAuxBuffer;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index d6021b3..cae296e 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1661,6 +1661,7 @@
mSuspendedFrames(0),
mActiveTracks(&this->mLocalLog),
// mStreamTypes[] initialized in constructor body
+ mTracks(type == MIXER),
mOutput(output),
mLastWriteTime(-1), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
mMixerStatus(MIXER_IDLE),
@@ -2157,6 +2158,53 @@
return track;
}
+template<typename T>
+ssize_t AudioFlinger::PlaybackThread::Tracks<T>::add(const sp<T> &track)
+{
+ const ssize_t index = mTracks.add(track);
+ if (index >= 0) {
+ // set name for track when adding.
+ int name;
+ if (mUnusedTrackNames.empty()) {
+ name = mTracks.size() - 1; // new name {0 ... size-1}.
+ } else {
+ // reuse smallest name for deleted track.
+ auto it = mUnusedTrackNames.begin();
+ name = *it;
+ (void)mUnusedTrackNames.erase(it);
+ }
+ track->setName(name);
+ } else {
+ LOG_ALWAYS_FATAL("cannot add track");
+ }
+ return index;
+}
+
+template<typename T>
+ssize_t AudioFlinger::PlaybackThread::Tracks<T>::remove(const sp<T> &track)
+{
+ const int name = track->name();
+ const ssize_t index = mTracks.remove(track);
+ if (index >= 0) {
+ // invalidate name when removing from mTracks.
+ LOG_ALWAYS_FATAL_IF(name < 0, "invalid name %d for track on mTracks", name);
+
+ if (mSaveDeletedTrackNames) {
+ // We can't directly access mAudioMixer since the caller may be outside of threadLoop.
+ // Instead, we add to mDeletedTrackNames which is solely used for mAudioMixer update,
+ // to be handled when MixerThread::prepareTracks_l() next changes mAudioMixer.
+ mDeletedTrackNames.emplace(name);
+ }
+
+ mUnusedTrackNames.emplace(name);
+ track->setName(T::TRACK_NAME_PENDING);
+ } else {
+ LOG_ALWAYS_FATAL_IF(name >= 0,
+ "valid name %d for track not in mTracks (returned %zd)", name, index);
+ }
+ return index;
+}
+
uint32_t AudioFlinger::PlaybackThread::correctLatency_l(uint32_t latency) const
{
return latency;
@@ -2313,9 +2361,6 @@
mLocalLog.log("removeTrack_l (%p) %s", track.get(), result.string());
mTracks.remove(track);
- deleteTrackName_l(track->name());
- // redundant as track is about to be destroyed, for dumpsys only
- track->mName = -1;
if (track->isFastTrack()) {
int index = track->mFastIndex;
ALOG_ASSERT(0 < index && index < (int)FastMixerState::sMaxFastTracks);
@@ -4111,6 +4156,14 @@
AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTracks_l(
Vector< sp<Track> > *tracksToRemove)
{
+ // clean up deleted track names in AudioMixer before allocating new tracks
+ (void)mTracks.processDeletedTrackNames([this](int name) {
+ // for each name, destroy it in the AudioMixer
+ if (mAudioMixer->exists(name)) {
+ mAudioMixer->destroy(name);
+ }
+ });
+ mTracks.clearDeletedTrackNames();
mixer_state mixerStatus = MIXER_IDLE;
// find out which tracks need to be processed
@@ -4332,6 +4385,24 @@
// The first time a track is added we wait
// for all its buffers to be filled before processing it
int name = track->name();
+
+ // if an active track doesn't exist in the AudioMixer, create it.
+ if (!mAudioMixer->exists(name)) {
+ status_t status = mAudioMixer->create(
+ name,
+ track->mChannelMask,
+ track->mFormat,
+ track->mSessionId);
+ if (status != OK) {
+ ALOGW("%s: cannot create track name"
+ " %d, mask %#x, format %#x, sessionId %d in AudioMixer",
+ __func__, name, track->mChannelMask, track->mFormat, track->mSessionId);
+ tracksToRemove->add(track);
+ track->invalidate(); // consider it dead.
+ continue;
+ }
+ }
+
// make sure that we have enough frames to mix one full buffer.
// enforce this condition only once to enable draining the buffer in case the client
// app does not call stop() and relies on underrun to stop:
@@ -4357,20 +4428,9 @@
size_t framesReady = track->framesReady();
if (ATRACE_ENABLED()) {
// I wish we had formatted trace names
- char traceName[16];
- strcpy(traceName, "nRdy");
- int name = track->name();
- if (AudioMixer::TRACK0 <= name &&
- name < (int) (AudioMixer::TRACK0 + AudioMixer::MAX_NUM_TRACKS)) {
- name -= AudioMixer::TRACK0;
- traceName[4] = (name / 10) + '0';
- traceName[5] = (name % 10) + '0';
- } else {
- traceName[4] = '?';
- traceName[5] = '?';
- }
- traceName[6] = '\0';
- ATRACE_INT(traceName, framesReady);
+ std::string traceName("nRdy");
+ traceName += std::to_string(track->name());
+ ATRACE_INT(traceName.c_str(), framesReady);
}
if ((framesReady >= minFrames) && track->isReady() &&
!track->isPaused() && !track->isTerminated())
@@ -4736,7 +4796,7 @@
}
// trackCountForUid_l() must be called with ThreadBase::mLock held
-uint32_t AudioFlinger::PlaybackThread::trackCountForUid_l(uid_t uid)
+uint32_t AudioFlinger::PlaybackThread::trackCountForUid_l(uid_t uid) const
{
uint32_t trackCount = 0;
for (size_t i = 0; i < mTracks.size() ; i++) {
@@ -4747,21 +4807,24 @@
return trackCount;
}
-// getTrackName_l() must be called with ThreadBase::mLock held
-int AudioFlinger::MixerThread::getTrackName_l(audio_channel_mask_t channelMask,
- audio_format_t format, audio_session_t sessionId, uid_t uid)
+// isTrackAllowed_l() must be called with ThreadBase::mLock held
+bool AudioFlinger::MixerThread::isTrackAllowed_l(
+ audio_channel_mask_t channelMask, audio_format_t format,
+ audio_session_t sessionId, uid_t uid) const
{
- if (trackCountForUid_l(uid) > (PlaybackThread::kMaxTracksPerUid - 1)) {
- return -1;
+ if (!PlaybackThread::isTrackAllowed_l(channelMask, format, sessionId, uid)) {
+ return false;
}
- return mAudioMixer->getTrackName(channelMask, format, sessionId);
-}
-
-// deleteTrackName_l() must be called with ThreadBase::mLock held
-void AudioFlinger::MixerThread::deleteTrackName_l(int name)
-{
- ALOGV("remove track (%d) and delete from mixer", name);
- mAudioMixer->deleteTrackName(name);
+ // Check validity as we don't call AudioMixer::create() here.
+ if (!AudioMixer::isValidFormat(format)) {
+ ALOGW("%s: invalid format: %#x", __func__, format);
+ return false;
+ }
+ if (!AudioMixer::isValidChannelMask(channelMask)) {
+ ALOGW("%s: invalid channelMask: %#x", __func__, channelMask);
+ return false;
+ }
+ return true;
}
// checkForNewParameter_l() must be called with ThreadBase::mLock held
@@ -4854,13 +4917,18 @@
readOutputParameters_l();
delete mAudioMixer;
mAudioMixer = new AudioMixer(mNormalFrameCount, mSampleRate);
- for (size_t i = 0; i < mTracks.size() ; i++) {
- int name = getTrackName_l(mTracks[i]->mChannelMask,
- mTracks[i]->mFormat, mTracks[i]->mSessionId, mTracks[i]->uid());
- if (name < 0) {
- break;
- }
- mTracks[i]->mName = name;
+ for (const auto &track : mTracks) {
+ const int name = track->name();
+ status_t status = mAudioMixer->create(
+ name,
+ track->mChannelMask,
+ track->mFormat,
+ track->mSessionId);
+ ALOGW_IF(status != NO_ERROR,
+ "%s: cannot create track name"
+ " %d, mask %#x, format %#x, sessionId %d in AudioMixer",
+ __func__,
+ name, track->mChannelMask, track->mFormat, track->mSessionId);
}
sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED);
}
@@ -5309,21 +5377,6 @@
return !mStandby && !(trackPaused || (mHwPaused && !trackStopped));
}
-// getTrackName_l() must be called with ThreadBase::mLock held
-int AudioFlinger::DirectOutputThread::getTrackName_l(audio_channel_mask_t channelMask __unused,
- audio_format_t format __unused, audio_session_t sessionId __unused, uid_t uid)
-{
- if (trackCountForUid_l(uid) > (PlaybackThread::kMaxTracksPerUid - 1)) {
- return -1;
- }
- return 0;
-}
-
-// deleteTrackName_l() must be called with ThreadBase::mLock held
-void AudioFlinger::DirectOutputThread::deleteTrackName_l(int name __unused)
-{
-}
-
// checkForNewParameter_l() must be called with ThreadBase::mLock held
bool AudioFlinger::DirectOutputThread::checkForNewParameter_l(const String8& keyValuePair,
status_t& status)
@@ -5941,6 +5994,31 @@
}
}
+void AudioFlinger::DuplicatingThread::dumpInternals(int fd, const Vector<String16>& args __unused)
+{
+ MixerThread::dumpInternals(fd, args);
+
+ std::stringstream ss;
+ const size_t numTracks = mOutputTracks.size();
+ ss << " " << numTracks << " OutputTracks";
+ if (numTracks > 0) {
+ ss << ":";
+ for (const auto &track : mOutputTracks) {
+ const sp<ThreadBase> thread = track->thread().promote();
+ ss << " (" << track->name() << " : ";
+ if (thread.get() != nullptr) {
+ ss << thread.get() << ", " << thread->id();
+ } else {
+ ss << "null";
+ }
+ ss << ")";
+ }
+ }
+ ss << "\n";
+ std::string result = ss.str();
+ write(fd, result.c_str(), result.size());
+}
+
void AudioFlinger::DuplicatingThread::saveOutputTracks()
{
outputTracks = mOutputTracks;
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 53cb8ad..ae14ac1 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -624,6 +624,7 @@
static const int8_t kMaxTrackStartupRetriesOffload = 100;
static const int8_t kMaxTrackStopRetriesOffload = 2;
static constexpr uint32_t kMaxTracksPerUid = 40;
+ static constexpr size_t kMaxTracks = 256;
// Maximum delay (in nanoseconds) for upcoming buffers in suspend mode, otherwise
// if delay is greater, the estimated time for timeLoopNextNs is reset.
@@ -778,6 +779,16 @@
virtual bool isOutput() const override { return true; }
+ // returns true if the track is allowed to be added to the thread.
+ virtual bool isTrackAllowed_l(
+ audio_channel_mask_t channelMask __unused,
+ audio_format_t format __unused,
+ audio_session_t sessionId __unused,
+ uid_t uid) const {
+ return trackCountForUid_l(uid) < PlaybackThread::kMaxTracksPerUid
+ && mTracks.size() < PlaybackThread::kMaxTracks;
+ }
+
protected:
// updated by readOutputParameters_l()
size_t mNormalFrameCount; // normal mixer and effects
@@ -866,12 +877,6 @@
protected:
ActiveTracks<Track> mActiveTracks;
- // Allocate a track name for a given channel mask.
- // Returns name >= 0 if successful, -1 on failure.
- virtual int getTrackName_l(audio_channel_mask_t channelMask, audio_format_t format,
- audio_session_t sessionId, uid_t uid) = 0;
- virtual void deleteTrackName_l(int name) = 0;
-
// Time to sleep between cycles when:
virtual uint32_t activeSleepTimeUs() const; // mixer state MIXER_TRACKS_ENABLED
virtual uint32_t idleSleepTimeUs() const = 0; // mixer state MIXER_IDLE
@@ -899,7 +904,7 @@
&& mHwSupportsPause
&& (mOutput->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC); }
- uint32_t trackCountForUid_l(uid_t uid);
+ uint32_t trackCountForUid_l(uid_t uid) const;
private:
@@ -916,7 +921,64 @@
virtual void dumpInternals(int fd, const Vector<String16>& args);
void dumpTracks(int fd, const Vector<String16>& args);
- SortedVector< sp<Track> > mTracks;
+ // The Tracks class manages names for all tracks
+ // added and removed from the Thread.
+ template <typename T>
+ class Tracks {
+ public:
+ Tracks(bool saveDeletedTrackNames) :
+ mSaveDeletedTrackNames(saveDeletedTrackNames) { }
+
+ // SortedVector methods
+ ssize_t add(const sp<T> &track);
+ ssize_t remove(const sp<T> &track);
+ size_t size() const {
+ return mTracks.size();
+ }
+ bool isEmpty() const {
+ return mTracks.isEmpty();
+ }
+ ssize_t indexOf(const sp<T> &item) {
+ return mTracks.indexOf(item);
+ }
+ sp<T> operator[](size_t index) const {
+ return mTracks[index];
+ }
+ typename SortedVector<sp<T>>::iterator begin() {
+ return mTracks.begin();
+ }
+ typename SortedVector<sp<T>>::iterator end() {
+ return mTracks.end();
+ }
+
+ size_t processDeletedTrackNames(std::function<void(int)> f) {
+ const size_t size = mDeletedTrackNames.size();
+ if (size > 0) {
+ for (const int name : mDeletedTrackNames) {
+ f(name);
+ }
+ }
+ return size;
+ }
+
+ void clearDeletedTrackNames() { mDeletedTrackNames.clear(); }
+
+ private:
+ // Track names pending deletion for MIXER type threads
+ const bool mSaveDeletedTrackNames; // true to enable tracking
+ std::set<int> mDeletedTrackNames;
+
+ // Fast lookup of previously deleted track names for reuse.
+ // This is an arbitrary decision (actually any non-negative
+ // integer that isn't in mTracks[*]->names() could be used) - we attempt
+ // to use the smallest possible available name.
+ std::set<int> mUnusedTrackNames;
+
+ SortedVector<sp<T>> mTracks; // wrapped SortedVector.
+ };
+
+ Tracks<Track> mTracks;
+
stream_type_t mStreamTypes[AUDIO_STREAM_CNT];
AudioStreamOut *mOutput;
@@ -1023,11 +1085,11 @@
status_t& status);
virtual void dumpInternals(int fd, const Vector<String16>& args);
+ virtual bool isTrackAllowed_l(
+ audio_channel_mask_t channelMask, audio_format_t format,
+ audio_session_t sessionId, uid_t uid) const override;
protected:
virtual mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove);
- virtual int getTrackName_l(audio_channel_mask_t channelMask, audio_format_t format,
- audio_session_t sessionId, uid_t uid);
- virtual void deleteTrackName_l(int name);
virtual uint32_t idleSleepTimeUs() const;
virtual uint32_t suspendSleepTimeUs() const;
virtual void cacheParameters_l();
@@ -1105,9 +1167,6 @@
virtual void flushHw_l();
protected:
- virtual int getTrackName_l(audio_channel_mask_t channelMask, audio_format_t format,
- audio_session_t sessionId, uid_t uid);
- virtual void deleteTrackName_l(int name);
virtual uint32_t activeSleepTimeUs() const;
virtual uint32_t idleSleepTimeUs() const;
virtual uint32_t suspendSleepTimeUs() const;
@@ -1211,6 +1270,8 @@
virtual ~DuplicatingThread();
// Thread virtuals
+ virtual void dumpInternals(int fd, const Vector<String16>& args) override;
+
void addOutputTrack(MixerThread* thread);
void removeOutputTrack(MixerThread* thread);
uint32_t waitTimeMs() const { return mWaitTimeMs; }
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index a3ea756..a7e966f 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -54,6 +54,11 @@
TYPE_PATCH,
};
+ enum {
+ TRACK_NAME_PENDING = -1,
+ TRACK_NAME_FAILURE = -2,
+ };
+
TrackBase(ThreadBase *thread,
const sp<Client>& client,
uint32_t sampleRate,
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 67f27d0..9b93939 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -394,7 +394,7 @@
// mRetryCount initialized later when needed
mSharedBuffer(sharedBuffer),
mStreamType(streamType),
- mName(-1), // see note below
+ mName(TRACK_NAME_FAILURE), // set to TRACK_NAME_PENDING on constructor success.
mMainBuffer(thread->sinkBuffer()),
mAuxBuffer(NULL),
mAuxEffectId(0), mHasVolumeController(false),
@@ -427,9 +427,8 @@
}
mServerProxy = mAudioTrackServerProxy;
- mName = thread->getTrackName_l(channelMask, format, sessionId, uid);
- if (mName < 0) {
- ALOGE("no more track names available");
+ if (!thread->isTrackAllowed_l(channelMask, format, sessionId, uid)) {
+ ALOGE("no more tracks available");
return;
}
// only allocate a fast track index if we were able to allocate a normal track name
@@ -448,6 +447,7 @@
mFastIndex = i;
thread->mFastTrackAvailMask &= ~(1 << i);
}
+ mName = TRACK_NAME_PENDING;
}
AudioFlinger::PlaybackThread::Track::~Track()
@@ -466,7 +466,7 @@
status_t AudioFlinger::PlaybackThread::Track::initCheck() const
{
status_t status = TrackBase::initCheck();
- if (status == NO_ERROR && mName < 0) {
+ if (status == NO_ERROR && mName == TRACK_NAME_FAILURE) {
status = NO_MEMORY;
}
return status;
@@ -527,10 +527,12 @@
if (isFastTrack()) {
result.appendFormat("F%c %3d", trackType, mFastIndex);
- } else if (mName >= AudioMixer::TRACK0) {
- result.appendFormat("%c %4d", trackType, mName - AudioMixer::TRACK0);
+ } else if (mName == TRACK_NAME_PENDING) {
+ result.appendFormat("%c pend", trackType);
+ } else if (mName == TRACK_NAME_FAILURE) {
+ result.appendFormat("%c fail", trackType);
} else {
- result.appendFormat("%c none", trackType);
+ result.appendFormat("%c %4d", trackType, mName);
}
char nowInUnderrun;