diff options
Diffstat (limited to 'services/audioflinger')
| -rw-r--r-- | services/audioflinger/Threads.cpp | 62 | ||||
| -rw-r--r-- | services/audioflinger/Threads.h | 7 | 
2 files changed, 45 insertions, 24 deletions
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index dc6710f..84c4fcf 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -4458,6 +4458,17 @@ void AudioFlinger::DirectOutputThread::processVolume_l(Track *track, bool lastTr      }  } +void AudioFlinger::DirectOutputThread::onAddNewTrack_l() +{ +    sp<Track> previousTrack = mPreviousTrack.promote(); +    sp<Track> latestTrack = mLatestActiveTrack.promote(); + +    if (previousTrack != 0 && latestTrack != 0 && +        (previousTrack->sessionId() != latestTrack->sessionId())) { +        mFlushPending = true; +    } +    PlaybackThread::onAddNewTrack_l(); +}  AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prepareTracks_l(      Vector< sp<Track> > *tracksToRemove @@ -4467,7 +4478,6 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep      mixer_state mixerStatus = MIXER_IDLE;      bool doHwPause = false;      bool doHwResume = false; -    bool flushPending = false;      // find out which tracks need to be processed      for (size_t i = 0; i < count; i++) { @@ -4477,6 +4487,12 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep              continue;          } +        if (t->isInvalid()) { +            ALOGW("An invalidated track shouldn't be in active list"); +            tracksToRemove->add(t); +            continue; +        } +          Track* const track = t.get();          audio_track_cblk_t* cblk = track->cblk();          // Only consider last track started for volume and mixer state control. @@ -4496,7 +4512,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep          } else if (track->isFlushPending()) {              track->flushAck();              if (last) { -                flushPending = true; +                mFlushPending = true;              }          } else if (track->isResumePending()) {              track->resumeAck(); @@ -4537,6 +4553,21 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep              // compute volume for this track              processVolume_l(track, last);              if (last) { +                sp<Track> previousTrack = mPreviousTrack.promote(); +                if (previousTrack != 0) { +                    if (track != previousTrack.get()) { +                        // Flush any data still being written from last track +                        mBytesRemaining = 0; +                        // flush data already sent if changing audio session as audio +                        // comes from a different source. Also invalidate previous track to force a +                        // seek when resuming. +                        if (previousTrack->sessionId() != track->sessionId()) { +                            previousTrack->invalidate(); +                        } +                    } +                } +                mPreviousTrack = track; +                  // reset retry count                  track->mRetryCount = kMaxTrackRetriesDirect;                  mActiveTrack = t; @@ -4603,11 +4634,11 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep      }      // if an active track did not command a flush, check for pending flush on stopped tracks -    if (!flushPending) { +    if (!mFlushPending) {          for (size_t i = 0; i < mTracks.size(); i++) {              if (mTracks[i]->isFlushPending()) {                  mTracks[i]->flushAck(); -                flushPending = true; +                mFlushPending = true;              }          }      } @@ -4617,10 +4648,10 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep      // before flush and then resume HW. This can happen in case of pause/flush/resume      // if resume is received before pause is executed.      if (mHwSupportsPause && !mStandby && -            (doHwPause || (flushPending && !mHwPaused && (count != 0)))) { +            (doHwPause || (mFlushPending && !mHwPaused && (count != 0)))) {          mOutput->stream->pause(mOutput->stream);      } -    if (flushPending) { +    if (mFlushPending) {          flushHw_l();      }      if (mHwSupportsPause && !mStandby && doHwResume) { @@ -4679,14 +4710,13 @@ void AudioFlinger::DirectOutputThread::threadLoop_exit()  {      {          Mutex::Autolock _l(mLock); -        bool flushPending = false;          for (size_t i = 0; i < mTracks.size(); i++) {              if (mTracks[i]->isFlushPending()) {                  mTracks[i]->flushAck(); -                flushPending = true; +                mFlushPending = true;              }          } -        if (flushPending) { +        if (mFlushPending) {              flushHw_l();          }      } @@ -4824,6 +4854,7 @@ void AudioFlinger::DirectOutputThread::flushHw_l()  {      mOutput->flush();      mHwPaused = false; +    mFlushPending = false;  }  // ---------------------------------------------------------------------------- @@ -5145,7 +5176,6 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr      }      if (mFlushPending) {          flushHw_l(); -        mFlushPending = false;      }      if (!mStandby && doHwResume) {          mOutput->stream->resume(mOutput->stream); @@ -5193,18 +5223,6 @@ void AudioFlinger::OffloadThread::flushHw_l()      }  } -void AudioFlinger::OffloadThread::onAddNewTrack_l() -{ -    sp<Track> previousTrack = mPreviousTrack.promote(); -    sp<Track> latestTrack = mLatestActiveTrack.promote(); - -    if (previousTrack != 0 && latestTrack != 0 && -        (previousTrack->sessionId() != latestTrack->sessionId())) { -        mFlushPending = true; -    } -    PlaybackThread::onAddNewTrack_l(); -} -  // ----------------------------------------------------------------------------  AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger, diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h index 7b4fb14..4ebe615 100644 --- a/services/audioflinger/Threads.h +++ b/services/audioflinger/Threads.h @@ -941,6 +941,8 @@ protected:      virtual     void        threadLoop_exit();      virtual     bool        shouldStandby_l(); +    virtual     void        onAddNewTrack_l(); +      // volumes last sent to audio HAL with stream->set_volume()      float mLeftVolFloat;      float mRightVolFloat; @@ -952,6 +954,9 @@ protected:      // prepareTracks_l() tells threadLoop_mix() the name of the single active track      sp<Track>               mActiveTrack; + +    wp<Track>               mPreviousTrack;         // used to detect track switch +  public:      virtual     bool        hasFastMixer() const { return false; }  }; @@ -971,12 +976,10 @@ protected:      virtual     bool        waitingAsyncCallback();      virtual     bool        waitingAsyncCallback_l(); -    virtual     void        onAddNewTrack_l();  private:      size_t      mPausedWriteLength;     // length in bytes of write interrupted by pause      size_t      mPausedBytesRemaining;  // bytes still waiting in mixbuffer after resume -    wp<Track>   mPreviousTrack;         // used to detect track switch  };  class AsyncCallbackThread : public Thread {  | 
