Loading services/audioflinger/PatchPanel.cpp +34 −0 Original line number Diff line number Diff line Loading @@ -168,12 +168,46 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa ALOGV("createAudioPatch() removing patch handle %d", *handle); halHandle = mPatches[index]->mHalHandle; Patch *removedPatch = mPatches[index]; // free resources owned by the removed patch if applicable // 1) if a software patch is present, release the playback and capture threads and // tracks created. This will also release the corresponding audio HAL patches if ((removedPatch->mRecordPatchHandle != AUDIO_PATCH_HANDLE_NONE) || (removedPatch->mPlaybackPatchHandle != AUDIO_PATCH_HANDLE_NONE)) { clearPatchConnections(removedPatch); } // 2) if the new patch and old patch source or sink are devices from different // hw modules, clear the audio HAL patches now because they will not be updated // by call to create_audio_patch() below which will happen on a different HW module if (halHandle != AUDIO_PATCH_HANDLE_NONE) { audio_module_handle_t hwModule = AUDIO_MODULE_HANDLE_NONE; if ((removedPatch->mAudioPatch.sources[0].type == AUDIO_PORT_TYPE_DEVICE) && ((patch->sources[0].type != AUDIO_PORT_TYPE_DEVICE) || (removedPatch->mAudioPatch.sources[0].ext.device.hw_module != patch->sources[0].ext.device.hw_module))) { hwModule = removedPatch->mAudioPatch.sources[0].ext.device.hw_module; } else if ((patch->num_sinks == 0) || ((removedPatch->mAudioPatch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE) && ((patch->sinks[0].type != AUDIO_PORT_TYPE_DEVICE) || (removedPatch->mAudioPatch.sinks[0].ext.device.hw_module != patch->sinks[0].ext.device.hw_module)))) { // Note on (patch->num_sinks == 0): this situation should not happen as // these special patches are only created by the policy manager but just // in case, systematically clear the HAL patch. // Note that removedPatch->mAudioPatch.num_sinks cannot be 0 here because // halHandle would be AUDIO_PATCH_HANDLE_NONE in this case. hwModule = removedPatch->mAudioPatch.sinks[0].ext.device.hw_module; } if (hwModule != AUDIO_MODULE_HANDLE_NONE) { ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(hwModule); if (index >= 0) { audio_hw_device_t *hwDevice = audioflinger->mAudioHwDevs.valueAt(index)->hwDevice(); hwDevice->release_audio_patch(hwDevice, halHandle); } } } mPatches.removeAt(index); delete removedPatch; break; Loading services/audioflinger/PatchPanel.h +12 −0 Original line number Diff line number Diff line Loading @@ -62,12 +62,24 @@ public: struct audio_patch mAudioPatch; audio_patch_handle_t mHandle; // handle for audio HAL patch handle present only when the audio HAL version is >= 3.0 audio_patch_handle_t mHalHandle; // below members are used by a software audio patch connecting a source device from a // given audio HW module to a sink device on an other audio HW module. // playback thread created by createAudioPatch() and released by clearPatchConnections() if // no existing playback thread can be used by the software patch sp<PlaybackThread> mPlaybackThread; // audio track created by createPatchConnections() and released by clearPatchConnections() sp<PlaybackThread::PatchTrack> mPatchTrack; // record thread created by createAudioPatch() and released by clearPatchConnections() sp<RecordThread> mRecordThread; // audio record created by createPatchConnections() and released by clearPatchConnections() sp<RecordThread::PatchRecord> mPatchRecord; // handle for audio patch connecting source device to record thread input. // created by createPatchConnections() and released by clearPatchConnections() audio_patch_handle_t mRecordPatchHandle; // handle for audio patch connecting playback thread output to sink device // created by createPatchConnections() and released by clearPatchConnections() audio_patch_handle_t mPlaybackPatchHandle; }; Loading Loading
services/audioflinger/PatchPanel.cpp +34 −0 Original line number Diff line number Diff line Loading @@ -168,12 +168,46 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa ALOGV("createAudioPatch() removing patch handle %d", *handle); halHandle = mPatches[index]->mHalHandle; Patch *removedPatch = mPatches[index]; // free resources owned by the removed patch if applicable // 1) if a software patch is present, release the playback and capture threads and // tracks created. This will also release the corresponding audio HAL patches if ((removedPatch->mRecordPatchHandle != AUDIO_PATCH_HANDLE_NONE) || (removedPatch->mPlaybackPatchHandle != AUDIO_PATCH_HANDLE_NONE)) { clearPatchConnections(removedPatch); } // 2) if the new patch and old patch source or sink are devices from different // hw modules, clear the audio HAL patches now because they will not be updated // by call to create_audio_patch() below which will happen on a different HW module if (halHandle != AUDIO_PATCH_HANDLE_NONE) { audio_module_handle_t hwModule = AUDIO_MODULE_HANDLE_NONE; if ((removedPatch->mAudioPatch.sources[0].type == AUDIO_PORT_TYPE_DEVICE) && ((patch->sources[0].type != AUDIO_PORT_TYPE_DEVICE) || (removedPatch->mAudioPatch.sources[0].ext.device.hw_module != patch->sources[0].ext.device.hw_module))) { hwModule = removedPatch->mAudioPatch.sources[0].ext.device.hw_module; } else if ((patch->num_sinks == 0) || ((removedPatch->mAudioPatch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE) && ((patch->sinks[0].type != AUDIO_PORT_TYPE_DEVICE) || (removedPatch->mAudioPatch.sinks[0].ext.device.hw_module != patch->sinks[0].ext.device.hw_module)))) { // Note on (patch->num_sinks == 0): this situation should not happen as // these special patches are only created by the policy manager but just // in case, systematically clear the HAL patch. // Note that removedPatch->mAudioPatch.num_sinks cannot be 0 here because // halHandle would be AUDIO_PATCH_HANDLE_NONE in this case. hwModule = removedPatch->mAudioPatch.sinks[0].ext.device.hw_module; } if (hwModule != AUDIO_MODULE_HANDLE_NONE) { ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(hwModule); if (index >= 0) { audio_hw_device_t *hwDevice = audioflinger->mAudioHwDevs.valueAt(index)->hwDevice(); hwDevice->release_audio_patch(hwDevice, halHandle); } } } mPatches.removeAt(index); delete removedPatch; break; Loading
services/audioflinger/PatchPanel.h +12 −0 Original line number Diff line number Diff line Loading @@ -62,12 +62,24 @@ public: struct audio_patch mAudioPatch; audio_patch_handle_t mHandle; // handle for audio HAL patch handle present only when the audio HAL version is >= 3.0 audio_patch_handle_t mHalHandle; // below members are used by a software audio patch connecting a source device from a // given audio HW module to a sink device on an other audio HW module. // playback thread created by createAudioPatch() and released by clearPatchConnections() if // no existing playback thread can be used by the software patch sp<PlaybackThread> mPlaybackThread; // audio track created by createPatchConnections() and released by clearPatchConnections() sp<PlaybackThread::PatchTrack> mPatchTrack; // record thread created by createAudioPatch() and released by clearPatchConnections() sp<RecordThread> mRecordThread; // audio record created by createPatchConnections() and released by clearPatchConnections() sp<RecordThread::PatchRecord> mPatchRecord; // handle for audio patch connecting source device to record thread input. // created by createPatchConnections() and released by clearPatchConnections() audio_patch_handle_t mRecordPatchHandle; // handle for audio patch connecting playback thread output to sink device // created by createPatchConnections() and released by clearPatchConnections() audio_patch_handle_t mPlaybackPatchHandle; }; Loading