|
|
|
@ -810,7 +810,7 @@ status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
|
|
|
|
|
"flags %#x",
|
|
|
|
|
device, config->sample_rate, config->format, config->channel_mask, *flags);
|
|
|
|
|
|
|
|
|
|
*output = getOutputForDevice(device, session, *stream, config, flags);
|
|
|
|
|
*output = getOutputForDevice(device, session, *stream, *output, config, flags);
|
|
|
|
|
if (*output == AUDIO_IO_HANDLE_NONE) {
|
|
|
|
|
mOutputRoutes.removeRoute(session);
|
|
|
|
|
return INVALID_OPERATION;
|
|
|
|
@ -829,10 +829,11 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice(
|
|
|
|
|
audio_devices_t device,
|
|
|
|
|
audio_session_t session,
|
|
|
|
|
audio_stream_type_t stream,
|
|
|
|
|
audio_io_handle_t originalOutput,
|
|
|
|
|
const audio_config_t *config,
|
|
|
|
|
audio_output_flags_t *flags)
|
|
|
|
|
{
|
|
|
|
|
audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
|
|
|
|
|
audio_io_handle_t output = originalOutput;
|
|
|
|
|
status_t status;
|
|
|
|
|
|
|
|
|
|
// open a direct output if required by specified parameters
|
|
|
|
@ -896,19 +897,22 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (profile != 0) {
|
|
|
|
|
for (size_t i = 0; i < mOutputs.size(); i++) {
|
|
|
|
|
sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
|
|
|
|
|
if (!desc->isDuplicated() && (profile == desc->mProfile)) {
|
|
|
|
|
// reuse direct output if currently open by the same client
|
|
|
|
|
// and configured with same parameters
|
|
|
|
|
if ((config->sample_rate == desc->mSamplingRate) &&
|
|
|
|
|
audio_formats_match(config->format, desc->mFormat) &&
|
|
|
|
|
(config->channel_mask == desc->mChannelMask) &&
|
|
|
|
|
(session == desc->mDirectClientSession)) {
|
|
|
|
|
desc->mDirectOpenCount++;
|
|
|
|
|
ALOGV("getOutputForDevice() reusing direct output %d for session %d",
|
|
|
|
|
mOutputs.keyAt(i), session);
|
|
|
|
|
return mOutputs.keyAt(i);
|
|
|
|
|
// exclude MMAP streams
|
|
|
|
|
if ((*flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) == 0 || output != AUDIO_IO_HANDLE_NONE) {
|
|
|
|
|
for (size_t i = 0; i < mOutputs.size(); i++) {
|
|
|
|
|
sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
|
|
|
|
|
if (!desc->isDuplicated() && (profile == desc->mProfile)) {
|
|
|
|
|
// reuse direct output if currently open by the same client
|
|
|
|
|
// and configured with same parameters
|
|
|
|
|
if ((config->sample_rate == desc->mSamplingRate) &&
|
|
|
|
|
audio_formats_match(config->format, desc->mFormat) &&
|
|
|
|
|
(config->channel_mask == desc->mChannelMask) &&
|
|
|
|
|
(session == desc->mDirectClientSession)) {
|
|
|
|
|
desc->mDirectOpenCount++;
|
|
|
|
|
ALOGI("getOutputForDevice() reusing direct output %d for session %d",
|
|
|
|
|
mOutputs.keyAt(i), session);
|
|
|
|
|
return mOutputs.keyAt(i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -962,7 +966,7 @@ non_direct_output:
|
|
|
|
|
|
|
|
|
|
// A request for HW A/V sync cannot fallback to a mixed output because time
|
|
|
|
|
// stamps are embedded in audio data
|
|
|
|
|
if ((*flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) {
|
|
|
|
|
if ((*flags & (AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_MMAP_NOIRQ)) != 0) {
|
|
|
|
|
return AUDIO_IO_HANDLE_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|