AudioFlinger: Extract inner Track classes
Finish removing inner Track classes from AudioFlinger.
Test: atest audiorecord_tests audiotrack_tests audiorouting_tests trackplayerbase_tests audiosystem_tests
Test: atest AudioTrackTest AudioRecordTest
Test: YouTube and Camera
Bug: 288339104
Bug: 288468076
Merged-In: Ib44c7eb854f9d447aa11223d76373b00c413a778
Change-Id: Ib44c7eb854f9d447aa11223d76373b00c413a778
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 07f0373..8c68751 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2208,7 +2208,7 @@
result.append(prefix);
mTracks[0]->appendDumpHeader(result);
for (size_t i = 0; i < numtracks; ++i) {
- sp<Track> track = mTracks[i];
+ sp<IAfTrack> track = mTracks[i];
if (track != 0) {
bool active = mActiveTracks.indexOf(track) >= 0;
if (active) {
@@ -2228,7 +2228,7 @@
result.append(prefix);
mActiveTracks[0]->appendDumpHeader(result);
for (size_t i = 0; i < numactive; ++i) {
- sp<Track> track = mActiveTracks[i];
+ sp<IAfTrack> track = mActiveTracks[i];
if (mTracks.indexOf(track) < 0) {
result.append(prefix);
track->appendDump(result, true /* active */);
@@ -2275,7 +2275,7 @@
}
// PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held
-sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrack_l(
+sp<IAfTrack> AudioFlinger::PlaybackThread::createTrack_l(
const sp<Client>& client,
audio_stream_type_t streamType,
const audio_attributes_t& attr,
@@ -2300,7 +2300,7 @@
{
size_t frameCount = *pFrameCount;
size_t notificationFrameCount = *pNotificationFrameCount;
- sp<Track> track;
+ sp<IAfTrack> track;
status_t lStatus;
audio_output_flags_t outputFlags = mOutput->flags;
audio_output_flags_t requestedFlags = *flags;
@@ -2593,7 +2593,7 @@
// manager
product_strategy_t strategy = getStrategyForStream(streamType);
for (size_t i = 0; i < mTracks.size(); ++i) {
- sp<Track> t = mTracks[i];
+ sp<IAfTrack> t = mTracks[i];
if (t != 0 && t->isExternalTrack()) {
product_strategy_t actual = getStrategyForStream(t->streamType());
if (sessionId == t->sessionId() && strategy != actual) {
@@ -2615,11 +2615,11 @@
trackFlags = static_cast<audio_output_flags_t>(trackFlags | AUDIO_OUTPUT_FLAG_DIRECT);
}
- track = new Track(this, client, streamType, attr, sampleRate, format,
+ track = IAfTrack::create(this, client, streamType, attr, sampleRate, format,
channelMask, frameCount,
nullptr /* buffer */, (size_t)0 /* bufferSize */, sharedBuffer,
sessionId, creatorPid, attributionSource, trackFlags,
- TrackBase::TYPE_DEFAULT, portId, SIZE_MAX /*frameCountToBeReady*/,
+ IAfTrackBase::TYPE_DEFAULT, portId, SIZE_MAX /*frameCountToBeReady*/,
speed, isSpatialized, isBitPerfect);
lStatus = track != 0 ? track->initCheck() : (status_t) NO_MEMORY;
@@ -2752,7 +2752,7 @@
}
// addTrack_l() must be called with ThreadBase::mLock held
-status_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track)
+status_t AudioFlinger::PlaybackThread::addTrack_l(const sp<IAfTrack>& track)
NO_THREAD_SAFETY_ANALYSIS // release and re-acquire mLock
{
status_t status = ALREADY_EXISTS;
@@ -2762,12 +2762,12 @@
// buffers before playing. This is to ensure the client will
// effectively get the latency it requested.
if (track->isExternalTrack()) {
- TrackBase::track_state state = track->mState;
+ IAfTrackBase::track_state state = track->state();
mLock.unlock();
status = AudioSystem::startOutput(track->portId());
mLock.lock();
// abort track was stopped/paused while we released the lock
- if (state != track->mState) {
+ if (state != track->state()) {
if (status == NO_ERROR) {
mLock.unlock();
AudioSystem::stopOutput(track->portId());
@@ -2793,15 +2793,15 @@
// set retry count for buffer fill
if (track->isOffloaded()) {
if (track->isStopping_1()) {
- track->mRetryCount = kMaxTrackStopRetriesOffload;
+ track->retryCount() = kMaxTrackStopRetriesOffload;
} else {
- track->mRetryCount = kMaxTrackStartupRetriesOffload;
+ track->retryCount() = kMaxTrackStartupRetriesOffload;
}
- track->mFillingUpStatus = mStandby ? Track::FS_FILLING : Track::FS_FILLED;
+ track->fillingStatus() = mStandby ? IAfTrack::FS_FILLING : IAfTrack::FS_FILLED;
} else {
- track->mRetryCount = kMaxTrackStartupRetries;
- track->mFillingUpStatus =
- track->sharedBuffer() != 0 ? Track::FS_FILLED : Track::FS_FILLING;
+ track->retryCount() = kMaxTrackStartupRetries;
+ track->fillingStatus() =
+ track->sharedBuffer() != 0 ? IAfTrack::FS_FILLED : IAfTrack::FS_FILLING;
}
sp<IAfEffectChain> chain = getEffectChain_l(track->sessionId());
@@ -2841,7 +2841,7 @@
}
}
- track->mResetDone = false;
+ track->setResetDone(false);
track->resetPresentationComplete();
mActiveTracks.add(track);
if (chain != 0) {
@@ -2858,25 +2858,25 @@
return status;
}
-bool AudioFlinger::PlaybackThread::destroyTrack_l(const sp<Track>& track)
+bool AudioFlinger::PlaybackThread::destroyTrack_l(const sp<IAfTrack>& track)
{
track->terminate();
// active tracks are removed by threadLoop()
bool trackActive = (mActiveTracks.indexOf(track) >= 0);
- track->mState = TrackBase::STOPPED;
+ track->setState(IAfTrackBase::STOPPED);
if (!trackActive) {
removeTrack_l(track);
} else if (track->isFastTrack() || track->isOffloaded() || track->isDirect()) {
if (track->isPausePending()) {
track->pauseAck();
}
- track->mState = TrackBase::STOPPING_1;
+ track->setState(IAfTrackBase::STOPPING_1);
}
return trackActive;
}
-void AudioFlinger::PlaybackThread::removeTrack_l(const sp<Track>& track)
+void AudioFlinger::PlaybackThread::removeTrack_l(const sp<IAfTrack>& track)
{
track->triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
@@ -2890,12 +2890,12 @@
mAudioTrackCallbacks.erase(track);
}
if (track->isFastTrack()) {
- int index = track->mFastIndex;
+ int index = track->fastIndex();
ALOG_ASSERT(0 < index && index < (int)FastMixerState::sMaxFastTracks);
ALOG_ASSERT(!(mFastTrackAvailMask & (1 << index)));
mFastTrackAvailMask |= 1 << index;
// redundant as track is about to be destroyed, for dumpsys only
- track->mFastIndex = -1;
+ track->fastIndex() = -1;
}
sp<IAfEffectChain> chain = getEffectChain_l(track->sessionId());
if (chain != 0) {
@@ -3223,7 +3223,7 @@
}
StreamOutHalInterface::SourceMetadata metadata;
auto backInserter = std::back_inserter(metadata.tracks);
- for (const sp<Track> &track : mActiveTracks) {
+ for (const sp<IAfTrack>& track : mActiveTracks) {
// No track is invalid as this is called after prepareTrack_l in the same critical section
track->copyMetadataTo(backInserter);
}
@@ -3274,7 +3274,7 @@
return getStrategyForStream(AUDIO_STREAM_MUSIC);
}
for (size_t i = 0; i < mTracks.size(); i++) {
- sp<Track> track = mTracks[i];
+ sp<IAfTrack> track = mTracks[i];
if (sessionId == track->sessionId() && !track->isInvalid()) {
return getStrategyForStream(track->streamType());
}
@@ -3325,7 +3325,7 @@
Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mTracks.size(); ++i) {
- sp<Track> track = mTracks[i];
+ sp<IAfTrack> track = mTracks[i];
if (event->triggerSession() == track->sessionId()) {
(void) track->setSyncEvent(event);
return NO_ERROR;
@@ -3342,7 +3342,7 @@
}
void AudioFlinger::PlaybackThread::threadLoop_removeTracks(
- [[maybe_unused]] const Vector< sp<Track> >& tracksToRemove)
+ [[maybe_unused]] const Vector<sp<IAfTrack>>& tracksToRemove)
{
// Miscellaneous track cleanup when removed from the active list,
// called without Thread lock but synchronized with threadLoop processing.
@@ -3493,7 +3493,7 @@
{
Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mTracks.size(); i++) {
- sp<Track> track = mTracks[i];
+ sp<IAfTrack> track = mTracks[i];
track->invalidate();
}
// Clear ActiveTracks to update BatteryNotifier in case active tracks remain.
@@ -3548,7 +3548,7 @@
bool trackMatch = false;
size_t size = mTracks.size();
for (size_t i = 0; i < size; i++) {
- sp<Track> t = mTracks[i];
+ sp<IAfTrack> t = mTracks[i];
if (t->streamType() == streamType && t->isExternalTrack()) {
t->invalidate();
trackMatch = true;
@@ -3572,7 +3572,7 @@
bool trackMatch = false;
const size_t size = mTracks.size();
for (size_t i = 0; i < size; i++) {
- sp<Track> t = mTracks[i];
+ sp<IAfTrack> t = mTracks[i];
if (t->isExternalTrack() && portIds.find(t->portId()) != portIds.end()) {
t->invalidate();
portIds.erase(t->portId());
@@ -3586,7 +3586,7 @@
}
// getTrackById_l must be called with holding thread lock
-AudioFlinger::PlaybackThread::Track* AudioFlinger::PlaybackThread::getTrackById_l(
+IAfTrack* AudioFlinger::PlaybackThread::getTrackById_l(
audio_port_handle_t trackPortId) {
for (size_t i = 0; i < mTracks.size(); i++) {
if (mTracks[i]->portId() == trackPortId) {
@@ -3680,7 +3680,7 @@
if (!audio_is_global_session(session)) {
// Attach all tracks with same session ID to this chain.
for (size_t i = 0; i < mTracks.size(); ++i) {
- sp<Track> track = mTracks[i];
+ sp<IAfTrack> track = mTracks[i];
if (session == track->sessionId()) {
ALOGV("addEffectChain_l() track->setMainBuffer track %p buffer %p",
track.get(), buffer);
@@ -3690,7 +3690,7 @@
}
// indicate all active tracks in the chain
- for (const sp<Track> &track : mActiveTracks) {
+ for (const sp<IAfTrack>& track : mActiveTracks) {
if (session == track->sessionId()) {
ALOGV("addEffectChain_l() activating track %p on session %d",
track.get(), session);
@@ -3742,7 +3742,7 @@
if (chain == mEffectChains[i]) {
mEffectChains.removeAt(i);
// detach all active tracks from the chain
- for (const sp<Track> &track : mActiveTracks) {
+ for (const sp<IAfTrack>& track : mActiveTracks) {
if (session == track->sessionId()) {
ALOGV("removeEffectChain_l(): stopping track on chain %p for session Id: %d",
chain.get(), session);
@@ -3752,7 +3752,7 @@
// detach all tracks with same session ID from this chain
for (size_t j = 0; j < mTracks.size(); ++j) {
- sp<Track> track = mTracks[j];
+ sp<IAfTrack> track = mTracks[j];
if (session == track->sessionId()) {
track->setMainBuffer(reinterpret_cast<float*>(mSinkBuffer));
chain->decTrackCnt();
@@ -3765,14 +3765,14 @@
}
status_t AudioFlinger::PlaybackThread::attachAuxEffect(
- const sp<AudioFlinger::PlaybackThread::Track>& track, int EffectId)
+ const sp<IAfTrack>& track, int EffectId)
{
Mutex::Autolock _l(mLock);
return attachAuxEffect_l(track, EffectId);
}
status_t AudioFlinger::PlaybackThread::attachAuxEffect_l(
- const sp<AudioFlinger::PlaybackThread::Track>& track, int EffectId)
+ const sp<IAfTrack>& track, int EffectId)
{
status_t status = NO_ERROR;
@@ -3797,7 +3797,7 @@
void AudioFlinger::PlaybackThread::detachAuxEffect_l(int effectId)
{
for (size_t i = 0; i < mTracks.size(); ++i) {
- sp<Track> track = mTracks[i];
+ sp<IAfTrack> track = mTracks[i];
if (track->auxEffectId() == effectId) {
attachAuxEffect_l(track, 0);
}
@@ -3809,7 +3809,7 @@
{
aflog::setThreadWriter(mNBLogWriter.get());
- Vector< sp<Track> > tracksToRemove;
+ Vector<sp<IAfTrack>> tracksToRemove;
mStandbyTimeNs = systemTime();
int64_t lastLoopCountWritten = -2; // never matches "previous" loop, when loopCount = 0.
@@ -3864,7 +3864,7 @@
Vector<sp<IAfEffectChain>> effectChains;
audio_session_t activeHapticSessionId = AUDIO_SESSION_NONE;
bool isHapticSessionSpatialized = false;
- std::vector<sp<Track>> activeTracks;
+ std::vector<sp<IAfTrack>> activeTracks;
// If the device is AUDIO_DEVICE_OUT_BUS, check for downstream latency.
//
@@ -4082,14 +4082,15 @@
// Tally underrun frames as we are inserting 0s here.
for (const auto& track : activeTracks) {
- if (track->mFillingUpStatus == Track::FS_ACTIVE
+ if (track->fillingStatus() == IAfTrack::FS_ACTIVE
&& !track->isStopped()
&& !track->isPaused()
&& !track->isTerminated()) {
ALOGV("%s: track(%d) %s underrun due to thread sleep of %zu frames",
__func__, track->id(), track->getTrackStateAsString(),
mNormalFrameCount);
- track->mAudioTrackServerProxy->tallyUnderrunFrames(mNormalFrameCount);
+ track->audioTrackServerProxy()->tallyUnderrunFrames(
+ mNormalFrameCount);
}
}
}
@@ -4564,10 +4565,10 @@
? systemTime() : mLastIoBeginNs;
}
- for (const sp<Track> &t : mActiveTracks) {
+ for (const sp<IAfTrack>& t : mActiveTracks) {
if (!t->isFastTrack()) {
t->updateTrackFrameInfo(
- t->mAudioTrackServerProxy->framesReleased(),
+ t->audioTrackServerProxy()->framesReleased(),
mFramesWritten,
mSampleRate,
mTimestamp);
@@ -4595,7 +4596,7 @@
}
// removeTracks_l() must be called with ThreadBase::mLock held
-void AudioFlinger::PlaybackThread::removeTracks_l(const Vector< sp<Track> >& tracksToRemove)
+void AudioFlinger::PlaybackThread::removeTracks_l(const Vector<sp<IAfTrack>>& tracksToRemove)
NO_THREAD_SAFETY_ANALYSIS // release and re-acquire mLock
{
for (const auto& track : tracksToRemove) {
@@ -4822,13 +4823,13 @@
return status;
}
-void AudioFlinger::PlaybackThread::addPatchTrack(const sp<PatchTrack>& track)
+void AudioFlinger::PlaybackThread::addPatchTrack(const sp<IAfPatchTrack>& track)
{
Mutex::Autolock _l(mLock);
mTracks.add(track);
}
-void AudioFlinger::PlaybackThread::deletePatchTrack(const sp<PatchTrack>& track)
+void AudioFlinger::PlaybackThread::deletePatchTrack(const sp<IAfPatchTrack>& track)
{
Mutex::Autolock _l(mLock);
destroyTrack_l(track);
@@ -5295,7 +5296,7 @@
// prepareTracks_l() must be called with ThreadBase::mLock held
AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTracks_l(
- Vector< sp<Track> > *tracksToRemove)
+ Vector<sp<IAfTrack>>* tracksToRemove)
{
// clean up deleted track ids in AudioMixer before allocating new tracks
(void)mTracks.processDeletedTrackIds([this](int trackId) {
@@ -5371,23 +5372,23 @@
// tallyUnderrunFrames() is called to update the track counters
// with the number of underrun frames for a particular mixer period.
// We defer tallying until we know the final mixer status.
- void tallyUnderrunFrames(const sp<Track>& track, size_t underrunFrames) {
+ void tallyUnderrunFrames(const sp<IAfTrack>& track, size_t underrunFrames) {
mUnderrunFrames.emplace_back(track, underrunFrames);
}
private:
const mixer_state * const mMixerStatus;
ThreadMetrics * const mThreadMetrics;
- std::vector<std::pair<sp<Track>, size_t>> mUnderrunFrames;
+ std::vector<std::pair<sp<IAfTrack>, size_t>> mUnderrunFrames;
} deferredOperations(&mixerStatus, &mThreadMetrics);
// implicit nested scope for variable capture
bool noFastHapticTrack = true;
for (size_t i=0 ; i<count ; i++) {
- const sp<Track> t = mActiveTracks[i];
+ const sp<IAfTrack> t = mActiveTracks[i];
// this const just means the local variable doesn't change
- Track* const track = t.get();
+ IAfTrack* const track = t.get();
// process fast tracks
if (track->isFastTrack()) {
@@ -5405,7 +5406,7 @@
// The converse, of removing an (active) track and then creating a new track
// at the identical fast mixer slot within the same normal mix cycle,
// is impossible because the slot isn't marked available until the end of each cycle.
- int j = track->mFastIndex;
+ int j = track->fastIndex();
ALOG_ASSERT(0 < j && j < (int)FastMixerState::sMaxFastTracks);
ALOG_ASSERT(!(mFastTrackAvailMask & (1 << j)));
FastTrack *fastTrack = &state->mFastTracks[j];
@@ -5415,13 +5416,13 @@
FastTrackDump *ftDump = &mFastMixerDumpState.mTracks[j];
FastTrackUnderruns underruns = ftDump->mUnderruns;
uint32_t recentFull = (underruns.mBitFields.mFull -
- track->mObservedUnderruns.mBitFields.mFull) & UNDERRUN_MASK;
+ track->fastTrackUnderruns().mBitFields.mFull) & UNDERRUN_MASK;
uint32_t recentPartial = (underruns.mBitFields.mPartial -
- track->mObservedUnderruns.mBitFields.mPartial) & UNDERRUN_MASK;
+ track->fastTrackUnderruns().mBitFields.mPartial) & UNDERRUN_MASK;
uint32_t recentEmpty = (underruns.mBitFields.mEmpty -
- track->mObservedUnderruns.mBitFields.mEmpty) & UNDERRUN_MASK;
+ track->fastTrackUnderruns().mBitFields.mEmpty) & UNDERRUN_MASK;
uint32_t recentUnderruns = recentPartial + recentEmpty;
- track->mObservedUnderruns = underruns;
+ track->fastTrackUnderruns() = underruns;
// don't count underruns that occur while stopping or pausing
// or stopped which can occur when flush() is called while active
size_t underrunFrames = 0;
@@ -5431,30 +5432,30 @@
underrunFrames = recentUnderruns * mFrameCount;
}
// Immediately account for FastTrack underruns.
- track->mAudioTrackServerProxy->tallyUnderrunFrames(underrunFrames);
+ track->audioTrackServerProxy()->tallyUnderrunFrames(underrunFrames);
// This is similar to the state machine for normal tracks,
// with a few modifications for fast tracks.
bool isActive = true;
- switch (track->mState) {
- case TrackBase::STOPPING_1:
+ switch (track->state()) {
+ case IAfTrackBase::STOPPING_1:
// track stays active in STOPPING_1 state until first underrun
if (recentUnderruns > 0 || track->isTerminated()) {
- track->mState = TrackBase::STOPPING_2;
+ track->setState(IAfTrackBase::STOPPING_2);
}
break;
- case TrackBase::PAUSING:
+ case IAfTrackBase::PAUSING:
// ramp down is not yet implemented
track->setPaused();
break;
- case TrackBase::RESUMING:
+ case IAfTrackBase::RESUMING:
// ramp up is not yet implemented
- track->mState = TrackBase::ACTIVE;
+ track->setState(IAfTrackBase::ACTIVE);
break;
- case TrackBase::ACTIVE:
+ case IAfTrackBase::ACTIVE:
if (recentFull > 0 || recentPartial > 0) {
// track has provided at least some frames recently: reset retry count
- track->mRetryCount = kMaxTrackRetries;
+ track->retryCount() = kMaxTrackRetries;
}
if (recentUnderruns == 0) {
// no recent underruns: stay active
@@ -5468,7 +5469,7 @@
break;
}
// there has recently been an "empty" underrun: decrement the retry counter
- if (--(track->mRetryCount) > 0) {
+ if (--(track->retryCount()) > 0) {
break;
}
// indicate to client process that the track was disabled because of underrun;
@@ -5479,10 +5480,10 @@
break;
}
FALLTHROUGH_INTENDED;
- case TrackBase::STOPPING_2:
- case TrackBase::PAUSED:
- case TrackBase::STOPPED:
- case TrackBase::FLUSHED: // flush() while active
+ case IAfTrackBase::STOPPING_2:
+ case IAfTrackBase::PAUSED:
+ case IAfTrackBase::STOPPED:
+ case IAfTrackBase::FLUSHED: // flush() while active
// Check for presentation complete if track is inactive
// We have consumed all the buffers of this track.
// This would be incomplete if we auto-paused on underrun
@@ -5499,7 +5500,7 @@
}
}
if (track->isStopping_2()) {
- track->mState = TrackBase::STOPPED;
+ track->setState(IAfTrackBase::STOPPED);
}
if (track->isStopped()) {
// Can't reset directly, as fast mixer is still polling this track
@@ -5509,20 +5510,20 @@
}
isActive = false;
break;
- case TrackBase::IDLE:
+ case IAfTrackBase::IDLE:
default:
- LOG_ALWAYS_FATAL("unexpected track state %d", (int)track->mState);
+ LOG_ALWAYS_FATAL("unexpected track state %d", (int)track->state());
}
if (isActive) {
// was it previously inactive?
if (!(state->mTrackMask & (1 << j))) {
- ExtendedAudioBufferProvider *eabp = track;
- VolumeProvider *vp = track;
+ ExtendedAudioBufferProvider *eabp = track->asExtendedAudioBufferProvider();
+ VolumeProvider *vp = track->asVolumeProvider();
fastTrack->mBufferProvider = eabp;
fastTrack->mVolumeProvider = vp;
- fastTrack->mChannelMask = track->mChannelMask;
- fastTrack->mFormat = track->mFormat;
+ fastTrack->mChannelMask = track->channelMask();
+ fastTrack->mFormat = track->format();
fastTrack->mHapticPlaybackEnabled = track->getHapticPlaybackEnabled();
fastTrack->mHapticIntensity = track->getHapticIntensity();
fastTrack->mHapticMaxAmplitude = track->getHapticMaxAmplitude();
@@ -5531,7 +5532,7 @@
didModify = true;
// no acknowledgement required for newly active tracks
}
- sp<AudioTrackServerProxy> proxy = track->mAudioTrackServerProxy;
+ sp<AudioTrackServerProxy> proxy = track->audioTrackServerProxy();
float volume;
if (track->isPlaybackRestricted() || mStreamTypes[track->streamType()].mute) {
volume = 0.f;
@@ -5546,7 +5547,7 @@
const float vh = track->getVolumeHandler()->getVolume(
proxy->framesReleased()).first;
volume *= vh;
- track->mCachedVolume = volume;
+ track->setCachedVolume(volume);
gain_minifloat_packed_t vlr = proxy->getVolumeLR();
float vlf = float_from_gain(gain_minifloat_unpack_left(vlr));
float vrf = float_from_gain(gain_minifloat_unpack_right(vlr));
@@ -5582,13 +5583,13 @@
// TODO Remove the ALOGW when this theory is confirmed.
ALOGW("fast track %d should have been active; "
"mState=%d, mTrackMask=%#x, recentUnderruns=%u, isShared=%d",
- j, (int)track->mState, state->mTrackMask, recentUnderruns,
+ j, (int)track->state(), state->mTrackMask, recentUnderruns,
track->sharedBuffer() != 0);
// Since the FastMixer state already has the track inactive, do nothing here.
}
tracksToRemove->add(track);
// Avoids a misleading display in dumpsys
- track->mObservedUnderruns.mBitFields.mMostRecent = UNDERRUN_FULL;
+ track->fastTrackUnderruns().mBitFields.mMostRecent = UNDERRUN_FULL;
}
if (fastTrack->mHapticPlaybackEnabled != track->getHapticPlaybackEnabled()) {
fastTrack->mHapticPlaybackEnabled = track->getHapticPlaybackEnabled();
@@ -5610,14 +5611,14 @@
if (!mAudioMixer->exists(trackId)) {
status_t status = mAudioMixer->create(
trackId,
- track->mChannelMask,
- track->mFormat,
- track->mSessionId);
+ track->channelMask(),
+ track->format(),
+ track->sessionId());
if (status != OK) {
ALOGW("%s(): AudioMixer cannot create track(%d)"
" mask %#x, format %#x, sessionId %d",
__func__, trackId,
- track->mChannelMask, track->mFormat, track->mSessionId);
+ track->channelMask(), track->format(), track->sessionId());
tracksToRemove->add(track);
track->invalidate(); // consider it dead.
continue;
@@ -5630,8 +5631,8 @@
// hence the test on (mMixerStatus == MIXER_TRACKS_READY) meaning the track was mixed
// during last round
size_t desiredFrames;
- const uint32_t sampleRate = track->mAudioTrackServerProxy->getSampleRate();
- const AudioPlaybackRate playbackRate = track->mAudioTrackServerProxy->getPlaybackRate();
+ const uint32_t sampleRate = track->audioTrackServerProxy()->getSampleRate();
+ const AudioPlaybackRate playbackRate = track->audioTrackServerProxy()->getPlaybackRate();
desiredFrames = sourceFramesNeededWithTimestretch(
sampleRate, mNormalFrameCount, mSampleRate, playbackRate.mSpeed);
@@ -5681,11 +5682,11 @@
int param = AudioMixer::VOLUME;
- if (track->mFillingUpStatus == Track::FS_FILLED) {
+ if (track->fillingStatus() == IAfTrack::FS_FILLED) {
// no ramp for the first volume setting
- track->mFillingUpStatus = Track::FS_ACTIVE;
- if (track->mState == TrackBase::RESUMING) {
- track->mState = TrackBase::ACTIVE;
+ track->fillingStatus() = IAfTrack::FS_ACTIVE;
+ if (track->state() == IAfTrackBase::RESUMING) {
+ track->setState(IAfTrackBase::ACTIVE);
// If a new track is paused immediately after start, do not ramp on resume.
if (cblk->mServer != 0) {
param = AudioMixer::RAMP_VOLUME;
@@ -5706,9 +5707,9 @@
// read original volumes with volume control
float v = masterVolume * mStreamTypes[track->streamType()].volume;
// Always fetch volumeshaper volume to ensure state is updated.
- const sp<AudioTrackServerProxy> proxy = track->mAudioTrackServerProxy;
+ const sp<AudioTrackServerProxy> proxy = track->audioTrackServerProxy();
const float vh = track->getVolumeHandler()->getVolume(
- track->mAudioTrackServerProxy->framesReleased()).first;
+ track->audioTrackServerProxy()->framesReleased()).first;
if (mStreamTypes[track->streamType()].mute || track->isPlaybackRestricted()) {
v = 0;
@@ -5770,18 +5771,18 @@
// Update remaining floating point volume levels
vlf = (float)vl / (1 << 24);
vrf = (float)vr / (1 << 24);
- track->mHasVolumeController = true;
+ track->setHasVolumeController(true);
} else {
// force no volume ramp when volume controller was just disabled or removed
// from effect chain to avoid volume spike
- if (track->mHasVolumeController) {
+ if (track->hasVolumeController()) {
param = AudioMixer::VOLUME;
}
- track->mHasVolumeController = false;
+ track->setHasVolumeController(false);
}
// XXX: these things DON'T need to be done each time
- mAudioMixer->setBufferProvider(trackId, track);
+ mAudioMixer->setBufferProvider(trackId, track->asExtendedAudioBufferProvider());
mAudioMixer->enable(trackId);
mAudioMixer->setParameter(trackId, param, AudioMixer::VOLUME0, &vlf);
@@ -5889,13 +5890,14 @@
trackId,
AudioMixer::TRACK,
AudioMixer::HAPTIC_INTENSITY, (void *)(uintptr_t)track->getHapticIntensity());
+ const float hapticMaxAmplitude = track->getHapticMaxAmplitude();
mAudioMixer->setParameter(
trackId,
AudioMixer::TRACK,
- AudioMixer::HAPTIC_MAX_AMPLITUDE, (void *)(&(track->mHapticMaxAmplitude)));
+ AudioMixer::HAPTIC_MAX_AMPLITUDE, (void *)&hapticMaxAmplitude);
// reset retry count
- track->mRetryCount = kMaxTrackRetries;
+ track->retryCount() = kMaxTrackRetries;
// If one track is ready, set the mixer ready if:
// - the mixer was not ready during previous round OR
@@ -5947,7 +5949,7 @@
} else {
// No buffers for this track. Give it a few chances to
// fill a buffer, then remove it from active list.
- if (--(track->mRetryCount) <= 0) {
+ if (--(track->retryCount()) <= 0) {
ALOGI("BUFFER TIMEOUT: remove(%d) from active list on thread %p",
trackId, this);
tracksToRemove->add(track);
@@ -6023,7 +6025,7 @@
size_t i = __builtin_ctz(resetMask);
ALOG_ASSERT(i < count);
resetMask &= ~(1 << i);
- sp<Track> track = mActiveTracks[i];
+ sp<IAfTrack> track = mActiveTracks[i];
ALOG_ASSERT(track->isFastTrack() && track->isStopped());
track->reset();
}
@@ -6215,14 +6217,14 @@
const int trackId = track->id();
const status_t createStatus = mAudioMixer->create(
trackId,
- track->mChannelMask,
- track->mFormat,
- track->mSessionId);
+ track->channelMask(),
+ track->format(),
+ track->sessionId());
ALOGW_IF(createStatus != NO_ERROR,
"%s(): AudioMixer cannot create track(%d)"
" mask %#x, format %#x, sessionId %d",
__func__,
- trackId, track->mChannelMask, track->mFormat, track->mSessionId);
+ trackId, track->channelMask(), track->format(), track->sessionId());
}
sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED);
}
@@ -6426,12 +6428,12 @@
}
}
-void AudioFlinger::DirectOutputThread::processVolume_l(Track *track, bool lastTrack)
+void AudioFlinger::DirectOutputThread::processVolume_l(IAfTrack *track, bool lastTrack)
{
float left, right;
// Ensure volumeshaper state always advances even when muted.
- const sp<AudioTrackServerProxy> proxy = track->mAudioTrackServerProxy;
+ const sp<AudioTrackServerProxy> proxy = track->audioTrackServerProxy();
const size_t framesReleased = proxy->framesReleased();
const int64_t frames = mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL];
@@ -6507,8 +6509,8 @@
void AudioFlinger::DirectOutputThread::onAddNewTrack_l()
{
- sp<Track> previousTrack = mPreviousTrack.promote();
- sp<Track> latestTrack = mActiveTracks.getLatest();
+ sp<IAfTrack> previousTrack = mPreviousTrack.promote();
+ sp<IAfTrack> latestTrack = mActiveTracks.getLatest();
if (previousTrack != 0 && latestTrack != 0) {
if (mType == DIRECT) {
@@ -6531,7 +6533,7 @@
}
AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prepareTracks_l(
- Vector< sp<Track> > *tracksToRemove
+ Vector<sp<IAfTrack>>* tracksToRemove
)
{
size_t count = mActiveTracks.size();
@@ -6540,14 +6542,14 @@
bool doHwResume = false;
// find out which tracks need to be processed
- for (const sp<Track> &t : mActiveTracks) {
+ for (const sp<IAfTrack>& t : mActiveTracks) {
if (t->isInvalid()) {
ALOGW("An invalidated track shouldn't be in active list");
tracksToRemove->add(t);
continue;
}
- Track* const track = t.get();
+ IAfTrack* const track = t.get();
#ifdef VERY_VERY_VERBOSE_LOGGING
audio_track_cblk_t* cblk = track->cblk();
#endif
@@ -6555,7 +6557,7 @@
// In theory an older track could underrun and restart after the new one starts
// but as we only care about the transition phase between two tracks on a
// direct output, it is not a problem to ignore the underrun case.
- sp<Track> l = mActiveTracks.getLatest();
+ sp<IAfTrack> l = mActiveTracks.getLatest();
bool last = l.get() == track;
if (track->isPausePending()) {
@@ -6591,8 +6593,8 @@
// for all its buffers to be filled before processing it.
// Allow draining the buffer in case the client
// app does not call stop() and relies on underrun to stop:
- // hence the test on (track->mRetryCount > 1).
- // If track->mRetryCount <= 1 then track is about to be disabled, paused, removed,
+ // hence the test on (track->retryCount() > 1).
+ // If track->retryCount() <= 1 then track is about to be disabled, paused, removed,
// so we accept any nonzero amount of data delivered by the AudioTrack (which will
// reset the retry counter).
// Do not use a high threshold for compressed audio.
@@ -6604,7 +6606,7 @@
const int32_t retryThreshold = targetRetryCount > 2 ? targetRetryCount - 1 : 1;
uint32_t minFrames;
if ((track->sharedBuffer() == 0) && !track->isStopping_1() && !track->isPausing()
- && (track->mRetryCount > retryThreshold) && audio_has_proportional_frames(mFormat)) {
+ && (track->retryCount() > retryThreshold) && audio_has_proportional_frames(mFormat)) {
minFrames = mNormalFrameCount;
} else {
minFrames = 1;
@@ -6622,8 +6624,8 @@
{
ALOGVV("track(%d) s=%08x [OK]", trackId, cblk->mServer);
- if (track->mFillingUpStatus == Track::FS_FILLED) {
- track->mFillingUpStatus = Track::FS_ACTIVE;
+ if (track->fillingStatus() == IAfTrack::FS_FILLED) {
+ track->fillingStatus() = IAfTrack::FS_ACTIVE;
if (last) {
// make sure processVolume_l() will apply new volume even if 0
mLeftVolFloat = mRightVolFloat = -1.0;
@@ -6636,7 +6638,7 @@
// compute volume for this track
processVolume_l(track, last);
if (last) {
- sp<Track> previousTrack = mPreviousTrack.promote();
+ sp<IAfTrack> previousTrack = mPreviousTrack.promote();
if (previousTrack != 0) {
if (track != previousTrack.get()) {
// Flush any data still being written from last track
@@ -6648,7 +6650,7 @@
mPreviousTrack = track;
// reset retry count
- track->mRetryCount = targetRetryCount;
+ track->retryCount() = targetRetryCount;
mActiveTrack = t;
mixerStatus = MIXER_TRACKS_READY;
if (mHwPaused) {
@@ -6663,7 +6665,7 @@
mEffectChains[0]->clearInputBuffer();
}
if (track->isStopping_1()) {
- track->mState = TrackBase::STOPPING_2;
+ track->setState(IAfTrackBase::STOPPING_2);
if (last && mHwPaused) {
doHwResume = true;
mHwPaused = false;
@@ -6681,7 +6683,7 @@
mOutput->presentationComplete();
}
if (track->isStopping_2()) {
- track->mState = TrackBase::STOPPED;
+ track->setState(IAfTrackBase::STOPPED);
}
if (track->isStopped()) {
track->reset();
@@ -6694,9 +6696,9 @@
// Only consider last track started for mixer state control
bool isTimestampAdvancing = mIsTimestampAdvancing.check(mOutput);
if (!isTunerStream() // tuner streams remain active in underrun
- && --(track->mRetryCount) <= 0) {
+ && --(track->retryCount()) <= 0) {
if (isTimestampAdvancing) { // HAL is still playing audio, give us more time.
- track->mRetryCount = kMaxTrackRetriesOffload;
+ track->retryCount() = kMaxTrackRetriesOffload;
} else {
ALOGV("BUFFER TIMEOUT: remove track(%d) from active list", trackId);
tracksToRemove->add(track);
@@ -6824,7 +6826,7 @@
if (mTracks.size() > 0) {
trackPaused = mTracks[mTracks.size() - 1]->isPaused();
trackStopped = mTracks[mTracks.size() - 1]->isStopped() ||
- mTracks[mTracks.size() - 1]->mState == TrackBase::IDLE;
+ mTracks[mTracks.size() - 1]->state() == IAfTrackBase::IDLE;
}
return !mStandby && !(trackPaused || (mHwPaused && !trackStopped));
@@ -7086,7 +7088,7 @@
}
AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTracks_l(
- Vector< sp<Track> > *tracksToRemove
+ Vector<sp<IAfTrack>>* tracksToRemove
)
{
size_t count = mActiveTracks.size();
@@ -7098,8 +7100,8 @@
ALOGV("OffloadThread::prepareTracks_l active tracks %zu", count);
// find out which tracks need to be processed
- for (const sp<Track> &t : mActiveTracks) {
- Track* const track = t.get();
+ for (const sp<IAfTrack>& t : mActiveTracks) {
+ IAfTrack* const track = t.get();
#ifdef VERY_VERY_VERBOSE_LOGGING
audio_track_cblk_t* cblk = track->cblk();
#endif
@@ -7107,7 +7109,7 @@
// In theory an older track could underrun and restart after the new one starts
// but as we only care about the transition phase between two tracks on a
// direct output, it is not a problem to ignore the underrun case.
- sp<Track> l = mActiveTracks.getLatest();
+ sp<IAfTrack> l = mActiveTracks.getLatest();
bool last = l.get() == track;
if (track->isInvalid()) {
@@ -7116,7 +7118,7 @@
continue;
}
- if (track->mState == TrackBase::IDLE) {
+ if (track->state() == IAfTrackBase::IDLE) {
ALOGW("An idle track shouldn't be in active list");
continue;
}
@@ -7148,9 +7150,9 @@
tracksToRemove->add(track);
} else if (track->isFlushPending()) {
if (track->isStopping_1()) {
- track->mRetryCount = kMaxTrackStopRetriesOffload;
+ track->retryCount() = kMaxTrackStopRetriesOffload;
} else {
- track->mRetryCount = kMaxTrackRetriesOffload;
+ track->retryCount() = kMaxTrackRetriesOffload;
}
track->flushAck();
if (last) {
@@ -7182,8 +7184,8 @@
} else if (track->framesReady() && track->isReady() &&
!track->isPaused() && !track->isTerminated() && !track->isStopping_2()) {
ALOGVV("OffloadThread: track(%d) s=%08x [OK]", track->id(), cblk->mServer);
- if (track->mFillingUpStatus == Track::FS_FILLED) {
- track->mFillingUpStatus = Track::FS_ACTIVE;
+ if (track->fillingStatus() == IAfTrack::FS_FILLED) {
+ track->fillingStatus() = IAfTrack::FS_ACTIVE;
if (last) {
// make sure processVolume_l() will apply new volume even if 0
mLeftVolFloat = mRightVolFloat = -1.0;
@@ -7191,7 +7193,7 @@
}
if (last) {
- sp<Track> previousTrack = mPreviousTrack.promote();
+ sp<IAfTrack> previousTrack = mPreviousTrack.promote();
if (previousTrack != 0) {
if (track != previousTrack.get()) {
// Flush any data still being written from last track
@@ -7217,9 +7219,9 @@
mPreviousTrack = track;
// reset retry count
if (track->isStopping_1()) {
- track->mRetryCount = kMaxTrackStopRetriesOffload;
+ track->retryCount() = kMaxTrackStopRetriesOffload;
} else {
- track->mRetryCount = kMaxTrackRetriesOffload;
+ track->retryCount() = kMaxTrackRetriesOffload;
}
mActiveTrack = t;
mixerStatus = MIXER_TRACKS_READY;
@@ -7227,7 +7229,7 @@
} else {
ALOGVV("OffloadThread: track(%d) s=%08x [NOT READY]", track->id(), cblk->mServer);
if (track->isStopping_1()) {
- if (--(track->mRetryCount) <= 0) {
+ if (--(track->retryCount()) <= 0) {
// Hardware buffer can hold a large amount of audio so we must
// wait for all current track's data to drain before we say
// that the track is stopped.
@@ -7235,7 +7237,8 @@
// Only start draining when all data in mixbuffer
// has been written
ALOGV("OffloadThread: underrun and STOPPING_1 -> draining, STOPPING_2");
- track->mState = TrackBase::STOPPING_2; // so presentation completes after
+ track->setState(IAfTrackBase::STOPPING_2);
+ // so presentation completes after
// drain do not drain if no data was ever sent to HAL (mStandby == true)
if (last && !mStandby) {
// do not modify drain sequence if we are already draining. This happens
@@ -7255,13 +7258,13 @@
}
}
} else if (last) {
- ALOGV("stopping1 underrun retries left %d", track->mRetryCount);
+ ALOGV("stopping1 underrun retries left %d", track->retryCount());
mixerStatus = MIXER_TRACKS_ENABLED;
}
} else if (track->isStopping_2()) {
// Drain has completed or we are in standby, signal presentation complete
if (!(mDrainSequence & 1) || !last || mStandby) {
- track->mState = TrackBase::STOPPED;
+ track->setState(IAfTrackBase::STOPPED);
mOutput->presentationComplete();
track->presentationComplete(latency_l()); // always returns true
track->reset();
@@ -7281,9 +7284,9 @@
// fill a buffer, then remove it from active list.
bool isTimestampAdvancing = mIsTimestampAdvancing.check(mOutput);
if (!isTunerStream() // tuner streams remain active in underrun
- && --(track->mRetryCount) <= 0) {
+ && --(track->retryCount()) <= 0) {
if (isTimestampAdvancing) { // HAL is still playing audio, give us more time.
- track->mRetryCount = kMaxTrackRetriesOffload;
+ track->retryCount() = kMaxTrackRetriesOffload;
} else {
ALOGV("OffloadThread: BUFFER TIMEOUT: remove track(%d) from active list",
track->id());
@@ -7526,7 +7529,7 @@
attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(
IPCThreadState::self()->getCallingPid()));
attributionSource.token = sp<BBinder>::make();
- sp<OutputTrack> outputTrack = new OutputTrack(thread,
+ sp<IAfOutputTrack> outputTrack = IAfOutputTrack::create(thread,
this,
mSampleRate,
mFormat,
@@ -7939,7 +7942,7 @@
ALOGV(" preExit()");
Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mTracks.size(); i++) {
- sp<RecordTrack> track = mTracks[i];
+ sp<IAfRecordTrack> track = mTracks[i];
track->invalidate();
}
mActiveTracks.clear();
@@ -7953,7 +7956,7 @@
inputStandBy();
reacquire_wakelock:
- sp<RecordTrack> activeTrack;
+ sp<IAfRecordTrack> activeTrack;
{
Mutex::Autolock _l(mLock);
acquireWakeLock_l();
@@ -7969,13 +7972,13 @@
Vector<sp<IAfEffectChain>> effectChains;
// activeTracks accumulates a copy of a subset of mActiveTracks
- Vector< sp<RecordTrack> > activeTracks;
+ Vector<sp<IAfRecordTrack>> activeTracks;
// reference to the (first and only) active fast track
- sp<RecordTrack> fastTrack;
+ sp<IAfRecordTrack> fastTrack;
// reference to a fast track which is about to be removed
- sp<RecordTrack> fastTrackToRemove;
+ sp<IAfRecordTrack> fastTrackToRemove;
bool silenceFastCapture = false;
@@ -8028,40 +8031,40 @@
continue;
}
- TrackBase::track_state activeTrackState = activeTrack->mState;
+ IAfTrackBase::track_state activeTrackState = activeTrack->state();
switch (activeTrackState) {
- case TrackBase::PAUSING:
+ case IAfTrackBase::PAUSING:
mActiveTracks.remove(activeTrack);
- activeTrack->mState = TrackBase::PAUSED;
+ activeTrack->setState(IAfTrackBase::PAUSED);
doBroadcast = true;
size--;
continue;
- case TrackBase::STARTING_1:
+ case IAfTrackBase::STARTING_1:
sleepUs = 10000;
i++;
allStopped = false;
continue;
- case TrackBase::STARTING_2:
+ case IAfTrackBase::STARTING_2:
doBroadcast = true;
if (mStandby) {
mThreadMetrics.logBeginInterval();
mThreadSnapshot.onBegin();
mStandby = false;
}
- activeTrack->mState = TrackBase::ACTIVE;
+ activeTrack->setState(IAfTrackBase::ACTIVE);
allStopped = false;
break;
- case TrackBase::ACTIVE:
+ case IAfTrackBase::ACTIVE:
allStopped = false;
break;
- case TrackBase::IDLE: // cannot be on ActiveTracks if idle
- case TrackBase::PAUSED: // cannot be on ActiveTracks if paused
- case TrackBase::STOPPED: // cannot be on ActiveTracks if destroyed/terminated
+ case IAfTrackBase::IDLE: // cannot be on ActiveTracks if idle
+ case IAfTrackBase::PAUSED: // cannot be on ActiveTracks if paused
+ case IAfTrackBase::STOPPED: // cannot be on ActiveTracks if destroyed/terminated
default:
LOG_ALWAYS_FATAL("%s: Unexpected active track state:%d, id:%d, tracks:%zu",
__func__, activeTrackState, activeTrack->id(), size);
@@ -8308,7 +8311,7 @@
// From the timestamp, input read latency is negative output write latency.
const audio_input_flags_t flags = mInput != NULL ? mInput->flags : AUDIO_INPUT_FLAG_NONE;
- const double latencyMs = RecordTrack::checkServerLatencySupported(mFormat, flags)
+ const double latencyMs = IAfRecordTrack::checkServerLatencySupported(mFormat, flags)
? - mTimestamp.getOutputServerLatencyMs(mSampleRate) : 0.;
if (latencyMs != 0.) { // note 0. means timestamp is empty.
mLatencyMs.add(latencyMs);
@@ -8365,16 +8368,16 @@
// loop over getNextBuffer to handle circular sink
for (;;) {
- activeTrack->mSink.frameCount = ~0;
- status_t status = activeTrack->getNextBuffer(&activeTrack->mSink);
- size_t framesOut = activeTrack->mSink.frameCount;
+ activeTrack->sinkBuffer().frameCount = ~0;
+ status_t status = activeTrack->getNextBuffer(&activeTrack->sinkBuffer());
+ size_t framesOut = activeTrack->sinkBuffer().frameCount;
LOG_ALWAYS_FATAL_IF((status == OK) != (framesOut > 0));
// check available frames and handle overrun conditions
// if the record track isn't draining fast enough.
bool hasOverrun;
size_t framesIn;
- activeTrack->mResamplerBufferProvider->sync(&framesIn, &hasOverrun);
+ activeTrack->resamplerBufferProvider()->sync(&framesIn, &hasOverrun);
if (hasOverrun) {
overrun = OVERRUN_TRUE;
}
@@ -8388,7 +8391,7 @@
// RecordBufferConverter. TODO: remove when no longer needed.
framesOut = min(framesOut,
destinationFramesPossible(
- framesIn, mSampleRate, activeTrack->mSampleRate));
+ framesIn, mSampleRate, activeTrack->sampleRate()));
if (activeTrack->isDirect()) {
// No RecordBufferConverter used for direct streams. Pass
@@ -8396,14 +8399,15 @@
AudioBufferProvider::Buffer buffer;
buffer.frameCount = framesOut;
const status_t getNextBufferStatus =
- activeTrack->mResamplerBufferProvider->getNextBuffer(&buffer);
+ activeTrack->resamplerBufferProvider()->getNextBuffer(&buffer);
if (getNextBufferStatus == OK && buffer.frameCount != 0) {
ALOGV_IF(buffer.frameCount != framesOut,
"%s() read less than expected (%zu vs %zu)",
__func__, buffer.frameCount, framesOut);
framesOut = buffer.frameCount;
- memcpy(activeTrack->mSink.raw, buffer.raw, buffer.frameCount * mFrameSize);
- activeTrack->mResamplerBufferProvider->releaseBuffer(&buffer);
+ memcpy(activeTrack->sinkBuffer().raw,
+ buffer.raw, buffer.frameCount * mFrameSize);
+ activeTrack->resamplerBufferProvider()->releaseBuffer(&buffer);
} else {
framesOut = 0;
ALOGE("%s() cannot fill request, status: %d, frameCount: %zu",
@@ -8412,9 +8416,9 @@
} else {
// process frames from the RecordThread buffer provider to the RecordTrack
// buffer
- framesOut = activeTrack->mRecordBufferConverter->convert(
- activeTrack->mSink.raw,
- activeTrack->mResamplerBufferProvider,
+ framesOut = activeTrack->recordBufferConverter()->convert(
+ activeTrack->sinkBuffer().raw,
+ activeTrack->resamplerBufferProvider(),
framesOut);
}
@@ -8424,17 +8428,18 @@
// MediaSyncEvent handling: Synchronize AudioRecord to AudioTrack completion.
const ssize_t framesToDrop =
- activeTrack->mSynchronizedRecordState.updateRecordFrames(framesOut);
+ activeTrack->synchronizedRecordState().updateRecordFrames(framesOut);
if (framesToDrop == 0) {
// no sync event, process normally, otherwise ignore.
if (framesOut > 0) {
- activeTrack->mSink.frameCount = framesOut;
+ activeTrack->sinkBuffer().frameCount = framesOut;
// Sanitize before releasing if the track has no access to the source data
// An idle UID receives silence from non virtual devices until active
if (activeTrack->isSilenced()) {
- memset(activeTrack->mSink.raw, 0, framesOut * activeTrack->frameSize());
+ memset(activeTrack->sinkBuffer().raw,
+ 0, framesOut * activeTrack->frameSize());
}
- activeTrack->releaseBuffer(&activeTrack->mSink);
+ activeTrack->releaseBuffer(&activeTrack->sinkBuffer());
}
}
if (framesOut == 0) {
@@ -8463,7 +8468,7 @@
// update frame information and push timestamp out
activeTrack->updateTrackFrameInfo(
- activeTrack->mServerProxy->framesReleased(),
+ activeTrack->serverProxy()->framesReleased(),
mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER],
mSampleRate, mTimestamp);
}
@@ -8496,7 +8501,7 @@
{
Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mTracks.size(); i++) {
- sp<RecordTrack> track = mTracks[i];
+ sp<IAfRecordTrack> track = mTracks[i];
track->invalidate();
}
mActiveTracks.clear();
@@ -8560,7 +8565,7 @@
}
// RecordThread::createRecordTrack_l() must be called with AudioFlinger::mLock held
-sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createRecordTrack_l(
+sp<IAfRecordTrack> AudioFlinger::RecordThread::createRecordTrack_l(
const sp<Client>& client,
const audio_attributes_t& attr,
uint32_t *pSampleRate,
@@ -8579,7 +8584,7 @@
{
size_t frameCount = *pFrameCount;
size_t notificationFrameCount = *pNotificationFrameCount;
- sp<RecordTrack> track;
+ sp<IAfRecordTrack> track;
status_t lStatus;
audio_input_flags_t inputFlags = mInput->flags;
audio_input_flags_t requestedFlags = *flags;
@@ -8725,10 +8730,10 @@
startFrames = mSharedAudioStartFrames;
}
- track = new RecordTrack(this, client, attr, sampleRate,
+ track = IAfRecordTrack::create(this, client, attr, sampleRate,
format, channelMask, frameCount,
nullptr /* buffer */, (size_t)0 /* bufferSize */, sessionId, creatorPid,
- attributionSource, *flags, TrackBase::TYPE_DEFAULT, portId,
+ attributionSource, *flags, IAfTrackBase::TYPE_DEFAULT, portId,
startFrames);
lStatus = track->initCheck();
@@ -8758,7 +8763,7 @@
return track;
}
-status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrack,
+status_t AudioFlinger::RecordThread::start(IAfRecordTrack* recordTrack,
AudioSystem::sync_event_t event,
audio_session_t triggerSession)
{
@@ -8769,7 +8774,7 @@
if (event == AudioSystem::SYNC_EVENT_NONE) {
recordTrack->clearSyncStartEvent();
} else if (event != AudioSystem::SYNC_EVENT_SAME) {
- recordTrack->mSynchronizedRecordState.startRecording(
+ recordTrack->synchronizedRecordState().startRecording(
mAudioFlinger->createSyncEvent(
event, triggerSession,
recordTrack->sessionId(), syncStartEventCallback, recordTrack));
@@ -8784,13 +8789,13 @@
return DEAD_OBJECT;
}
if (mActiveTracks.indexOf(recordTrack) >= 0) {
- if (recordTrack->mState == TrackBase::PAUSING) {
+ if (recordTrack->state() == IAfTrackBase::PAUSING) {
// We haven't stopped yet (moved to PAUSED and not in mActiveTracks)
// so no need to startInput().
ALOGV("active record track PAUSING -> ACTIVE");
- recordTrack->mState = TrackBase::ACTIVE;
+ recordTrack->setState(IAfTrackBase::ACTIVE);
} else {
- ALOGV("active record track state %d", (int)recordTrack->mState);
+ ALOGV("active record track state %d", (int)recordTrack->state());
}
return status;
}
@@ -8798,7 +8803,7 @@
// TODO consider other ways of handling this, such as changing the state to :STARTING and
// adding the track to mActiveTracks after returning from AudioSystem::startInput(),
// or using a separate command thread
- recordTrack->mState = TrackBase::STARTING_1;
+ recordTrack->setState(IAfTrackBase::STARTING_1);
mActiveTracks.add(recordTrack);
if (recordTrack->isExternalTrack()) {
mLock.unlock();
@@ -8806,16 +8811,16 @@
mLock.lock();
if (recordTrack->isInvalid()) {
recordTrack->clearSyncStartEvent();
- if (status == NO_ERROR && recordTrack->mState == TrackBase::STARTING_1) {
- recordTrack->mState = TrackBase::STARTING_2;
+ if (status == NO_ERROR && recordTrack->state() == IAfTrackBase::STARTING_1) {
+ recordTrack->setState(IAfTrackBase::STARTING_2);
// STARTING_2 forces destroy to call stopInput.
}
ALOGW("%s track %d: invalidated after startInput", __func__, recordTrack->portId());
return DEAD_OBJECT;
}
- if (recordTrack->mState != TrackBase::STARTING_1) {
+ if (recordTrack->state() != IAfTrackBase::STARTING_1) {
ALOGW("%s(%d): unsynchronized mState:%d change",
- __func__, recordTrack->id(), (int)recordTrack->mState);
+ __func__, recordTrack->id(), (int)recordTrack->state());
// Someone else has changed state, let them take over,
// leave mState in the new state.
recordTrack->clearSyncStartEvent();
@@ -8842,12 +8847,12 @@
// was initialized to some value closer to the thread's mRsmpInFront, then the track could
// see previously buffered data before it called start(), but with greater risk of overrun.
- recordTrack->mResamplerBufferProvider->reset();
+ recordTrack->resamplerBufferProvider()->reset();
if (!recordTrack->isDirect()) {
// clear any converter state as new data will be discontinuous
- recordTrack->mRecordBufferConverter->reset();
+ recordTrack->recordBufferConverter()->reset();
}
- recordTrack->mState = TrackBase::STARTING_2;
+ recordTrack->setState(IAfTrackBase::STARTING_2);
// signal thread to start
mWaitWorkCV.broadcast();
return status;
@@ -8868,31 +8873,31 @@
}
}
-bool AudioFlinger::RecordThread::stop(RecordThread::RecordTrack* recordTrack) {
+bool AudioFlinger::RecordThread::stop(IAfRecordTrack* recordTrack) {
ALOGV("RecordThread::stop");
AutoMutex _l(mLock);
// if we're invalid, we can't be on the ActiveTracks.
- if (mActiveTracks.indexOf(recordTrack) < 0 || recordTrack->mState == TrackBase::PAUSING) {
+ if (mActiveTracks.indexOf(recordTrack) < 0 || recordTrack->state() == IAfTrackBase::PAUSING) {
return false;
}
// note that threadLoop may still be processing the track at this point [without lock]
- recordTrack->mState = TrackBase::PAUSING;
+ recordTrack->setState(IAfTrackBase::PAUSING);
// NOTE: Waiting here is important to keep stop synchronous.
// This is needed for proper patchRecord peer release.
- while (recordTrack->mState == TrackBase::PAUSING && !recordTrack->isInvalid()) {
+ while (recordTrack->state() == IAfTrackBase::PAUSING && !recordTrack->isInvalid()) {
mWaitWorkCV.broadcast(); // signal thread to stop
mStartStopCond.wait(mLock);
}
- if (recordTrack->mState == TrackBase::PAUSED) { // successful stop
+ if (recordTrack->state() == IAfTrackBase::PAUSED) { // successful stop
ALOGV("Record stopped OK");
return true;
}
// don't handle anything - we've been invalidated or restarted and in a different state
ALOGW_IF("%s(%d): unsynchronized stop, state: %d",
- __func__, recordTrack->id(), recordTrack->mState);
+ __func__, recordTrack->id(), recordTrack->state());
return false;
}
@@ -8916,7 +8921,7 @@
Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mTracks.size(); i++) {
- sp<RecordTrack> track = mTracks[i];
+ sp<IAfRecordTrack> track = mTracks[i];
if (eventSession == track->sessionId()) {
(void) track->setSyncEvent(event);
ret = NO_ERROR;
@@ -9021,7 +9026,7 @@
}
StreamInHalInterface::SinkMetadata metadata;
auto backInserter = std::back_inserter(metadata.tracks);
- for (const sp<RecordTrack> &track : mActiveTracks) {
+ for (const sp<IAfRecordTrack>& track : mActiveTracks) {
track->copyMetadataTo(backInserter);
}
mInput->stream->updateSinkMetadata(metadata);
@@ -9031,10 +9036,10 @@
}
// destroyTrack_l() must be called with ThreadBase::mLock held
-void AudioFlinger::RecordThread::destroyTrack_l(const sp<RecordTrack>& track)
+void AudioFlinger::RecordThread::destroyTrack_l(const sp<IAfRecordTrack>& track)
{
track->terminate();
- track->mState = TrackBase::STOPPED;
+ track->setState(IAfTrackBase::STOPPED);
// active tracks are removed by threadLoop()
if (mActiveTracks.indexOf(track) < 0) {
@@ -9042,7 +9047,7 @@
}
}
-void AudioFlinger::RecordThread::removeTrack_l(const sp<RecordTrack>& track)
+void AudioFlinger::RecordThread::removeTrack_l(const sp<IAfRecordTrack>& track)
{
String8 result;
track->appendDump(result, false /* active */);
@@ -9097,7 +9102,7 @@
result.append(prefix);
mTracks[0]->appendDumpHeader(result);
for (size_t i = 0; i < numtracks ; ++i) {
- sp<RecordTrack> track = mTracks[i];
+ sp<IAfRecordTrack> track = mTracks[i];
if (track != 0) {
bool active = mActiveTracks.indexOf(track) >= 0;
if (active) {
@@ -9117,7 +9122,7 @@
result.append(prefix);
mActiveTracks[0]->appendDumpHeader(result);
for (size_t i = 0; i < numactive; ++i) {
- sp<RecordTrack> track = mActiveTracks[i];
+ sp<IAfRecordTrack> track = mActiveTracks[i];
if (mTracks.indexOf(track) < 0) {
result.append(prefix);
track->appendDump(result, true /* active */);
@@ -9132,17 +9137,17 @@
{
Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mTracks.size() ; i++) {
- sp<RecordTrack> track = mTracks[i];
+ sp<IAfRecordTrack> track = mTracks[i];
if (track != 0 && track->portId() == portId) {
track->setSilenced(silenced);
}
}
}
-void AudioFlinger::RecordThread::ResamplerBufferProvider::reset()
+void ResamplerBufferProvider::reset()
{
- sp<ThreadBase> threadBase = mRecordTrack->mThread.promote();
- RecordThread *recordThread = (RecordThread *) threadBase.get();
+ const auto threadBase = sp<AudioFlinger::ThreadBase>::cast(mRecordTrack->thread().promote());
+ auto* const recordThread = static_cast<AudioFlinger::RecordThread *>(threadBase.get());
mRsmpInUnrel = 0;
const int32_t rear = recordThread->mRsmpInRear;
ssize_t deltaFrames = 0;
@@ -9162,11 +9167,11 @@
mRsmpInFront = audio_utils::safe_sub_overflow(rear, static_cast<int32_t>(deltaFrames));
}
-void AudioFlinger::RecordThread::ResamplerBufferProvider::sync(
+void ResamplerBufferProvider::sync(
size_t *framesAvailable, bool *hasOverrun)
{
- sp<ThreadBase> threadBase = mRecordTrack->mThread.promote();
- RecordThread *recordThread = (RecordThread *) threadBase.get();
+ const auto threadBase = sp<AudioFlinger::ThreadBase>::cast(mRecordTrack->thread().promote());
+ auto* const recordThread = static_cast<AudioFlinger::RecordThread *>(threadBase.get());
const int32_t rear = recordThread->mRsmpInRear;
const int32_t front = mRsmpInFront;
const ssize_t filled = audio_utils::safe_sub_overflow(rear, front);
@@ -9196,16 +9201,16 @@
}
// AudioBufferProvider interface
-status_t AudioFlinger::RecordThread::ResamplerBufferProvider::getNextBuffer(
+status_t ResamplerBufferProvider::getNextBuffer(
AudioBufferProvider::Buffer* buffer)
{
- sp<ThreadBase> threadBase = mRecordTrack->mThread.promote();
+ const auto threadBase = sp<AudioFlinger::ThreadBase>::cast(mRecordTrack->thread().promote());
if (threadBase == 0) {
buffer->frameCount = 0;
buffer->raw = NULL;
return NOT_ENOUGH_DATA;
}
- RecordThread *recordThread = (RecordThread *) threadBase.get();
+ auto* const recordThread = static_cast<AudioFlinger::RecordThread *>(threadBase.get());
int32_t rear = recordThread->mRsmpInRear;
int32_t front = mRsmpInFront;
ssize_t filled = audio_utils::safe_sub_overflow(rear, front);
@@ -9239,7 +9244,7 @@
}
// AudioBufferProvider interface
-void AudioFlinger::RecordThread::ResamplerBufferProvider::releaseBuffer(
+void ResamplerBufferProvider::releaseBuffer(
AudioBufferProvider::Buffer* buffer)
{
int32_t stepCount = static_cast<int32_t>(buffer->frameCount);
@@ -9453,7 +9458,7 @@
KeyedVector<audio_session_t, bool> ids;
Mutex::Autolock _l(mLock);
for (size_t j = 0; j < mTracks.size(); ++j) {
- sp<RecordThread::RecordTrack> track = mTracks[j];
+ sp<IAfRecordTrack> track = mTracks[j];
audio_session_t sessionId = track->sessionId();
if (ids.indexOfKey(sessionId) < 0) {
ids.add(sessionId, true);
@@ -9604,7 +9609,7 @@
int32_t oldestFront = mRsmpInRear;
int32_t maxFilled = 0;
for (size_t i = 0; i < mTracks.size(); i++) {
- int32_t front = mTracks[i]->mResamplerBufferProvider->getFront();
+ int32_t front = mTracks[i]->resamplerBufferProvider()->getFront();
int32_t filled;
(void)__builtin_sub_overflow(mRsmpInRear, front, &filled);
if (filled > maxFilled) {
@@ -9624,9 +9629,9 @@
return;
}
for (size_t i = 0; i < mTracks.size(); i++) {
- int32_t front = mTracks[i]->mResamplerBufferProvider->getFront();
+ int32_t front = mTracks[i]->resamplerBufferProvider()->getFront();
front = audio_utils::safe_sub_overflow(front, offset);
- mTracks[i]->mResamplerBufferProvider->setFront(front);
+ mTracks[i]->resamplerBufferProvider()->setFront(front);
}
}
@@ -9723,7 +9728,7 @@
mRsmpInBuffer = rsmpInBuffer;
}
-void AudioFlinger::RecordThread::addPatchTrack(const sp<PatchRecord>& record)
+void AudioFlinger::RecordThread::addPatchTrack(const sp<IAfPatchRecord>& record)
{
Mutex::Autolock _l(mLock);
mTracks.add(record);
@@ -9732,7 +9737,7 @@
}
}
-void AudioFlinger::RecordThread::deletePatchTrack(const sp<PatchRecord>& record)
+void AudioFlinger::RecordThread::deletePatchTrack(const sp<IAfPatchRecord>& record)
{
Mutex::Autolock _l(mLock);
if (mSource == record->getSource()) {
@@ -9832,14 +9837,14 @@
void AudioFlinger::MmapThread::disconnect()
{
- ActiveTracks<MmapTrack> activeTracks;
+ ActiveTracks<IAfMmapTrack> activeTracks;
{
Mutex::Autolock _l(mLock);
- for (const sp<MmapTrack> &t : mActiveTracks) {
+ for (const sp<IAfMmapTrack>& t : mActiveTracks) {
activeTracks.add(t);
}
}
- for (const sp<MmapTrack> &t : activeTracks) {
+ for (const sp<IAfMmapTrack>& t : activeTracks) {
stop(t->portId());
}
// This will decrement references and may cause the destruction of this thread.
@@ -10004,7 +10009,8 @@
}
// Given that MmapThread::mAttr is mutable, should a MmapTrack have attributes ?
- sp<MmapTrack> track = new MmapTrack(this, attr == nullptr ? mAttr : *attr, mSampleRate, mFormat,
+ sp<IAfMmapTrack> track = IAfMmapTrack::create(
+ this, attr == nullptr ? mAttr : *attr, mSampleRate, mFormat,
mChannelMask, mSessionId, isOutput(),
client.attributionSource,
IPCThreadState::self()->getCallingPid(), portId);
@@ -10016,7 +10022,7 @@
// force volume update when a new track is added
mHalVolFloat = -1.0f;
} else if (!track->isSilenced_l()) {
- for (const sp<MmapTrack> &t : mActiveTracks) {
+ for (const sp<IAfMmapTrack>& t : mActiveTracks) {
if (t->isSilenced_l()
&& t->uid() != static_cast<uid_t>(client.attributionSource.uid)) {
t->invalidate();
@@ -10061,8 +10067,8 @@
Mutex::Autolock _l(mLock);
- sp<MmapTrack> track;
- for (const sp<MmapTrack> &t : mActiveTracks) {
+ sp<IAfMmapTrack> track;
+ for (const sp<IAfMmapTrack>& t : mActiveTracks) {
if (handle == t->portId()) {
track = t;
break;
@@ -10419,7 +10425,7 @@
ALOGV("addEffectChain_l() %p on thread %p for session %d", chain.get(), this, session);
// Attach all tracks with same session ID to this chain.
// indicate all active tracks in the chain
- for (const sp<MmapTrack> &track : mActiveTracks) {
+ for (const sp<IAfMmapTrack>& track : mActiveTracks) {
if (session == track->sessionId()) {
chain->incTrackCnt();
chain->incActiveTrackCnt();
@@ -10447,7 +10453,7 @@
mEffectChains.removeAt(i);
// detach all active tracks from the chain
// detach all tracks with same session ID from this chain
- for (const sp<MmapTrack> &track : mActiveTracks) {
+ for (const sp<IAfMmapTrack>& track : mActiveTracks) {
if (session == track->sessionId()) {
chain->decActiveTrackCnt();
chain->decTrackCnt();
@@ -10519,7 +10525,7 @@
NO_THREAD_SAFETY_ANALYSIS // release and re-acquire mLock
{
sp<MmapStreamCallback> callback;
- for (const sp<MmapTrack> &track : mActiveTracks) {
+ for (const sp<IAfMmapTrack>& track : mActiveTracks) {
if (track->isInvalid()) {
callback = mCallback.promote();
if (callback == nullptr && mNoCallbackWarningCount < kMaxNoCallbackWarnings) {
@@ -10556,7 +10562,7 @@
result.append(prefix);
mActiveTracks[0]->appendDumpHeader(result);
for (size_t i = 0; i < numtracks ; ++i) {
- sp<MmapTrack> track = mActiveTracks[i];
+ sp<IAfMmapTrack> track = mActiveTracks[i];
result.append(prefix);
track->appendDump(result, true /* active */);
}
@@ -10663,7 +10669,7 @@
{
Mutex::Autolock _l(mLock);
if (streamType == mStreamType) {
- for (const sp<MmapTrack> &track : mActiveTracks) {
+ for (const sp<IAfMmapTrack>& track : mActiveTracks) {
track->invalidate();
}
broadcast_l();
@@ -10674,7 +10680,7 @@
{
Mutex::Autolock _l(mLock);
bool trackMatch = false;
- for (const sp<MmapTrack> &track : mActiveTracks) {
+ for (const sp<IAfMmapTrack>& track : mActiveTracks) {
if (portIds.find(track->portId()) != portIds.end()) {
track->invalidate();
trackMatch = true;
@@ -10731,7 +10737,7 @@
}
}
}
- for (const sp<MmapTrack> &track : mActiveTracks) {
+ for (const sp<IAfMmapTrack>& track : mActiveTracks) {
track->setMetadataHasChanged();
track->processMuteEvent_l(mAudioFlinger->getOrCreateAudioManager(),
/*muteState=*/{mMasterMute,
@@ -10751,7 +10757,7 @@
return {}; // nothing to do
}
StreamOutHalInterface::SourceMetadata metadata;
- for (const sp<MmapTrack> &track : mActiveTracks) {
+ for (const sp<IAfMmapTrack>& track : mActiveTracks) {
// No track is invalid as this is called after prepareTrack_l in the same critical section
playback_track_metadata_v7_t trackMetadata;
trackMetadata.base = {
@@ -10916,7 +10922,7 @@
return {}; // nothing to do
}
StreamInHalInterface::SinkMetadata metadata;
- for (const sp<MmapTrack> &track : mActiveTracks) {
+ for (const sp<IAfMmapTrack>& track : mActiveTracks) {
// No track is invalid as this is called after prepareTrack_l in the same critical section
record_track_metadata_v7_t trackMetadata;
trackMetadata.base = {
@@ -10970,7 +10976,7 @@
: MixerThread(audioflinger, output, id, systemReady, BIT_PERFECT) {}
AudioFlinger::PlaybackThread::mixer_state AudioFlinger::BitPerfectThread::prepareTracks_l(
- Vector<sp<Track>> *tracksToRemove) {
+ Vector<sp<IAfTrack>>* tracksToRemove) {
mixer_state result = MixerThread::prepareTracks_l(tracksToRemove);
// If there is only one active track and it is bit-perfect, enable tee buffer.
float volumeLeft = 1.0f;