Merge "In favor of SW patch in AudioPolicyManager::connectAudioSource"

gugelfrei
Hongwei Wang 6 years ago committed by Android (Google) Code Review
commit d00c4607a5

@ -780,17 +780,39 @@ audio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream)
return output;
}
status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *output,
audio_session_t session,
audio_stream_type_t *stream,
uid_t uid,
const audio_config_t *config,
audio_output_flags_t *flags,
audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId)
status_t AudioPolicyManager::getAudioAttributes(audio_attributes_t *dstAttr,
const audio_attributes_t *srcAttr,
audio_stream_type_t srcStream)
{
if (srcAttr != NULL) {
if (!isValidAttributes(srcAttr)) {
ALOGE("%s invalid attributes: usage=%d content=%d flags=0x%x tags=[%s]",
__func__,
srcAttr->usage, srcAttr->content_type, srcAttr->flags,
srcAttr->tags);
return BAD_VALUE;
}
*dstAttr = *srcAttr;
} else {
if (srcStream < AUDIO_STREAM_MIN || srcStream >= AUDIO_STREAM_PUBLIC_CNT) {
ALOGE("%s: invalid stream type", __func__);
return BAD_VALUE;
}
stream_type_to_audio_attributes(srcStream, dstAttr);
}
return NO_ERROR;
}
status_t AudioPolicyManager::getOutputForAttrInt(audio_attributes_t *resultAttr,
audio_io_handle_t *output,
audio_session_t session,
const audio_attributes_t *attr,
audio_stream_type_t *stream,
uid_t uid,
const audio_config_t *config,
audio_output_flags_t *flags,
audio_port_handle_t *selectedDeviceId)
{
audio_attributes_t attributes;
DeviceVector outputDevices;
routing_strategy strategy;
audio_devices_t device;
@ -798,35 +820,20 @@ status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
audio_devices_t msdDevice =
getModuleDeviceTypes(mAvailableOutputDevices, AUDIO_HARDWARE_MODULE_ID_MSD);
// The supplied portId must be AUDIO_PORT_HANDLE_NONE
if (*portId != AUDIO_PORT_HANDLE_NONE) {
return INVALID_OPERATION;
}
if (attr != NULL) {
if (!isValidAttributes(attr)) {
ALOGE("getOutputForAttr() invalid attributes: usage=%d content=%d flags=0x%x tags=[%s]",
attr->usage, attr->content_type, attr->flags,
attr->tags);
return BAD_VALUE;
}
attributes = *attr;
} else {
if (*stream < AUDIO_STREAM_MIN || *stream >= AUDIO_STREAM_PUBLIC_CNT) {
ALOGE("getOutputForAttr(): invalid stream type");
return BAD_VALUE;
}
stream_type_to_audio_attributes(*stream, &attributes);
status_t status = getAudioAttributes(resultAttr, attr, *stream);
if (status != NO_ERROR) {
return status;
}
ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s flags=%08x"
ALOGV("%s usage=%d, content=%d, tag=%s flags=%08x"
" session %d selectedDeviceId %d",
attributes.usage, attributes.content_type, attributes.tags, attributes.flags,
__func__,
resultAttr->usage, resultAttr->content_type, resultAttr->tags, resultAttr->flags,
session, requestedDeviceId);
*stream = streamTypefromAttributesInt(&attributes);
*stream = streamTypefromAttributesInt(resultAttr);
strategy = getStrategyForAttr(&attributes);
strategy = getStrategyForAttr(resultAttr);
// First check for explicit routing (eg. setPreferredDevice)
if (requestedDeviceId != AUDIO_PORT_HANDLE_NONE) {
@ -836,30 +843,30 @@ status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
} else {
// If no explict route, is there a matching dynamic policy that applies?
sp<SwAudioOutputDescriptor> desc;
if (mPolicyMixes.getOutputForAttr(attributes, uid, desc) == NO_ERROR) {
if (mPolicyMixes.getOutputForAttr(*resultAttr, uid, desc) == NO_ERROR) {
ALOG_ASSERT(desc != 0, "Invalid desc returned by getOutputForAttr");
if (!audio_has_proportional_frames(config->format)) {
return BAD_VALUE;
}
*stream = streamTypefromAttributesInt(&attributes);
*stream = streamTypefromAttributesInt(resultAttr);
*output = desc->mIoHandle;
AudioMix *mix = desc->mPolicyMix;
sp<DeviceDescriptor> deviceDesc =
mAvailableOutputDevices.getDevice(mix->mDeviceType, mix->mDeviceAddress);
*selectedDeviceId = deviceDesc != 0 ? deviceDesc->getId() : AUDIO_PORT_HANDLE_NONE;
ALOGV("getOutputForAttr() returns output %d", *output);
goto exit;
ALOGV("%s returns output %d", __func__, *output);
return NO_ERROR;
}
// Virtual sources must always be dynamicaly or explicitly routed
if (attributes.usage == AUDIO_USAGE_VIRTUAL_SOURCE) {
ALOGW("getOutputForAttr() no policy mix found for usage AUDIO_USAGE_VIRTUAL_SOURCE");
if (resultAttr->usage == AUDIO_USAGE_VIRTUAL_SOURCE) {
ALOGW("%s no policy mix found for usage AUDIO_USAGE_VIRTUAL_SOURCE", __func__);
return BAD_VALUE;
}
device = getDeviceForStrategy(strategy, false /*fromCache*/);
}
if ((attributes.flags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
if ((resultAttr->flags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
*flags = (audio_output_flags_t)(*flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
}
@ -869,7 +876,7 @@ status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
// to getOutputForDevice.
// TODO: Remove check of AUDIO_STREAM_MUSIC once migration is completed on the app side.
if (device == AUDIO_DEVICE_OUT_TELEPHONY_TX &&
(*stream == AUDIO_STREAM_MUSIC || attributes.usage == AUDIO_USAGE_VOICE_COMMUNICATION) &&
(*stream == AUDIO_STREAM_MUSIC || resultAttr->usage == AUDIO_USAGE_VOICE_COMMUNICATION) &&
audio_is_linear_pcm(config->format) &&
isInCall()) {
if (requestedDeviceId != AUDIO_PORT_HANDLE_NONE) {
@ -880,9 +887,9 @@ status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
}
}
ALOGV("getOutputForAttr() device 0x%x, sampling rate %d, format %#x, channel mask %#x, "
ALOGV("%s device 0x%x, sampling rate %d, format %#x, channel mask %#x, "
"flags %#x",
device, config->sample_rate, config->format, config->channel_mask, *flags);
__func__, device, config->sample_rate, config->format, config->channel_mask, *flags);
*output = AUDIO_IO_HANDLE_NONE;
if (msdDevice != AUDIO_DEVICE_NONE) {
@ -906,22 +913,48 @@ status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
*selectedDeviceId = outputDevices.size() > 0 ? outputDevices.itemAt(0)->getId()
: AUDIO_PORT_HANDLE_NONE;
exit:
ALOGV("%s returns output %d selectedDeviceId %d", __func__, *output, *selectedDeviceId);
return NO_ERROR;
}
status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *output,
audio_session_t session,
audio_stream_type_t *stream,
uid_t uid,
const audio_config_t *config,
audio_output_flags_t *flags,
audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId)
{
// The supplied portId must be AUDIO_PORT_HANDLE_NONE
if (*portId != AUDIO_PORT_HANDLE_NONE) {
return INVALID_OPERATION;
}
const audio_port_handle_t requestedDeviceId = *selectedDeviceId;
audio_attributes_t resultAttr;
status_t status = getOutputForAttrInt(&resultAttr, output, session, attr, stream, uid,
config, flags, selectedDeviceId);
if (status != NO_ERROR) {
return status;
}
audio_config_base_t clientConfig = {.sample_rate = config->sample_rate,
.format = config->format,
.channel_mask = config->channel_mask };
*portId = AudioPort::getNextUniqueId();
sp<TrackClientDescriptor> clientDesc =
new TrackClientDescriptor(*portId, uid, session, attributes, clientConfig,
new TrackClientDescriptor(*portId, uid, session, resultAttr, clientConfig,
requestedDeviceId, *stream,
getStrategyForAttr(&attributes),
getStrategyForAttr(&resultAttr),
*flags);
sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(*output);
outputDesc->addClient(clientDesc);
ALOGV(" getOutputForAttr() returns output %d selectedDeviceId %d for port ID %d",
*output, *selectedDeviceId, *portId);
ALOGV("%s returns output %d selectedDeviceId %d for port ID %d",
__func__, *output, requestedDeviceId, *portId);
return NO_ERROR;
}
@ -3400,11 +3433,20 @@ status_t AudioPolicyManager::connectAudioSource(const sp<SourceClientDescriptor>
srcDeviceDesc->getAudioPort()->mModule->getHalVersionMajor() >= 3 &&
srcDeviceDesc->getAudioPort()->mGains.size() > 0) {
ALOGV("%s AUDIO_DEVICE_API_VERSION_3_0", __FUNCTION__);
// create patch between src device and output device
// create Hwoutput and add to mHwOutputs
// TODO: may explicitly specify whether we should use HW or SW patch
// create patch between src device and output device
// create Hwoutput and add to mHwOutputs
} else {
SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(sinkDevice, mOutputs);
audio_io_handle_t output = selectOutput(outputs);
audio_attributes_t resultAttr;
audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
audio_config_t config = AUDIO_CONFIG_INITIALIZER;
config.sample_rate = sourceDesc->config().sample_rate;
config.channel_mask = sourceDesc->config().channel_mask;
config.format = sourceDesc->config().format;
audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
getOutputForAttrInt(&resultAttr, &output, AUDIO_SESSION_NONE,
&attributes, &stream, sourceDesc->uid(), &config, &flags, &selectedDeviceId);
if (output == AUDIO_IO_HANDLE_NONE) {
ALOGV("%s no output for device %08x", __FUNCTION__, sinkDevice);
return INVALID_OPERATION;
@ -3437,6 +3479,13 @@ status_t AudioPolicyManager::connectAudioSource(const sp<SourceClientDescriptor>
__FUNCTION__, status);
return INVALID_OPERATION;
}
if (outputDesc->getClient(sourceDesc->portId()) != nullptr) {
ALOGW("%s source portId has already been attached to outputDesc", __func__);
return INVALID_OPERATION;
}
outputDesc->addClient(sourceDesc);
uint32_t delayMs = 0;
status = startSource(outputDesc, sourceDesc, &delayMs);

@ -661,6 +661,21 @@ private:
const String8& address /*in*/,
SortedVector<audio_io_handle_t>& outputs /*out*/);
uint32_t curAudioPortGeneration() const { return mAudioPortGeneration; }
// internal method, get audio_attributes_t from either a source audio_attributes_t
// or audio_stream_type_t, respectively.
status_t getAudioAttributes(audio_attributes_t *dstAttr,
const audio_attributes_t *srcAttr,
audio_stream_type_t srcStream);
// internal method, called by getOutputForAttr() and connectAudioSource.
status_t getOutputForAttrInt(audio_attributes_t *resultAttr,
audio_io_handle_t *output,
audio_session_t session,
const audio_attributes_t *attr,
audio_stream_type_t *stream,
uid_t uid,
const audio_config_t *config,
audio_output_flags_t *flags,
audio_port_handle_t *selectedDeviceId);
// internal method to return the output handle for the given device and format
audio_io_handle_t getOutputForDevice(
audio_devices_t device,

Loading…
Cancel
Save