CSD: Improve the MelProcessor lifecycle.

The MelProcessor lifecycle is now tied to the streaming thread
lifecycle. Whenever there are new patches and tracks for
sound dose we resume/pause the MEL calculation depending on
the track use case and device type.

Test: logging and dumpsys
Bug: 275370058
Change-Id: I9fb90df9ffb991f41f4209483bdafaf2b7474964
diff --git a/media/libnbaio/AudioStreamOutSink.cpp b/media/libnbaio/AudioStreamOutSink.cpp
index 8c54a3a..0ab5874 100644
--- a/media/libnbaio/AudioStreamOutSink.cpp
+++ b/media/libnbaio/AudioStreamOutSink.cpp
@@ -103,19 +103,24 @@
 void AudioStreamOutSink::startMelComputation(const sp<audio_utils::MelProcessor>& processor)
 {
     ALOGV("%s start mel computation for device %d", __func__, processor->getDeviceId());
-    mMelProcessor = processor;
-    // update format for MEL computation
+
+    mMelProcessor.store(processor);
     if (processor) {
-        processor->updateAudioFormat(mFormat.mSampleRate,  mFormat.mChannelCount, mFormat.mFormat);
+        // update format for MEL computation
+        processor->updateAudioFormat(mFormat.mSampleRate,
+                                     mFormat.mChannelCount,
+                                     mFormat.mFormat);
+        processor->resume();
     }
+
 }
 
 void AudioStreamOutSink::stopMelComputation()
 {
     auto melProcessor = mMelProcessor.load();
     if (melProcessor != nullptr) {
-        ALOGV("%s stop mel computation for device %d", __func__, melProcessor->getDeviceId());
-        mMelProcessor = nullptr;
+        ALOGV("%s pause mel computation for device %d", __func__, melProcessor->getDeviceId());
+        melProcessor->pause();
     }
 }
 
diff --git a/services/audioflinger/MelReporter.cpp b/services/audioflinger/MelReporter.cpp
index c5c9652..1b2f6c3 100644
--- a/services/audioflinger/MelReporter.cpp
+++ b/services/audioflinger/MelReporter.cpp
@@ -174,12 +174,14 @@
         }
     }
 
-    std::lock_guard _afl(mAudioFlinger.mLock);
-    std::lock_guard _l(mLock);
-    ALOGV("%s add patch handle %d to active devices", __func__, handle);
-    startMelComputationForActivePatch_l(newPatch);
-    newPatch.csdActive = true;
-    mActiveMelPatches[handle] = newPatch;
+    if (!newPatch.deviceHandles.empty()) {
+        std::lock_guard _afl(mAudioFlinger.mLock);
+        std::lock_guard _l(mLock);
+        ALOGV("%s add patch handle %d to active devices", __func__, handle);
+        startMelComputationForActivePatch_l(newPatch);
+        newPatch.csdActive = true;
+        mActiveMelPatches[handle] = newPatch;
+    }
 }
 
 void AudioFlinger::MelReporter::startMelComputationForActivePatch_l(const ActiveMelPatch& patch) {
@@ -250,7 +252,7 @@
         return;
     }
 
-   auto outputThread = mAudioFlinger.checkOutputThread_l(patch.streamHandle);
+    auto outputThread = mAudioFlinger.checkOutputThread_l(patch.streamHandle);
 
     ALOGV("%s: stop MEL for stream id: %d", __func__, patch.streamHandle);
     for (const auto& deviceId : patch.deviceHandles) {
@@ -264,7 +266,6 @@
         }
     }
 
