Loading services/audioflinger/AudioFlinger.cpp +57 −9 Original line number Diff line number Diff line Loading @@ -650,6 +650,7 @@ sp<IAudioTrack> AudioFlinger::createTrack( } } setAudioHwSyncForSession_l(thread, (audio_session_t)lSessionId); } if (lStatus != NO_ERROR) { Loading Loading @@ -1604,22 +1605,69 @@ status_t AudioFlinger::setLowRamDevice(bool isLowRamDevice) audio_hw_sync_t AudioFlinger::getAudioHwSyncForSession(audio_session_t sessionId) { Mutex::Autolock _l(mLock); for (size_t i = 0; i < mPlaybackThreads.size(); i++) { sp<PlaybackThread> thread = mPlaybackThreads.valueAt(i); if ((thread->hasAudioSession(sessionId) & ThreadBase::TRACK_SESSION) != 0) { // A session can only be on one thread, so exit after first match String8 reply = thread->getParameters(String8(AUDIO_PARAMETER_STREAM_HW_AV_SYNC)); AudioParameter param = AudioParameter(reply); ssize_t index = mHwAvSyncIds.indexOfKey(sessionId); if (index >= 0) { ALOGV("getAudioHwSyncForSession found ID %d for session %d", mHwAvSyncIds.valueAt(index), sessionId); return mHwAvSyncIds.valueAt(index); } audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice(); if (dev == NULL) { return AUDIO_HW_SYNC_INVALID; } char *reply = dev->get_parameters(dev, AUDIO_PARAMETER_HW_AV_SYNC); AudioParameter param = AudioParameter(String8(reply)); free(reply); int value; if (param.getInt(String8(AUDIO_PARAMETER_STREAM_HW_AV_SYNC), value) == NO_ERROR) { return value; if (param.getInt(String8(AUDIO_PARAMETER_HW_AV_SYNC), value) != NO_ERROR) { ALOGW("getAudioHwSyncForSession error getting sync for session %d", sessionId); return AUDIO_HW_SYNC_INVALID; } // allow only one session for a given HW A/V sync ID. for (size_t i = 0; i < mHwAvSyncIds.size(); i++) { if (mHwAvSyncIds.valueAt(i) == (audio_hw_sync_t)value) { ALOGV("getAudioHwSyncForSession removing ID %d for session %d", value, mHwAvSyncIds.keyAt(i)); mHwAvSyncIds.removeItemsAt(i); break; } } return AUDIO_HW_SYNC_INVALID; mHwAvSyncIds.add(sessionId, value); for (size_t i = 0; i < mPlaybackThreads.size(); i++) { sp<PlaybackThread> thread = mPlaybackThreads.valueAt(i); uint32_t sessions = thread->hasAudioSession(sessionId); if (sessions & PlaybackThread::TRACK_SESSION) { AudioParameter param = AudioParameter(); param.addInt(String8(AUDIO_PARAMETER_STREAM_HW_AV_SYNC), value); thread->setParameters(param.toString()); break; } } ALOGV("getAudioHwSyncForSession adding ID %d for session %d", value, sessionId); return (audio_hw_sync_t)value; } // setAudioHwSyncForSession_l() must be called with AudioFlinger::mLock held void AudioFlinger::setAudioHwSyncForSession_l(PlaybackThread *thread, audio_session_t sessionId) { ssize_t index = mHwAvSyncIds.indexOfKey(sessionId); if (index >= 0) { audio_hw_sync_t syncId = mHwAvSyncIds.valueAt(index); ALOGV("setAudioHwSyncForSession_l found ID %d for session %d", syncId, sessionId); AudioParameter param = AudioParameter(); param.addInt(String8(AUDIO_PARAMETER_STREAM_HW_AV_SYNC), syncId); thread->setParameters(param.toString()); } } // ---------------------------------------------------------------------------- Loading services/audioflinger/AudioFlinger.h +3 −0 Original line number Diff line number Diff line Loading @@ -733,6 +733,8 @@ private: // Effect chains without a valid thread DefaultKeyedVector< audio_session_t , sp<EffectChain> > mOrphanEffectChains; // list of sessions for which a valid HW A/V sync ID was retrieved from the HAL DefaultKeyedVector< audio_session_t , audio_hw_sync_t >mHwAvSyncIds; private: sp<Client> registerPid(pid_t pid); // always returns non-0 Loading @@ -741,6 +743,7 @@ private: void closeOutputInternal_l(sp<PlaybackThread> thread); status_t closeInput_nonvirtual(audio_io_handle_t input); void closeInputInternal_l(sp<RecordThread> thread); void setAudioHwSyncForSession_l(PlaybackThread *thread, audio_session_t sessionId); #ifdef TEE_SINK // all record threads serially share a common tee sink, which is re-created on format change Loading Loading
services/audioflinger/AudioFlinger.cpp +57 −9 Original line number Diff line number Diff line Loading @@ -650,6 +650,7 @@ sp<IAudioTrack> AudioFlinger::createTrack( } } setAudioHwSyncForSession_l(thread, (audio_session_t)lSessionId); } if (lStatus != NO_ERROR) { Loading Loading @@ -1604,22 +1605,69 @@ status_t AudioFlinger::setLowRamDevice(bool isLowRamDevice) audio_hw_sync_t AudioFlinger::getAudioHwSyncForSession(audio_session_t sessionId) { Mutex::Autolock _l(mLock); for (size_t i = 0; i < mPlaybackThreads.size(); i++) { sp<PlaybackThread> thread = mPlaybackThreads.valueAt(i); if ((thread->hasAudioSession(sessionId) & ThreadBase::TRACK_SESSION) != 0) { // A session can only be on one thread, so exit after first match String8 reply = thread->getParameters(String8(AUDIO_PARAMETER_STREAM_HW_AV_SYNC)); AudioParameter param = AudioParameter(reply); ssize_t index = mHwAvSyncIds.indexOfKey(sessionId); if (index >= 0) { ALOGV("getAudioHwSyncForSession found ID %d for session %d", mHwAvSyncIds.valueAt(index), sessionId); return mHwAvSyncIds.valueAt(index); } audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice(); if (dev == NULL) { return AUDIO_HW_SYNC_INVALID; } char *reply = dev->get_parameters(dev, AUDIO_PARAMETER_HW_AV_SYNC); AudioParameter param = AudioParameter(String8(reply)); free(reply); int value; if (param.getInt(String8(AUDIO_PARAMETER_STREAM_HW_AV_SYNC), value) == NO_ERROR) { return value; if (param.getInt(String8(AUDIO_PARAMETER_HW_AV_SYNC), value) != NO_ERROR) { ALOGW("getAudioHwSyncForSession error getting sync for session %d", sessionId); return AUDIO_HW_SYNC_INVALID; } // allow only one session for a given HW A/V sync ID. for (size_t i = 0; i < mHwAvSyncIds.size(); i++) { if (mHwAvSyncIds.valueAt(i) == (audio_hw_sync_t)value) { ALOGV("getAudioHwSyncForSession removing ID %d for session %d", value, mHwAvSyncIds.keyAt(i)); mHwAvSyncIds.removeItemsAt(i); break; } } return AUDIO_HW_SYNC_INVALID; mHwAvSyncIds.add(sessionId, value); for (size_t i = 0; i < mPlaybackThreads.size(); i++) { sp<PlaybackThread> thread = mPlaybackThreads.valueAt(i); uint32_t sessions = thread->hasAudioSession(sessionId); if (sessions & PlaybackThread::TRACK_SESSION) { AudioParameter param = AudioParameter(); param.addInt(String8(AUDIO_PARAMETER_STREAM_HW_AV_SYNC), value); thread->setParameters(param.toString()); break; } } ALOGV("getAudioHwSyncForSession adding ID %d for session %d", value, sessionId); return (audio_hw_sync_t)value; } // setAudioHwSyncForSession_l() must be called with AudioFlinger::mLock held void AudioFlinger::setAudioHwSyncForSession_l(PlaybackThread *thread, audio_session_t sessionId) { ssize_t index = mHwAvSyncIds.indexOfKey(sessionId); if (index >= 0) { audio_hw_sync_t syncId = mHwAvSyncIds.valueAt(index); ALOGV("setAudioHwSyncForSession_l found ID %d for session %d", syncId, sessionId); AudioParameter param = AudioParameter(); param.addInt(String8(AUDIO_PARAMETER_STREAM_HW_AV_SYNC), syncId); thread->setParameters(param.toString()); } } // ---------------------------------------------------------------------------- Loading
services/audioflinger/AudioFlinger.h +3 −0 Original line number Diff line number Diff line Loading @@ -733,6 +733,8 @@ private: // Effect chains without a valid thread DefaultKeyedVector< audio_session_t , sp<EffectChain> > mOrphanEffectChains; // list of sessions for which a valid HW A/V sync ID was retrieved from the HAL DefaultKeyedVector< audio_session_t , audio_hw_sync_t >mHwAvSyncIds; private: sp<Client> registerPid(pid_t pid); // always returns non-0 Loading @@ -741,6 +743,7 @@ private: void closeOutputInternal_l(sp<PlaybackThread> thread); status_t closeInput_nonvirtual(audio_io_handle_t input); void closeInputInternal_l(sp<RecordThread> thread); void setAudioHwSyncForSession_l(PlaybackThread *thread, audio_session_t sessionId); #ifdef TEE_SINK // all record threads serially share a common tee sink, which is re-created on format change Loading