Loading services/audioflinger/MelReporter.cpp +95 −34 Original line number Diff line number Diff line Loading @@ -100,14 +100,50 @@ bool AudioFlinger::MelReporter::shouldComputeMelForDeviceType(audio_devices_t de } } void AudioFlinger::MelReporter::updateMetadataForCsd(audio_io_handle_t streamHandle, const std::vector<playback_track_metadata_v7_t>& metadataVec) { std::lock_guard _laf(mAudioFlinger.mLock); std::lock_guard _l(mLock); auto activeMelPatchId = activePatchStreamHandle_l(streamHandle); if (!activeMelPatchId) { ALOGV("%s stream handle %d does not have an active patch", __func__, streamHandle); return; } bool shouldActivateCsd = false; for (const auto& metadata : metadataVec) { if (metadata.base.usage == AUDIO_USAGE_GAME || metadata.base.usage == AUDIO_USAGE_MEDIA) { shouldActivateCsd = true; } } auto activeMelPatchIt = mActiveMelPatches.find(activeMelPatchId.value()); if (activeMelPatchIt != mActiveMelPatches.end() && shouldActivateCsd != activeMelPatchIt->second.csdActive) { if (activeMelPatchIt->second.csdActive) { ALOGV("%s should not compute CSD for stream handle %d", __func__, streamHandle); stopMelComputationForPatch_l(activeMelPatchIt->second); } else { ALOGV("%s should compute CSD for stream handle %d", __func__, streamHandle); startMelComputationForActivePatch_l(activeMelPatchIt->second); } activeMelPatchIt->second.csdActive = shouldActivateCsd; } } void AudioFlinger::MelReporter::onCreateAudioPatch(audio_patch_handle_t handle, const PatchPanel::Patch& patch) { if (useHalSoundDoseInterface()) { ALOGV("%s using HAL sound dose, ignore new patch", __func__); return; } ALOGV("%s: handle %d mHalHandle %d device sink %08x", __func__, handle, patch.mHalHandle, patch.mAudioPatch.num_sinks > 0 ? patch.mAudioPatch.sinks[0].ext.device.type : 0); if (patch.mAudioPatch.num_sources == 0 || patch.mAudioPatch.sources[0].type != AUDIO_PORT_TYPE_MIX) { ALOGW("%s: patch does not contain any mix sources", __func__); ALOGV("%s: patch does not contain any mix sources", __func__); return; } Loading @@ -122,31 +158,31 @@ void AudioFlinger::MelReporter::onCreateAudioPatch(audio_patch_handle_t handle, AudioDeviceTypeAddr adt{patch.mAudioPatch.sinks[i].ext.device.type, patch.mAudioPatch.sinks[i].ext.device.address}; mSoundDoseManager->mapAddressToDeviceId(adt, deviceId); bool useHalSoundDoseInterface = !mSoundDoseManager->forceUseFrameworkMel(); { std::lock_guard _l(mLock); useHalSoundDoseInterface &= mUseHalSoundDoseInterface; } if (!useHalSoundDoseInterface) { startMelComputationForNewPatch(streamHandle, deviceId); } } } std::lock_guard _afl(mAudioFlinger.mLock); std::lock_guard _l(mLock); mActiveMelPatches[patch.mAudioPatch.id] = newPatch; ALOGV("%s add patch handle %d to active devices", __func__, handle); startMelComputationForActivePatch_l(newPatch); newPatch.csdActive = true; mActiveMelPatches[handle] = newPatch; } void AudioFlinger::MelReporter::startMelComputationForNewPatch( audio_io_handle_t streamHandle, audio_port_handle_t deviceId) { // Start the MEL calculation in the PlaybackThread std::lock_guard _lAf(mAudioFlinger.mLock); auto thread = mAudioFlinger.checkPlaybackThread_l(streamHandle); if (thread != nullptr) { void AudioFlinger::MelReporter::startMelComputationForActivePatch_l(const ActiveMelPatch& patch) { auto thread = mAudioFlinger.checkPlaybackThread_l(patch.streamHandle); if (thread == nullptr) { ALOGE("%s cannot find thread for stream handle %d", __func__, patch.streamHandle); return; } for (const auto& deviceHandle : patch.deviceHandles) { ++mActiveDevices[deviceHandle]; ALOGI("%s add stream %d that uses device %d for CSD, nr of streams: %d", __func__, patch.streamHandle, deviceHandle, mActiveDevices[deviceHandle]); thread->startMelComputation(mSoundDoseManager->getOrCreateProcessorForDevice( deviceId, streamHandle, deviceHandle, patch.streamHandle, thread->mSampleRate, thread->mChannelCount, thread->mFormat)); Loading @@ -154,17 +190,14 @@ void AudioFlinger::MelReporter::startMelComputationForNewPatch( } void AudioFlinger::MelReporter::onReleaseAudioPatch(audio_patch_handle_t handle) { ALOGV("%s", __func__); ActiveMelPatch melPatch; { std::lock_guard _l(mLock); auto patchIt = mActiveMelPatches.find(handle); if (patchIt == mActiveMelPatches.end()) { ALOGW( "%s patch does not contain any mix sources with active MEL calculation", __func__); ALOGV("%s patch handle %d does not contain any mix sources with active MEL calculation", __func__, handle); return; } Loading @@ -172,10 +205,9 @@ void AudioFlinger::MelReporter::onReleaseAudioPatch(audio_patch_handle_t handle) mActiveMelPatches.erase(patchIt); } for (const auto& deviceId : melPatch.deviceHandles) { mSoundDoseManager->clearMapDeviceIdEntries(deviceId); } stopInternalMelComputationForStream(melPatch.streamHandle); std::lock_guard _afl(mAudioFlinger.mLock); std::lock_guard _l(mLock); stopMelComputationForPatch_l(melPatch); } sp<media::ISoundDose> AudioFlinger::MelReporter::getSoundDoseInterface( Loading @@ -191,17 +223,46 @@ void AudioFlinger::MelReporter::stopInternalMelComputation() { mUseHalSoundDoseInterface = true; } void AudioFlinger::MelReporter::stopInternalMelComputationForStream(audio_io_handle_t streamId) { ALOGV("%s: stop internal mel for stream id: %d", __func__, streamId); void AudioFlinger::MelReporter::stopMelComputationForPatch_l(const ActiveMelPatch& patch) { auto thread = mAudioFlinger.checkPlaybackThread_l(patch.streamHandle); ALOGV("%s: stop MEL for stream id: %d", __func__, patch.streamHandle); for (const auto& deviceId : patch.deviceHandles) { if (mActiveDevices[deviceId] > 0) { --mActiveDevices[deviceId]; if (mActiveDevices[deviceId] == 0) { // no stream is using deviceId anymore ALOGI("%s removing device %d from active CSD devices", __func__, deviceId); mSoundDoseManager->clearMapDeviceIdEntries(deviceId); } } } std::lock_guard _lAf(mAudioFlinger.mLock); mSoundDoseManager->removeStreamProcessor(streamId); auto thread = mAudioFlinger.checkPlaybackThread_l(streamId); mSoundDoseManager->removeStreamProcessor(patch.streamHandle); if (thread != nullptr) { thread->stopMelComputation(); } } std::optional<audio_patch_handle_t> AudioFlinger::MelReporter::activePatchStreamHandle_l( audio_io_handle_t streamHandle) { for(const auto& patchIt : mActiveMelPatches) { if (patchIt.second.streamHandle == streamHandle) { return patchIt.first; } } return std::nullopt; } bool AudioFlinger::MelReporter::useHalSoundDoseInterface() { bool useHalSoundDoseInterface = !mSoundDoseManager->forceUseFrameworkMel(); { std::lock_guard _l(mLock); useHalSoundDoseInterface &= mUseHalSoundDoseInterface; } return useHalSoundDoseInterface; } std::string AudioFlinger::MelReporter::dump() { std::lock_guard _l(mLock); std::string output("\nSound Dose:\n"); Loading services/audioflinger/MelReporter.h +27 −11 Original line number Diff line number Diff line Loading @@ -37,9 +37,6 @@ public: void onFirstRef() override; /** Returns true if we should compute MEL for the given device. */ bool shouldComputeMelForDeviceType(audio_devices_t device); /** * Activates the MEL reporting from the HAL sound dose interface. If the HAL * does not support the sound dose interface for this module, the internal MEL Loading Loading @@ -73,22 +70,39 @@ public: const PatchPanel::Patch& patch) override; void onReleaseAudioPatch(audio_patch_handle_t handle) override; /** * The new metadata can determine whether we should compute MEL for the given thread. * This is the case only if one of the tracks in the thread mix is using MEDIA or GAME. * Otherwise, this method will disable CSD. **/ void updateMetadataForCsd(audio_io_handle_t streamHandle, const std::vector<playback_track_metadata_v7_t>& metadataVec); private: struct ActiveMelPatch { audio_io_handle_t streamHandle{AUDIO_IO_HANDLE_NONE}; std::vector<audio_port_handle_t> deviceHandles; bool csdActive; }; /** Returns true if we should compute MEL for the given device. */ bool shouldComputeMelForDeviceType(audio_devices_t device); void stopInternalMelComputation(); void stopInternalMelComputationForStream(audio_io_handle_t streamId); void startMelComputationForNewPatch(audio_io_handle_t streamHandle, audio_port_handle_t deviceId); /** Should be called with the following order of locks: mAudioFlinger.mLock -> mLock. */ void stopMelComputationForPatch_l(const ActiveMelPatch& patch); /** Should be called with the following order of locks: mAudioFlinger.mLock -> mLock. */ void startMelComputationForActivePatch_l(const ActiveMelPatch& patch); std::optional<audio_patch_handle_t> activePatchStreamHandle_l(audio_io_handle_t streamHandle); bool useHalSoundDoseInterface(); AudioFlinger& mAudioFlinger; // does not own the object sp<SoundDoseManager> mSoundDoseManager; struct ActiveMelPatch { audio_io_handle_t streamHandle{AUDIO_IO_HANDLE_NONE}; std::vector<audio_port_handle_t> deviceHandles; }; /** * Lock for protecting the active mel patches. Do not mix with the AudioFlinger lock. * Locking order AudioFlinger::mLock -> PatchCommandThread::mLock -> MelReporter::mLock. Loading @@ -96,5 +110,7 @@ private: std::mutex mLock; std::unordered_map<audio_patch_handle_t, ActiveMelPatch> mActiveMelPatches GUARDED_BY(AudioFlinger::MelReporter::mLock); std::unordered_map<audio_port_handle_t, int> mActiveDevices GUARDED_BY(AudioFlinger::MelReporter::mLock); bool mUseHalSoundDoseInterface GUARDED_BY(AudioFlinger::MelReporter::mLock) = false; }; services/audioflinger/Threads.cpp +34 −13 Original line number Diff line number Diff line Loading @@ -3229,10 +3229,10 @@ void AudioFlinger::PlaybackThread::readOutputParameters_l() item.record(); } void AudioFlinger::PlaybackThread::updateMetadata_l() AudioFlinger::ThreadBase::MetadataUpdate AudioFlinger::PlaybackThread::updateMetadata_l() { if (!isStreamInitialized() || !mActiveTracks.readAndClearHasChanged()) { return; // nothing to do return {}; // nothing to do } StreamOutHalInterface::SourceMetadata metadata; auto backInserter = std::back_inserter(metadata.tracks); Loading @@ -3241,6 +3241,9 @@ void AudioFlinger::PlaybackThread::updateMetadata_l() track->copyMetadataTo(backInserter); } sendMetadataToBackend_l(metadata); MetadataUpdate change; change.playbackMetadataUpdate = metadata.tracks; return change; } void AudioFlinger::PlaybackThread::sendMetadataToBackend_l( Loading Loading @@ -3478,9 +3481,11 @@ void AudioFlinger::PlaybackThread::startMelComputation( } void AudioFlinger::PlaybackThread::stopMelComputation() { if (mMelProcessor.load() != nullptr) { ALOGV("%s: stopping mel processor for thread %d", __func__, id()); mMelProcessor = nullptr; } } void AudioFlinger::PlaybackThread::threadLoop_drain() { Loading Loading @@ -3933,6 +3938,7 @@ bool AudioFlinger::PlaybackThread::threadLoop() checkOutputStageEffects(); } MetadataUpdate metadataUpdate; { // scope for mLock Mutex::Autolock _l(mLock); Loading Loading @@ -4034,7 +4040,7 @@ bool AudioFlinger::PlaybackThread::threadLoop() mActiveTracks.updatePowerState(this); updateMetadata_l(); metadataUpdate = updateMetadata_l(); // prevent any changes in effect chain list and in each effect chain // during mixing and effect process as the audio buffers could be deleted Loading Loading @@ -4074,6 +4080,11 @@ bool AudioFlinger::PlaybackThread::threadLoop() setHalLatencyMode_l(); } // mLock scope ends if (!metadataUpdate.playbackMetadataUpdate.empty()) { mAudioFlinger->mMelReporter->updateMetadataForCsd(id(), metadataUpdate.playbackMetadataUpdate); } if (mBytesRemaining == 0) { mCurrentWriteLength = 0; if (mMixerStatus == MIXER_TRACKS_READY) { Loading Loading @@ -4783,7 +4794,7 @@ status_t AudioFlinger::PlaybackThread::createAudioPatch_l(const struct audio_pat if (configChanged) { sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED); } // Force meteadata update after a route change // Force metadata update after a route change mActiveTracks.setHasChanged(); return status; Loading Loading @@ -9023,10 +9034,10 @@ void AudioFlinger::RecordThread::resetAudioHistory_l() { mSharedAudioPackageName = ""; } void AudioFlinger::RecordThread::updateMetadata_l() AudioFlinger::ThreadBase::MetadataUpdate AudioFlinger::RecordThread::updateMetadata_l() { if (!isStreamInitialized() || !mActiveTracks.readAndClearHasChanged()) { return; // nothing to do return {}; // nothing to do } StreamInHalInterface::SinkMetadata metadata; auto backInserter = std::back_inserter(metadata.tracks); Loading @@ -9034,6 +9045,9 @@ void AudioFlinger::RecordThread::updateMetadata_l() track->copyMetadataTo(backInserter); } mInput->stream->updateSinkMetadata(metadata); MetadataUpdate change; change.recordMetadataUpdate = metadata.tracks; return change; } // destroyTrack_l() must be called with ThreadBase::mLock held Loading Loading @@ -10733,10 +10747,10 @@ void AudioFlinger::MmapPlaybackThread::processVolume_l() } } void AudioFlinger::MmapPlaybackThread::updateMetadata_l() AudioFlinger::ThreadBase::MetadataUpdate AudioFlinger::MmapPlaybackThread::updateMetadata_l() { if (!isStreamInitialized() || !mActiveTracks.readAndClearHasChanged()) { return; // nothing to do return {}; // nothing to do } StreamOutHalInterface::SourceMetadata metadata; for (const sp<MmapTrack> &track : mActiveTracks) { Loading @@ -10752,7 +10766,11 @@ void AudioFlinger::MmapPlaybackThread::updateMetadata_l() metadata.tracks.push_back(trackMetadata); } mOutput->stream->updateSourceMetadata(metadata); } MetadataUpdate change; change.playbackMetadataUpdate = metadata.tracks; return change; }; void AudioFlinger::MmapPlaybackThread::checkSilentMode_l() { Loading Loading @@ -10860,10 +10878,10 @@ void AudioFlinger::MmapCaptureThread::processVolume_l() } } void AudioFlinger::MmapCaptureThread::updateMetadata_l() AudioFlinger::ThreadBase::MetadataUpdate AudioFlinger::MmapCaptureThread::updateMetadata_l() { if (!isStreamInitialized() || !mActiveTracks.readAndClearHasChanged()) { return; // nothing to do return {}; // nothing to do } StreamInHalInterface::SinkMetadata metadata; for (const sp<MmapTrack> &track : mActiveTracks) { Loading @@ -10878,6 +10896,9 @@ void AudioFlinger::MmapCaptureThread::updateMetadata_l() metadata.tracks.push_back(trackMetadata); } mInput->stream->updateSinkMetadata(metadata); MetadataUpdate change; change.recordMetadataUpdate = metadata.tracks; return change; } void AudioFlinger::MmapCaptureThread::setRecordSilenced(audio_port_handle_t portId, bool silenced) Loading services/audioflinger/Threads.h +9 −5 Original line number Diff line number Diff line Loading @@ -607,7 +607,11 @@ protected: void checkSuspendOnAddEffectChain_l(const sp<EffectChain>& chain); // sends the metadata of the active tracks to the HAL virtual void updateMetadata_l() = 0; struct MetadataUpdate { std::vector<playback_track_metadata_v7_t> playbackMetadataUpdate; std::vector<record_track_metadata_v7_t> recordMetadataUpdate; }; virtual MetadataUpdate updateMetadata_l() = 0; String16 getWakeLockTag(); Loading Loading @@ -1277,7 +1281,7 @@ private: void removeTrack_l(const sp<Track>& track); void readOutputParameters_l(); void updateMetadata_l() final; MetadataUpdate updateMetadata_l() final; virtual void sendMetadataToBackend_l(const StreamOutHalInterface::SourceMetadata& metadata); void collectTimestamps_l(); Loading Loading @@ -1983,7 +1987,7 @@ public: status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction); status_t setPreferredMicrophoneFieldDimension(float zoom); void updateMetadata_l() override; MetadataUpdate updateMetadata_l() override; bool fastTrackAvailable() const { return mFastTrackAvail; } Loading Loading @@ -2257,7 +2261,7 @@ public: virtual void checkSilentMode_l(); void processVolume_l() override; void updateMetadata_l() override; MetadataUpdate updateMetadata_l() override; virtual void toAudioPortConfig(struct audio_port_config *config); Loading Loading @@ -2290,7 +2294,7 @@ public: status_t exitStandby_l() REQUIRES(mLock) override; void updateMetadata_l() override; MetadataUpdate updateMetadata_l() override; void processVolume_l() override; void setRecordSilenced(audio_port_handle_t portId, bool silenced) override; Loading services/audioflinger/sounddose/SoundDoseManager.cpp +3 −4 Original line number Diff line number Diff line Loading @@ -163,7 +163,7 @@ audio_port_handle_t SoundDoseManager::getIdForAudioDevice(const AudioDevice& aud auto adt = AudioDeviceTypeAddr(type, address); auto deviceIt = mActiveDevices.find(adt); if (deviceIt == mActiveDevices.end()) { ALOGE("%s: could not find port id for device %s", __func__, adt.toString().c_str()); ALOGI("%s: could not find port id for device %s", __func__, adt.toString().c_str()); return AUDIO_PORT_HANDLE_NONE; } return deviceIt->second; Loading @@ -187,7 +187,6 @@ void SoundDoseManager::clearMapDeviceIdEntries(audio_port_handle_t deviceId) { } ++activeDevice; } return; } ndk::ScopedAStatus SoundDoseManager::HalSoundDoseCallback::onMomentaryExposureWarning( Loading @@ -206,7 +205,7 @@ ndk::ScopedAStatus SoundDoseManager::HalSoundDoseCallback::onMomentaryExposureWa auto id = soundDoseManager->getIdForAudioDevice(in_audioDevice); if (id == AUDIO_PORT_HANDLE_NONE) { ALOGW("%s: no mapped id for audio device with type %d and address %s", ALOGI("%s: no mapped id for audio device with type %d and address %s", __func__, in_audioDevice.type.type, in_audioDevice.address.get<AudioDeviceAddress::id>().c_str()); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); Loading @@ -233,7 +232,7 @@ ndk::ScopedAStatus SoundDoseManager::HalSoundDoseCallback::onNewMelValues( auto id = soundDoseManager->getIdForAudioDevice(in_audioDevice); if (id == AUDIO_PORT_HANDLE_NONE) { ALOGW("%s: no mapped id for audio device with type %d and address %s", ALOGI("%s: no mapped id for audio device with type %d and address %s", __func__, in_audioDevice.type.type, in_audioDevice.address.get<AudioDeviceAddress::id>().c_str()); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); Loading Loading
services/audioflinger/MelReporter.cpp +95 −34 Original line number Diff line number Diff line Loading @@ -100,14 +100,50 @@ bool AudioFlinger::MelReporter::shouldComputeMelForDeviceType(audio_devices_t de } } void AudioFlinger::MelReporter::updateMetadataForCsd(audio_io_handle_t streamHandle, const std::vector<playback_track_metadata_v7_t>& metadataVec) { std::lock_guard _laf(mAudioFlinger.mLock); std::lock_guard _l(mLock); auto activeMelPatchId = activePatchStreamHandle_l(streamHandle); if (!activeMelPatchId) { ALOGV("%s stream handle %d does not have an active patch", __func__, streamHandle); return; } bool shouldActivateCsd = false; for (const auto& metadata : metadataVec) { if (metadata.base.usage == AUDIO_USAGE_GAME || metadata.base.usage == AUDIO_USAGE_MEDIA) { shouldActivateCsd = true; } } auto activeMelPatchIt = mActiveMelPatches.find(activeMelPatchId.value()); if (activeMelPatchIt != mActiveMelPatches.end() && shouldActivateCsd != activeMelPatchIt->second.csdActive) { if (activeMelPatchIt->second.csdActive) { ALOGV("%s should not compute CSD for stream handle %d", __func__, streamHandle); stopMelComputationForPatch_l(activeMelPatchIt->second); } else { ALOGV("%s should compute CSD for stream handle %d", __func__, streamHandle); startMelComputationForActivePatch_l(activeMelPatchIt->second); } activeMelPatchIt->second.csdActive = shouldActivateCsd; } } void AudioFlinger::MelReporter::onCreateAudioPatch(audio_patch_handle_t handle, const PatchPanel::Patch& patch) { if (useHalSoundDoseInterface()) { ALOGV("%s using HAL sound dose, ignore new patch", __func__); return; } ALOGV("%s: handle %d mHalHandle %d device sink %08x", __func__, handle, patch.mHalHandle, patch.mAudioPatch.num_sinks > 0 ? patch.mAudioPatch.sinks[0].ext.device.type : 0); if (patch.mAudioPatch.num_sources == 0 || patch.mAudioPatch.sources[0].type != AUDIO_PORT_TYPE_MIX) { ALOGW("%s: patch does not contain any mix sources", __func__); ALOGV("%s: patch does not contain any mix sources", __func__); return; } Loading @@ -122,31 +158,31 @@ void AudioFlinger::MelReporter::onCreateAudioPatch(audio_patch_handle_t handle, AudioDeviceTypeAddr adt{patch.mAudioPatch.sinks[i].ext.device.type, patch.mAudioPatch.sinks[i].ext.device.address}; mSoundDoseManager->mapAddressToDeviceId(adt, deviceId); bool useHalSoundDoseInterface = !mSoundDoseManager->forceUseFrameworkMel(); { std::lock_guard _l(mLock); useHalSoundDoseInterface &= mUseHalSoundDoseInterface; } if (!useHalSoundDoseInterface) { startMelComputationForNewPatch(streamHandle, deviceId); } } } std::lock_guard _afl(mAudioFlinger.mLock); std::lock_guard _l(mLock); mActiveMelPatches[patch.mAudioPatch.id] = newPatch; ALOGV("%s add patch handle %d to active devices", __func__, handle); startMelComputationForActivePatch_l(newPatch); newPatch.csdActive = true; mActiveMelPatches[handle] = newPatch; } void AudioFlinger::MelReporter::startMelComputationForNewPatch( audio_io_handle_t streamHandle, audio_port_handle_t deviceId) { // Start the MEL calculation in the PlaybackThread std::lock_guard _lAf(mAudioFlinger.mLock); auto thread = mAudioFlinger.checkPlaybackThread_l(streamHandle); if (thread != nullptr) { void AudioFlinger::MelReporter::startMelComputationForActivePatch_l(const ActiveMelPatch& patch) { auto thread = mAudioFlinger.checkPlaybackThread_l(patch.streamHandle); if (thread == nullptr) { ALOGE("%s cannot find thread for stream handle %d", __func__, patch.streamHandle); return; } for (const auto& deviceHandle : patch.deviceHandles) { ++mActiveDevices[deviceHandle]; ALOGI("%s add stream %d that uses device %d for CSD, nr of streams: %d", __func__, patch.streamHandle, deviceHandle, mActiveDevices[deviceHandle]); thread->startMelComputation(mSoundDoseManager->getOrCreateProcessorForDevice( deviceId, streamHandle, deviceHandle, patch.streamHandle, thread->mSampleRate, thread->mChannelCount, thread->mFormat)); Loading @@ -154,17 +190,14 @@ void AudioFlinger::MelReporter::startMelComputationForNewPatch( } void AudioFlinger::MelReporter::onReleaseAudioPatch(audio_patch_handle_t handle) { ALOGV("%s", __func__); ActiveMelPatch melPatch; { std::lock_guard _l(mLock); auto patchIt = mActiveMelPatches.find(handle); if (patchIt == mActiveMelPatches.end()) { ALOGW( "%s patch does not contain any mix sources with active MEL calculation", __func__); ALOGV("%s patch handle %d does not contain any mix sources with active MEL calculation", __func__, handle); return; } Loading @@ -172,10 +205,9 @@ void AudioFlinger::MelReporter::onReleaseAudioPatch(audio_patch_handle_t handle) mActiveMelPatches.erase(patchIt); } for (const auto& deviceId : melPatch.deviceHandles) { mSoundDoseManager->clearMapDeviceIdEntries(deviceId); } stopInternalMelComputationForStream(melPatch.streamHandle); std::lock_guard _afl(mAudioFlinger.mLock); std::lock_guard _l(mLock); stopMelComputationForPatch_l(melPatch); } sp<media::ISoundDose> AudioFlinger::MelReporter::getSoundDoseInterface( Loading @@ -191,17 +223,46 @@ void AudioFlinger::MelReporter::stopInternalMelComputation() { mUseHalSoundDoseInterface = true; } void AudioFlinger::MelReporter::stopInternalMelComputationForStream(audio_io_handle_t streamId) { ALOGV("%s: stop internal mel for stream id: %d", __func__, streamId); void AudioFlinger::MelReporter::stopMelComputationForPatch_l(const ActiveMelPatch& patch) { auto thread = mAudioFlinger.checkPlaybackThread_l(patch.streamHandle); ALOGV("%s: stop MEL for stream id: %d", __func__, patch.streamHandle); for (const auto& deviceId : patch.deviceHandles) { if (mActiveDevices[deviceId] > 0) { --mActiveDevices[deviceId]; if (mActiveDevices[deviceId] == 0) { // no stream is using deviceId anymore ALOGI("%s removing device %d from active CSD devices", __func__, deviceId); mSoundDoseManager->clearMapDeviceIdEntries(deviceId); } } } std::lock_guard _lAf(mAudioFlinger.mLock); mSoundDoseManager->removeStreamProcessor(streamId); auto thread = mAudioFlinger.checkPlaybackThread_l(streamId); mSoundDoseManager->removeStreamProcessor(patch.streamHandle); if (thread != nullptr) { thread->stopMelComputation(); } } std::optional<audio_patch_handle_t> AudioFlinger::MelReporter::activePatchStreamHandle_l( audio_io_handle_t streamHandle) { for(const auto& patchIt : mActiveMelPatches) { if (patchIt.second.streamHandle == streamHandle) { return patchIt.first; } } return std::nullopt; } bool AudioFlinger::MelReporter::useHalSoundDoseInterface() { bool useHalSoundDoseInterface = !mSoundDoseManager->forceUseFrameworkMel(); { std::lock_guard _l(mLock); useHalSoundDoseInterface &= mUseHalSoundDoseInterface; } return useHalSoundDoseInterface; } std::string AudioFlinger::MelReporter::dump() { std::lock_guard _l(mLock); std::string output("\nSound Dose:\n"); Loading
services/audioflinger/MelReporter.h +27 −11 Original line number Diff line number Diff line Loading @@ -37,9 +37,6 @@ public: void onFirstRef() override; /** Returns true if we should compute MEL for the given device. */ bool shouldComputeMelForDeviceType(audio_devices_t device); /** * Activates the MEL reporting from the HAL sound dose interface. If the HAL * does not support the sound dose interface for this module, the internal MEL Loading Loading @@ -73,22 +70,39 @@ public: const PatchPanel::Patch& patch) override; void onReleaseAudioPatch(audio_patch_handle_t handle) override; /** * The new metadata can determine whether we should compute MEL for the given thread. * This is the case only if one of the tracks in the thread mix is using MEDIA or GAME. * Otherwise, this method will disable CSD. **/ void updateMetadataForCsd(audio_io_handle_t streamHandle, const std::vector<playback_track_metadata_v7_t>& metadataVec); private: struct ActiveMelPatch { audio_io_handle_t streamHandle{AUDIO_IO_HANDLE_NONE}; std::vector<audio_port_handle_t> deviceHandles; bool csdActive; }; /** Returns true if we should compute MEL for the given device. */ bool shouldComputeMelForDeviceType(audio_devices_t device); void stopInternalMelComputation(); void stopInternalMelComputationForStream(audio_io_handle_t streamId); void startMelComputationForNewPatch(audio_io_handle_t streamHandle, audio_port_handle_t deviceId); /** Should be called with the following order of locks: mAudioFlinger.mLock -> mLock. */ void stopMelComputationForPatch_l(const ActiveMelPatch& patch); /** Should be called with the following order of locks: mAudioFlinger.mLock -> mLock. */ void startMelComputationForActivePatch_l(const ActiveMelPatch& patch); std::optional<audio_patch_handle_t> activePatchStreamHandle_l(audio_io_handle_t streamHandle); bool useHalSoundDoseInterface(); AudioFlinger& mAudioFlinger; // does not own the object sp<SoundDoseManager> mSoundDoseManager; struct ActiveMelPatch { audio_io_handle_t streamHandle{AUDIO_IO_HANDLE_NONE}; std::vector<audio_port_handle_t> deviceHandles; }; /** * Lock for protecting the active mel patches. Do not mix with the AudioFlinger lock. * Locking order AudioFlinger::mLock -> PatchCommandThread::mLock -> MelReporter::mLock. Loading @@ -96,5 +110,7 @@ private: std::mutex mLock; std::unordered_map<audio_patch_handle_t, ActiveMelPatch> mActiveMelPatches GUARDED_BY(AudioFlinger::MelReporter::mLock); std::unordered_map<audio_port_handle_t, int> mActiveDevices GUARDED_BY(AudioFlinger::MelReporter::mLock); bool mUseHalSoundDoseInterface GUARDED_BY(AudioFlinger::MelReporter::mLock) = false; };
services/audioflinger/Threads.cpp +34 −13 Original line number Diff line number Diff line Loading @@ -3229,10 +3229,10 @@ void AudioFlinger::PlaybackThread::readOutputParameters_l() item.record(); } void AudioFlinger::PlaybackThread::updateMetadata_l() AudioFlinger::ThreadBase::MetadataUpdate AudioFlinger::PlaybackThread::updateMetadata_l() { if (!isStreamInitialized() || !mActiveTracks.readAndClearHasChanged()) { return; // nothing to do return {}; // nothing to do } StreamOutHalInterface::SourceMetadata metadata; auto backInserter = std::back_inserter(metadata.tracks); Loading @@ -3241,6 +3241,9 @@ void AudioFlinger::PlaybackThread::updateMetadata_l() track->copyMetadataTo(backInserter); } sendMetadataToBackend_l(metadata); MetadataUpdate change; change.playbackMetadataUpdate = metadata.tracks; return change; } void AudioFlinger::PlaybackThread::sendMetadataToBackend_l( Loading Loading @@ -3478,9 +3481,11 @@ void AudioFlinger::PlaybackThread::startMelComputation( } void AudioFlinger::PlaybackThread::stopMelComputation() { if (mMelProcessor.load() != nullptr) { ALOGV("%s: stopping mel processor for thread %d", __func__, id()); mMelProcessor = nullptr; } } void AudioFlinger::PlaybackThread::threadLoop_drain() { Loading Loading @@ -3933,6 +3938,7 @@ bool AudioFlinger::PlaybackThread::threadLoop() checkOutputStageEffects(); } MetadataUpdate metadataUpdate; { // scope for mLock Mutex::Autolock _l(mLock); Loading Loading @@ -4034,7 +4040,7 @@ bool AudioFlinger::PlaybackThread::threadLoop() mActiveTracks.updatePowerState(this); updateMetadata_l(); metadataUpdate = updateMetadata_l(); // prevent any changes in effect chain list and in each effect chain // during mixing and effect process as the audio buffers could be deleted Loading Loading @@ -4074,6 +4080,11 @@ bool AudioFlinger::PlaybackThread::threadLoop() setHalLatencyMode_l(); } // mLock scope ends if (!metadataUpdate.playbackMetadataUpdate.empty()) { mAudioFlinger->mMelReporter->updateMetadataForCsd(id(), metadataUpdate.playbackMetadataUpdate); } if (mBytesRemaining == 0) { mCurrentWriteLength = 0; if (mMixerStatus == MIXER_TRACKS_READY) { Loading Loading @@ -4783,7 +4794,7 @@ status_t AudioFlinger::PlaybackThread::createAudioPatch_l(const struct audio_pat if (configChanged) { sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED); } // Force meteadata update after a route change // Force metadata update after a route change mActiveTracks.setHasChanged(); return status; Loading Loading @@ -9023,10 +9034,10 @@ void AudioFlinger::RecordThread::resetAudioHistory_l() { mSharedAudioPackageName = ""; } void AudioFlinger::RecordThread::updateMetadata_l() AudioFlinger::ThreadBase::MetadataUpdate AudioFlinger::RecordThread::updateMetadata_l() { if (!isStreamInitialized() || !mActiveTracks.readAndClearHasChanged()) { return; // nothing to do return {}; // nothing to do } StreamInHalInterface::SinkMetadata metadata; auto backInserter = std::back_inserter(metadata.tracks); Loading @@ -9034,6 +9045,9 @@ void AudioFlinger::RecordThread::updateMetadata_l() track->copyMetadataTo(backInserter); } mInput->stream->updateSinkMetadata(metadata); MetadataUpdate change; change.recordMetadataUpdate = metadata.tracks; return change; } // destroyTrack_l() must be called with ThreadBase::mLock held Loading Loading @@ -10733,10 +10747,10 @@ void AudioFlinger::MmapPlaybackThread::processVolume_l() } } void AudioFlinger::MmapPlaybackThread::updateMetadata_l() AudioFlinger::ThreadBase::MetadataUpdate AudioFlinger::MmapPlaybackThread::updateMetadata_l() { if (!isStreamInitialized() || !mActiveTracks.readAndClearHasChanged()) { return; // nothing to do return {}; // nothing to do } StreamOutHalInterface::SourceMetadata metadata; for (const sp<MmapTrack> &track : mActiveTracks) { Loading @@ -10752,7 +10766,11 @@ void AudioFlinger::MmapPlaybackThread::updateMetadata_l() metadata.tracks.push_back(trackMetadata); } mOutput->stream->updateSourceMetadata(metadata); } MetadataUpdate change; change.playbackMetadataUpdate = metadata.tracks; return change; }; void AudioFlinger::MmapPlaybackThread::checkSilentMode_l() { Loading Loading @@ -10860,10 +10878,10 @@ void AudioFlinger::MmapCaptureThread::processVolume_l() } } void AudioFlinger::MmapCaptureThread::updateMetadata_l() AudioFlinger::ThreadBase::MetadataUpdate AudioFlinger::MmapCaptureThread::updateMetadata_l() { if (!isStreamInitialized() || !mActiveTracks.readAndClearHasChanged()) { return; // nothing to do return {}; // nothing to do } StreamInHalInterface::SinkMetadata metadata; for (const sp<MmapTrack> &track : mActiveTracks) { Loading @@ -10878,6 +10896,9 @@ void AudioFlinger::MmapCaptureThread::updateMetadata_l() metadata.tracks.push_back(trackMetadata); } mInput->stream->updateSinkMetadata(metadata); MetadataUpdate change; change.recordMetadataUpdate = metadata.tracks; return change; } void AudioFlinger::MmapCaptureThread::setRecordSilenced(audio_port_handle_t portId, bool silenced) Loading
services/audioflinger/Threads.h +9 −5 Original line number Diff line number Diff line Loading @@ -607,7 +607,11 @@ protected: void checkSuspendOnAddEffectChain_l(const sp<EffectChain>& chain); // sends the metadata of the active tracks to the HAL virtual void updateMetadata_l() = 0; struct MetadataUpdate { std::vector<playback_track_metadata_v7_t> playbackMetadataUpdate; std::vector<record_track_metadata_v7_t> recordMetadataUpdate; }; virtual MetadataUpdate updateMetadata_l() = 0; String16 getWakeLockTag(); Loading Loading @@ -1277,7 +1281,7 @@ private: void removeTrack_l(const sp<Track>& track); void readOutputParameters_l(); void updateMetadata_l() final; MetadataUpdate updateMetadata_l() final; virtual void sendMetadataToBackend_l(const StreamOutHalInterface::SourceMetadata& metadata); void collectTimestamps_l(); Loading Loading @@ -1983,7 +1987,7 @@ public: status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction); status_t setPreferredMicrophoneFieldDimension(float zoom); void updateMetadata_l() override; MetadataUpdate updateMetadata_l() override; bool fastTrackAvailable() const { return mFastTrackAvail; } Loading Loading @@ -2257,7 +2261,7 @@ public: virtual void checkSilentMode_l(); void processVolume_l() override; void updateMetadata_l() override; MetadataUpdate updateMetadata_l() override; virtual void toAudioPortConfig(struct audio_port_config *config); Loading Loading @@ -2290,7 +2294,7 @@ public: status_t exitStandby_l() REQUIRES(mLock) override; void updateMetadata_l() override; MetadataUpdate updateMetadata_l() override; void processVolume_l() override; void setRecordSilenced(audio_port_handle_t portId, bool silenced) override; Loading
services/audioflinger/sounddose/SoundDoseManager.cpp +3 −4 Original line number Diff line number Diff line Loading @@ -163,7 +163,7 @@ audio_port_handle_t SoundDoseManager::getIdForAudioDevice(const AudioDevice& aud auto adt = AudioDeviceTypeAddr(type, address); auto deviceIt = mActiveDevices.find(adt); if (deviceIt == mActiveDevices.end()) { ALOGE("%s: could not find port id for device %s", __func__, adt.toString().c_str()); ALOGI("%s: could not find port id for device %s", __func__, adt.toString().c_str()); return AUDIO_PORT_HANDLE_NONE; } return deviceIt->second; Loading @@ -187,7 +187,6 @@ void SoundDoseManager::clearMapDeviceIdEntries(audio_port_handle_t deviceId) { } ++activeDevice; } return; } ndk::ScopedAStatus SoundDoseManager::HalSoundDoseCallback::onMomentaryExposureWarning( Loading @@ -206,7 +205,7 @@ ndk::ScopedAStatus SoundDoseManager::HalSoundDoseCallback::onMomentaryExposureWa auto id = soundDoseManager->getIdForAudioDevice(in_audioDevice); if (id == AUDIO_PORT_HANDLE_NONE) { ALOGW("%s: no mapped id for audio device with type %d and address %s", ALOGI("%s: no mapped id for audio device with type %d and address %s", __func__, in_audioDevice.type.type, in_audioDevice.address.get<AudioDeviceAddress::id>().c_str()); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); Loading @@ -233,7 +232,7 @@ ndk::ScopedAStatus SoundDoseManager::HalSoundDoseCallback::onNewMelValues( auto id = soundDoseManager->getIdForAudioDevice(in_audioDevice); if (id == AUDIO_PORT_HANDLE_NONE) { ALOGW("%s: no mapped id for audio device with type %d and address %s", ALOGI("%s: no mapped id for audio device with type %d and address %s", __func__, in_audioDevice.type.type, in_audioDevice.address.get<AudioDeviceAddress::id>().c_str()); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); Loading