summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/libstagefright/AwesomePlayer.cpp42
-rw-r--r--services/audioflinger/Threads.cpp23
2 files changed, 33 insertions, 32 deletions
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 15506ef..3cd0b0e 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -65,8 +65,6 @@
#define USE_SURFACE_ALLOC 1
#define FRAME_DROP_FREQ 0
-#define PROPERTY_OFFLOAD_HIWATERMARK "audio.offload.hiwatermark"
-#define PROPERTY_OFFLOAD_LOWATERMARK "audio.offload.lowatermark"
namespace android {
@@ -74,8 +72,7 @@ static int64_t kLowWaterMarkUs = 2000000ll; // 2secs
static int64_t kHighWaterMarkUs = 5000000ll; // 5secs
static const size_t kLowWaterMarkBytes = 40000;
static const size_t kHighWaterMarkBytes = 200000;
-static size_t kOffloadLowWaterMarkBytes = kLowWaterMarkBytes;
-static size_t kOffloadHighWaterMarkBytes = kHighWaterMarkBytes;
+
// maximum time in paused state when offloading audio decompression. When elapsed, the AudioPlayer
// is destroyed to allow the audio DSP to power down.
static int64_t kOffloadPauseMaxUs = 10000000ll;
@@ -641,11 +638,6 @@ void AwesomePlayer::reset_l() {
mMediaRenderingStartGeneration = 0;
mStartGeneration = 0;
-
- kOffloadLowWaterMarkBytes =
- property_get_int32(PROPERTY_OFFLOAD_LOWATERMARK, kLowWaterMarkBytes);
- kOffloadHighWaterMarkBytes =
- property_get_int32(PROPERTY_OFFLOAD_HIWATERMARK, kHighWaterMarkBytes);
}
void AwesomePlayer::notifyListener_l(int msg, int ext1, int ext2) {
@@ -736,7 +728,6 @@ void AwesomePlayer::onBufferingUpdate() {
size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&finalStatus);
bool eos = (finalStatus != OK);
- ALOGV("cachedDataRemaining = %zu b, eos=%d", cachedDataRemaining, eos);
if (eos) {
if (finalStatus == ERROR_END_OF_STREAM) {
notifyListener_l(MEDIA_BUFFERING_UPDATE, 100);
@@ -747,42 +738,36 @@ void AwesomePlayer::onBufferingUpdate() {
}
} else {
bool eos2;
- bool knownDuration = false;
int64_t cachedDurationUs;
if (getCachedDuration_l(&cachedDurationUs, &eos2) && mDurationUs > 0) {
- knownDuration = true;
int percentage = 100.0 * (double)cachedDurationUs / mDurationUs;
if (percentage > 100) {
percentage = 100;
}
notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);
- }
- if (!knownDuration || mOffloadAudio) {
- // If we don't know the bitrate/duration of the stream, or are offloading
- // decode, use absolute size limits to maintain the cache.
-
- size_t lowWatermark =
- mOffloadAudio ? kOffloadLowWaterMarkBytes : kLowWaterMarkBytes;
- size_t highWatermark =
- mOffloadAudio ? kOffloadHighWaterMarkBytes : kHighWaterMarkBytes;
+ } else {
+ // We don't know the bitrate/duration of the stream, use absolute size
+ // limits to maintain the cache.
- if ((mFlags & PLAYING) && !eos && (cachedDataRemaining < lowWatermark)) {
- ALOGI("cache is running low (< %zu) , pausing.", lowWatermark);
+ if ((mFlags & PLAYING) && !eos
+ && (cachedDataRemaining < kLowWaterMarkBytes)) {
+ ALOGI("cache is running low (< %zu) , pausing.",
+ kLowWaterMarkBytes);
modifyFlags(CACHE_UNDERRUN, SET);
pause_l();
ensureCacheIsFetching_l();
sendCacheStats();
notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
- } else if (eos || cachedDataRemaining > highWatermark) {
+ } else if (eos || cachedDataRemaining > kHighWaterMarkBytes) {
if (mFlags & CACHE_UNDERRUN) {
ALOGI("cache has filled up (> %zu), resuming.",
- highWatermark);
+ kHighWaterMarkBytes);
modifyFlags(CACHE_UNDERRUN, CLEAR);
play_l();
} else if (mFlags & PREPARING) {
ALOGV("cache has filled up (> %zu), prepare is done",
- highWatermark);
+ kHighWaterMarkBytes);
finishAsyncPrepare_l();
}
}
@@ -816,7 +801,7 @@ void AwesomePlayer::onBufferingUpdate() {
int64_t cachedDurationUs;
bool eos;
- if (!mOffloadAudio && getCachedDuration_l(&cachedDurationUs, &eos)) {
+ if (getCachedDuration_l(&cachedDurationUs, &eos)) {
ALOGV("cachedDurationUs = %.2f secs, eos=%d",
cachedDurationUs / 1E6, eos);
@@ -843,8 +828,7 @@ void AwesomePlayer::onBufferingUpdate() {
}
}
- if ( ((mFlags & PLAYING) && !eos) ||
- (mFlags & (PREPARING | CACHE_UNDERRUN)) ) {
+ if (mFlags & (PLAYING | PREPARING | CACHE_UNDERRUN)) {
postBufferingEvent_l();
}
}
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 71fc498..7d2d550 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1589,6 +1589,7 @@ void AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>&
dprintf(fd, " Mixer buffer: %p\n", mMixerBuffer);
dprintf(fd, " Effect buffer: %p\n", mEffectBuffer);
dprintf(fd, " Fast track availMask=%#x\n", mFastTrackAvailMask);
+ dprintf(fd, " Standby delay ns=%lld\n", (long long)mStandbyDelayNs);
AudioStreamOut *output = mOutput;
audio_output_flags_t flags = output != NULL ? output->flags : AUDIO_OUTPUT_FLAG_NONE;
String8 flagsAsString = outputFlagsToString(flags);
@@ -2513,7 +2514,8 @@ The derived values that are cached:
- mSinkBufferSize from frame count * frame size
- mActiveSleepTimeUs from activeSleepTimeUs()
- mIdleSleepTimeUs from idleSleepTimeUs()
- - mStandbyDelayNs from mActiveSleepTimeUs (DIRECT only)
+ - mStandbyDelayNs from mActiveSleepTimeUs (DIRECT only) or forced to at least
+ kDefaultStandbyTimeInNsecs when connected to an A2DP device.
- maxPeriod from frame count and sample rate (MIXER only)
The parameters that affect these derived values are:
@@ -2532,6 +2534,15 @@ void AudioFlinger::PlaybackThread::cacheParameters_l()
mSinkBufferSize = mNormalFrameCount * mFrameSize;
mActiveSleepTimeUs = activeSleepTimeUs();
mIdleSleepTimeUs = idleSleepTimeUs();
+
+ // make sure standby delay is not too short when connected to an A2DP sink to avoid
+ // truncating audio when going to standby.
+ mStandbyDelayNs = AudioFlinger::mStandbyTimeInNsecs;
+ if ((mOutDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != 0) {
+ if (mStandbyDelayNs < kDefaultStandbyTimeInNsecs) {
+ mStandbyDelayNs = kDefaultStandbyTimeInNsecs;
+ }
+ }
}
void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamType)
@@ -4248,6 +4259,7 @@ bool AudioFlinger::MixerThread::checkForNewParameter_l(const String8& keyValuePa
status_t& status)
{
bool reconfig = false;
+ bool a2dpDeviceChanged = false;
status = NO_ERROR;
@@ -4324,6 +4336,8 @@ bool AudioFlinger::MixerThread::checkForNewParameter_l(const String8& keyValuePa
// forward device change to effects that have requested to be
// aware of attached audio device.
if (value != AUDIO_DEVICE_NONE) {
+ a2dpDeviceChanged =
+ (mOutDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != (value & AUDIO_DEVICE_OUT_ALL_A2DP);
mOutDevice = value;
for (size_t i = 0; i < mEffectChains.size(); i++) {
mEffectChains[i]->setDevice_l(mOutDevice);
@@ -4367,7 +4381,7 @@ bool AudioFlinger::MixerThread::checkForNewParameter_l(const String8& keyValuePa
sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
}
- return reconfig;
+ return reconfig || a2dpDeviceChanged;
}
@@ -4803,6 +4817,7 @@ bool AudioFlinger::DirectOutputThread::checkForNewParameter_l(const String8& key
status_t& status)
{
bool reconfig = false;
+ bool a2dpDeviceChanged = false;
status = NO_ERROR;
@@ -4812,6 +4827,8 @@ bool AudioFlinger::DirectOutputThread::checkForNewParameter_l(const String8& key
// forward device change to effects that have requested to be
// aware of attached audio device.
if (value != AUDIO_DEVICE_NONE) {
+ a2dpDeviceChanged =
+ (mOutDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != (value & AUDIO_DEVICE_OUT_ALL_A2DP);
mOutDevice = value;
for (size_t i = 0; i < mEffectChains.size(); i++) {
mEffectChains[i]->setDevice_l(mOutDevice);
@@ -4844,7 +4861,7 @@ bool AudioFlinger::DirectOutputThread::checkForNewParameter_l(const String8& key
}
}
- return reconfig;
+ return reconfig || a2dpDeviceChanged;
}
uint32_t AudioFlinger::DirectOutputThread::activeSleepTimeUs() const