-    mSoundDoseManager->removeStreamProcessor(patch.streamHandle);
     if (outputThread != nullptr) {
         outputThread->stopMelComputation_l();
     }
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index e113efb..cdcd4e3 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -10851,16 +10851,23 @@
         const sp<audio_utils::MelProcessor>& processor)
 {
     ALOGV("%s: starting mel processor for thread %d", __func__, id());
-    if (processor != nullptr) {
-        mMelProcessor = processor;
+    mMelProcessor.store(processor);
+    if (processor) {
+        processor->resume();
     }
+
+    // no need to update output format for MMapPlaybackThread since it is
+    // assigned constant for each thread
 }
 
 // stopMelComputation_l() must be called with AudioFlinger::mLock held
 void AudioFlinger::MmapPlaybackThread::stopMelComputation_l()
 {
-    ALOGV("%s: stopping mel processor for thread %d", __func__, id());
-    mMelProcessor = nullptr;
+    ALOGV("%s: pausing mel processor for thread %d", __func__, id());
+    auto melProcessor = mMelProcessor.load();
+    if (melProcessor != nullptr) {
+        melProcessor->pause();
+    }
 }
 
 void AudioFlinger::MmapPlaybackThread::dumpInternals_l(int fd, const Vector<String16>& args)
diff --git a/services/audioflinger/sounddose/SoundDoseManager.cpp b/services/audioflinger/sounddose/SoundDoseManager.cpp
index 21252d6..827f7d4 100644
--- a/services/audioflinger/sounddose/SoundDoseManager.cpp
+++ b/services/audioflinger/sounddose/SoundDoseManager.cpp
@@ -51,33 +51,36 @@
     std::lock_guard _l(mLock);
 
     if (mHalSoundDose != nullptr && !mDisableCsd) {
-        ALOGW("%s: using HAL MEL computation, no MelProcessor needed.", __func__);
+        ALOGD("%s: using HAL MEL computation, no MelProcessor needed.", __func__);
         return nullptr;
     }
 
     auto streamProcessor = mActiveProcessors.find(streamHandle);
-    sp<audio_utils::MelProcessor> processor;
-    if (streamProcessor != mActiveProcessors.end() &&
-            (processor = streamProcessor->second.promote())) {
-        ALOGV("%s: found callback for stream id %d", __func__, streamHandle);
-        const auto activeTypeIt = mActiveDeviceTypes.find(deviceId);
-        if (activeTypeIt != mActiveDeviceTypes.end()) {
-            processor->setAttenuation(mMelAttenuationDB[activeTypeIt->second]);
+    if (streamProcessor != mActiveProcessors.end()) {
+        auto processor = streamProcessor->second.promote();
+        // if processor is nullptr it means it was removed by the playback
+        // thread and can be replaced in the mActiveProcessors map
+        if (processor != nullptr) {
+            ALOGV("%s: found callback for stream id %d", __func__, streamHandle);
+            const auto activeTypeIt = mActiveDeviceTypes.find(deviceId);
+            if (activeTypeIt != mActiveDeviceTypes.end()) {
+                processor->setAttenuation(mMelAttenuationDB[activeTypeIt->second]);
+            }
+            processor->setDeviceId(deviceId);
+            processor->setOutputRs2UpperBound(mRs2UpperBound);
+            return processor;
         }
-        processor->setDeviceId(deviceId);
-        processor->setOutputRs2UpperBound(mRs2UpperBound);
-        return processor;
-    } else {
-        ALOGV("%s: creating new callback for stream id %d", __func__, streamHandle);
-        sp<audio_utils::MelProcessor> melProcessor = sp<audio_utils::MelProcessor>::make(
-                sampleRate, channelCount, format, this, deviceId, mRs2UpperBound);
-        const auto activeTypeIt = mActiveDeviceTypes.find(deviceId);
-        if (activeTypeIt != mActiveDeviceTypes.end()) {
-            melProcessor->setAttenuation(mMelAttenuationDB[activeTypeIt->second]);
-        }
-        mActiveProcessors[streamHandle] = melProcessor;
-        return melProcessor;
     }
+
+    ALOGV("%s: creating new callback for stream id %d", __func__, streamHandle);
+    sp<audio_utils::MelProcessor> melProcessor = sp<audio_utils::MelProcessor>::make(
+            sampleRate, channelCount, format, this, deviceId, mRs2UpperBound);
+    const auto activeTypeIt = mActiveDeviceTypes.find(deviceId);
+    if (activeTypeIt != mActiveDeviceTypes.end()) {
+        melProcessor->setAttenuation(mMelAttenuationDB[activeTypeIt->second]);
+    }
+    mActiveProcessors[streamHandle] = melProcessor;
+    return melProcessor;
 }
 
 bool SoundDoseManager::setHalSoundDoseInterface(const std::shared_ptr<ISoundDose>& halSoundDose) {