summaryrefslogtreecommitdiffstats
path: root/services/audioflinger/PatchPanel.cpp
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2014-08-08 15:13:39 -0700
committerEric Laurent <elaurent@google.com>2014-08-08 17:07:31 -0700
commit874c4287a4e49c59ac88767751dce00fcd3edb73 (patch)
tree2a0e4adc0bd18f26c8488b74d7e3df9751d493df /services/audioflinger/PatchPanel.cpp
parent0912a5738d6baf2df7cd62e877240e3807b4b21f (diff)
downloadframeworks_av-874c4287a4e49c59ac88767751dce00fcd3edb73.zip
frameworks_av-874c4287a4e49c59ac88767751dce00fcd3edb73.tar.gz
frameworks_av-874c4287a4e49c59ac88767751dce00fcd3edb73.tar.bz2
audio policy: enable more than one sink per audio patch.
Allow creation of audio patches with more than one sink. More than one sink is enabled when: - Connecting an input device to output devices on the same audio HW module. - Connecting an output mix to output devices on the same audio HA module. All other patches are limited to one sink. Bug: 16879363. Change-Id: I95be6948ef29df64e51e5b8ace38c2db7f3e89f2
Diffstat (limited to 'services/audioflinger/PatchPanel.cpp')
-rw-r--r--services/audioflinger/PatchPanel.cpp64
1 files changed, 35 insertions, 29 deletions
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 49422a9..2d0a25f 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -151,12 +151,15 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
if (handle == NULL || patch == NULL) {
return BAD_VALUE;
}
- // limit number of sources to 1 for now or 2 sources for special cross hw module case.
- // only the audio policy manager can request a patch creation with 2 sources.
- if (patch->num_sources == 0 || patch->num_sources > 2 ||
+ if (patch->num_sources == 0 || patch->num_sources > AUDIO_PATCH_PORTS_MAX ||
patch->num_sinks == 0 || patch->num_sinks > AUDIO_PATCH_PORTS_MAX) {
return BAD_VALUE;
}
+ // limit number of sources to 1 for now or 2 sources for special cross hw module case.
+ // only the audio policy manager can request a patch creation with 2 sources.
+ if (patch->num_sources > 2) {
+ return INVALID_OPERATION;
+ }
if (*handle != AUDIO_PATCH_HANDLE_NONE) {
for (size_t index = 0; *handle != 0 && index < mPatches.size(); index++) {
@@ -173,20 +176,22 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
switch (patch->sources[0].type) {
case AUDIO_PORT_TYPE_DEVICE: {
- // limit number of sinks to 1 for now
- if (patch->num_sinks > 1) {
- status = BAD_VALUE;
- goto exit;
- }
- audio_module_handle_t src_module = patch->sources[0].ext.device.hw_module;
- ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(src_module);
+ audio_module_handle_t srcModule = patch->sources[0].ext.device.hw_module;
+ ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(srcModule);
if (index < 0) {
- ALOGW("createAudioPatch() bad src hw module %d", src_module);
+ ALOGW("createAudioPatch() bad src hw module %d", srcModule);
status = BAD_VALUE;
goto exit;
}
AudioHwDevice *audioHwDevice = audioflinger->mAudioHwDevs.valueAt(index);
for (unsigned int i = 0; i < patch->num_sinks; i++) {
+ // support only one sink if connection to a mix or across HW modules
+ if ((patch->sinks[i].type == AUDIO_PORT_TYPE_MIX ||
+ patch->sinks[i].ext.mix.hw_module != srcModule) &&
+ patch->num_sinks > 1) {
+ status = INVALID_OPERATION;
+ goto exit;
+ }
// reject connection to different sink types
if (patch->sinks[i].type != patch->sinks[0].type) {
ALOGW("createAudioPatch() different sink types in same patch not supported");
@@ -194,7 +199,7 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
goto exit;
}
// limit to connections between devices and input streams for HAL before 3.0
- if (patch->sinks[i].ext.mix.hw_module == src_module &&
+ 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",
@@ -204,7 +209,7 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
}
}
- if (patch->sinks[0].ext.device.hw_module != src_module) {
+ 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");
@@ -258,7 +263,7 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
config.channel_mask = inChannelMask;
config.format = newPatch->mPlaybackThread->format();
audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
- newPatch->mRecordThread = audioflinger->openInput_l(src_module,
+ newPatch->mRecordThread = audioflinger->openInput_l(srcModule,
&input,
&config,
device,
@@ -279,10 +284,10 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
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);
+ 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;
}
@@ -298,10 +303,10 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
}
} else {
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;
}
@@ -326,10 +331,10 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
}
} break;
case AUDIO_PORT_TYPE_MIX: {
- audio_module_handle_t src_module = patch->sources[0].ext.mix.hw_module;
- ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(src_module);
+ audio_module_handle_t srcModule = patch->sources[0].ext.mix.hw_module;
+ ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(srcModule);
if (index < 0) {
- ALOGW("createAudioPatch() bad src hw module %d", src_module);
+ ALOGW("createAudioPatch() bad src hw module %d", srcModule);
status = BAD_VALUE;
goto exit;
}
@@ -342,7 +347,7 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
goto exit;
}
// limit to connections between sinks and sources on same HW module
- if (patch->sinks[i].ext.device.hw_module != src_module) {
+ if (patch->sinks[i].ext.device.hw_module != srcModule) {
status = BAD_VALUE;
goto exit;
}
@@ -365,6 +370,7 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
}
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);
@@ -562,16 +568,16 @@ status_t AudioFlinger::PatchPanel::releaseAudioPatch(audio_patch_handle_t handle
switch (patch->sources[0].type) {
case AUDIO_PORT_TYPE_DEVICE: {
- audio_module_handle_t src_module = patch->sources[0].ext.device.hw_module;
- ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(src_module);
+ audio_module_handle_t srcModule = patch->sources[0].ext.device.hw_module;
+ ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(srcModule);
if (index < 0) {
- ALOGW("releaseAudioPatch() bad src hw module %d", src_module);
+ ALOGW("releaseAudioPatch() bad src hw module %d", srcModule);
status = BAD_VALUE;
break;
}
if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE &&
- patch->sinks[0].ext.device.hw_module != src_module) {
+ patch->sinks[0].ext.device.hw_module != srcModule) {
clearPatchConnections(removedPatch);
break;
}
@@ -609,10 +615,10 @@ status_t AudioFlinger::PatchPanel::releaseAudioPatch(audio_patch_handle_t handle
}
} break;
case AUDIO_PORT_TYPE_MIX: {
- audio_module_handle_t src_module = patch->sources[0].ext.mix.hw_module;
- ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(src_module);
+ audio_module_handle_t srcModule = patch->sources[0].ext.mix.hw_module;
+ ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(srcModule);
if (index < 0) {
- ALOGW("releaseAudioPatch() bad src hw module %d", src_module);
+ ALOGW("releaseAudioPatch() bad src hw module %d", srcModule);
status = BAD_VALUE;
break;
}