Merge "Implement AudioTrack.isDirectPlaybackSupported method"

gugelfrei
TreeHugger Robot 6 years ago committed by Android (Google) Code Review
commit a223769e77

@ -30,9 +30,11 @@
#include <utils/Log.h>
#include <private/media/AudioTrackShared.h>
#include <media/IAudioFlinger.h>
#include <media/IAudioPolicyService.h>
#include <media/AudioParameter.h>
#include <media/AudioPolicyHelper.h>
#include <media/AudioResamplerPublic.h>
#include <media/AudioSystem.h>
#include <media/MediaAnalyticsItem.h>
#include <media/TypeConverter.h>
@ -157,6 +159,15 @@ status_t AudioTrack::getMinFrameCount(
return NO_ERROR;
}
// static
bool AudioTrack::isDirectOutputSupported(const audio_config_base_t& config,
const audio_attributes_t& attributes) {
ALOGV("%s()", __FUNCTION__);
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return false;
return aps->isDirectOutputSupported(config, attributes);
}
// ---------------------------------------------------------------------------
static std::string audioContentTypeString(audio_content_type_t value) {
@ -465,16 +476,7 @@ status_t AudioTrack::set(
__func__,
mAttributes.usage, mAttributes.content_type, mAttributes.flags, mAttributes.tags);
mStreamType = AUDIO_STREAM_DEFAULT;
if ((mAttributes.flags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
}
if ((mAttributes.flags & AUDIO_FLAG_LOW_LATENCY) != 0) {
flags = (audio_output_flags_t) (flags | AUDIO_OUTPUT_FLAG_FAST);
}
// check deep buffer after flags have been modified above
if (flags == AUDIO_OUTPUT_FLAG_NONE && (mAttributes.flags & AUDIO_FLAG_DEEP_BUFFER) != 0) {
flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
}
audio_attributes_flags_to_audio_output_flags(mAttributes.flags, flags);
}
// these below should probably come from the audioFlinger too...

@ -62,6 +62,7 @@ enum {
SET_EFFECT_ENABLED,
IS_STREAM_ACTIVE_REMOTELY,
IS_OFFLOAD_SUPPORTED,
IS_DIRECT_OUTPUT_SUPPORTED,
LIST_AUDIO_PORTS,
GET_AUDIO_PORT,
CREATE_AUDIO_PATCH,
@ -523,6 +524,16 @@ public:
return reply.readInt32();
}
virtual bool isDirectOutputSupported(const audio_config_base_t& config,
const audio_attributes_t& attributes) {
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.write(&config, sizeof(audio_config_base_t));
data.write(&attributes, sizeof(audio_attributes_t));
status_t status = remote()->transact(IS_DIRECT_OUTPUT_SUPPORTED, data, &reply);
return status == NO_ERROR ? static_cast<bool>(reply.readInt32()) : false;
}
virtual status_t listAudioPorts(audio_port_role_t role,
audio_port_type_t type,
unsigned int *num_ports,
@ -1388,6 +1399,18 @@ status_t BnAudioPolicyService::onTransact(
return NO_ERROR;
}
case IS_DIRECT_OUTPUT_SUPPORTED: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
audio_config_base_t config = {};
audio_attributes_t attributes = {};
status_t status = data.read(&config, sizeof(audio_config_base_t));
if (status != NO_ERROR) return status;
status = data.read(&attributes, sizeof(audio_attributes_t));
if (status != NO_ERROR) return status;
reply->writeInt32(isDirectOutputSupported(config, attributes));
return NO_ERROR;
}
case LIST_AUDIO_PORTS: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
audio_port_role_t role = (audio_port_role_t)data.readInt32();

@ -123,4 +123,21 @@ void stream_type_to_audio_attributes(audio_stream_type_t streamType,
}
}
// Convert flags sent from Java AudioAttributes.getFlags() method to audio_output_flags_t
static inline
void audio_attributes_flags_to_audio_output_flags(const audio_flags_mask_t audioAttributeFlags,
audio_output_flags_t &flags) {
if ((audioAttributeFlags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
flags = static_cast<audio_output_flags_t>(flags |
AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_DIRECT);
}
if ((audioAttributeFlags & AUDIO_FLAG_LOW_LATENCY) != 0) {
flags = static_cast<audio_output_flags_t>(flags | AUDIO_OUTPUT_FLAG_FAST);
}
// check deep buffer after flags have been modified above
if (flags == AUDIO_OUTPUT_FLAG_NONE && (audioAttributeFlags & AUDIO_FLAG_DEEP_BUFFER) != 0) {
flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
}
}
#endif //AUDIO_POLICY_HELPER_H_

@ -147,6 +147,12 @@ public:
audio_stream_type_t streamType,
uint32_t sampleRate);
/* Check if direct playback is possible for the given audio configuration and attributes.
* Return true if output is possible for the given parameters. Otherwise returns false.
*/
static bool isDirectOutputSupported(const audio_config_base_t& config,
const audio_attributes_t& attributes);
/* How data is transferred to AudioTrack
*/
enum transfer_type {

@ -125,6 +125,10 @@ public:
// bit rate, duration, video and streaming or offload property is enabled
virtual bool isOffloadSupported(const audio_offload_info_t& info) = 0;
// Check if direct playback is possible for given format, sample rate, channel mask and flags.
virtual bool isDirectOutputSupported(const audio_config_base_t& config,
const audio_attributes_t& attributes) = 0;
/* List available audio ports and their attributes */
virtual status_t listAudioPorts(audio_port_role_t role,
audio_port_type_t type,

@ -181,6 +181,8 @@ public:
virtual status_t dump(int fd) = 0;
virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo) = 0;
virtual bool isDirectOutputSupported(const audio_config_base_t& config,
const audio_attributes_t& attributes) = 0;
virtual status_t listAudioPorts(audio_port_role_t role,
audio_port_type_t type,

@ -712,22 +712,25 @@ void AudioPolicyManager::setSystemProperty(const char* property, const char* val
ALOGV("setSystemProperty() property %s, value %s", property, value);
}
// Find a direct output profile compatible with the parameters passed, even if the input flags do
// not explicitly request a direct output
sp<IOProfile> AudioPolicyManager::getProfileForDirectOutput(
audio_devices_t device,
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
audio_output_flags_t flags)
// Find an output profile compatible with the parameters passed. When "directOnly" is set, restrict
// search to profiles for direct outputs.
sp<IOProfile> AudioPolicyManager::getProfileForOutput(
audio_devices_t device,
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
audio_output_flags_t flags,
bool directOnly)
{
// only retain flags that will drive the direct output profile selection
// if explicitly requested
static const uint32_t kRelevantFlags =
(AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
AUDIO_OUTPUT_FLAG_VOIP_RX);
flags =
(audio_output_flags_t)((flags & kRelevantFlags) | AUDIO_OUTPUT_FLAG_DIRECT);
if (directOnly) {
// only retain flags that will drive the direct output profile selection
// if explicitly requested
static const uint32_t kRelevantFlags =
(AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
AUDIO_OUTPUT_FLAG_VOIP_RX);
flags =
(audio_output_flags_t)((flags & kRelevantFlags) | AUDIO_OUTPUT_FLAG_DIRECT);
}
sp<IOProfile> profile;
@ -744,7 +747,9 @@ sp<IOProfile> AudioPolicyManager::getProfileForDirectOutput(
if ((mAvailableOutputDevices.types() & curProfile->getSupportedDevicesType()) == 0) {
continue;
}
// if several profiles are compatible, give priority to one with offload capability
if (!directOnly) return curProfile;
// when searching for direct outputs, if several profiles are compatible, give priority
// to one with offload capability
if (profile != 0 && ((curProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0)) {
continue;
}
@ -980,11 +985,12 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice(
if (((*flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) ||
!(mEffects.isNonOffloadableEffectEnabled() || mMasterMono)) {
profile = getProfileForDirectOutput(device,
config->sample_rate,
config->format,
config->channel_mask,
(audio_output_flags_t)*flags);
profile = getProfileForOutput(device,
config->sample_rate,
config->format,
config->channel_mask,
(audio_output_flags_t)*flags,
true /* directOnly */);
}
if (profile != 0) {
@ -2691,15 +2697,34 @@ bool AudioPolicyManager::isOffloadSupported(const audio_offload_info_t& offloadI
// See if there is a profile to support this.
// AUDIO_DEVICE_NONE
sp<IOProfile> profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */,
sp<IOProfile> profile = getProfileForOutput(AUDIO_DEVICE_NONE /*ignore device */,
offloadInfo.sample_rate,
offloadInfo.format,
offloadInfo.channel_mask,
AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD,
true /* directOnly */);
ALOGV("isOffloadSupported() profile %sfound", profile != 0 ? "" : "NOT ");
return (profile != 0);
}
bool AudioPolicyManager::isDirectOutputSupported(const audio_config_base_t& config,
const audio_attributes_t& attributes) {
audio_output_flags_t output_flags = AUDIO_OUTPUT_FLAG_NONE;
audio_attributes_flags_to_audio_output_flags(attributes.flags, output_flags);
sp<IOProfile> profile = getProfileForOutput(AUDIO_DEVICE_NONE /*ignore device */,
config.sample_rate,
config.format,
config.channel_mask,
output_flags,
true /* directOnly */);
ALOGV("%s() profile %sfound with name: %s, "
"sample rate: %u, format: 0x%x, channel_mask: 0x%x, output flags: 0x%x",
__FUNCTION__, profile != 0 ? "" : "NOT ",
(profile != 0 ? profile->getTagName().string() : "null"),
config.sample_rate, config.format, config.channel_mask, output_flags);
return (profile != 0);
}
status_t AudioPolicyManager::listAudioPorts(audio_port_role_t role,
audio_port_type_t type,
unsigned int *num_ports,

@ -192,6 +192,9 @@ public:
virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo);
virtual bool isDirectOutputSupported(const audio_config_base_t& config,
const audio_attributes_t& attributes);
virtual status_t listAudioPorts(audio_port_role_t role,
audio_port_type_t type,
unsigned int *num_ports,
@ -479,11 +482,12 @@ protected:
audio_format_t& format,
audio_channel_mask_t& channelMask,
audio_input_flags_t flags);
sp<IOProfile> getProfileForDirectOutput(audio_devices_t device,
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
audio_output_flags_t flags);
sp<IOProfile> getProfileForOutput(audio_devices_t device,
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
audio_output_flags_t flags,
bool directOnly);
audio_io_handle_t selectOutputForMusicEffects();

@ -909,6 +909,17 @@ bool AudioPolicyService::isOffloadSupported(const audio_offload_info_t& info)
return mAudioPolicyManager->isOffloadSupported(info);
}
bool AudioPolicyService::isDirectOutputSupported(const audio_config_base_t& config,
const audio_attributes_t& attributes) {
if (mAudioPolicyManager == NULL) {
ALOGV("mAudioPolicyManager == NULL");
return false;
}
Mutex::Autolock _l(mLock);
return mAudioPolicyManager->isDirectOutputSupported(config, attributes);
}
status_t AudioPolicyService::listAudioPorts(audio_port_role_t role,
audio_port_type_t type,
unsigned int *num_ports,

@ -167,6 +167,8 @@ public:
int delayMs = 0);
virtual status_t setVoiceVolume(float volume, int delayMs = 0);
virtual bool isOffloadSupported(const audio_offload_info_t &config);
virtual bool isDirectOutputSupported(const audio_config_base_t& config,
const audio_attributes_t& attributes);
virtual status_t listAudioPorts(audio_port_role_t role,
audio_port_type_t type,

Loading…
Cancel
Save