diff options
author | Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de> | 2016-12-12 15:01:24 +0100 |
---|---|---|
committer | Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de> | 2016-12-12 15:01:24 +0100 |
commit | e15fd68c5dc4089690b5d3086776c3851e504bb7 (patch) | |
tree | 2c75274dee02b07463c9164efdf6888e1a9c75dc /services/audioflinger | |
parent | 185e2110a53feb7720d91b6f8366ad27402f21cc (diff) | |
parent | 26c5fa31d17a638bf314de6e12e86bb8a86db44b (diff) | |
download | frameworks_av-e15fd68c5dc4089690b5d3086776c3851e504bb7.zip frameworks_av-e15fd68c5dc4089690b5d3086776c3851e504bb7.tar.gz frameworks_av-e15fd68c5dc4089690b5d3086776c3851e504bb7.tar.bz2 |
Merge branch 'cm-13.0' of https://github.com/CyanogenMod/android_frameworks_av into replicant-6.0
Diffstat (limited to 'services/audioflinger')
-rw-r--r-- | services/audioflinger/Android.mk | 11 | ||||
-rw-r--r-- | services/audioflinger/AudioMixer.cpp | 3 | ||||
-rw-r--r-- | services/audioflinger/AudioResamplerQTI.cpp | 21 | ||||
-rw-r--r-- | services/audioflinger/AudioResamplerQTI.h | 2 | ||||
-rw-r--r-- | services/audioflinger/Effects.cpp | 29 | ||||
-rw-r--r-- | services/audioflinger/FastCapture.cpp | 1 | ||||
-rw-r--r-- | services/audioflinger/FastCaptureDumpState.cpp | 2 | ||||
-rw-r--r-- | services/audioflinger/FastMixer.cpp | 18 | ||||
-rw-r--r-- | services/audioflinger/ServiceUtilities.cpp | 8 | ||||
-rw-r--r-- | services/audioflinger/ServiceUtilities.h | 1 | ||||
-rw-r--r-- | services/audioflinger/Threads.cpp | 52 | ||||
-rw-r--r-- | services/audioflinger/Threads.h | 4 |
12 files changed, 119 insertions, 33 deletions
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk index 0dd2af6..8ea26d3 100644 --- a/services/audioflinger/Android.mk +++ b/services/audioflinger/Android.mk @@ -160,12 +160,19 @@ LOCAL_SHARED_LIBRARIES := \ libaudioutils #QTI Resampler -ifeq ($(call is-vendor-board-platform,QCOM), true) -ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_RESAMPLER)), true) +ifeq ($(call is-vendor-board-platform,QCOM),true) +ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_RESAMPLER)),true) +ifdef TARGET_2ND_ARCH LOCAL_SRC_FILES_$(TARGET_2ND_ARCH) += AudioResamplerQTI.cpp.arm LOCAL_C_INCLUDES_$(TARGET_2ND_ARCH) += $(TARGET_OUT_HEADERS)/mm-audio/audio-src LOCAL_SHARED_LIBRARIES_$(TARGET_2ND_ARCH) += libqct_resampler LOCAL_CFLAGS_$(TARGET_2ND_ARCH) += -DQTI_RESAMPLER +else +LOCAL_SRC_FILES += AudioResamplerQTI.cpp.arm +LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/audio-src +LOCAL_SHARED_LIBRARIES += libqct_resampler +LOCAL_CFLAGS += -DQTI_RESAMPLER +endif endif endif #QTI Resampler diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp index 806eaf1..bb9d4e5 100644 --- a/services/audioflinger/AudioMixer.cpp +++ b/services/audioflinger/AudioMixer.cpp @@ -781,7 +781,8 @@ bool AudioMixer::track_t::setResampler(uint32_t trackSampleRate, uint32_t devSam #ifdef QTI_RESAMPLER if ((trackSampleRate <= QTI_RESAMPLER_MAX_SAMPLERATE) && (trackSampleRate > devSampleRate * 2) && - ((devSampleRate == 48000)||(devSampleRate == 44100))) { + ((devSampleRate == 48000)||(devSampleRate == 44100)) && + (resamplerChannelCount <= 2)) { quality = AudioResampler::QTI_QUALITY; } #endif diff --git a/services/audioflinger/AudioResamplerQTI.cpp b/services/audioflinger/AudioResamplerQTI.cpp index 44b741e..0d57e09 100644 --- a/services/audioflinger/AudioResamplerQTI.cpp +++ b/services/audioflinger/AudioResamplerQTI.cpp @@ -51,8 +51,9 @@ size_t AudioResamplerQTI::resample(int32_t* out, size_t outFrameCount, { int16_t vl = mVolume[0]; int16_t vr = mVolume[1]; - int16_t *pBuf; + int32_t *pBuf; + int64_t tempL, tempR; size_t inFrameRequest; size_t inFrameCount = getNumInSample(outFrameCount); size_t index = 0; @@ -74,7 +75,7 @@ size_t AudioResamplerQTI::resample(int32_t* out, size_t outFrameCount, if(mResamplerOutBuf) { delete [] mResamplerOutBuf; } - mTmpBuf = new int16_t[inFrameRequest + 16]; + mTmpBuf = new int32_t[inFrameRequest + 16]; mResamplerOutBuf = new int32_t[out_count]; } @@ -95,7 +96,7 @@ size_t AudioResamplerQTI::resample(int32_t* out, size_t outFrameCount, goto resample_exit; } - mTmpBuf[index++] = clamp16_from_float(*((float *)mBuffer.raw + frameIndex++)); + mTmpBuf[index++] = clampq4_27_from_float(*((float *)mBuffer.raw + frameIndex++)); if (frameIndex >= mBuffer.frameCount) { provider->releaseBuffer(&mBuffer); @@ -121,8 +122,8 @@ size_t AudioResamplerQTI::resample(int32_t* out, size_t outFrameCount, goto resample_exit; } - mTmpBuf[index] = clamp16_from_float(*((float *)mBuffer.raw + frameIndex++)); - pBuf[index++] = clamp16_from_float(*((float *)mBuffer.raw + frameIndex++)); + mTmpBuf[index] = clampq4_27_from_float(*((float *)mBuffer.raw + frameIndex++)); + pBuf[index++] = clampq4_27_from_float(*((float *)mBuffer.raw + frameIndex++)); if (frameIndex >= mBuffer.frameCount * 2) { provider->releaseBuffer(&mBuffer); } @@ -133,8 +134,12 @@ size_t AudioResamplerQTI::resample(int32_t* out, size_t outFrameCount, resample_exit: for (int i = 0; i < out_count; i += 2) { - fout[i] += float_from_q4_27(mResamplerOutBuf[i] * vl); - fout[i+1] += float_from_q4_27(mResamplerOutBuf[i+1] * vr); + // Multiplying q4.27 data with u4.12 gain could result in 39 fractional bit data(27+12) + // To get back the 27 fractional bit format output data, do right shift by 12 + tempL = (int64_t)mResamplerOutBuf[i] * vl; + tempR = (int64_t)mResamplerOutBuf[i+1] * vr; + fout[i] += float_from_q4_27((int32_t)(tempL>>12)); + fout[i+1] += float_from_q4_27((int32_t)(tempR>>12)); } mFrameIndex = frameIndex; @@ -151,7 +156,7 @@ void AudioResamplerQTI::setSampleRate(int32_t inSampleRate) void AudioResamplerQTI::init() { - QCT_Resampler::Init(mState, mChannelCount, mInSampleRate, mSampleRate); + QCT_Resampler::Init(mState, mChannelCount, mInSampleRate, mSampleRate, 1/*32bit in*/); } size_t AudioResamplerQTI::getNumInSample(size_t outFrameCount) diff --git a/services/audioflinger/AudioResamplerQTI.h b/services/audioflinger/AudioResamplerQTI.h index 0b30a9f..1cf93fc 100644 --- a/services/audioflinger/AudioResamplerQTI.h +++ b/services/audioflinger/AudioResamplerQTI.h @@ -35,7 +35,7 @@ public: size_t getNumInSample(size_t outFrameCount); int16_t *mState; - int16_t *mTmpBuf; + int32_t *mTmpBuf; int32_t *mResamplerOutBuf; size_t mFrameIndex; size_t stateSize; diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp index 879b6c9..5505d2e 100644 --- a/services/audioflinger/Effects.cpp +++ b/services/audioflinger/Effects.cpp @@ -543,6 +543,13 @@ status_t AudioFlinger::EffectModule::remove_effect_from_hal_l() return NO_ERROR; } +// round up delta valid if value and divisor are positive. +template <typename T> +static T roundUpDelta(const T &value, const T &divisor) { + T remainder = value % divisor; + return remainder == 0 ? 0 : divisor - remainder; +} + status_t AudioFlinger::EffectModule::command(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, @@ -558,6 +565,28 @@ status_t AudioFlinger::EffectModule::command(uint32_t cmdCode, if (mStatus != NO_ERROR) { return mStatus; } + if (cmdCode == EFFECT_CMD_GET_PARAM && + (*replySize < sizeof(effect_param_t) || + ((effect_param_t *)pCmdData)->psize > *replySize - sizeof(effect_param_t))) { + android_errorWriteLog(0x534e4554, "29251553"); + return -EINVAL; + } + if ((cmdCode == EFFECT_CMD_SET_PARAM + || cmdCode == EFFECT_CMD_SET_PARAM_DEFERRED) && // DEFERRED not generally used + (sizeof(effect_param_t) > cmdSize + || ((effect_param_t *)pCmdData)->psize > cmdSize + - sizeof(effect_param_t) + || ((effect_param_t *)pCmdData)->vsize > cmdSize + - sizeof(effect_param_t) + - ((effect_param_t *)pCmdData)->psize + || roundUpDelta(((effect_param_t *)pCmdData)->psize, (uint32_t)sizeof(int)) > + cmdSize + - sizeof(effect_param_t) + - ((effect_param_t *)pCmdData)->psize + - ((effect_param_t *)pCmdData)->vsize)) { + android_errorWriteLog(0x534e4554, "30204301"); + return -EINVAL; + } status_t status = (*mEffectInterface)->command(mEffectInterface, cmdCode, cmdSize, diff --git a/services/audioflinger/FastCapture.cpp b/services/audioflinger/FastCapture.cpp index 2493fb7..7c8a25f 100644 --- a/services/audioflinger/FastCapture.cpp +++ b/services/audioflinger/FastCapture.cpp @@ -25,6 +25,7 @@ #include <media/AudioBufferProvider.h> #include <utils/Log.h> #include <utils/Trace.h> +#include "AudioFlinger.h" #include "FastCapture.h" namespace android { diff --git a/services/audioflinger/FastCaptureDumpState.cpp b/services/audioflinger/FastCaptureDumpState.cpp index 53eeba5..de4a6db 100644 --- a/services/audioflinger/FastCaptureDumpState.cpp +++ b/services/audioflinger/FastCaptureDumpState.cpp @@ -15,7 +15,7 @@ */ #define LOG_TAG "FastCaptureDumpState" -//define LOG_NDEBUG 0 +//#define LOG_NDEBUG 0 #include "Configuration.h" #include <utils/Log.h> diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp index 45c68b5..2bc8066 100644 --- a/services/audioflinger/FastMixer.cpp +++ b/services/audioflinger/FastMixer.cpp @@ -334,6 +334,11 @@ void FastMixer::onWork() if ((command & FastMixerState::MIX) && (mMixer != NULL) && mIsWarm) { ALOG_ASSERT(mMixerBuffer != NULL); + + // AudioMixer::mState.enabledTracks is undefined if mState.hook == process__validate, + // so we keep a side copy of enabledTracks + bool anyEnabledTracks = false; + // for each track, update volume and check for underrun unsigned currentTrackMask = current->mTrackMask; while (currentTrackMask != 0) { @@ -392,11 +397,13 @@ void FastMixer::onWork() underruns.mBitFields.mPartial++; underruns.mBitFields.mMostRecent = UNDERRUN_PARTIAL; mMixer->enable(name); + anyEnabledTracks = true; } } else { underruns.mBitFields.mFull++; underruns.mBitFields.mMostRecent = UNDERRUN_FULL; mMixer->enable(name); + anyEnabledTracks = true; } ftDump->mUnderruns = underruns; ftDump->mFramesReady = framesReady; @@ -407,9 +414,14 @@ void FastMixer::onWork() pts = AudioBufferProvider::kInvalidPTS; } - // process() is CPU-bound - mMixer->process(pts); - mMixerBufferState = MIXED; + if (anyEnabledTracks) { + // process() is CPU-bound + mMixer->process(pts); + mMixerBufferState = MIXED; + } else if (mMixerBufferState != ZEROED) { + mMixerBufferState = UNDEFINED; + } + } else if (mMixerBufferState == MIXED) { mMixerBufferState = UNDEFINED; } diff --git a/services/audioflinger/ServiceUtilities.cpp b/services/audioflinger/ServiceUtilities.cpp index 2e68dad..031ff05 100644 --- a/services/audioflinger/ServiceUtilities.cpp +++ b/services/audioflinger/ServiceUtilities.cpp @@ -106,6 +106,14 @@ bool captureAudioOutputAllowed() { return ok; } +bool accessFmRadioAllowed() { + static const String16 sAccessFmRadio("android.permission.ACCESS_FM_RADIO"); + // IMPORTANT: Use PermissionCache - not a runtime permission and may not change. + bool ok = PermissionCache::checkCallingPermission(sAccessFmRadio); + if (!ok) ALOGE("Request requires android.permission.ACCESS_FM_RADIO"); + return ok; +} + bool captureHotwordAllowed() { static const String16 sCaptureHotwordAllowed("android.permission.CAPTURE_AUDIO_HOTWORD"); // IMPORTANT: Use PermissionCache - not a runtime permission and may not change. diff --git a/services/audioflinger/ServiceUtilities.h b/services/audioflinger/ServiceUtilities.h index fba6dce..dffb114 100644 --- a/services/audioflinger/ServiceUtilities.h +++ b/services/audioflinger/ServiceUtilities.h @@ -21,6 +21,7 @@ namespace android { extern pid_t getpid_cached; bool recordingAllowed(const String16& opPackageName); +bool accessFmRadioAllowed(); bool captureAudioOutputAllowed(); bool captureHotwordAllowed(); bool settingsAllowed(); diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index c3ee6c2..e5e8bdb 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -2574,11 +2574,10 @@ void AudioFlinger::PlaybackThread::cacheParameters_l() } } -void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamType) +void AudioFlinger::PlaybackThread::invalidateTracks_l(audio_stream_type_t streamType) { ALOGV("MixerThread::invalidateTracks() mixer %p, streamType %d, mTracks.size %d", this, streamType, mTracks.size()); - Mutex::Autolock _l(mLock); size_t size = mTracks.size(); for (size_t i = 0; i < size; i++) { @@ -2589,6 +2588,12 @@ void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamTy } } +void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamType) +{ + Mutex::Autolock _l(mLock); + invalidateTracks_l(streamType); +} + status_t AudioFlinger::PlaybackThread::addEffectChain_l(const sp<EffectChain>& chain) { int session = chain->sessionId(); @@ -4470,8 +4475,12 @@ void AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& ar dprintf(fd, " AudioMixer tracks: 0x%08x\n", mAudioMixer->trackNames()); // Make a non-atomic copy of fast mixer dump state so it won't change underneath us - const FastMixerDumpState copy(mFastMixerDumpState); - copy.dump(fd); + // while we are dumping it. It may be inconsistent, but it won't mutate! + // This is a large object so we place it on the heap. + // FIXME 25972958: Need an intelligent copy constructor that does not touch unused pages. + const FastMixerDumpState *copy = new FastMixerDumpState(mFastMixerDumpState); + copy->dump(fd); + delete copy; #ifdef STATE_QUEUE_DUMP // Similar for state queue @@ -4863,6 +4872,10 @@ bool AudioFlinger::DirectOutputThread::shouldStandby_l() bool trackPaused = false; bool trackStopped = false; + if ((mType == DIRECT) && audio_is_linear_pcm(mFormat) && !usesHwAvSync()) { + return !mStandby; + } + // do not put the HAL in standby when paused. AwesomePlayer clear the offloaded AudioTrack // after a timeout and we will enter standby then. if (mTracks.size() > 0) { @@ -4983,6 +4996,8 @@ void AudioFlinger::DirectOutputThread::cacheParameters_l() mStandbyDelayNs = 0; } else if ((mType == OFFLOAD) && !audio_is_linear_pcm(mFormat)) { mStandbyDelayNs = kOffloadStandbyDelayNs; + } else if (mType == DIRECT && mIsDirectPcm) { + mStandbyDelayNs = kOffloadStandbyDelayNs; } else { mStandbyDelayNs = microseconds(mActiveSleepTimeUs*2); } @@ -5154,15 +5169,9 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr if (track->isInvalid()) { ALOGW("An invalidated track shouldn't be in active list"); tracksToRemove->add(track); - continue; - } - - if (track->mState == TrackBase::IDLE) { + } else if (track->mState == TrackBase::IDLE) { ALOGW("An idle track shouldn't be in active list"); - continue; - } - - if (track->isPausing()) { + } else if (track->isPausing()) { track->setPaused(); if (last) { if (mHwSupportsPause && !mHwPaused) { @@ -5185,7 +5194,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr if (last) { mFlushPending = true; } - } else if (track->isResumePending()){ + } else if (track->isResumePending()) { track->resumeAck(); if (last) { if (mPausedBytesRemaining) { @@ -5361,6 +5370,13 @@ void AudioFlinger::OffloadThread::flushHw_l() } } +void AudioFlinger::OffloadThread::invalidateTracks(audio_stream_type_t streamType) +{ + Mutex::Autolock _l(mLock); + mFlushPending = true; + PlaybackThread::invalidateTracks_l(streamType); +} + // ---------------------------------------------------------------------------- AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger, @@ -6454,9 +6470,13 @@ void AudioFlinger::RecordThread::dumpInternals(int fd, const Vector<String16>& a dprintf(fd, " Fast capture thread: %s\n", hasFastCapture() ? "yes" : "no"); dprintf(fd, " Fast track available: %s\n", mFastTrackAvail ? "yes" : "no"); - // Make a non-atomic copy of fast capture dump state so it won't change underneath us - const FastCaptureDumpState copy(mFastCaptureDumpState); - copy.dump(fd); + // Make a non-atomic copy of fast capture dump state so it won't change underneath us + // while we are dumping it. It may be inconsistent, but it won't mutate! + // This is a large object so we place it on the heap. + // FIXME 25972958: Need an intelligent copy constructor that does not touch unused pages. + const FastCaptureDumpState *copy = new FastCaptureDumpState(mFastCaptureDumpState); + copy->dump(fd); + delete copy; } void AudioFlinger::RecordThread::dumpTracks(int fd, const Vector<String16>& args __unused) diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h index 48ff77d..8fab1e4 100644 --- a/services/audioflinger/Threads.h +++ b/services/audioflinger/Threads.h @@ -617,7 +617,8 @@ public: virtual bool isValidSyncEvent(const sp<SyncEvent>& event) const; // called with AudioFlinger lock held - void invalidateTracks(audio_stream_type_t streamType); + void invalidateTracks_l(audio_stream_type_t streamType); + virtual void invalidateTracks(audio_stream_type_t streamType); virtual size_t frameCount() const { return mNormalFrameCount; } @@ -1000,6 +1001,7 @@ protected: virtual bool waitingAsyncCallback(); virtual bool waitingAsyncCallback_l(); + virtual void invalidateTracks(audio_stream_type_t streamType); private: size_t mPausedWriteLength; // length in bytes of write interrupted by pause |