summaryrefslogtreecommitdiffstats
path: root/services/audiopolicy/managerdefault
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2015-05-18 15:40:16 -0700
committerEric Laurent <elaurent@google.com>2015-05-19 16:42:42 -0700
commit861a628adbcbe7c3baa6eab1b765b87b480ff4a2 (patch)
tree8d1e10f24987535156df45df180c366b97f19b31 /services/audiopolicy/managerdefault
parent4a95e69406aa2e9896d865962d6d947ebbdac6fc (diff)
downloadframeworks_av-861a628adbcbe7c3baa6eab1b765b87b480ff4a2.zip
frameworks_av-861a628adbcbe7c3baa6eab1b765b87b480ff4a2.tar.gz
frameworks_av-861a628adbcbe7c3baa6eab1b765b87b480ff4a2.tar.bz2
audio policy: fix direct output profile selection
Fix logic in AudioPolicyManager::getProfileForDirectOutput() to select the direct output with most matching flags and not just the first compatible one. Also fixes issue 17783395 which was fixed by commit f7bc29b02 in lmp-tv-dev branch only but in a way that caused a regression for HW A/V sync (issue 19384172). Also removed duplicated code lines in getOutputForDevice() Bug: 20819715. Bug: 17783395. Bug: 19384172. Change-Id: I7fc793b37f9b53fabd92cab6b884ef85cfdafee4
Diffstat (limited to 'services/audiopolicy/managerdefault')
-rw-r--r--services/audiopolicy/managerdefault/AudioPolicyManager.cpp56
1 files changed, 44 insertions, 12 deletions
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index d1ee400..17060e9 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -579,24 +579,43 @@ sp<IOProfile> AudioPolicyManager::getProfileForDirectOutput(
audio_channel_mask_t channelMask,
audio_output_flags_t flags)
{
+ // 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);
+ flags =
+ (audio_output_flags_t)((flags & kRelevantFlags) | AUDIO_OUTPUT_FLAG_DIRECT);
+
+ sp<IOProfile> profile;
+
for (size_t i = 0; i < mHwModules.size(); i++) {
if (mHwModules[i]->mHandle == 0) {
continue;
}
for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) {
- sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j];
- bool found = profile->isCompatibleProfile(device, String8(""),
+ sp<IOProfile> curProfile = mHwModules[i]->mOutputProfiles[j];
+ if (!curProfile->isCompatibleProfile(device, String8(""),
samplingRate, NULL /*updatedSamplingRate*/,
format, NULL /*updatedFormat*/,
channelMask, NULL /*updatedChannelMask*/,
- flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD ?
- AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD : AUDIO_OUTPUT_FLAG_DIRECT);
- if (found && (mAvailableOutputDevices.types() & profile->mSupportedDevices.types())) {
- return profile;
+ flags)) {
+ continue;
+ }
+ // reject profiles not corresponding to a device currently available
+ if ((mAvailableOutputDevices.types() & curProfile->mSupportedDevices.types()) == 0) {
+ continue;
+ }
+ // if several profiles are compatible, give priority to one with offload capability
+ if (profile != 0 && ((curProfile->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0)) {
+ continue;
+ }
+ profile = curProfile;
+ if ((profile->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
+ break;
}
}
}
- return 0;
+ return profile;
}
audio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream,
@@ -819,10 +838,27 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice(
if (outputDesc != NULL) {
closeOutput(outputDesc->mIoHandle);
}
+
+ // if the selected profile is offloaded and no offload info was specified,
+ // create a default one
+ audio_offload_info_t defaultOffloadInfo = AUDIO_INFO_INITIALIZER;
+ if ((profile->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) && !offloadInfo) {
+ flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
+ defaultOffloadInfo.sample_rate = samplingRate;
+ defaultOffloadInfo.channel_mask = channelMask;
+ defaultOffloadInfo.format = format;
+ defaultOffloadInfo.stream_type = stream;
+ defaultOffloadInfo.bit_rate = 0;
+ defaultOffloadInfo.duration_us = -1;
+ defaultOffloadInfo.has_video = true; // conservative
+ defaultOffloadInfo.is_streaming = true; // likely
+ offloadInfo = &defaultOffloadInfo;
+ }
+
outputDesc = new SwAudioOutputDescriptor(profile, mpClientInterface);
outputDesc->mDevice = device;
outputDesc->mLatency = 0;
- outputDesc->mFlags =(audio_output_flags_t) (outputDesc->mFlags | flags);
+ outputDesc->mFlags = (audio_output_flags_t)(outputDesc->mFlags | flags);
audio_config_t config = AUDIO_CONFIG_INITIALIZER;
config.sample_rate = samplingRate;
config.channel_mask = channelMask;
@@ -854,10 +890,6 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice(
if (audio_is_linear_pcm(format) && samplingRate <= MAX_MIXER_SAMPLING_RATE) {
goto non_direct_output;
}
- // fall back to mixer output if possible when the direct output could not be open
- if (audio_is_linear_pcm(format) && samplingRate <= MAX_MIXER_SAMPLING_RATE) {
- goto non_direct_output;
- }
return AUDIO_IO_HANDLE_NONE;
}
outputDesc->mSamplingRate = config.sample_rate;