summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorJean-Michel Trivi <jmtrivi@google.com>2014-06-19 15:33:55 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-06-18 18:28:24 +0000
commit29a8b2fe294a34ac7f004203426961a599e725ea (patch)
tree06769995a441946136147a03e26817167e92bf88 /media
parent7a4d7d6670f1766442b54045fb420dbf42b75750 (diff)
parent5bd3f38638acab633d181359cc9ec27b80f84d43 (diff)
downloadframeworks_av-29a8b2fe294a34ac7f004203426961a599e725ea.zip
frameworks_av-29a8b2fe294a34ac7f004203426961a599e725ea.tar.gz
frameworks_av-29a8b2fe294a34ac7f004203426961a599e725ea.tar.bz2
Merge changes I0fef0584,I322b91fa
* changes: AudioPolicyManager: return output for audio attributes AudioTrack construction with audio attributes
Diffstat (limited to 'media')
-rw-r--r--media/libmedia/AudioSystem.cpp26
-rw-r--r--media/libmedia/AudioTrack.cpp180
-rw-r--r--media/libmedia/IAudioPolicyService.cpp57
3 files changed, 247 insertions, 16 deletions
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 15b32ff..f5e7a78 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -245,6 +245,19 @@ status_t AudioSystem::getOutputSamplingRate(uint32_t* samplingRate, audio_stream
return getSamplingRate(output, samplingRate);
}
+status_t AudioSystem::getOutputSamplingRateForAttr(uint32_t* samplingRate,
+ const audio_attributes_t *attr)
+{
+ if (attr == NULL) {
+ return BAD_VALUE;
+ }
+ audio_io_handle_t output = getOutputForAttr(attr);
+ if (output == 0) {
+ return PERMISSION_DENIED;
+ }
+ return getSamplingRate(output, samplingRate);
+}
+
status_t AudioSystem::getSamplingRate(audio_io_handle_t output,
uint32_t* samplingRate)
{
@@ -633,6 +646,19 @@ audio_io_handle_t AudioSystem::getOutput(audio_stream_type_t stream,
return aps->getOutput(stream, samplingRate, format, channelMask, flags, offloadInfo);
}
+audio_io_handle_t AudioSystem::getOutputForAttr(const audio_attributes_t *attr,
+ uint32_t samplingRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ audio_output_flags_t flags,
+ const audio_offload_info_t *offloadInfo)
+{
+ if (attr == NULL) return 0;
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) return 0;
+ return aps->getOutputForAttr(attr, samplingRate, format, channelMask, flags, offloadInfo);
+}
+
status_t AudioSystem::startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
int session)
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index e6827ee..77419f0 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -103,6 +103,10 @@ AudioTrack::AudioTrack()
mPreviousSchedulingGroup(SP_DEFAULT),
mPausedPosition(0)
{
+ mAttributes.content_type = AUDIO_CONTENT_TYPE_UNKNOWN;
+ mAttributes.usage = AUDIO_USAGE_UNKNOWN;
+ mAttributes.flags = 0x0;
+ strcpy(mAttributes.tags, "");
}
AudioTrack::AudioTrack(
@@ -129,7 +133,7 @@ AudioTrack::AudioTrack(
mStatus = set(streamType, sampleRate, format, channelMask,
frameCount, flags, cbf, user, notificationFrames,
0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType,
- offloadInfo, uid, pid);
+ offloadInfo, uid, pid, NULL /*no audio attributes*/);
}
AudioTrack::AudioTrack(
@@ -156,7 +160,7 @@ AudioTrack::AudioTrack(
mStatus = set(streamType, sampleRate, format, channelMask,
0 /*frameCount*/, flags, cbf, user, notificationFrames,
sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo,
- uid, pid);
+ uid, pid, NULL /*no audio attributes*/);
}
AudioTrack::~AudioTrack()
@@ -199,7 +203,8 @@ status_t AudioTrack::set(
transfer_type transferType,
const audio_offload_info_t *offloadInfo,
int uid,
- pid_t pid)
+ pid_t pid,
+ audio_attributes_t* pAttributes)
{
ALOGV("set(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
"flags #%x, notificationFrames %u, sessionId %d, transferType %d",
@@ -259,18 +264,33 @@ status_t AudioTrack::set(
if (streamType == AUDIO_STREAM_DEFAULT) {
streamType = AUDIO_STREAM_MUSIC;
}
- if (uint32_t(streamType) >= AUDIO_STREAM_CNT) {
- ALOGE("Invalid stream type %d", streamType);
- return BAD_VALUE;
+
+ if (pAttributes == NULL) {
+ if (uint32_t(streamType) >= AUDIO_STREAM_CNT) {
+ ALOGE("Invalid stream type %d", streamType);
+ return BAD_VALUE;
+ }
+ setAttributesFromStreamType(streamType);
+ mStreamType = streamType;
+ } else {
+ if (!isValidAttributes(pAttributes)) {
+ ALOGE("Invalid attributes: usage=%d content=%d flags=0x%x tags=[%s]",
+ pAttributes->usage, pAttributes->content_type, pAttributes->flags,
+ pAttributes->tags);
+ }
+ // stream type shouldn't be looked at, this track has audio attributes
+ memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t));
+ setStreamTypeFromAttributes(mAttributes);
+ ALOGV("Building AudioTrack with attributes: usage=%d content=%d flags=0x%x tags=[%s]",
+ mAttributes.usage, mAttributes.content_type, mAttributes.flags, mAttributes.tags);
}
- mStreamType = streamType;
status_t status;
if (sampleRate == 0) {
- status = AudioSystem::getOutputSamplingRate(&sampleRate, streamType);
+ status = AudioSystem::getOutputSamplingRateForAttr(&sampleRate, &mAttributes);
if (status != NO_ERROR) {
ALOGE("Could not get output sample rate for stream type %d; status %d",
- streamType, status);
+ mStreamType, status);
return status;
}
}
@@ -314,7 +334,7 @@ status_t AudioTrack::set(
((flags | AUDIO_OUTPUT_FLAG_DIRECT) & ~AUDIO_OUTPUT_FLAG_FAST);
}
// only allow deep buffering for music stream type
- if (streamType != AUDIO_STREAM_MUSIC) {
+ if (mStreamType != AUDIO_STREAM_MUSIC) {
flags = (audio_output_flags_t)(flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
}
@@ -620,7 +640,7 @@ status_t AudioTrack::setSampleRate(uint32_t rate)
}
uint32_t afSamplingRate;
- if (AudioSystem::getOutputSamplingRate(&afSamplingRate, mStreamType) != NO_ERROR) {
+ if (AudioSystem::getOutputSamplingRateForAttr(&afSamplingRate, &mAttributes) != NO_ERROR) {
return NO_INIT;
}
// Resampler implementation limits input sampling rate to 2 x output sampling rate.
@@ -867,12 +887,12 @@ status_t AudioTrack::createTrack_l(size_t epoch)
return NO_INIT;
}
- audio_io_handle_t output = AudioSystem::getOutput(mStreamType, mSampleRate, mFormat,
+ audio_io_handle_t output = AudioSystem::getOutputForAttr(&mAttributes, mSampleRate, mFormat,
mChannelMask, mFlags, mOffloadInfo);
if (output == AUDIO_IO_HANDLE_NONE) {
- ALOGE("Could not get audio output for stream type %d, sample rate %u, format %#x, "
- "channel mask %#x, flags %#x",
- mStreamType, mSampleRate, mFormat, mChannelMask, mFlags);
+ ALOGE("Could not get audio output for stream type %d, usage %d, sample rate %u, format %#x,"
+ " channel mask %#x, flags %#x",
+ mStreamType, mAttributes.usage, mSampleRate, mFormat, mChannelMask, mFlags);
return BAD_VALUE;
}
{
@@ -1858,6 +1878,136 @@ uint32_t AudioTrack::getUnderrunFrames() const
return mProxy->getUnderrunFrames();
}
+void AudioTrack::setAttributesFromStreamType(audio_stream_type_t streamType) {
+ mAttributes.flags = 0x0;
+
+ switch(streamType) {
+ case AUDIO_STREAM_DEFAULT:
+ case AUDIO_STREAM_MUSIC:
+ mAttributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
+ mAttributes.usage = AUDIO_USAGE_MEDIA;
+ break;
+ case AUDIO_STREAM_VOICE_CALL:
+ mAttributes.content_type = AUDIO_CONTENT_TYPE_SPEECH;
+ mAttributes.usage = AUDIO_USAGE_VOICE_COMMUNICATION;
+ break;
+ case AUDIO_STREAM_ENFORCED_AUDIBLE:
+ mAttributes.flags |= AUDIO_FLAG_AUDIBILITY_ENFORCED;
+ // intended fall through, attributes in common with STREAM_SYSTEM
+ case AUDIO_STREAM_SYSTEM:
+ mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
+ mAttributes.usage = AUDIO_USAGE_ASSISTANCE_SONIFICATION;
+ break;
+ case AUDIO_STREAM_RING:
+ mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
+ mAttributes.usage = AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
+ break;
+ case AUDIO_STREAM_ALARM:
+ mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
+ mAttributes.usage = AUDIO_USAGE_ALARM;
+ break;
+ case AUDIO_STREAM_NOTIFICATION:
+ mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
+ mAttributes.usage = AUDIO_USAGE_NOTIFICATION;
+ break;
+ case AUDIO_STREAM_BLUETOOTH_SCO:
+ mAttributes.content_type = AUDIO_CONTENT_TYPE_SPEECH;
+ mAttributes.usage = AUDIO_USAGE_VOICE_COMMUNICATION;
+ mAttributes.flags |= AUDIO_FLAG_SCO;
+ break;
+ case AUDIO_STREAM_DTMF:
+ mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
+ mAttributes.usage = AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING;
+ break;
+ case AUDIO_STREAM_TTS:
+ mAttributes.content_type = AUDIO_CONTENT_TYPE_SPEECH;
+ mAttributes.usage = AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY;
+ break;
+ default:
+ ALOGE("invalid stream type %d when converting to attributes", streamType);
+ }
+}
+
+void AudioTrack::setStreamTypeFromAttributes(audio_attributes_t& aa) {
+ // flags to stream type mapping
+ if ((aa.flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
+ mStreamType = AUDIO_STREAM_ENFORCED_AUDIBLE;
+ return;
+ }
+ if ((aa.flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) {
+ mStreamType = AUDIO_STREAM_BLUETOOTH_SCO;
+ return;
+ }
+
+ // usage to stream type mapping
+ switch (aa.usage) {
+ case AUDIO_USAGE_MEDIA:
+ case AUDIO_USAGE_GAME:
+ case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
+ case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
+ mStreamType = AUDIO_STREAM_MUSIC;
+ return;
+ case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
+ mStreamType = AUDIO_STREAM_SYSTEM;
+ return;
+ case AUDIO_USAGE_VOICE_COMMUNICATION:
+ mStreamType = AUDIO_STREAM_VOICE_CALL;
+ return;
+
+ case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
+ mStreamType = AUDIO_STREAM_DTMF;
+ return;
+
+ case AUDIO_USAGE_ALARM:
+ mStreamType = AUDIO_STREAM_ALARM;
+ return;
+ case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
+ mStreamType = AUDIO_STREAM_RING;
+ return;
+
+ case AUDIO_USAGE_NOTIFICATION:
+ case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
+ case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
+ case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
+ case AUDIO_USAGE_NOTIFICATION_EVENT:
+ mStreamType = AUDIO_STREAM_NOTIFICATION;
+ return;
+
+ case AUDIO_USAGE_UNKNOWN:
+ default:
+ mStreamType = AUDIO_STREAM_MUSIC;
+ }
+}
+
+bool AudioTrack::isValidAttributes(const audio_attributes_t *paa) {
+ // has flags that map to a strategy?
+ if ((paa->flags & (AUDIO_FLAG_AUDIBILITY_ENFORCED | AUDIO_FLAG_SCO)) != 0) {
+ return true;
+ }
+
+ // has known usage?
+ switch (paa->usage) {
+ case AUDIO_USAGE_UNKNOWN:
+ case AUDIO_USAGE_MEDIA:
+ case AUDIO_USAGE_VOICE_COMMUNICATION:
+ case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
+ case AUDIO_USAGE_ALARM:
+ case AUDIO_USAGE_NOTIFICATION:
+ case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
+ case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
+ case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
+ case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
+ case AUDIO_USAGE_NOTIFICATION_EVENT:
+ case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
+ case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
+ case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
+ case AUDIO_USAGE_GAME:
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
// =========================================================================
void AudioTrack::DeathNotifier::binderDied(const wp<IBinder>& who __unused)
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 77d131b..41a9065 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -64,7 +64,8 @@ enum {
RELEASE_AUDIO_PATCH,
LIST_AUDIO_PATCHES,
SET_AUDIO_PORT_CONFIG,
- REGISTER_CLIENT
+ REGISTER_CLIENT,
+ GET_OUTPUT_FOR_ATTR
};
class BpAudioPolicyService : public BpInterface<IAudioPolicyService>
@@ -155,6 +156,36 @@ public:
return static_cast <audio_io_handle_t> (reply.readInt32());
}
+ virtual audio_io_handle_t getOutputForAttr(
+ const audio_attributes_t *attr,
+ uint32_t samplingRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ audio_output_flags_t flags,
+ const audio_offload_info_t *offloadInfo)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+ if (attr == NULL) {
+ ALOGE("Writing NULL audio attributes - shouldn't happen");
+ return (audio_io_handle_t) 0;
+ }
+ data.write(attr, sizeof(audio_attributes_t));
+ data.writeInt32(samplingRate);
+ data.writeInt32(static_cast <uint32_t>(format));
+ data.writeInt32(channelMask);
+ data.writeInt32(static_cast <uint32_t>(flags));
+ // hasOffloadInfo
+ if (offloadInfo == NULL) {
+ data.writeInt32(0);
+ } else {
+ data.writeInt32(1);
+ data.write(offloadInfo, sizeof(audio_offload_info_t));
+ }
+ remote()->transact(GET_OUTPUT_FOR_ATTR, data, &reply);
+ return static_cast <audio_io_handle_t> (reply.readInt32());
+ }
+
virtual status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
int session)
@@ -614,6 +645,30 @@ status_t BnAudioPolicyService::onTransact(
return NO_ERROR;
} break;
+ case GET_OUTPUT_FOR_ATTR: {
+ CHECK_INTERFACE(IAudioPolicyService, data, reply);
+ audio_attributes_t *attr = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
+ data.read(attr, sizeof(audio_attributes_t));
+ uint32_t samplingRate = data.readInt32();
+ audio_format_t format = (audio_format_t) data.readInt32();
+ audio_channel_mask_t channelMask = data.readInt32();
+ audio_output_flags_t flags =
+ static_cast <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 = getOutputForAttr(attr,
+ samplingRate,
+ format,
+ channelMask,
+ flags,
+ hasOffloadInfo ? &offloadInfo : NULL);
+ reply->writeInt32(static_cast <int>(output));
+ return NO_ERROR;
+ } break;
+
case START_OUTPUT: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32());