From cf2c0210c8afbe7d0661ccbbae3835b5ce73c0bf Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Fri, 25 Jul 2014 16:20:43 -0700 Subject: 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 --- include/media/IAudioFlinger.h | 28 +- media/libmedia/IAudioFlinger.cpp | 201 +++++------- services/audioflinger/AudioFlinger.cpp | 202 +++++------- services/audioflinger/AudioFlinger.h | 39 ++- services/audioflinger/PatchPanel.cpp | 58 +++- services/audiopolicy/AudioPolicyClientImpl.cpp | 37 ++- .../audiopolicy/AudioPolicyClientImplLegacy.cpp | 106 +++++-- services/audiopolicy/AudioPolicyInterface.h | 28 +- services/audiopolicy/AudioPolicyManager.cpp | 343 ++++++++++++--------- services/audiopolicy/AudioPolicyManager.h | 2 - services/audiopolicy/AudioPolicyService.h | 24 +- 11 files changed, 564 insertions(+), 504 deletions(-) diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h index 31312d3..58fb84a 100644 --- a/include/media/IAudioFlinger.h +++ b/include/media/IAudioFlinger.h @@ -145,26 +145,26 @@ public: virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask) const = 0; - 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 = NULL) = 0; + 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) = 0; virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1, audio_io_handle_t output2) = 0; virtual status_t closeOutput(audio_io_handle_t output) = 0; virtual status_t suspendOutput(audio_io_handle_t output) = 0; virtual status_t restoreOutput(audio_io_handle_t output) = 0; - 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) = 0; + 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) = 0; virtual status_t closeInput(audio_io_handle_t input) = 0; virtual status_t invalidateStream(audio_stream_type_t stream) = 0; diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp index bd7ea46..0f4e632 100644 --- a/media/libmedia/IAudioFlinger.cpp +++ b/media/libmedia/IAudioFlinger.cpp @@ -434,61 +434,40 @@ public: return reply.readInt64(); } - 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) { + if (output == NULL || config == NULL || devices == NULL || latencyMs == NULL) { + return BAD_VALUE; + } Parcel data, reply; - audio_devices_t devices = pDevices != NULL ? *pDevices : AUDIO_DEVICE_NONE; - uint32_t samplingRate = pSamplingRate != NULL ? *pSamplingRate : 0; - audio_format_t format = pFormat != NULL ? *pFormat : AUDIO_FORMAT_DEFAULT; - audio_channel_mask_t channelMask = pChannelMask != NULL ? - *pChannelMask : (audio_channel_mask_t)0; - uint32_t latency = pLatencyMs != NULL ? *pLatencyMs : 0; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); data.writeInt32(module); - data.writeInt32(devices); - data.writeInt32(samplingRate); - data.writeInt32(format); - data.writeInt32(channelMask); - data.writeInt32(latency); + data.write(config, sizeof(audio_config_t)); + data.writeInt32(*devices); + data.writeString8(address); data.writeInt32((int32_t) flags); - // hasOffloadInfo - if (offloadInfo == NULL) { - data.writeInt32(0); - } else { - data.writeInt32(1); - data.write(offloadInfo, sizeof(audio_offload_info_t)); - } - remote()->transact(OPEN_OUTPUT, data, &reply); - audio_io_handle_t output = (audio_io_handle_t) reply.readInt32(); - ALOGV("openOutput() returned output, %d", output); - devices = (audio_devices_t)reply.readInt32(); - if (pDevices != NULL) { - *pDevices = devices; - } - samplingRate = reply.readInt32(); - if (pSamplingRate != NULL) { - *pSamplingRate = samplingRate; - } - format = (audio_format_t) reply.readInt32(); - if (pFormat != NULL) { - *pFormat = format; - } - channelMask = (audio_channel_mask_t)reply.readInt32(); - if (pChannelMask != NULL) { - *pChannelMask = channelMask; + status_t status = remote()->transact(OPEN_OUTPUT, data, &reply); + if (status != NO_ERROR) { + *output = AUDIO_IO_HANDLE_NONE; + return status; } - latency = reply.readInt32(); - if (pLatencyMs != NULL) { - *pLatencyMs = latency; + status = (status_t)reply.readInt32(); + if (status != NO_ERROR) { + *output = AUDIO_IO_HANDLE_NONE; + return status; } - return output; + *output = (audio_io_handle_t)reply.readInt32(); + ALOGV("openOutput() returned output, %d", *output); + reply.read(config, sizeof(audio_config_t)); + *devices = (audio_devices_t)reply.readInt32(); + *latencyMs = reply.readInt32(); + return NO_ERROR; } virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1, @@ -529,46 +508,40 @@ public: return reply.readInt32(); } - 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) { + if (input == NULL || config == NULL || device == NULL) { + return BAD_VALUE; + } Parcel data, reply; - audio_devices_t devices = pDevices != NULL ? *pDevices : AUDIO_DEVICE_NONE; - uint32_t samplingRate = pSamplingRate != NULL ? *pSamplingRate : 0; - audio_format_t format = pFormat != NULL ? *pFormat : AUDIO_FORMAT_DEFAULT; - audio_channel_mask_t channelMask = pChannelMask != NULL ? - *pChannelMask : (audio_channel_mask_t)0; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); data.writeInt32(module); - data.writeInt32(devices); - data.writeInt32(samplingRate); - data.writeInt32(format); - data.writeInt32(channelMask); + data.writeInt32(*input); + data.write(config, sizeof(audio_config_t)); + data.writeInt32(*device); + data.writeString8(address); + data.writeInt32(source); data.writeInt32(flags); - remote()->transact(OPEN_INPUT, data, &reply); - audio_io_handle_t input = (audio_io_handle_t) reply.readInt32(); - devices = (audio_devices_t)reply.readInt32(); - if (pDevices != NULL) { - *pDevices = devices; - } - samplingRate = reply.readInt32(); - if (pSamplingRate != NULL) { - *pSamplingRate = samplingRate; - } - format = (audio_format_t) reply.readInt32(); - if (pFormat != NULL) { - *pFormat = format; + status_t status = remote()->transact(OPEN_INPUT, data, &reply); + if (status != NO_ERROR) { + *input = AUDIO_IO_HANDLE_NONE; + return status; } - channelMask = (audio_channel_mask_t)reply.readInt32(); - if (pChannelMask != NULL) { - *pChannelMask = channelMask; + status = (status_t)reply.readInt32(); + if (status != NO_ERROR) { + *input = AUDIO_IO_HANDLE_NONE; + return status; } - return input; + *input = (audio_io_handle_t)reply.readInt32(); + reply.read(config, sizeof(audio_config_t)); + *device = (audio_devices_t)reply.readInt32(); + return NO_ERROR; } virtual status_t closeInput(int input) @@ -1103,32 +1076,23 @@ status_t BnAudioFlinger::onTransact( case OPEN_OUTPUT: { CHECK_INTERFACE(IAudioFlinger, data, reply); audio_module_handle_t module = (audio_module_handle_t)data.readInt32(); + audio_config_t config; + data.read(&config, sizeof(audio_config_t)); audio_devices_t devices = (audio_devices_t)data.readInt32(); - uint32_t samplingRate = data.readInt32(); - audio_format_t format = (audio_format_t) data.readInt32(); - audio_channel_mask_t channelMask = (audio_channel_mask_t)data.readInt32(); - uint32_t latency = data.readInt32(); + String8 address(data.readString8()); audio_output_flags_t flags = (audio_output_flags_t) data.readInt32(); - bool hasOffloadInfo = data.readInt32() != 0; - audio_offload_info_t offloadInfo; - if (hasOffloadInfo) { - data.read(&offloadInfo, sizeof(audio_offload_info_t)); - } - audio_io_handle_t output = openOutput(module, - &devices, - &samplingRate, - &format, - &channelMask, - &latency, - flags, - hasOffloadInfo ? &offloadInfo : NULL); + uint32_t latencyMs; + audio_io_handle_t output; + status_t status = openOutput(module, &output, &config, + &devices, address, &latencyMs, flags); ALOGV("OPEN_OUTPUT output, %d", output); - reply->writeInt32((int32_t) output); - reply->writeInt32(devices); - reply->writeInt32(samplingRate); - reply->writeInt32(format); - reply->writeInt32(channelMask); - reply->writeInt32(latency); + reply->writeInt32((int32_t)status); + if (status == NO_ERROR) { + reply->writeInt32((int32_t)output); + reply->write(&config, sizeof(audio_config_t)); + reply->writeInt32(devices); + reply->writeInt32(latencyMs); + } return NO_ERROR; } break; case OPEN_DUPLICATE_OUTPUT: { @@ -1156,23 +1120,22 @@ status_t BnAudioFlinger::onTransact( case OPEN_INPUT: { CHECK_INTERFACE(IAudioFlinger, data, reply); audio_module_handle_t module = (audio_module_handle_t)data.readInt32(); - audio_devices_t devices = (audio_devices_t)data.readInt32(); - uint32_t samplingRate = data.readInt32(); - audio_format_t format = (audio_format_t) data.readInt32(); - audio_channel_mask_t channelMask = (audio_channel_mask_t)data.readInt32(); + audio_io_handle_t input = (audio_io_handle_t)data.readInt32(); + audio_config_t config; + data.read(&config, sizeof(audio_config_t)); + audio_devices_t device = (audio_devices_t)data.readInt32(); + String8 address(data.readString8()); + audio_source_t source = (audio_source_t)data.readInt32(); audio_input_flags_t flags = (audio_input_flags_t) data.readInt32(); - audio_io_handle_t input = openInput(module, - &devices, - &samplingRate, - &format, - &channelMask, - flags); - reply->writeInt32((int32_t) input); - reply->writeInt32(devices); - reply->writeInt32(samplingRate); - reply->writeInt32(format); - reply->writeInt32(channelMask); + status_t status = openInput(module, &input, &config, + &device, address, source, flags); + reply->writeInt32((int32_t) status); + if (status == NO_ERROR) { + reply->writeInt32((int32_t) input); + reply->write(&config, sizeof(audio_config_t)); + reply->writeInt32(device); + } return NO_ERROR; } break; case CLOSE_INPUT: { 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::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::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::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::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 thread = openOutput_l(module, *pDevices, &config, flags); + sp 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 thread = openInput_l(module, *pDevices, &config, flags); + sp 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::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::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::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 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 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 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 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; diff --git a/services/audiopolicy/AudioPolicyClientImpl.cpp b/services/audiopolicy/AudioPolicyClientImpl.cpp index b5af089..aa309d1 100644 --- a/services/audiopolicy/AudioPolicyClientImpl.cpp +++ b/services/audiopolicy/AudioPolicyClientImpl.cpp @@ -35,22 +35,20 @@ audio_module_handle_t AudioPolicyService::AudioPolicyClient::loadHwModule(const return af->loadHwModule(name); } -audio_io_handle_t AudioPolicyService::AudioPolicyClient::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 AudioPolicyService::AudioPolicyClient::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) { sp af = AudioSystem::get_audio_flinger(); if (af == 0) { ALOGW("%s: could not get AudioFlinger", __func__); - return 0; + return PERMISSION_DENIED; } - return af->openOutput(module, pDevices, pSamplingRate, pFormat, pChannelMask, - pLatencyMs, flags, offloadInfo); + return af->openOutput(module, output, config, devices, address, latencyMs, flags); } audio_io_handle_t AudioPolicyService::AudioPolicyClient::openDuplicateOutput( @@ -97,20 +95,21 @@ status_t AudioPolicyService::AudioPolicyClient::restoreOutput(audio_io_handle_t return af->restoreOutput(output); } -audio_io_handle_t AudioPolicyService::AudioPolicyClient::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) +status_t AudioPolicyService::AudioPolicyClient::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) { sp af = AudioSystem::get_audio_flinger(); if (af == 0) { ALOGW("%s: could not get AudioFlinger", __func__); - return 0; + return PERMISSION_DENIED; } - return af->openInput(module, pDevices, pSamplingRate, pFormat, pChannelMask, flags); + return af->openInput(module, input, config, device, address, source, flags); } status_t AudioPolicyService::AudioPolicyClient::closeInput(audio_io_handle_t input) diff --git a/services/audiopolicy/AudioPolicyClientImplLegacy.cpp b/services/audiopolicy/AudioPolicyClientImplLegacy.cpp index 97e12cc..9639096 100644 --- a/services/audiopolicy/AudioPolicyClientImplLegacy.cpp +++ b/services/audiopolicy/AudioPolicyClientImplLegacy.cpp @@ -62,6 +62,46 @@ audio_module_handle_t aps_load_hw_module(void *service __unused, return af->loadHwModule(name); } +static audio_io_handle_t open_output(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) +{ + sp af = AudioSystem::get_audio_flinger(); + if (af == 0) { + ALOGW("%s: could not get AudioFlinger", __func__); + return AUDIO_IO_HANDLE_NONE; + } + + if (pSamplingRate == NULL || pFormat == NULL || pChannelMask == NULL || + pDevices == NULL || pLatencyMs == NULL) { + return AUDIO_IO_HANDLE_NONE; + } + audio_config_t config = AUDIO_CONFIG_INITIALIZER; + config.sample_rate = *pSamplingRate; + config.format = *pFormat; + config.channel_mask = *pChannelMask; + if (offloadInfo != NULL) { + config.offload_info = *offloadInfo; + } + audio_io_handle_t output = AUDIO_IO_HANDLE_NONE; + status_t status = af->openOutput(module, &output, &config, pDevices, + String8(""), pLatencyMs, flags); + if (status == NO_ERROR) { + *pSamplingRate = config.sample_rate; + *pFormat = config.format; + *pChannelMask = config.channel_mask; + if (offloadInfo != NULL) { + *offloadInfo = config.offload_info; + } + } + return output; +} + // deprecated: replaced by aps_open_output_on_module() audio_io_handle_t aps_open_output(void *service __unused, audio_devices_t *pDevices, @@ -71,14 +111,8 @@ audio_io_handle_t aps_open_output(void *service __unused, uint32_t *pLatencyMs, audio_output_flags_t flags) { - sp af = AudioSystem::get_audio_flinger(); - if (af == 0) { - ALOGW("%s: could not get AudioFlinger", __func__); - return 0; - } - - return af->openOutput((audio_module_handle_t)0, pDevices, pSamplingRate, pFormat, pChannelMask, - pLatencyMs, flags); + return open_output((audio_module_handle_t)0, pDevices, pSamplingRate, pFormat, pChannelMask, + pLatencyMs, flags, NULL); } audio_io_handle_t aps_open_output_on_module(void *service __unused, @@ -91,12 +125,7 @@ audio_io_handle_t aps_open_output_on_module(void *service __unused, audio_output_flags_t flags, const audio_offload_info_t *offloadInfo) { - sp af = AudioSystem::get_audio_flinger(); - if (af == 0) { - ALOGW("%s: could not get AudioFlinger", __func__); - return 0; - } - return af->openOutput(module, pDevices, pSamplingRate, pFormat, pChannelMask, + return open_output(module, pDevices, pSamplingRate, pFormat, pChannelMask, pLatencyMs, flags, offloadInfo); } @@ -144,6 +173,37 @@ int aps_restore_output(void *service __unused, audio_io_handle_t output) return af->restoreOutput(output); } +static audio_io_handle_t open_input(audio_module_handle_t module, + audio_devices_t *pDevices, + uint32_t *pSamplingRate, + audio_format_t *pFormat, + audio_channel_mask_t *pChannelMask) +{ + sp af = AudioSystem::get_audio_flinger(); + if (af == 0) { + ALOGW("%s: could not get AudioFlinger", __func__); + return AUDIO_IO_HANDLE_NONE; + } + + if (pSamplingRate == NULL || pFormat == NULL || pChannelMask == NULL || pDevices == NULL) { + return AUDIO_IO_HANDLE_NONE; + } + audio_config_t config = AUDIO_CONFIG_INITIALIZER;; + config.sample_rate = *pSamplingRate; + config.format = *pFormat; + config.channel_mask = *pChannelMask; + audio_io_handle_t input = AUDIO_IO_HANDLE_NONE; + status_t status = af->openInput(module, &input, &config, pDevices, + String8(""), AUDIO_SOURCE_MIC, AUDIO_INPUT_FLAG_FAST /*FIXME*/); + if (status == NO_ERROR) { + *pSamplingRate = config.sample_rate; + *pFormat = config.format; + *pChannelMask = config.channel_mask; + } + return input; +} + + // deprecated: replaced by aps_open_input_on_module(), and acoustics parameter is ignored audio_io_handle_t aps_open_input(void *service __unused, audio_devices_t *pDevices, @@ -152,14 +212,7 @@ audio_io_handle_t aps_open_input(void *service __unused, audio_channel_mask_t *pChannelMask, audio_in_acoustics_t acoustics __unused) { - sp af = AudioSystem::get_audio_flinger(); - if (af == 0) { - ALOGW("%s: could not get AudioFlinger", __func__); - return 0; - } - - return af->openInput((audio_module_handle_t)0, pDevices, pSamplingRate, pFormat, pChannelMask, - AUDIO_INPUT_FLAG_FAST /*FIXME*/); + return open_input((audio_module_handle_t)0, pDevices, pSamplingRate, pFormat, pChannelMask); } audio_io_handle_t aps_open_input_on_module(void *service __unused, @@ -169,14 +222,7 @@ audio_io_handle_t aps_open_input_on_module(void *service __unused, audio_format_t *pFormat, audio_channel_mask_t *pChannelMask) { - sp af = AudioSystem::get_audio_flinger(); - if (af == 0) { - ALOGW("%s: could not get AudioFlinger", __func__); - return 0; - } - - return af->openInput(module, pDevices, pSamplingRate, pFormat, pChannelMask, - AUDIO_INPUT_FLAG_FAST /*FIXME*/); + return open_input(module, pDevices, pSamplingRate, pFormat, pChannelMask); } int aps_close_input(void *service __unused, audio_io_handle_t input) diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h index d45776b..0e53afc 100644 --- a/services/audiopolicy/AudioPolicyInterface.h +++ b/services/audiopolicy/AudioPolicyInterface.h @@ -211,14 +211,13 @@ public: // in case the audio policy manager has no specific requirements for the output being opened. // When the function returns, the parameter values reflect the actual values used by the audio hardware output stream. // The audio policy manager can check if the proposed parameters are suitable or not and act accordingly. - 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 = NULL) = 0; + 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) = 0; // creates a special output that is duplicated to the two outputs passed as arguments. The duplication is performed by // a special mixer thread in the AudioFlinger. virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1, audio_io_handle_t output2) = 0; @@ -235,12 +234,13 @@ public: // // opens an audio input - 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) = 0; + 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) = 0; // closes an audio input virtual status_t closeInput(audio_io_handle_t input) = 0; // diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp index c5248fe..7fd9b3a 100644 --- a/services/audiopolicy/AudioPolicyManager.cpp +++ b/services/audiopolicy/AudioPolicyManager.cpp @@ -686,8 +686,9 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice( audio_output_flags_t flags, const audio_offload_info_t *offloadInfo) { - audio_io_handle_t output = 0; + audio_io_handle_t output = AUDIO_IO_HANDLE_NONE; uint32_t latency = 0; + status_t status; #ifdef AUDIO_POLICY_TEST if (mCurOutput != 0) { @@ -698,21 +699,26 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice( ALOGV("getOutput() opening test output"); sp outputDesc = new AudioOutputDescriptor(NULL); outputDesc->mDevice = mTestDevice; - outputDesc->mSamplingRate = mTestSamplingRate; - outputDesc->mFormat = mTestFormat; - outputDesc->mChannelMask = mTestChannels; outputDesc->mLatency = mTestLatencyMs; outputDesc->mFlags = (audio_output_flags_t)(mDirectOutput ? AUDIO_OUTPUT_FLAG_DIRECT : 0); outputDesc->mRefCount[stream] = 0; - mTestOutputs[mCurOutput] = mpClientInterface->openOutput(0, &outputDesc->mDevice, - &outputDesc->mSamplingRate, - &outputDesc->mFormat, - &outputDesc->mChannelMask, - &outputDesc->mLatency, - outputDesc->mFlags, - offloadInfo); - if (mTestOutputs[mCurOutput]) { + audio_config_t config = AUDIO_CONFIG_INITIALIZER; + config.sample_rate = mTestSamplingRate; + config.channel_mask = mTestChannels; + config.format = mTestFormat; + config.offload_info = *offloadInfo; + status = mpClientInterface->openOutput(0, + &mTestOutputs[mCurOutput], + &config, + &outputDesc->mDevice, + String8(""), + &outputDesc->mLatency, + outputDesc->mFlags); + if (status == NO_ERROR) { + outputDesc->mSamplingRate = config.sample_rate; + outputDesc->mFormat = config.format; + outputDesc->mChannelMask = config.channel_mask; AudioParameter outputCmd = AudioParameter(); outputCmd.addInt(String8("set_id"),mCurOutput); mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString()); @@ -770,37 +776,42 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice( } outputDesc = new AudioOutputDescriptor(profile); outputDesc->mDevice = device; - outputDesc->mSamplingRate = samplingRate; - outputDesc->mFormat = format; - outputDesc->mChannelMask = channelMask; outputDesc->mLatency = 0; outputDesc->mFlags =(audio_output_flags_t) (outputDesc->mFlags | flags); - outputDesc->mRefCount[stream] = 0; - outputDesc->mStopTime[stream] = 0; - outputDesc->mDirectOpenCount = 1; - output = mpClientInterface->openOutput(profile->mModule->mHandle, - &outputDesc->mDevice, - &outputDesc->mSamplingRate, - &outputDesc->mFormat, - &outputDesc->mChannelMask, - &outputDesc->mLatency, - outputDesc->mFlags, - offloadInfo); + audio_config_t config = AUDIO_CONFIG_INITIALIZER; + config.sample_rate = samplingRate; + config.channel_mask = channelMask; + config.format = format; + config.offload_info = *offloadInfo; + status = mpClientInterface->openOutput(profile->mModule->mHandle, + &output, + &config, + &outputDesc->mDevice, + String8(""), + &outputDesc->mLatency, + outputDesc->mFlags); // only accept an output with the requested parameters - if (output == 0 || - (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) || - (format != AUDIO_FORMAT_DEFAULT && format != outputDesc->mFormat) || - (channelMask != 0 && channelMask != outputDesc->mChannelMask)) { + if (status != NO_ERROR || + (samplingRate != 0 && samplingRate != config.sample_rate) || + (format != AUDIO_FORMAT_DEFAULT && format != config.format) || + (channelMask != 0 && channelMask != config.channel_mask)) { ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d," "format %d %d, channelMask %04x %04x", output, samplingRate, outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask, outputDesc->mChannelMask); - if (output != 0) { + if (output != AUDIO_IO_HANDLE_NONE) { mpClientInterface->closeOutput(output); } - return 0; + return AUDIO_IO_HANDLE_NONE; } + outputDesc->mSamplingRate = config.sample_rate; + outputDesc->mChannelMask = config.channel_mask; + outputDesc->mFormat = config.format; + outputDesc->mRefCount[stream] = 0; + outputDesc->mStopTime[stream] = 0; + outputDesc->mDirectOpenCount = 1; + audio_io_handle_t srcOutput = getOutputForEffect(); addOutput(output, outputDesc); audio_io_handle_t dstOutput = getOutputForEffect(); @@ -1062,7 +1073,7 @@ audio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource, if (device == AUDIO_DEVICE_NONE) { ALOGW("getInput() could not find device for inputSource %d", inputSource); - return 0; + return AUDIO_IO_HANDLE_NONE; } // adapt channel selection to input source @@ -1089,43 +1100,49 @@ audio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource, ALOGW("getInput() could not find profile for device 0x%X, samplingRate %u, format %#x, " "channelMask 0x%X, flags %#x", device, samplingRate, format, channelMask, flags); - return 0; + return AUDIO_IO_HANDLE_NONE; } if (profile->mModule->mHandle == 0) { ALOGE("getInput(): HW module %s not opened", profile->mModule->mName); - return 0; + return AUDIO_IO_HANDLE_NONE; + } + + audio_config_t config = AUDIO_CONFIG_INITIALIZER; + config.sample_rate = samplingRate; + config.channel_mask = channelMask; + config.format = format; + audio_io_handle_t input = AUDIO_IO_HANDLE_NONE; + status_t status = mpClientInterface->openInput(profile->mModule->mHandle, + &input, + &config, + &device, + String8(""), + inputSource, + flags); + + // only accept input with the exact requested set of parameters + if (status != NO_ERROR || + (samplingRate != config.sample_rate) || + (format != config.format) || + (channelMask != config.channel_mask)) { + ALOGW("getInput() failed opening input: samplingRate %d, format %d, channelMask %x", + samplingRate, format, channelMask); + if (input != AUDIO_IO_HANDLE_NONE) { + mpClientInterface->closeInput(input); + } + return AUDIO_IO_HANDLE_NONE; } sp inputDesc = new AudioInputDescriptor(profile); - inputDesc->mInputSource = inputSource; - inputDesc->mDevice = device; + inputDesc->mRefCount = 0; + inputDesc->mOpenRefCount = 1; inputDesc->mSamplingRate = samplingRate; inputDesc->mFormat = format; inputDesc->mChannelMask = channelMask; - inputDesc->mRefCount = 0; - inputDesc->mOpenRefCount = 1; - - audio_io_handle_t input = mpClientInterface->openInput(profile->mModule->mHandle, - &inputDesc->mDevice, - &inputDesc->mSamplingRate, - &inputDesc->mFormat, - &inputDesc->mChannelMask, - flags); + inputDesc->mDevice = device; - // only accept input with the exact requested set of parameters - if (input == 0 || - (samplingRate != inputDesc->mSamplingRate) || - (format != inputDesc->mFormat) || - (channelMask != inputDesc->mChannelMask)) { - ALOGW("getInput() failed opening input: samplingRate %d, format %d, channelMask %x", - samplingRate, format, channelMask); - if (input != 0) { - mpClientInterface->closeInput(input); - } - return 0; - } addInput(input, inputDesc); mpClientInterface->onAudioPortListUpdate(); return input; @@ -2317,19 +2334,28 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa sp outputDesc = new AudioOutputDescriptor(outProfile); outputDesc->mDevice = profileType; - audio_io_handle_t output = mpClientInterface->openOutput( - outProfile->mModule->mHandle, - &outputDesc->mDevice, - &outputDesc->mSamplingRate, - &outputDesc->mFormat, - &outputDesc->mChannelMask, - &outputDesc->mLatency, - outputDesc->mFlags); - if (output == 0) { + audio_config_t config = AUDIO_CONFIG_INITIALIZER; + config.sample_rate = outputDesc->mSamplingRate; + config.channel_mask = outputDesc->mChannelMask; + config.format = outputDesc->mFormat; + audio_io_handle_t output = AUDIO_IO_HANDLE_NONE; + status_t status = mpClientInterface->openOutput(outProfile->mModule->mHandle, + &output, + &config, + &outputDesc->mDevice, + String8(""), + &outputDesc->mLatency, + outputDesc->mFlags); + + if (status != NO_ERROR) { ALOGW("Cannot open output stream for device %08x on hw module %s", outputDesc->mDevice, mHwModules[i]->mName); } else { + outputDesc->mSamplingRate = config.sample_rate; + outputDesc->mChannelMask = config.channel_mask; + outputDesc->mFormat = config.format; + for (size_t k = 0; k < outProfile->mSupportedDevices.size(); k++) { audio_devices_t type = outProfile->mSupportedDevices[k]->mDeviceType; ssize_t index = @@ -2368,15 +2394,21 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa inputDesc->mInputSource = AUDIO_SOURCE_MIC; inputDesc->mDevice = profileType; - audio_io_handle_t input = mpClientInterface->openInput( - inProfile->mModule->mHandle, - &inputDesc->mDevice, - &inputDesc->mSamplingRate, - &inputDesc->mFormat, - &inputDesc->mChannelMask, - AUDIO_INPUT_FLAG_NONE /*FIXME*/); - if (input != 0) { + audio_config_t config = AUDIO_CONFIG_INITIALIZER; + config.sample_rate = inputDesc->mSamplingRate; + config.channel_mask = inputDesc->mChannelMask; + config.format = inputDesc->mFormat; + audio_io_handle_t input = AUDIO_IO_HANDLE_NONE; + status_t status = mpClientInterface->openInput(inProfile->mModule->mHandle, + &input, + &config, + &inputDesc->mDevice, + String8(""), + AUDIO_SOURCE_MIC, + AUDIO_INPUT_FLAG_NONE); + + if (status == NO_ERROR) { for (size_t k = 0; k < inProfile->mSupportedDevices.size(); k++) { audio_devices_t type = inProfile->mSupportedDevices[k]->mDeviceType; ssize_t index = @@ -2575,17 +2607,25 @@ bool AudioPolicyManager::threadLoop() sp outputDesc = new AudioOutputDescriptor(NULL); outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER; - mPrimaryOutput = mpClientInterface->openOutput(moduleHandle, - &outputDesc->mDevice, - &outputDesc->mSamplingRate, - &outputDesc->mFormat, - &outputDesc->mChannelMask, - &outputDesc->mLatency, - outputDesc->mFlags); - if (mPrimaryOutput == 0) { - ALOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d", - outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask); + audio_config_t config = AUDIO_CONFIG_INITIALIZER; + config.sample_rate = outputDesc->mSamplingRate; + config.channel_mask = outputDesc->mChannelMask; + config.format = outputDesc->mFormat; + status_t status = mpClientInterface->openOutput(moduleHandle, + &mPrimaryOutput, + &config, + &outputDesc->mDevice, + String8(""), + &outputDesc->mLatency, + outputDesc->mFlags); + if (status != NO_ERROR) { + ALOGE("Failed to reopen hardware output stream, " + "samplingRate: %d, format %d, channels %d", + outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask); } else { + outputDesc->mSamplingRate = config.sample_rate; + outputDesc->mChannelMask = config.channel_mask; + outputDesc->mFormat = config.format; AudioParameter outputCmd = AudioParameter(); outputCmd.addInt(String8("set_id"), 0); mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); @@ -2637,16 +2677,6 @@ void AudioPolicyManager::addInput(audio_io_handle_t input, spmChannelMasks.size() < 2))) { ALOGW("checkOutputsForDevice() missing param"); mpClientInterface->closeOutput(output); - output = 0; + output = AUDIO_IO_HANDLE_NONE; } else if (profile->mSamplingRates[0] == 0 || profile->mFormats[0] == 0 || profile->mChannelMasks[0] == 0) { mpClientInterface->closeOutput(output); - desc->mSamplingRate = profile->pickSamplingRate(); - desc->mFormat = profile->pickFormat(); - desc->mChannelMask = profile->pickChannelMask(); - offloadInfo.sample_rate = desc->mSamplingRate; - offloadInfo.format = desc->mFormat; - offloadInfo.channel_mask = desc->mChannelMask; - output = mpClientInterface->openOutput( - profile->mModule->mHandle, - &desc->mDevice, - &desc->mSamplingRate, - &desc->mFormat, - &desc->mChannelMask, - &desc->mLatency, - desc->mFlags, - &offloadInfo); + config.sample_rate = profile->pickSamplingRate(); + config.channel_mask = profile->pickChannelMask(); + config.format = profile->pickFormat(); + config.offload_info.sample_rate = config.sample_rate; + config.offload_info.channel_mask = config.channel_mask; + config.offload_info.format = config.format; + status = mpClientInterface->openOutput(profile->mModule->mHandle, + &output, + &config, + &desc->mDevice, + address, + &desc->mLatency, + desc->mFlags); + if (status == NO_ERROR) { + desc->mSamplingRate = config.sample_rate; + desc->mChannelMask = config.channel_mask; + desc->mFormat = config.format; + } else { + output = AUDIO_IO_HANDLE_NONE; + } } - if (output != 0) { + if (output != AUDIO_IO_HANDLE_NONE) { addOutput(output, desc); if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) { - audio_io_handle_t duplicatedOutput = 0; + audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE; // set initial stream volume for device applyStreamVolumes(output, device, 0, true); @@ -2833,9 +2876,10 @@ status_t AudioPolicyManager::checkOutputsForDevice(audio_devices_t device, // open a duplicating output thread for the new output and the primary output duplicatedOutput = mpClientInterface->openDuplicateOutput(output, mPrimaryOutput); - if (duplicatedOutput != 0) { + if (duplicatedOutput != AUDIO_IO_HANDLE_NONE) { // add duplicated output descriptor - sp dupOutputDesc = new AudioOutputDescriptor(NULL); + sp dupOutputDesc = + new AudioOutputDescriptor(NULL); dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput); dupOutputDesc->mOutput2 = mOutputs.valueFor(output); dupOutputDesc->mSamplingRate = desc->mSamplingRate; @@ -2850,12 +2894,14 @@ status_t AudioPolicyManager::checkOutputsForDevice(audio_devices_t device, mpClientInterface->closeOutput(output); mOutputs.removeItem(output); nextAudioPortGeneration(); - output = 0; + output = AUDIO_IO_HANDLE_NONE; } } } + } else { + output = AUDIO_IO_HANDLE_NONE; } - if (output == 0) { + if (output == AUDIO_IO_HANDLE_NONE) { ALOGW("checkOutputsForDevice() could not open output for device %x", device); profiles.removeAt(profile_index); profile_index--; @@ -2984,17 +3030,28 @@ status_t AudioPolicyManager::checkInputsForDevice(audio_devices_t device, ALOGV("opening input for device 0x%X with params %s", device, address.string()); desc = new AudioInputDescriptor(profile); desc->mDevice = device; + audio_config_t config = AUDIO_CONFIG_INITIALIZER; + config.sample_rate = desc->mSamplingRate; + config.channel_mask = desc->mChannelMask; + config.format = desc->mFormat; + audio_io_handle_t input = AUDIO_IO_HANDLE_NONE; + status_t status = mpClientInterface->openInput(profile->mModule->mHandle, + &input, + &config, + &desc->mDevice, + address, + AUDIO_SOURCE_MIC, + AUDIO_INPUT_FLAG_NONE /*FIXME*/); - audio_io_handle_t input = mpClientInterface->openInput(profile->mModule->mHandle, - &desc->mDevice, - &desc->mSamplingRate, - &desc->mFormat, - &desc->mChannelMask, - AUDIO_INPUT_FLAG_NONE /*FIXME*/); + if (status == NO_ERROR) { + desc->mSamplingRate = config.sample_rate; + desc->mChannelMask = config.channel_mask; + desc->mFormat = config.format; - if (input != 0) { if (!address.isEmpty()) { - mpClientInterface->setParameters(input, addressToParameter(device, address)); + char *param = audio_device_address_to_parameter(device, address); + mpClientInterface->setParameters(input, String8(param)); + free(param); } // Here is where we step through and resolve any "dynamic" fields @@ -3034,7 +3091,7 @@ status_t AudioPolicyManager::checkInputsForDevice(audio_devices_t device, ((profile->mChannelMasks[0] == 0) && (profile->mChannelMasks.size() < 2))) { ALOGW("checkInputsForDevice() direct input missing param"); mpClientInterface->closeInput(input); - input = 0; + input = AUDIO_IO_HANDLE_NONE; } if (input != 0) { @@ -3042,7 +3099,7 @@ status_t AudioPolicyManager::checkInputsForDevice(audio_devices_t device, } } // endif input != 0 - if (input == 0) { + if (input == AUDIO_IO_HANDLE_NONE) { ALOGW("checkInputsForDevice() could not open input for device 0x%X", device); profiles.removeAt(profile_index); profile_index--; @@ -5621,7 +5678,7 @@ void AudioPolicyManager::AudioPort::dump(int fd, int spaces) const if (i == 0 && strcmp(formatStr, "") == 0) { snprintf(buffer, SIZE, "Dynamic"); } else { - snprintf(buffer, SIZE, "%-48s", formatStr); + snprintf(buffer, SIZE, "%s", formatStr); } result.append(buffer); result.append(i == (mFormats.size() - 1) ? "" : ", "); diff --git a/services/audiopolicy/AudioPolicyManager.h b/services/audiopolicy/AudioPolicyManager.h index 62b3ce5..cb4b056 100644 --- a/services/audiopolicy/AudioPolicyManager.h +++ b/services/audiopolicy/AudioPolicyManager.h @@ -802,8 +802,6 @@ private: uint32_t nextUniqueId(); uint32_t nextAudioPortGeneration(); uint32_t curAudioPortGeneration() const { return mAudioPortGeneration; } - // converts device address to string sent to audio HAL via setParameters - static String8 addressToParameter(audio_devices_t device, const String8 address); // internal method to return the output handle for the given device and format audio_io_handle_t getOutputForDevice( audio_devices_t device, diff --git a/services/audiopolicy/AudioPolicyService.h b/services/audiopolicy/AudioPolicyService.h index 08942ee..63fc0c3 100644 --- a/services/audiopolicy/AudioPolicyService.h +++ b/services/audiopolicy/AudioPolicyService.h @@ -361,14 +361,13 @@ private: // in case the audio policy manager has no specific requirements for the output being opened. // When the function returns, the parameter values reflect the actual values used by the audio hardware output stream. // The audio policy manager can check if the proposed parameters are suitable or not and act accordingly. - 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 = NULL); + 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); // creates a special output that is duplicated to the two outputs passed as arguments. The duplication is performed by // a special mixer thread in the AudioFlinger. virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1, audio_io_handle_t output2); @@ -386,10 +385,11 @@ private: // opens an audio input 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_io_handle_t *input, + audio_config_t *config, + audio_devices_t *devices, + const String8& address, + audio_source_t source, audio_input_flags_t flags); // closes an audio input virtual status_t closeInput(audio_io_handle_t input); -- cgit v1.1