summaryrefslogtreecommitdiffstats
path: root/services/audioflinger
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2014-07-25 16:20:43 -0700
committerEric Laurent <elaurent@google.com>2014-07-28 12:06:00 -0700
commitcf2c0210c8afbe7d0661ccbbae3835b5ce73c0bf (patch)
tree26824707249d553efaabe2003381b4e9159e199d /services/audioflinger
parent97117153a0d681be70bfa9dc9876541375355c47 (diff)
downloadframeworks_av-cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bf.zip
frameworks_av-cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bf.tar.gz
frameworks_av-cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bf.tar.bz2
AudioFlinger: update openInput() and openOutput()
Add parameters to openInput() and openOutput(): device address, input source. Allow caller to specify a given I/O handle Group parameters in a struct audio_config. Bug: 12378680. Change-Id: I7e9af74c0d996561cc13cbee7d9012d2daf33025
Diffstat (limited to 'services/audioflinger')
-rw-r--r--services/audioflinger/AudioFlinger.cpp202
-rw-r--r--services/audioflinger/AudioFlinger.h39
-rw-r--r--services/audioflinger/PatchPanel.cpp58
3 files changed, 148 insertions, 151 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index f10a561..b2f46f5 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1097,7 +1097,7 @@ size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t form
AutoMutex lock(mHardwareLock);
mHardwareStatus = AUDIO_HW_GET_INPUT_BUFFER_SIZE;
- struct audio_config config;
+ audio_config_t config;
memset(&config, 0, sizeof(config));
config.sample_rate = sampleRate;
config.channel_mask = channelMask;
@@ -1577,17 +1577,21 @@ status_t AudioFlinger::setLowRamDevice(bool isLowRamDevice)
sp<AudioFlinger::PlaybackThread> AudioFlinger::openOutput_l(audio_module_handle_t module,
- audio_devices_t device,
- struct audio_config *config,
+ audio_io_handle_t *output,
+ audio_config_t *config,
+ audio_devices_t devices,
+ const String8& address,
audio_output_flags_t flags)
{
- AudioHwDevice *outHwDev = findSuitableHwDev_l(module, device);
+ AudioHwDevice *outHwDev = findSuitableHwDev_l(module, devices);
if (outHwDev == NULL) {
- return AUDIO_IO_HANDLE_NONE;
+ return 0;
}
audio_hw_device_t *hwDevHal = outHwDev->hwDevice();
- audio_io_handle_t id = nextUniqueId();
+ if (*output == AUDIO_IO_HANDLE_NONE) {
+ *output = nextUniqueId();
+ }
mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
@@ -1604,7 +1608,7 @@ sp<AudioFlinger::PlaybackThread> AudioFlinger::openOutput_l(audio_module_handle_
//config->format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
//config->format = AUDIO_FORMAT_PCM_32_BIT;
//config->format = AUDIO_FORMAT_PCM_8_24_BIT;
- // ALOGV("openOutput() upgrading format to %#08x", config.format);
+ // ALOGV("openOutput_l() upgrading format to %#08x", config->format);
}
if (kEnableExtendedChannels) {
// Specify channel mask (uncomment one below to choose)
@@ -1615,14 +1619,15 @@ sp<AudioFlinger::PlaybackThread> AudioFlinger::openOutput_l(audio_module_handle_
}
status_t status = hwDevHal->open_output_stream(hwDevHal,
- id,
- device,
- flags,
- config,
- &outStream);
+ *output,
+ devices,
+ flags,
+ config,
+ &outStream,
+ address.string());
mHardwareStatus = AUDIO_HW_IDLE;
- ALOGV("openOutput() openOutputStream returned output %p, sampleRate %d, Format %#x, "
+ ALOGV("openOutput_l() openOutputStream returned output %p, sampleRate %d, Format %#x, "
"channelMask %#x, status %d",
outStream,
config->sample_rate,
@@ -1631,76 +1636,53 @@ sp<AudioFlinger::PlaybackThread> AudioFlinger::openOutput_l(audio_module_handle_
status);
if (status == NO_ERROR && outStream != NULL) {
- AudioStreamOut *output = new AudioStreamOut(outHwDev, outStream, flags);
+ AudioStreamOut *outputStream = new AudioStreamOut(outHwDev, outStream, flags);
PlaybackThread *thread;
if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
- thread = new OffloadThread(this, output, id, device);
- ALOGV("openOutput() created offload output: ID %d thread %p", id, thread);
+ thread = new OffloadThread(this, outputStream, *output, devices);
+ ALOGV("openOutput_l() created offload output: ID %d thread %p", *output, thread);
} else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT)
|| !isValidPcmSinkFormat(config->format)
|| !isValidPcmSinkChannelMask(config->channel_mask)) {
- thread = new DirectOutputThread(this, output, id, device);
- ALOGV("openOutput() created direct output: ID %d thread %p", id, thread);
+ thread = new DirectOutputThread(this, outputStream, *output, devices);
+ ALOGV("openOutput_l() created direct output: ID %d thread %p", *output, thread);
} else {
- thread = new MixerThread(this, output, id, device);
- ALOGV("openOutput() created mixer output: ID %d thread %p", id, thread);
+ thread = new MixerThread(this, outputStream, *output, devices);
+ ALOGV("openOutput_l() created mixer output: ID %d thread %p", *output, thread);
}
- mPlaybackThreads.add(id, thread);
+ mPlaybackThreads.add(*output, thread);
return thread;
}
return 0;
}
-audio_io_handle_t AudioFlinger::openOutput(audio_module_handle_t module,
- audio_devices_t *pDevices,
- uint32_t *pSamplingRate,
- audio_format_t *pFormat,
- audio_channel_mask_t *pChannelMask,
- uint32_t *pLatencyMs,
- audio_output_flags_t flags,
- const audio_offload_info_t *offloadInfo)
+status_t AudioFlinger::openOutput(audio_module_handle_t module,
+ audio_io_handle_t *output,
+ audio_config_t *config,
+ audio_devices_t *devices,
+ const String8& address,
+ uint32_t *latencyMs,
+ audio_output_flags_t flags)
{
- struct audio_config config;
- memset(&config, 0, sizeof(config));
- config.sample_rate = (pSamplingRate != NULL) ? *pSamplingRate : 0;
- config.channel_mask = (pChannelMask != NULL) ? *pChannelMask : 0;
- config.format = (pFormat != NULL) ? *pFormat : AUDIO_FORMAT_DEFAULT;
- if (offloadInfo != NULL) {
- config.offload_info = *offloadInfo;
- }
-
ALOGV("openOutput(), module %d Device %x, SamplingRate %d, Format %#08x, Channels %x, flags %x",
module,
- (pDevices != NULL) ? *pDevices : 0,
- config.sample_rate,
- config.format,
- config.channel_mask,
+ (devices != NULL) ? *devices : 0,
+ config->sample_rate,
+ config->format,
+ config->channel_mask,
flags);
- ALOGV("openOutput(), offloadInfo %p version 0x%04x",
- offloadInfo, offloadInfo == NULL ? -1 : offloadInfo->version);
- if (pDevices == NULL || *pDevices == AUDIO_DEVICE_NONE) {
- return AUDIO_IO_HANDLE_NONE;
+ if (*devices == AUDIO_DEVICE_NONE) {
+ return BAD_VALUE;
}
Mutex::Autolock _l(mLock);
- sp<PlaybackThread> thread = openOutput_l(module, *pDevices, &config, flags);
+ sp<PlaybackThread> thread = openOutput_l(module, output, config, *devices, address, flags);
if (thread != 0) {
- if (pSamplingRate != NULL) {
- *pSamplingRate = config.sample_rate;
- }
- if (pFormat != NULL) {
- *pFormat = config.format;
- }
- if (pChannelMask != NULL) {
- *pChannelMask = config.channel_mask;
- }
- if (pLatencyMs != NULL) {
- *pLatencyMs = thread->latency();
- }
+ *latencyMs = thread->latency();
// notify client processes of the new output creation
thread->audioConfigChanged(AudioSystem::OUTPUT_OPENED);
@@ -1715,12 +1697,12 @@ audio_io_handle_t AudioFlinger::openOutput(audio_module_handle_t module,
mPrimaryHardwareDev->hwDevice()->set_mode(mPrimaryHardwareDev->hwDevice(), mMode);
mHardwareStatus = AUDIO_HW_IDLE;
- mPrimaryOutputSampleRate = config.sample_rate;
+ mPrimaryOutputSampleRate = config->sample_rate;
}
- return thread->id();
+ return NO_ERROR;
}
- return AUDIO_IO_HANDLE_NONE;
+ return NO_INIT;
}
audio_io_handle_t AudioFlinger::openDuplicateOutput(audio_io_handle_t output1,
@@ -1851,75 +1833,59 @@ status_t AudioFlinger::restoreOutput(audio_io_handle_t output)
return NO_ERROR;
}
-audio_io_handle_t AudioFlinger::openInput(audio_module_handle_t module,
- audio_devices_t *pDevices,
- uint32_t *pSamplingRate,
- audio_format_t *pFormat,
- audio_channel_mask_t *pChannelMask,
+status_t AudioFlinger::openInput(audio_module_handle_t module,
+ audio_io_handle_t *input,
+ audio_config_t *config,
+ audio_devices_t *device,
+ const String8& address,
+ audio_source_t source,
audio_input_flags_t flags)
{
Mutex::Autolock _l(mLock);
- if (pDevices == NULL || *pDevices == AUDIO_DEVICE_NONE) {
- return AUDIO_IO_HANDLE_NONE;
+ if (*device == AUDIO_DEVICE_NONE) {
+ return BAD_VALUE;
}
- struct audio_config config;
- memset(&config, 0, sizeof(config));
- config.sample_rate = (pSamplingRate != NULL) ? *pSamplingRate : 0;
- config.channel_mask = (pChannelMask != NULL) ? *pChannelMask : 0;
- config.format = (pFormat != NULL) ? *pFormat : AUDIO_FORMAT_DEFAULT;
-
- uint32_t reqSamplingRate = config.sample_rate;
- audio_format_t reqFormat = config.format;
- audio_channel_mask_t reqChannelMask = config.channel_mask;
-
- sp<RecordThread> thread = openInput_l(module, *pDevices, &config, flags);
+ sp<RecordThread> thread = openInput_l(module, input, config, *device, address, source, flags);
if (thread != 0) {
- if (pSamplingRate != NULL) {
- *pSamplingRate = reqSamplingRate;
- }
- if (pFormat != NULL) {
- *pFormat = config.format;
- }
- if (pChannelMask != NULL) {
- *pChannelMask = reqChannelMask;
- }
-
// notify client processes of the new input creation
thread->audioConfigChanged(AudioSystem::INPUT_OPENED);
- return thread->id();
+ return NO_ERROR;
}
- return AUDIO_IO_HANDLE_NONE;
+ return NO_INIT;
}
sp<AudioFlinger::RecordThread> AudioFlinger::openInput_l(audio_module_handle_t module,
+ audio_io_handle_t *input,
+ audio_config_t *config,
audio_devices_t device,
- struct audio_config *config,
+ const String8& address,
+ audio_source_t source,
audio_input_flags_t flags)
{
- uint32_t reqSamplingRate = config->sample_rate;
- audio_format_t reqFormat = config->format;
- audio_channel_mask_t reqChannelMask = config->channel_mask;
-
AudioHwDevice *inHwDev = findSuitableHwDev_l(module, device);
if (inHwDev == NULL) {
+ *input = AUDIO_IO_HANDLE_NONE;
return 0;
}
- audio_hw_device_t *inHwHal = inHwDev->hwDevice();
- audio_io_handle_t id = nextUniqueId();
+ if (*input == AUDIO_IO_HANDLE_NONE) {
+ *input = nextUniqueId();
+ }
+ audio_config_t halconfig = *config;
+ audio_hw_device_t *inHwHal = inHwDev->hwDevice();
audio_stream_in_t *inStream = NULL;
- status_t status = inHwHal->open_input_stream(inHwHal, id, device, config,
- &inStream, flags);
- ALOGV("openInput() openInputStream returned input %p, SamplingRate %d, Format %#x, Channels %x, "
- "flags %#x, status %d",
+ status_t status = inHwHal->open_input_stream(inHwHal, *input, device, &halconfig,
+ &inStream, flags, address.string(), source);
+ ALOGV("openInput_l() openInputStream returned input %p, SamplingRate %d"
+ ", Format %#x, Channels %x, flags %#x, status %d",
inStream,
- config->sample_rate,
- config->format,
- config->channel_mask,
+ halconfig.sample_rate,
+ halconfig.format,
+ halconfig.channel_mask,
flags,
status);
@@ -1927,14 +1893,15 @@ sp<AudioFlinger::RecordThread> AudioFlinger::openInput_l(audio_module_handle_t m
// conversion internally, try to open again with the proposed parameters. The AudioFlinger can
// resample the input and do mono to stereo or stereo to mono conversions on 16 bit PCM inputs.
if (status == BAD_VALUE &&
- reqFormat == config->format && config->format == AUDIO_FORMAT_PCM_16_BIT &&
- (config->sample_rate <= 2 * reqSamplingRate) &&
- (audio_channel_count_from_in_mask(config->channel_mask) <= FCC_2) &&
- (audio_channel_count_from_in_mask(reqChannelMask) <= FCC_2)) {
+ config->format == halconfig.format && halconfig.format == AUDIO_FORMAT_PCM_16_BIT &&
+ (halconfig.sample_rate <= 2 * config->sample_rate) &&
+ (audio_channel_count_from_in_mask(halconfig.channel_mask) <= FCC_2) &&
+ (audio_channel_count_from_in_mask(config->channel_mask) <= FCC_2)) {
// FIXME describe the change proposed by HAL (save old values so we can log them here)
- ALOGV("openInput() reopening with proposed sampling rate and channel mask");
+ ALOGV("openInput_l() reopening with proposed sampling rate and channel mask");
inStream = NULL;
- status = inHwHal->open_input_stream(inHwHal, id, device, config, &inStream, flags);
+ status = inHwHal->open_input_stream(inHwHal, *input, device, &halconfig,
+ &inStream, flags, address.string(), source);
// FIXME log this new status; HAL should not propose any further changes
}
@@ -1990,25 +1957,26 @@ sp<AudioFlinger::RecordThread> AudioFlinger::openInput_l(audio_module_handle_t m
}
#endif
- AudioStreamIn *input = new AudioStreamIn(inHwDev, inStream);
+ AudioStreamIn *inputStream = new AudioStreamIn(inHwDev, inStream);
// Start record thread
// RecordThread requires both input and output device indication to forward to audio
// pre processing modules
sp<RecordThread> thread = new RecordThread(this,
- input,
- id,
+ inputStream,
+ *input,
primaryOutputDevice_l(),
device
#ifdef TEE_SINK
, teeSink
#endif
);
- mRecordThreads.add(id, thread);
- ALOGV("openInput() created record thread: ID %d thread %p", id, thread.get());
+ mRecordThreads.add(*input, thread);
+ ALOGV("openInput_l() created record thread: ID %d thread %p", *input, thread.get());
return thread;
}
+ *input = AUDIO_IO_HANDLE_NONE;
return 0;
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index ab4c567..754273d 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -158,14 +158,13 @@ public:
virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
audio_channel_mask_t channelMask) const;
- virtual audio_io_handle_t openOutput(audio_module_handle_t module,
- audio_devices_t *pDevices,
- uint32_t *pSamplingRate,
- audio_format_t *pFormat,
- audio_channel_mask_t *pChannelMask,
- uint32_t *pLatencyMs,
- audio_output_flags_t flags,
- const audio_offload_info_t *offloadInfo);
+ virtual status_t openOutput(audio_module_handle_t module,
+ audio_io_handle_t *output,
+ audio_config_t *config,
+ audio_devices_t *devices,
+ const String8& address,
+ uint32_t *latencyMs,
+ audio_output_flags_t flags);
virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
audio_io_handle_t output2);
@@ -176,12 +175,13 @@ public:
virtual status_t restoreOutput(audio_io_handle_t output);
- virtual audio_io_handle_t openInput(audio_module_handle_t module,
- audio_devices_t *pDevices,
- uint32_t *pSamplingRate,
- audio_format_t *pFormat,
- audio_channel_mask_t *pChannelMask,
- audio_input_flags_t flags);
+ virtual status_t openInput(audio_module_handle_t module,
+ audio_io_handle_t *input,
+ audio_config_t *config,
+ audio_devices_t *device,
+ const String8& address,
+ audio_source_t source,
+ audio_input_flags_t flags);
virtual status_t closeInput(audio_io_handle_t input);
@@ -515,12 +515,17 @@ private:
MixerThread *checkMixerThread_l(audio_io_handle_t output) const;
RecordThread *checkRecordThread_l(audio_io_handle_t input) const;
sp<RecordThread> openInput_l(audio_module_handle_t module,
+ audio_io_handle_t *input,
+ audio_config_t *config,
audio_devices_t device,
- struct audio_config *config,
+ const String8& address,
+ audio_source_t source,
audio_input_flags_t flags);
sp<PlaybackThread> openOutput_l(audio_module_handle_t module,
- audio_devices_t device,
- struct audio_config *config,
+ audio_io_handle_t *output,
+ audio_config_t *config,
+ audio_devices_t devices,
+ const String8& address,
audio_output_flags_t flags);
void closeOutputFinish(sp<PlaybackThread> thread);
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index bf509e7..49422a9 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -231,14 +231,16 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
goto exit;
}
} else {
- struct audio_config config;
- config.sample_rate = 0;
- config.channel_mask = AUDIO_CHANNEL_NONE;
- config.format = AUDIO_FORMAT_DEFAULT;
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+ audio_devices_t device = patch->sinks[0].ext.device.type;
+ String8 address = String8(patch->sinks[0].ext.device.address);
+ audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
newPatch->mPlaybackThread = audioflinger->openOutput_l(
patch->sinks[0].ext.device.hw_module,
- patch->sinks[0].ext.device.type,
+ &output,
&config,
+ device,
+ address,
AUDIO_OUTPUT_FLAG_NONE);
ALOGV("audioflinger->openOutput_l() returned %p",
newPatch->mPlaybackThread.get());
@@ -249,14 +251,19 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
}
uint32_t channelCount = newPatch->mPlaybackThread->channelCount();
audio_devices_t device = patch->sources[0].ext.device.type;
- struct audio_config config;
+ String8 address = String8(patch->sources[0].ext.device.address);
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
audio_channel_mask_t inChannelMask = audio_channel_in_mask_from_count(channelCount);
config.sample_rate = newPatch->mPlaybackThread->sampleRate();
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,
- device,
+ &input,
&config,
+ device,
+ address,
+ AUDIO_SOURCE_MIC,
AUDIO_INPUT_FLAG_NONE);
ALOGV("audioflinger->openInput_l() returned %p inChannelMask %08x",
newPatch->mRecordThread.get(), inChannelMask);
@@ -298,14 +305,22 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
status = BAD_VALUE;
goto exit;
}
- AudioParameter param;
- param.addInt(String8(AudioParameter::keyRouting),
+ 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);
+ }
+ AudioParameter param = AudioParameter(String8(address));
+ free(address);
+ param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING),
(int)patch->sources[0].ext.device.type);
- param.addInt(String8(AudioParameter::keyInputSource),
- (int)patch->sinks[0].ext.mix.usecase.source);
-
+ 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());
+ param.toString().string());
status = thread->setParameters(param.toString());
}
}
@@ -348,8 +363,17 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
for (unsigned int i = 0; i < patch->num_sinks; i++) {
type |= patch->sinks[i].ext.device.type;
}
- AudioParameter param;
- param.addInt(String8(AudioParameter::keyRouting), (int)type);
+ char *address;
+ if (strcmp(patch->sinks[0].ext.device.address, "") != 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);
+ param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), (int)type);
status = thread->setParameters(param.toString());
}
@@ -578,7 +602,7 @@ status_t AudioFlinger::PatchPanel::releaseAudioPatch(audio_patch_handle_t handle
break;
}
AudioParameter param;
- param.addInt(String8(AudioParameter::keyRouting), 0);
+ param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), 0);
ALOGV("releaseAudioPatch() AUDIO_PORT_TYPE_DEVICE setParameters %s",
param.toString().string());
status = thread->setParameters(param.toString());
@@ -605,7 +629,7 @@ status_t AudioFlinger::PatchPanel::releaseAudioPatch(audio_patch_handle_t handle
status = thread->sendReleaseAudioPatchConfigEvent(mPatches[index]->mHalHandle);
} else {
AudioParameter param;
- param.addInt(String8(AudioParameter::keyRouting), (int)0);
+ param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), 0);
status = thread->setParameters(param.toString());
}
} break;