Implement AudioTrack.isDirectPlaybackSupported method
The method checks whether the provided AudioFormat can be played
via currently connected output devices w/o SRC or downmixing
by the framework.
The implementation methods are called 'isDirectOutputSupported'
to match APM's terminology.
Bug: 120044865
Test: atest CtsMediaTestCases:AudioTrackTest#testBuilderValidate
Change-Id: I11769f796c34583fb2641415d2faab00ac526123
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 02324ac..8f06ee7 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -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 @@
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 @@
__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...
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index a406658..5f47761 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -62,6 +62,7 @@
SET_EFFECT_ENABLED,
IS_STREAM_ACTIVE_REMOTELY,
IS_OFFLOAD_SUPPORTED,
+ IS_DIRECT_OUTPUT_SUPPORTED,
LIST_AUDIO_PORTS,
GET_AUDIO_PORT,
CREATE_AUDIO_PATCH,
@@ -526,6 +527,16 @@
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,
@@ -1393,6 +1404,18 @@
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();
diff --git a/media/libaudioclient/include/media/AudioPolicyHelper.h b/media/libaudioclient/include/media/AudioPolicyHelper.h
index 49432b7..46de6b3 100644
--- a/media/libaudioclient/include/media/AudioPolicyHelper.h
+++ b/media/libaudioclient/include/media/AudioPolicyHelper.h
@@ -123,4 +123,21 @@
}
}
+// 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_
diff --git a/media/libaudioclient/include/media/AudioTrack.h b/media/libaudioclient/include/media/AudioTrack.h
index 8238ea2..7fdf7cc 100644
--- a/media/libaudioclient/include/media/AudioTrack.h
+++ b/media/libaudioclient/include/media/AudioTrack.h
@@ -147,6 +147,12 @@
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 {
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index a246df6..f8debb2 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -126,6 +126,10 @@
// 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,