am 9e3d9575: Merge "stagefright aacenc: Add prototypes for arm specific implementations of functions"
* commit '9e3d957599c76ba19e23fd25b75ccc02d54efe3e':
stagefright aacenc: Add prototypes for arm specific implementations of functions
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 7a2d7b3..d0cb7ff 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -1841,6 +1841,10 @@
return;
}
mAudioStatusEventPending = true;
+ // Do not honor delay when looping in order to limit audio gap
+ if (mFlags & (LOOPING | AUTO_LOOPING)) {
+ delayUs = 0;
+ }
mQueue.postEventWithDelay(mCheckAudioStatusEvent, delayUs);
}
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 30f8e12..5a46e44 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1832,7 +1832,7 @@
AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device)
: PlaybackThread(audioFlinger, output, id, device),
- mAudioMixer(0)
+ mAudioMixer(0), mPrevMixerStatus(MIXER_IDLE)
{
mType = ThreadBase::MIXER;
mAudioMixer = new AudioMixer(mFrameCount, mSampleRate);
@@ -1945,6 +1945,7 @@
ALOGV("MixerThread %p TID %d waking up\n", this, gettid());
acquireWakeLock_l();
+ mPrevMixerStatus = MIXER_IDLE;
if (mMasterMute == false) {
char value[PROPERTY_VALUE_MAX];
property_get("ro.audio.silent", value, "0");
@@ -1972,11 +1973,14 @@
if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
// mix buffers...
mAudioMixer->process();
- sleepTime = 0;
- // increase sleep time progressively when application underrun condition clears
- if (sleepTimeShift > 0) {
+ // increase sleep time progressively when application underrun condition clears.
+ // 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)) {
sleepTimeShift--;
}
+ sleepTime = 0;
standbyTime = systemTime() + kStandbyTimeInNsecs;
//TODO: delay standby when effects have a tail
} else {
@@ -2103,15 +2107,23 @@
// 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:
- // hence the test on (track->mRetryCount >= kMaxTrackRetries) meaning the track was mixed
+ // hence the test on (mPrevMixerStatus == MIXER_TRACKS_READY) meaning the track was mixed
// during last round
uint32_t minFrames = 1;
if (!track->isStopped() && !track->isPausing() &&
- (track->mRetryCount >= kMaxTrackRetries)) {
+ (mPrevMixerStatus == MIXER_TRACKS_READY)) {
if (t->sampleRate() == (int)mSampleRate) {
minFrames = mFrameCount;
} else {
- minFrames = (mFrameCount * t->sampleRate()) / mSampleRate + 1;
+ // +1 for rounding and +1 for additional sample needed for interpolation
+ minFrames = (mFrameCount * t->sampleRate()) / mSampleRate + 1 + 1;
+ // add frames already consumed but not yet released by the resampler
+ // because cblk->framesReady() will include these frames
+ minFrames += mAudioMixer->getUnreleasedFrames(track->name());
+ // the minimum track buffer size is normally twice the number of frames necessary
+ // to fill one buffer and the resampler should not leave more than one buffer worth
+ // of unreleased frames after each pass, but just in case...
+ LOG_ASSERT(minFrames <= cblk->frameCount);
}
}
if ((cblk->framesReady() >= minFrames) && track->isReady() &&
@@ -2221,7 +2233,13 @@
// reset retry count
track->mRetryCount = kMaxTrackRetries;
- mixerStatus = MIXER_TRACKS_READY;
+ // If one track is ready, set the mixer ready if:
+ // - the mixer was not ready during previous round OR
+ // - no other track is not ready
+ if (mPrevMixerStatus != MIXER_TRACKS_READY ||
+ mixerStatus != MIXER_TRACKS_ENABLED) {
+ mixerStatus = MIXER_TRACKS_READY;
+ }
} else {
//ALOGV("track %d u=%08x, s=%08x [NOT READY] on thread %p", track->name(), cblk->user, cblk->server, this);
if (track->isStopped()) {
@@ -2239,7 +2257,11 @@
tracksToRemove->add(track);
// indicate to client process that the track was disabled because of underrun
android_atomic_or(CBLK_DISABLED_ON, &cblk->flags);
- } else if (mixerStatus != MIXER_TRACKS_READY) {
+ // If one track is not ready, mark the mixer also not ready if:
+ // - the mixer was ready during previous round OR
+ // - no other track is ready
+ } else if (mPrevMixerStatus == MIXER_TRACKS_READY ||
+ mixerStatus != MIXER_TRACKS_READY) {
mixerStatus = MIXER_TRACKS_ENABLED;
}
}
@@ -2273,6 +2295,7 @@
memset(mMixBuffer, 0, mFrameCount * mChannelCount * sizeof(int16_t));
}
+ mPrevMixerStatus = mixerStatus;
return mixerStatus;
}
@@ -3008,6 +3031,7 @@
ALOGV("DuplicatingThread %p TID %d waking up\n", this, gettid());
acquireWakeLock_l();
+ mPrevMixerStatus = MIXER_IDLE;
if (mMasterMute == false) {
char value[PROPERTY_VALUE_MAX];
property_get("ro.audio.silent", value, "0");
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 6cafa7e..9bd2c7f 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -836,7 +836,9 @@
virtual uint32_t idleSleepTimeUs();
virtual uint32_t suspendSleepTimeUs();
- AudioMixer* mAudioMixer;
+ AudioMixer* mAudioMixer;
+ uint32_t mPrevMixerStatus; // previous status (mixer_state) returned by
+ // prepareTracks_l()
};
class DirectOutputThread : public PlaybackThread {
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index dcb0b13..9dda256 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -331,6 +331,23 @@
}
}
+size_t AudioMixer::track_t::getUnreleasedFrames()
+{
+ if (resampler != NULL) {
+ return resampler->getUnreleasedFrames();
+ }
+ return 0;
+}
+
+size_t AudioMixer::getUnreleasedFrames(int name)
+{
+ name -= TRACK0;
+ if (uint32_t(name) < MAX_NUM_TRACKS) {
+ track_t& track(mState.tracks[name]);
+ return track.getUnreleasedFrames();
+ }
+ return 0;
+}
status_t AudioMixer::setBufferProvider(AudioBufferProvider* buffer)
{
diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h
index 75c9170..0137185 100644
--- a/services/audioflinger/AudioMixer.h
+++ b/services/audioflinger/AudioMixer.h
@@ -91,6 +91,8 @@
static void ditherAndClamp(int32_t* out, int32_t const *sums, size_t c);
+ size_t getUnreleasedFrames(int name);
+
private:
enum {
@@ -167,6 +169,7 @@
bool doesResample() const;
void resetResampler();
void adjustVolumeRamp(bool aux);
+ size_t getUnreleasedFrames();
};
// pad to 32-bytes to fill cache line
diff --git a/services/audioflinger/AudioResampler.h b/services/audioflinger/AudioResampler.h
index 9f06c1c..ffa690a 100644
--- a/services/audioflinger/AudioResampler.h
+++ b/services/audioflinger/AudioResampler.h
@@ -54,6 +54,7 @@
AudioBufferProvider* provider) = 0;
virtual void reset();
+ virtual size_t getUnreleasedFrames() { return mInputIndex; }
protected:
// number of bits for phase fraction - 30 bits allows nearly 2x downsampling
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 6333bd8..918f31e 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -97,16 +97,6 @@
setCameraFree(i);
}
}
-
- // Read the system property to determine if we have to use the
- // AUDIO_STREAM_ENFORCED_AUDIBLE type.
- char value[PROPERTY_VALUE_MAX];
- property_get("ro.camera.sound.forced", value, "0");
- if (strcmp(value, "0") != 0) {
- mAudioStreamType = AUDIO_STREAM_ENFORCED_AUDIBLE;
- } else {
- mAudioStreamType = AUDIO_STREAM_MUSIC;
- }
}
CameraService::~CameraService() {
@@ -295,7 +285,7 @@
MediaPlayer* CameraService::newMediaPlayer(const char *file) {
MediaPlayer* mp = new MediaPlayer();
if (mp->setDataSource(file, NULL) == NO_ERROR) {
- mp->setAudioStreamType(mAudioStreamType);
+ mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
mp->prepare();
} else {
ALOGE("Failed to load CameraService sounds: %s", file);
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index cdfbc56..bad41f5 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -76,7 +76,6 @@
void setCameraFree(int cameraId);
// sounds
- audio_stream_type_t mAudioStreamType;
MediaPlayer* newMediaPlayer(const char *file);
Mutex mSoundLock;