Loading services/audioflinger/PatchPanel.cpp +17 −21 Original line number Diff line number Diff line Loading @@ -200,26 +200,17 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa status = BAD_VALUE; goto exit; } // limit to connections between devices and input streams for HAL before 3.0 if (patch->sinks[i].ext.mix.hw_module == srcModule && (audioHwDevice->version() < AUDIO_DEVICE_API_VERSION_3_0) && (patch->sinks[i].type != AUDIO_PORT_TYPE_MIX)) { ALOGW("createAudioPatch() invalid sink type %d for device source", patch->sinks[i].type); status = BAD_VALUE; goto exit; } } if (patch->sinks[0].ext.device.hw_module != srcModule) { // limit to device to device connection if not on same hw module if (patch->sinks[0].type != AUDIO_PORT_TYPE_DEVICE) { ALOGW("createAudioPatch() invalid sink type for cross hw module"); status = INVALID_OPERATION; goto exit; } // special case num sources == 2 -=> reuse an exiting output mix to connect to the // sink // manage patches requiring a software bridge // - Device to device AND // - source HW module != destination HW module OR // - audio HAL version < 3.0 // - special patch request with 2 sources (reuse one existing output mix) if ((patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) && ((patch->sinks[0].ext.device.hw_module != srcModule) || (audioHwDevice->version() < AUDIO_DEVICE_API_VERSION_3_0) || (patch->num_sources == 2))) { if (patch->num_sources == 2) { if (patch->sources[1].type != AUDIO_PORT_TYPE_MIX || patch->sinks[0].ext.device.hw_module != Loading Loading @@ -304,6 +295,11 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa &halHandle); } } else { if (patch->sinks[0].type != AUDIO_PORT_TYPE_MIX) { status = INVALID_OPERATION; goto exit; } sp<ThreadBase> thread = audioflinger->checkRecordThread_l( patch->sinks[0].ext.mix.handle); if (thread == 0) { Loading Loading @@ -472,6 +468,7 @@ status_t AudioFlinger::PatchPanel::createPatchConnections(Patch *patch, // this track is given the same buffer as the PatchRecord buffer patch->mPatchTrack = new PlaybackThread::PatchTrack( patch->mPlaybackThread.get(), audioPatch->sources[1].ext.mix.usecase.stream, sampleRate, outChannelMask, format, Loading Loading @@ -578,8 +575,8 @@ status_t AudioFlinger::PatchPanel::releaseAudioPatch(audio_patch_handle_t handle break; } if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE && patch->sinks[0].ext.device.hw_module != srcModule) { if (removedPatch->mRecordPatchHandle != AUDIO_PATCH_HANDLE_NONE || removedPatch->mPlaybackPatchHandle != AUDIO_PATCH_HANDLE_NONE) { clearPatchConnections(removedPatch); break; } Loading Loading @@ -693,5 +690,4 @@ status_t AudioFlinger::PatchPanel::setAudioPortConfig(const struct audio_port_co return NO_ERROR; } } // namespace android services/audioflinger/PlaybackTracks.h +1 −0 Original line number Diff line number Diff line Loading @@ -298,6 +298,7 @@ class PatchTrack : public Track, public PatchProxyBufferProvider { public: PatchTrack(PlaybackThread *playbackThread, audio_stream_type_t streamType, uint32_t sampleRate, audio_channel_mask_t channelMask, audio_format_t format, Loading services/audioflinger/Tracks.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -1861,13 +1861,14 @@ void AudioFlinger::PlaybackThread::OutputTrack::clearBufferQueue() AudioFlinger::PlaybackThread::PatchTrack::PatchTrack(PlaybackThread *playbackThread, audio_stream_type_t streamType, uint32_t sampleRate, audio_channel_mask_t channelMask, audio_format_t format, size_t frameCount, void *buffer, IAudioFlinger::track_flags_t flags) : Track(playbackThread, NULL, AUDIO_STREAM_PATCH, : Track(playbackThread, NULL, streamType, sampleRate, format, channelMask, frameCount, buffer, 0, 0, getuid(), flags, TYPE_PATCH), mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true)) Loading services/audiopolicy/managerdefault/AudioPolicyManager.cpp +9 −2 Original line number Diff line number Diff line Loading @@ -353,6 +353,7 @@ void AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, int delayMs ALOG_ASSERT(!outputDesc->isDuplicated(), "updateCallRouting() RX device output is duplicated"); outputDesc->toAudioPortConfig(&patch.sources[1]); patch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH; patch.num_sources = 2; } Loading Loading @@ -395,6 +396,7 @@ void AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, int delayMs ALOG_ASSERT(!outputDesc->isDuplicated(), "updateCallRouting() RX device output is duplicated"); outputDesc->toAudioPortConfig(&patch.sources[1]); patch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH; patch.num_sources = 2; } Loading Loading @@ -2184,8 +2186,12 @@ status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch, } sinkDeviceDesc->toAudioPortConfig(&newPatch.sinks[i], &patch->sinks[i]); if (srcDeviceDesc->getModuleHandle() != sinkDeviceDesc->getModuleHandle()) { // only one sink supported when connected devices across HW modules // create a software bridge in PatchPanel if: // - source and sink devices are on differnt HW modules OR // - audio HAL version is < 3.0 if ((srcDeviceDesc->getModuleHandle() != sinkDeviceDesc->getModuleHandle()) || (srcDeviceDesc->mModule->mHalVersion < AUDIO_DEVICE_API_VERSION_3_0)) { // support only one sink device for now to simplify output selection logic if (patch->num_sinks > 1) { return INVALID_OPERATION; } Loading @@ -2202,6 +2208,7 @@ status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch, return INVALID_OPERATION; } outputDesc->toAudioPortConfig(&newPatch.sources[1], &patch->sources[0]); newPatch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH; newPatch.num_sources = 2; } } Loading Loading
services/audioflinger/PatchPanel.cpp +17 −21 Original line number Diff line number Diff line Loading @@ -200,26 +200,17 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa status = BAD_VALUE; goto exit; } // limit to connections between devices and input streams for HAL before 3.0 if (patch->sinks[i].ext.mix.hw_module == srcModule && (audioHwDevice->version() < AUDIO_DEVICE_API_VERSION_3_0) && (patch->sinks[i].type != AUDIO_PORT_TYPE_MIX)) { ALOGW("createAudioPatch() invalid sink type %d for device source", patch->sinks[i].type); status = BAD_VALUE; goto exit; } } if (patch->sinks[0].ext.device.hw_module != srcModule) { // limit to device to device connection if not on same hw module if (patch->sinks[0].type != AUDIO_PORT_TYPE_DEVICE) { ALOGW("createAudioPatch() invalid sink type for cross hw module"); status = INVALID_OPERATION; goto exit; } // special case num sources == 2 -=> reuse an exiting output mix to connect to the // sink // manage patches requiring a software bridge // - Device to device AND // - source HW module != destination HW module OR // - audio HAL version < 3.0 // - special patch request with 2 sources (reuse one existing output mix) if ((patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) && ((patch->sinks[0].ext.device.hw_module != srcModule) || (audioHwDevice->version() < AUDIO_DEVICE_API_VERSION_3_0) || (patch->num_sources == 2))) { if (patch->num_sources == 2) { if (patch->sources[1].type != AUDIO_PORT_TYPE_MIX || patch->sinks[0].ext.device.hw_module != Loading Loading @@ -304,6 +295,11 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa &halHandle); } } else { if (patch->sinks[0].type != AUDIO_PORT_TYPE_MIX) { status = INVALID_OPERATION; goto exit; } sp<ThreadBase> thread = audioflinger->checkRecordThread_l( patch->sinks[0].ext.mix.handle); if (thread == 0) { Loading Loading @@ -472,6 +468,7 @@ status_t AudioFlinger::PatchPanel::createPatchConnections(Patch *patch, // this track is given the same buffer as the PatchRecord buffer patch->mPatchTrack = new PlaybackThread::PatchTrack( patch->mPlaybackThread.get(), audioPatch->sources[1].ext.mix.usecase.stream, sampleRate, outChannelMask, format, Loading Loading @@ -578,8 +575,8 @@ status_t AudioFlinger::PatchPanel::releaseAudioPatch(audio_patch_handle_t handle break; } if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE && patch->sinks[0].ext.device.hw_module != srcModule) { if (removedPatch->mRecordPatchHandle != AUDIO_PATCH_HANDLE_NONE || removedPatch->mPlaybackPatchHandle != AUDIO_PATCH_HANDLE_NONE) { clearPatchConnections(removedPatch); break; } Loading Loading @@ -693,5 +690,4 @@ status_t AudioFlinger::PatchPanel::setAudioPortConfig(const struct audio_port_co return NO_ERROR; } } // namespace android
services/audioflinger/PlaybackTracks.h +1 −0 Original line number Diff line number Diff line Loading @@ -298,6 +298,7 @@ class PatchTrack : public Track, public PatchProxyBufferProvider { public: PatchTrack(PlaybackThread *playbackThread, audio_stream_type_t streamType, uint32_t sampleRate, audio_channel_mask_t channelMask, audio_format_t format, Loading
services/audioflinger/Tracks.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -1861,13 +1861,14 @@ void AudioFlinger::PlaybackThread::OutputTrack::clearBufferQueue() AudioFlinger::PlaybackThread::PatchTrack::PatchTrack(PlaybackThread *playbackThread, audio_stream_type_t streamType, uint32_t sampleRate, audio_channel_mask_t channelMask, audio_format_t format, size_t frameCount, void *buffer, IAudioFlinger::track_flags_t flags) : Track(playbackThread, NULL, AUDIO_STREAM_PATCH, : Track(playbackThread, NULL, streamType, sampleRate, format, channelMask, frameCount, buffer, 0, 0, getuid(), flags, TYPE_PATCH), mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true)) Loading
services/audiopolicy/managerdefault/AudioPolicyManager.cpp +9 −2 Original line number Diff line number Diff line Loading @@ -353,6 +353,7 @@ void AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, int delayMs ALOG_ASSERT(!outputDesc->isDuplicated(), "updateCallRouting() RX device output is duplicated"); outputDesc->toAudioPortConfig(&patch.sources[1]); patch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH; patch.num_sources = 2; } Loading Loading @@ -395,6 +396,7 @@ void AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, int delayMs ALOG_ASSERT(!outputDesc->isDuplicated(), "updateCallRouting() RX device output is duplicated"); outputDesc->toAudioPortConfig(&patch.sources[1]); patch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH; patch.num_sources = 2; } Loading Loading @@ -2184,8 +2186,12 @@ status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch, } sinkDeviceDesc->toAudioPortConfig(&newPatch.sinks[i], &patch->sinks[i]); if (srcDeviceDesc->getModuleHandle() != sinkDeviceDesc->getModuleHandle()) { // only one sink supported when connected devices across HW modules // create a software bridge in PatchPanel if: // - source and sink devices are on differnt HW modules OR // - audio HAL version is < 3.0 if ((srcDeviceDesc->getModuleHandle() != sinkDeviceDesc->getModuleHandle()) || (srcDeviceDesc->mModule->mHalVersion < AUDIO_DEVICE_API_VERSION_3_0)) { // support only one sink device for now to simplify output selection logic if (patch->num_sinks > 1) { return INVALID_OPERATION; } Loading @@ -2202,6 +2208,7 @@ status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch, return INVALID_OPERATION; } outputDesc->toAudioPortConfig(&newPatch.sources[1], &patch->sources[0]); newPatch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH; newPatch.num_sources = 2; } } Loading