diff options
Diffstat (limited to 'services/audioflinger/PatchPanel.cpp')
-rw-r--r-- | services/audioflinger/PatchPanel.cpp | 177 |
1 files changed, 61 insertions, 116 deletions
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp index 4f0c6b1..f6078a2 100644 --- a/services/audioflinger/PatchPanel.cpp +++ b/services/audioflinger/PatchPanel.cpp @@ -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 != @@ -283,52 +274,29 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa goto exit; } } else { - if (audioHwDevice->version() >= AUDIO_DEVICE_API_VERSION_3_0) { - if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) { - sp<ThreadBase> thread = audioflinger->checkRecordThread_l( - patch->sinks[0].ext.mix.handle); - if (thread == 0) { - ALOGW("createAudioPatch() bad capture I/O handle %d", - patch->sinks[0].ext.mix.handle); - status = BAD_VALUE; - goto exit; - } - status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle); - } else { - audio_hw_device_t *hwDevice = audioHwDevice->hwDevice(); - status = hwDevice->create_audio_patch(hwDevice, - patch->num_sources, - patch->sources, - patch->num_sinks, - patch->sinks, - &halHandle); - } - } else { + if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) { sp<ThreadBase> thread = audioflinger->checkRecordThread_l( - patch->sinks[0].ext.mix.handle); + patch->sinks[0].ext.mix.handle); if (thread == 0) { ALOGW("createAudioPatch() bad capture I/O handle %d", - patch->sinks[0].ext.mix.handle); + patch->sinks[0].ext.mix.handle); status = BAD_VALUE; goto exit; } - char *address; - if (strcmp(patch->sources[0].ext.device.address, "") != 0) { - address = audio_device_address_to_parameter( - patch->sources[0].ext.device.type, - patch->sources[0].ext.device.address); - } else { - address = (char *)calloc(1, 1); + status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle); + } else { + if (audioHwDevice->version() < AUDIO_DEVICE_API_VERSION_3_0) { + status = INVALID_OPERATION; + goto exit; } - AudioParameter param = AudioParameter(String8(address)); - free(address); - param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), - (int)patch->sources[0].ext.device.type); - param.addInt(String8(AUDIO_PARAMETER_STREAM_INPUT_SOURCE), - (int)patch->sinks[0].ext.mix.usecase.source); - ALOGV("createAudioPatch() AUDIO_PORT_TYPE_DEVICE setParameters %s", - param.toString().string()); - status = thread->setParameters(param.toString()); + + audio_hw_device_t *hwDevice = audioHwDevice->hwDevice(); + status = hwDevice->create_audio_patch(hwDevice, + patch->num_sources, + patch->sources, + patch->num_sinks, + patch->sinks, + &halHandle); } } } break; @@ -341,6 +309,7 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa goto exit; } // limit to connections between devices and output streams + audio_devices_t type = AUDIO_DEVICE_NONE; for (unsigned int i = 0; i < patch->num_sinks; i++) { if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) { ALOGW("createAudioPatch() invalid sink type %d for mix source", @@ -353,8 +322,8 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa status = BAD_VALUE; goto exit; } + type |= patch->sinks[i].ext.device.type; } - AudioHwDevice *audioHwDevice = audioflinger->mAudioHwDevs.valueAt(index); sp<ThreadBase> thread = audioflinger->checkPlaybackThread_l(patch->sources[0].ext.mix.handle); if (thread == 0) { @@ -363,28 +332,14 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa status = BAD_VALUE; goto exit; } - if (audioHwDevice->version() >= AUDIO_DEVICE_API_VERSION_3_0) { - status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle); - } else { - audio_devices_t type = AUDIO_DEVICE_NONE; - for (unsigned int i = 0; i < patch->num_sinks; i++) { - type |= patch->sinks[i].ext.device.type; - } - char *address; - if (strcmp(patch->sinks[0].ext.device.address, "") != 0) { - //FIXME: we only support address on first sink with HAL version < 3.0 - address = audio_device_address_to_parameter( - patch->sinks[0].ext.device.type, - patch->sinks[0].ext.device.address); - } else { - address = (char *)calloc(1, 1); - } - AudioParameter param = AudioParameter(String8(address)); - free(address); + if (thread == audioflinger->primaryPlaybackThread_l()) { + AudioParameter param = AudioParameter(); param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), (int)type); - status = thread->setParameters(param.toString()); + + audioflinger->broacastParametersToRecordThreads_l(param.toString()); } + status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle); } break; default: status = BAD_VALUE; @@ -472,6 +427,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, @@ -525,22 +481,31 @@ void AudioFlinger::PatchPanel::clearPatchConnections(Patch *patch) if (patch->mRecordThread != 0) { if (patch->mPatchRecord != 0) { patch->mRecordThread->deletePatchRecord(patch->mPatchRecord); - patch->mPatchRecord.clear(); } audioflinger->closeInputInternal_l(patch->mRecordThread); - patch->mRecordThread.clear(); } if (patch->mPlaybackThread != 0) { if (patch->mPatchTrack != 0) { patch->mPlaybackThread->deletePatchTrack(patch->mPatchTrack); - patch->mPatchTrack.clear(); } // if num sources == 2 we are reusing an existing playback thread so we do not close it if (patch->mAudioPatch.num_sources != 2) { audioflinger->closeOutputInternal_l(patch->mPlaybackThread); } + } + if (patch->mRecordThread != 0) { + if (patch->mPatchRecord != 0) { + patch->mPatchRecord.clear(); + } + patch->mRecordThread.clear(); + } + if (patch->mPlaybackThread != 0) { + if (patch->mPatchTrack != 0) { + patch->mPatchTrack.clear(); + } patch->mPlaybackThread.clear(); } + } /* Disconnect a patch */ @@ -578,42 +543,30 @@ 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; } - AudioHwDevice *audioHwDevice = audioflinger->mAudioHwDevs.valueAt(index); - if (audioHwDevice->version() >= AUDIO_DEVICE_API_VERSION_3_0) { - if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) { - sp<ThreadBase> thread = audioflinger->checkRecordThread_l( - patch->sinks[0].ext.mix.handle); - if (thread == 0) { - ALOGW("releaseAudioPatch() bad capture I/O handle %d", - patch->sinks[0].ext.mix.handle); - status = BAD_VALUE; - break; - } - status = thread->sendReleaseAudioPatchConfigEvent(removedPatch->mHalHandle); - } else { - audio_hw_device_t *hwDevice = audioHwDevice->hwDevice(); - status = hwDevice->release_audio_patch(hwDevice, removedPatch->mHalHandle); - } - } else { + if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) { sp<ThreadBase> thread = audioflinger->checkRecordThread_l( - patch->sinks[0].ext.mix.handle); + patch->sinks[0].ext.mix.handle); if (thread == 0) { ALOGW("releaseAudioPatch() bad capture I/O handle %d", - patch->sinks[0].ext.mix.handle); + patch->sinks[0].ext.mix.handle); status = BAD_VALUE; break; } - AudioParameter param; - param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), 0); - ALOGV("releaseAudioPatch() AUDIO_PORT_TYPE_DEVICE setParameters %s", - param.toString().string()); - status = thread->setParameters(param.toString()); + status = thread->sendReleaseAudioPatchConfigEvent(removedPatch->mHalHandle); + } else { + AudioHwDevice *audioHwDevice = audioflinger->mAudioHwDevs.valueAt(index); + if (audioHwDevice->version() < AUDIO_DEVICE_API_VERSION_3_0) { + status = INVALID_OPERATION; + break; + } + audio_hw_device_t *hwDevice = audioHwDevice->hwDevice(); + status = hwDevice->release_audio_patch(hwDevice, removedPatch->mHalHandle); } } break; case AUDIO_PORT_TYPE_MIX: { @@ -632,14 +585,7 @@ status_t AudioFlinger::PatchPanel::releaseAudioPatch(audio_patch_handle_t handle status = BAD_VALUE; break; } - AudioHwDevice *audioHwDevice = audioflinger->mAudioHwDevs.valueAt(index); - if (audioHwDevice->version() >= AUDIO_DEVICE_API_VERSION_3_0) { - status = thread->sendReleaseAudioPatchConfigEvent(removedPatch->mHalHandle); - } else { - AudioParameter param; - param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), 0); - status = thread->setParameters(param.toString()); - } + status = thread->sendReleaseAudioPatchConfigEvent(removedPatch->mHalHandle); } break; default: status = BAD_VALUE; @@ -693,5 +639,4 @@ status_t AudioFlinger::PatchPanel::setAudioPortConfig(const struct audio_port_co return NO_ERROR; } - -}; // namespace android +} // namespace android |