summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2014-08-01 14:48:35 -0700
committerEric Laurent <elaurent@google.com>2014-08-06 00:38:23 +0000
commit93c3d41bdb15e39dac0faea9c5b60f1637cd477c (patch)
treea0d739ad732f10bc9d4548923c78c590841b14da
parent92ce4715315bddd158c7d4028556632f0547e3b9 (diff)
downloadframeworks_av-93c3d41bdb15e39dac0faea9c5b60f1637cd477c.zip
frameworks_av-93c3d41bdb15e39dac0faea9c5b60f1637cd477c.tar.gz
frameworks_av-93c3d41bdb15e39dac0faea9c5b60f1637cd477c.tar.bz2
AudioSystem: add API to query audio HW sync source
Add a method to query from the audio HAL the HW sync source used for a given audio session. Modify audio policy to select a direct output with HW sync when requested. Bug: 16132368. Change-Id: I03038f9188f2d389f8a5fd76a671854013a4513e
-rw-r--r--include/media/AudioSystem.h5
-rw-r--r--include/media/IAudioFlinger.h2
-rw-r--r--media/libmedia/AudioSystem.cpp7
-rw-r--r--media/libmedia/IAudioFlinger.cpp19
-rw-r--r--services/audioflinger/AudioFlinger.cpp19
-rw-r--r--services/audioflinger/AudioFlinger.h3
-rw-r--r--services/audiopolicy/AudioPolicyManager.cpp13
7 files changed, 65 insertions, 3 deletions
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index f22792f..dd63a23 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -149,6 +149,11 @@ public:
static void acquireAudioSessionId(int audioSession, pid_t pid);
static void releaseAudioSessionId(int audioSession, pid_t pid);
+ // Get the HW synchronization source used for an audio session.
+ // Return a valid source or AUDIO_HW_SYNC_INVALID if an error occurs
+ // or no HW sync source is used.
+ static audio_hw_sync_t getAudioHwSyncForSession(audio_session_t sessionId);
+
// types of io configuration change events received with ioConfigChanged()
enum io_config_event {
OUTPUT_OPENED,
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 82ec09c..31a14f0 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -235,6 +235,8 @@ public:
/* Set audio port configuration */
virtual status_t setAudioPortConfig(const struct audio_port_config *config) = 0;
+ /* Get the HW synchronization source used for an audio session */
+ virtual audio_hw_sync_t getAudioHwSyncForSession(audio_session_t sessionId) = 0;
};
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 172b056..3486d21 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -450,6 +450,13 @@ void AudioSystem::releaseAudioSessionId(int audioSession, pid_t pid)
}
}
+audio_hw_sync_t AudioSystem::getAudioHwSyncForSession(audio_session_t sessionId)
+{
+ const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ if (af == 0) return AUDIO_HW_SYNC_INVALID;
+ return af->getAudioHwSyncForSession(sessionId);
+}
+
// ---------------------------------------------------------------------------
void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who __unused)
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index 5331fce..346a192 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -79,7 +79,8 @@ enum {
CREATE_AUDIO_PATCH,
RELEASE_AUDIO_PATCH,
LIST_AUDIO_PATCHES,
- SET_AUDIO_PORT_CONFIG
+ SET_AUDIO_PORT_CONFIG,
+ GET_AUDIO_HW_SYNC
};
class BpAudioFlinger : public BpInterface<IAudioFlinger>
@@ -883,6 +884,17 @@ public:
}
return status;
}
+ virtual audio_hw_sync_t getAudioHwSyncForSession(audio_session_t sessionId)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+ data.writeInt32(sessionId);
+ status_t status = remote()->transact(GET_AUDIO_HW_SYNC, data, &reply);
+ if (status != NO_ERROR) {
+ return AUDIO_HW_SYNC_INVALID;
+ }
+ return (audio_hw_sync_t)reply.readInt32();
+ }
};
IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");
@@ -1345,6 +1357,11 @@ status_t BnAudioFlinger::onTransact(
reply->writeInt32(status);
return NO_ERROR;
} break;
+ case GET_AUDIO_HW_SYNC: {
+ CHECK_INTERFACE(IAudioFlinger, data, reply);
+ reply->writeInt32(getAudioHwSyncForSession((audio_session_t)data.readInt32()));
+ return NO_ERROR;
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index b8cc33a..1f77b2f 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1579,6 +1579,25 @@ status_t AudioFlinger::setLowRamDevice(bool isLowRamDevice)
return NO_ERROR;
}
+audio_hw_sync_t AudioFlinger::getAudioHwSyncForSession(audio_session_t sessionId)
+{
+ Mutex::Autolock _l(mLock);
+ for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+ sp<PlaybackThread> thread = mPlaybackThreads.valueAt(i);
+ if ((thread->hasAudioSession(sessionId) & ThreadBase::TRACK_SESSION) != 0) {
+ // A session can only be on one thread, so exit after first match
+ String8 reply = thread->getParameters(String8(AUDIO_PARAMETER_STREAM_HW_AV_SYNC));
+ AudioParameter param = AudioParameter(reply);
+ int value;
+ if (param.getInt(String8(AUDIO_PARAMETER_STREAM_HW_AV_SYNC), value) == NO_ERROR) {
+ return value;
+ }
+ break;
+ }
+ }
+ return AUDIO_HW_SYNC_INVALID;
+}
+
// ----------------------------------------------------------------------------
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 31c5a1a..4e9d49b 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -248,6 +248,9 @@ public:
/* Set audio port configuration */
virtual status_t setAudioPortConfig(const struct audio_port_config *config);
+ /* Get the HW synchronization source used for an audio session */
+ virtual audio_hw_sync_t getAudioHwSyncForSession(audio_session_t sessionId);
+
virtual status_t onTransact(
uint32_t code,
const Parcel& data,
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index c519593..c00541c 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -118,6 +118,7 @@ const StringToEnum sFlagNameToEnumTable[] = {
STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER),
STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_NON_BLOCKING),
+ STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_HW_AV_SYNC),
};
const StringToEnum sFormatNameToEnumTable[] = {
@@ -671,12 +672,17 @@ audio_io_handle_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t
ALOGE("getOutputForAttr() called with NULL audio attributes");
return 0;
}
- ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s",
- attr->usage, attr->content_type, attr->tags);
+ ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s flags=%08x",
+ attr->usage, attr->content_type, attr->tags, attr->flags);
// TODO this is where filtering for custom policies (rerouting, dynamic sources) will go
routing_strategy strategy = (routing_strategy) getStrategyForAttr(attr);
audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
+
+ if ((attr->flags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
+ flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
+ }
+
ALOGV("getOutputForAttr() device %d, samplingRate %d, format %x, channelMask %x, flags %x",
device, samplingRate, format, channelMask, flags);
@@ -746,6 +752,9 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice(
if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
}
+ if ((flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) {
+ flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
+ }
// Do not allow offloading if one non offloadable effect is enabled. This prevents from
// creating an offloaded track and tearing it down immediately after start when audioflinger