diff options
-rw-r--r-- | media/libstagefright/AwesomePlayer.cpp | 42 | ||||
-rw-r--r-- | services/audioflinger/Threads.cpp | 23 |
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 |