Merge "AudioFlinger, AudioPolicy: Add binder time check statistics" into tm-dev
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.cpp b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
index b7a5686..4f5caec 100644
--- a/media/codec2/components/hevc/C2SoftHevcEnc.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
@@ -123,7 +123,7 @@
// matches size limits in codec library
addParameter(
DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
- .withDefault(new C2StreamPictureSizeInfo::input(0u, 320, 240))
+ .withDefault(new C2StreamPictureSizeInfo::input(0u, 64, 64))
.withFields({
C2F(mSize, width).inRange(2, 1920, 2),
C2F(mSize, height).inRange(2, 1088, 2),
@@ -133,7 +133,7 @@
addParameter(
DefineParam(mFrameRate, C2_PARAMKEY_FRAME_RATE)
- .withDefault(new C2StreamFrameRateInfo::output(0u, 30.))
+ .withDefault(new C2StreamFrameRateInfo::output(0u, 1.))
.withFields({C2F(mFrameRate, value).greaterThan(0.)})
.withSetter(
Setter<decltype(*mFrameRate)>::StrictValueWithNoDeps)
diff --git a/media/libaaudio/TEST_MAPPING b/media/libaaudio/TEST_MAPPING
new file mode 100644
index 0000000..1b7c714
--- /dev/null
+++ b/media/libaaudio/TEST_MAPPING
@@ -0,0 +1,12 @@
+{
+ "postsubmit": [
+ {
+ "name": "CtsNativeMediaAAudioTestCases",
+ "options" : [
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic.*"
+ }
+ ]
+ }
+ ]
+}
diff --git a/media/libaudioclient/TEST_MAPPING b/media/libaudioclient/TEST_MAPPING
index d8c18c0..4bf34b7 100644
--- a/media/libaudioclient/TEST_MAPPING
+++ b/media/libaudioclient/TEST_MAPPING
@@ -1,7 +1,17 @@
{
"presubmit": [
{
- "name": "audio_aidl_conversion_tests"
+ "name": "audio_aidl_conversion_tests"
+ }
+ ],
+ "postsubmit": [
+ {
+ "name": "CtsNativeMediaAAudioTestCases",
+ "options" : [
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic.*"
+ }
+ ]
}
]
}
diff --git a/media/libaudiofoundation/TEST_MAPPING b/media/libaudiofoundation/TEST_MAPPING
index f6d249a..a0876f9 100644
--- a/media/libaudiofoundation/TEST_MAPPING
+++ b/media/libaudiofoundation/TEST_MAPPING
@@ -1,7 +1,17 @@
{
"presubmit": [
{
- "name": "audiofoundation_parcelable_test"
+ "name": "audiofoundation_parcelable_test"
+ }
+ ],
+ "postsubmit": [
+ {
+ "name": "CtsNativeMediaAAudioTestCases",
+ "options" : [
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic.*"
+ }
+ ]
}
]
}
diff --git a/media/libaudiohal/TEST_MAPPING b/media/libaudiohal/TEST_MAPPING
new file mode 100644
index 0000000..1b7c714
--- /dev/null
+++ b/media/libaudiohal/TEST_MAPPING
@@ -0,0 +1,12 @@
+{
+ "postsubmit": [
+ {
+ "name": "CtsNativeMediaAAudioTestCases",
+ "options" : [
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic.*"
+ }
+ ]
+ }
+ ]
+}
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index dd435fe..4002fbf 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -143,8 +143,9 @@
":audio_core_hal_client_sources",
":audio_effect_hal_client_sources",
],
- shared_libs: [
+ static_libs: [
"android.hardware.audio.common@7.0",
+ "android.hardware.audio.common@7.0-enums",
"android.hardware.audio.common@7.0-util",
"android.hardware.audio.effect@7.0",
"android.hardware.audio.effect@7.0-util",
@@ -164,8 +165,9 @@
srcs: [
":audio_core_hal_client_sources",
],
- shared_libs: [
+ static_libs: [
"android.hardware.audio.common@7.0",
+ "android.hardware.audio.common@7.1-enums",
"android.hardware.audio.common@7.1-util",
"android.hardware.audio@7.0",
"android.hardware.audio@7.1",
diff --git a/media/libaudioprocessing/TEST_MAPPING b/media/libaudioprocessing/TEST_MAPPING
new file mode 100644
index 0000000..1b7c714
--- /dev/null
+++ b/media/libaudioprocessing/TEST_MAPPING
@@ -0,0 +1,12 @@
+{
+ "postsubmit": [
+ {
+ "name": "CtsNativeMediaAAudioTestCases",
+ "options" : [
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic.*"
+ }
+ ]
+ }
+ ]
+}
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 45d0ae7..50a3f0d 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -2151,7 +2151,7 @@
bool reverse) {
AString mediaType;
if (!format->findString("mime", &mediaType)) {
- ALOGW("mapFormat: no mediaType information");
+ ALOGV("mapFormat: no mediaType information");
return;
}
ALOGV("mapFormat: codec %s mediatype %s kind %s reverse %d", componentName.c_str(),
diff --git a/services/audioflinger/TEST_MAPPING b/services/audioflinger/TEST_MAPPING
new file mode 100644
index 0000000..1b7c714
--- /dev/null
+++ b/services/audioflinger/TEST_MAPPING
@@ -0,0 +1,12 @@
+{
+ "postsubmit": [
+ {
+ "name": "CtsNativeMediaAAudioTestCases",
+ "options" : [
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic.*"
+ }
+ ]
+ }
+ ]
+}
diff --git a/services/audiopolicy/TEST_MAPPING b/services/audiopolicy/TEST_MAPPING
index 9b4cc8a..e169357 100644
--- a/services/audiopolicy/TEST_MAPPING
+++ b/services/audiopolicy/TEST_MAPPING
@@ -12,5 +12,15 @@
}
]
}
+ ],
+ "postsubmit": [
+ {
+ "name": "CtsNativeMediaAAudioTestCases",
+ "options" : [
+ {
+ "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic.*"
+ }
+ ]
+ }
]
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index fcef136..e45de32 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -935,6 +935,32 @@
ALOGV("setSystemProperty() property %s, value %s", property, value);
}
+// Find an MSD output profile compatible with the parameters passed.
+// When "directOnly" is set, restrict search to profiles for direct outputs.
+sp<IOProfile> AudioPolicyManager::getMsdProfileForOutput(
+ const DeviceVector& devices,
+ uint32_t samplingRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ audio_output_flags_t flags,
+ bool directOnly)
+{
+ flags = getRelevantFlags(flags, directOnly);
+
+ sp<HwModule> msdModule = mHwModules.getModuleFromName(AUDIO_HARDWARE_MODULE_ID_MSD);
+ if (msdModule != nullptr) {
+ // for the msd module check if there are patches to the output devices
+ if (msdHasPatchesToAllDevices(devices.toTypeAddrVector())) {
+ HwModuleCollection modules;
+ modules.add(msdModule);
+ return searchCompatibleProfileHwModules(
+ modules, getMsdAudioOutDevices(), samplingRate, format, channelMask,
+ flags, directOnly);
+ }
+ }
+ return nullptr;
+}
+
// Find an output profile compatible with the parameters passed. When "directOnly" is set, restrict
// search to profiles for direct outputs.
sp<IOProfile> AudioPolicyManager::getProfileForOutput(
@@ -945,45 +971,65 @@
audio_output_flags_t flags,
bool directOnly)
{
+ flags = getRelevantFlags(flags, directOnly);
+
+ return searchCompatibleProfileHwModules(
+ mHwModules, devices, samplingRate, format, channelMask, flags, directOnly);
+}
+
+audio_output_flags_t AudioPolicyManager::getRelevantFlags (
+ audio_output_flags_t flags, bool directOnly) {
if (directOnly) {
- // only retain flags that will drive the direct output profile selection
- // if explicitly requested
- static const uint32_t kRelevantFlags =
+ // 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 | AUDIO_OUTPUT_FLAG_MMAP_NOIRQ);
- flags =
- (audio_output_flags_t)((flags & kRelevantFlags) | AUDIO_OUTPUT_FLAG_DIRECT);
+ AUDIO_OUTPUT_FLAG_VOIP_RX | AUDIO_OUTPUT_FLAG_MMAP_NOIRQ);
+ flags = (audio_output_flags_t)((flags & kRelevantFlags) | AUDIO_OUTPUT_FLAG_DIRECT);
}
+ return flags;
+}
+sp<IOProfile> AudioPolicyManager::searchCompatibleProfileHwModules (
+ const HwModuleCollection& hwModules,
+ const DeviceVector& devices,
+ uint32_t samplingRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ audio_output_flags_t flags,
+ bool directOnly) {
sp<IOProfile> profile;
-
- for (const auto& hwModule : mHwModules) {
+ for (const auto& hwModule : hwModules) {
for (const auto& curProfile : hwModule->getOutputProfiles()) {
- if (!curProfile->isCompatibleProfile(devices,
- samplingRate, NULL /*updatedSamplingRate*/,
- format, NULL /*updatedFormat*/,
- channelMask, NULL /*updatedChannelMask*/,
- flags)) {
+ if (!curProfile->isCompatibleProfile(devices,
+ samplingRate, NULL /*updatedSamplingRate*/,
+ format, NULL /*updatedFormat*/,
+ channelMask, NULL /*updatedChannelMask*/,
+ flags)) {
+ continue;
+ }
+ // reject profiles not corresponding to a device currently available
+ if (!mAvailableOutputDevices.containsAtLeastOne(curProfile->getSupportedDevices())) {
+ continue;
+ }
+ // reject profiles if connected device does not support codec
+ if (!curProfile->devicesSupportEncodedFormats(devices.types())) {
+ continue;
+ }
+ 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;
- }
- // reject profiles not corresponding to a device currently available
- if (!mAvailableOutputDevices.containsAtLeastOne(curProfile->getSupportedDevices())) {
- continue;
- }
- // reject profiles if connected device does not support codec
- if (!curProfile->devicesSupportEncodedFormats(devices.types())) {
- continue;
- }
- 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;
- }
- profile = curProfile;
- if ((profile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
- break;
- }
+ }
+ profile = curProfile;
+ if ((profile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
+ break;
+ }
}
}
return profile;
@@ -3820,7 +3866,22 @@
__FUNCTION__, profile != 0 ? "" : "NOT ",
(profile != 0 ? profile->getTagName().c_str() : "null"),
config.sample_rate, config.format, config.channel_mask, output_flags);
- return (profile != 0);
+
+ // also try the MSD module if compatible profile not found
+ if (profile == nullptr) {
+ profile = getMsdProfileForOutput(outputDevices,
+ config.sample_rate,
+ config.format,
+ config.channel_mask,
+ output_flags,
+ true /* directOnly */);
+ ALOGV("%s() MSD 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().c_str() : "null"),
+ config.sample_rate, config.format, config.channel_mask, output_flags);
+ }
+ return (profile != nullptr);
}
bool AudioPolicyManager::isOffloadPossible(const audio_offload_info_t &offloadInfo,
@@ -3901,8 +3962,16 @@
}
flags = (audio_output_flags_t)((flags & relevantFlags) | AUDIO_OUTPUT_FLAG_DIRECT);
- DeviceVector outputDevices = mEngine->getOutputDevicesForAttributes(*attr);
+ DeviceVector engineOutputDevices = mEngine->getOutputDevicesForAttributes(*attr);
for (const auto& hwModule : mHwModules) {
+ DeviceVector outputDevices = engineOutputDevices;
+ // the MSD module checks for different conditions and output devices
+ if (strcmp(hwModule->getName(), AUDIO_HARDWARE_MODULE_ID_MSD) == 0) {
+ if (!msdHasPatchesToAllDevices(engineOutputDevices.toTypeAddrVector())) {
+ continue;
+ }
+ outputDevices = getMsdAudioOutDevices();
+ }
for (const auto& curProfile : hwModule->getOutputProfiles()) {
if (!curProfile->isCompatibleProfile(outputDevices,
config->sample_rate, nullptr /*updatedSamplingRate*/,
@@ -3929,11 +3998,10 @@
~AUDIO_DIRECT_OFFLOAD_SUPPORTED) |
AUDIO_DIRECT_OFFLOAD_GAPLESS_SUPPORTED);
} else {
- directMode = (audio_direct_mode_t)(directMode |AUDIO_DIRECT_OFFLOAD_SUPPORTED);
+ directMode = (audio_direct_mode_t)(directMode | AUDIO_DIRECT_OFFLOAD_SUPPORTED);
}
} else {
- directMode = (audio_direct_mode_t) (directMode |
- AUDIO_DIRECT_BITSTREAM_SUPPORTED);
+ directMode = (audio_direct_mode_t) (directMode | AUDIO_DIRECT_BITSTREAM_SUPPORTED);
}
}
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 6f8b897..68ae8cb 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -768,6 +768,15 @@
audio_channel_mask_t channelMask,
audio_output_flags_t flags,
bool directOnly);
+ /**
+ * Same as getProfileForOutput, but it looks for an MSD profile
+ */
+ sp<IOProfile> getMsdProfileForOutput(const DeviceVector &devices,
+ uint32_t samplingRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ audio_output_flags_t flags,
+ bool directOnly);
audio_io_handle_t selectOutputForMusicEffects();
@@ -1201,6 +1210,21 @@
// without duplicating them if already present
void addPortProfilesToVector(sp<IOProfile> outputProfile,
AudioProfileVector& audioProfilesVector);
+
+ // Searches for a compatible profile with the sample rate, audio format and channel mask
+ // in the list of passed HwModule(s).
+ // returns a compatible profile if found, nullptr otherwise
+ sp<IOProfile> searchCompatibleProfileHwModules (
+ const HwModuleCollection& hwModules,
+ const DeviceVector& devices,
+ uint32_t samplingRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ audio_output_flags_t flags,
+ bool directOnly);
+
+ // Filters only the relevant flags for getProfileForOutput
+ audio_output_flags_t getRelevantFlags (audio_output_flags_t flags, bool directOnly);
};
};
diff --git a/services/audiopolicy/service/Spatializer.cpp b/services/audiopolicy/service/Spatializer.cpp
index d9e89aa..579b852 100644
--- a/services/audiopolicy/service/Spatializer.cpp
+++ b/services/audiopolicy/service/Spatializer.cpp
@@ -300,7 +300,7 @@
if (levelChanged && mEngine != nullptr) {
setEffectParameter_l(SPATIALIZER_PARAM_LEVEL, std::vector<SpatializationLevel>{level});
}
- checkHeadSensor_l();
+ checkSensorsState_l();
}
if (levelChanged) {
@@ -375,7 +375,7 @@
if (mPoseController != nullptr) {
mPoseController->setDesiredMode(mDesiredHeadTrackingMode);
- checkHeadSensor_l();
+ checkSensorsState_l();
}
return Status::ok();
@@ -449,9 +449,7 @@
}
std::lock_guard lock(mLock);
mHeadSensor = sensorHandle;
- if (mPoseController != nullptr) {
- checkHeadSensor_l();
- }
+ checkSensorsState_l();
return Status::ok();
}
@@ -462,9 +460,7 @@
}
std::lock_guard lock(mLock);
mScreenSensor = sensorHandle;
- if (mPoseController != nullptr) {
- mPoseController->setScreenSensor(mScreenSensor);
- }
+ checkSensorsState_l();
return Status::ok();
}
@@ -669,8 +665,7 @@
mPoseController->setDesiredMode(mDesiredHeadTrackingMode);
mNumActiveTracks = numActiveTracks;
- checkHeadSensor_l();
- mPoseController->setScreenSensor(mScreenSensor);
+ checkSensorsState_l();
mPoseController->setDisplayOrientation(mDisplayOrientation);
poseController = mPoseController;
}
@@ -715,17 +710,19 @@
void Spatializer::updateActiveTracks(size_t numActiveTracks) {
std::lock_guard lock(mLock);
mNumActiveTracks = numActiveTracks;
- checkHeadSensor_l();
+ checkSensorsState_l();
}
-void Spatializer::checkHeadSensor_l() {
+void Spatializer::checkSensorsState_l() {
if (mSupportsHeadTracking && mPoseController != nullptr) {
- if(mNumActiveTracks > 0 && mLevel != SpatializationLevel::NONE
+ if (mNumActiveTracks > 0 && mLevel != SpatializationLevel::NONE
&& mDesiredHeadTrackingMode != HeadTrackingMode::STATIC
&& mHeadSensor != SpatializerPoseController::INVALID_SENSOR) {
mPoseController->setHeadSensor(mHeadSensor);
+ mPoseController->setScreenSensor(mScreenSensor);
} else {
mPoseController->setHeadSensor(SpatializerPoseController::INVALID_SENSOR);
+ mPoseController->setScreenSensor(SpatializerPoseController::INVALID_SENSOR);
}
}
}
@@ -746,11 +743,11 @@
switch (event) {
case AudioEffect::EVENT_FRAMES_PROCESSED: {
int frames = info == nullptr ? 0 : *(int*)info;
- ALOGD("%s frames processed %d for me %p", __func__, frames, me);
+ ALOGV("%s frames processed %d for me %p", __func__, frames, me);
me->postFramesProcessedMsg(frames);
} break;
default:
- ALOGD("%s event %d", __func__, event);
+ ALOGV("%s event %d", __func__, event);
break;
}
}
diff --git a/services/audiopolicy/service/Spatializer.h b/services/audiopolicy/service/Spatializer.h
index 4ce99d8..1382124 100644
--- a/services/audiopolicy/service/Spatializer.h
+++ b/services/audiopolicy/service/Spatializer.h
@@ -276,7 +276,12 @@
void postFramesProcessedMsg(int frames);
- void checkHeadSensor_l() REQUIRES(mLock);
+ /**
+ * Checks if head and screen sensors must be actively monitored based on
+ * spatializer state and playback activity and configures the pose controller
+ * accordingly.
+ */
+ void checkSensorsState_l() REQUIRES(mLock);
/** Effect engine descriptor */
const effect_descriptor_t mEngineDescriptor;
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index 551f5e9..da42ab4 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -699,6 +699,158 @@
ASSERT_EQ(countDirectProfilesPrimary, getDirectProfilesForAttributes(attr).size());
}
+TEST_P(AudioPolicyManagerTestMsd, IsDirectPlaybackSupportedWithMsd) {
+ const audio_attributes_t attr = {
+ AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN,
+ AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
+
+ audio_config_base_t directConfig = AUDIO_CONFIG_BASE_INITIALIZER;
+ directConfig.format = AUDIO_FORMAT_DTS;
+ directConfig.sample_rate = 48000;
+ directConfig.channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
+
+ audio_config_base_t nonDirectConfig = AUDIO_CONFIG_BASE_INITIALIZER;
+ nonDirectConfig.format = AUDIO_FORMAT_PCM_16_BIT;
+ nonDirectConfig.sample_rate = 48000;
+ nonDirectConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+
+ audio_config_base_t nonExistentConfig = AUDIO_CONFIG_BASE_INITIALIZER;
+ nonExistentConfig.format = AUDIO_FORMAT_E_AC3;
+ nonExistentConfig.sample_rate = 48000;
+ nonExistentConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+
+ audio_config_base_t msdDirectConfig1 = AUDIO_CONFIG_BASE_INITIALIZER;
+ msdDirectConfig1.format = AUDIO_FORMAT_AC3;
+ msdDirectConfig1.sample_rate = 48000;
+ msdDirectConfig1.channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
+
+ audio_config_base_t msdDirectConfig2 = AUDIO_CONFIG_BASE_INITIALIZER;
+ msdDirectConfig2.format = AUDIO_FORMAT_IEC60958;
+ msdDirectConfig2.sample_rate = 48000;
+ msdDirectConfig2.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+
+ audio_config_base_t msdNonDirectConfig = AUDIO_CONFIG_BASE_INITIALIZER;
+ msdNonDirectConfig.format = AUDIO_FORMAT_PCM_16_BIT;
+ msdNonDirectConfig.sample_rate = 96000;
+ msdNonDirectConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+
+ ASSERT_TRUE(mManager->isDirectOutputSupported(directConfig, attr));
+ ASSERT_FALSE(mManager->isDirectOutputSupported(nonDirectConfig, attr));
+ ASSERT_FALSE(mManager->isDirectOutputSupported(nonExistentConfig, attr));
+ // before setting MSD patches the direct MSD configs return false
+ ASSERT_FALSE(mManager->isDirectOutputSupported(msdDirectConfig1, attr));
+ ASSERT_FALSE(mManager->isDirectOutputSupported(msdDirectConfig2, attr));
+ ASSERT_FALSE(mManager->isDirectOutputSupported(msdNonDirectConfig, attr));
+
+ DeviceVector outputDevices = mManager->getAvailableOutputDevices();
+ // Remove MSD output device to avoid patching to itself
+ outputDevices.remove(mMsdOutputDevice);
+ mManager->setMsdOutputPatches(&outputDevices);
+
+ ASSERT_TRUE(mManager->isDirectOutputSupported(directConfig, attr));
+ ASSERT_FALSE(mManager->isDirectOutputSupported(nonDirectConfig, attr));
+ ASSERT_FALSE(mManager->isDirectOutputSupported(nonExistentConfig, attr));
+ // after setting MSD patches the direct MSD configs return true
+ ASSERT_TRUE(mManager->isDirectOutputSupported(msdDirectConfig1, attr));
+ ASSERT_TRUE(mManager->isDirectOutputSupported(msdDirectConfig2, attr));
+ ASSERT_FALSE(mManager->isDirectOutputSupported(msdNonDirectConfig, attr));
+
+ mManager->releaseMsdOutputPatches(outputDevices);
+
+ ASSERT_TRUE(mManager->isDirectOutputSupported(directConfig, attr));
+ ASSERT_FALSE(mManager->isDirectOutputSupported(nonDirectConfig, attr));
+ ASSERT_FALSE(mManager->isDirectOutputSupported(nonExistentConfig, attr));
+ // AFTER releasing MSD patches the direct MSD configs return false
+ ASSERT_FALSE(mManager->isDirectOutputSupported(msdDirectConfig1, attr));
+ ASSERT_FALSE(mManager->isDirectOutputSupported(msdDirectConfig2, attr));
+ ASSERT_FALSE(mManager->isDirectOutputSupported(msdNonDirectConfig, attr));
+}
+
+TEST_P(AudioPolicyManagerTestMsd, GetDirectPlaybackSupportWithMsd) {
+ const audio_attributes_t attr = {
+ AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN,
+ AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
+
+ audio_config_t directConfig = AUDIO_CONFIG_INITIALIZER;
+ directConfig.format = AUDIO_FORMAT_DTS;
+ directConfig.sample_rate = 48000;
+ directConfig.channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
+
+ audio_config_t nonDirectConfig = AUDIO_CONFIG_INITIALIZER;
+ nonDirectConfig.format = AUDIO_FORMAT_PCM_16_BIT;
+ nonDirectConfig.sample_rate = 48000;
+ nonDirectConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+
+ audio_config_t nonExistentConfig = AUDIO_CONFIG_INITIALIZER;
+ nonExistentConfig.format = AUDIO_FORMAT_E_AC3;
+ nonExistentConfig.sample_rate = 48000;
+ nonExistentConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+
+ audio_config_t msdDirectConfig1 = AUDIO_CONFIG_INITIALIZER;
+ msdDirectConfig1.format = AUDIO_FORMAT_AC3;
+ msdDirectConfig1.sample_rate = 48000;
+ msdDirectConfig1.channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
+
+ audio_config_t msdDirectConfig2 = AUDIO_CONFIG_INITIALIZER;
+ msdDirectConfig2.format = AUDIO_FORMAT_IEC60958;
+ msdDirectConfig2.sample_rate = 48000;
+ msdDirectConfig2.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+
+ audio_config_t msdNonDirectConfig = AUDIO_CONFIG_INITIALIZER;
+ msdNonDirectConfig.format = AUDIO_FORMAT_PCM_16_BIT;
+ msdNonDirectConfig.sample_rate = 96000;
+ msdNonDirectConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+
+ ASSERT_EQ(AUDIO_DIRECT_BITSTREAM_SUPPORTED,
+ mManager->getDirectPlaybackSupport(&attr, &directConfig));
+ ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
+ mManager->getDirectPlaybackSupport(&attr, &nonDirectConfig));
+ ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
+ mManager->getDirectPlaybackSupport(&attr, &nonExistentConfig));
+ // before setting MSD patches the direct MSD configs return AUDIO_DIRECT_NOT_SUPPORTED
+ ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
+ mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig1));
+ ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
+ mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig2));
+ ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
+ mManager->getDirectPlaybackSupport(&attr, &msdNonDirectConfig));
+
+ DeviceVector outputDevices = mManager->getAvailableOutputDevices();
+ // Remove MSD output device to avoid patching to itself
+ outputDevices.remove(mMsdOutputDevice);
+ mManager->setMsdOutputPatches(&outputDevices);
+
+ ASSERT_EQ(AUDIO_DIRECT_BITSTREAM_SUPPORTED,
+ mManager->getDirectPlaybackSupport(&attr, &directConfig));
+ ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
+ mManager->getDirectPlaybackSupport(&attr, &nonDirectConfig));
+ ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
+ mManager->getDirectPlaybackSupport(&attr, &nonExistentConfig));
+ // after setting MSD patches the direct MSD configs return values according to their flags
+ ASSERT_EQ(AUDIO_DIRECT_OFFLOAD_SUPPORTED,
+ mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig1));
+ ASSERT_EQ(AUDIO_DIRECT_BITSTREAM_SUPPORTED,
+ mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig2));
+ ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
+ mManager->getDirectPlaybackSupport(&attr, &msdNonDirectConfig));
+
+ mManager->releaseMsdOutputPatches(outputDevices);
+
+ ASSERT_EQ(AUDIO_DIRECT_BITSTREAM_SUPPORTED,
+ mManager->getDirectPlaybackSupport(&attr, &directConfig));
+ ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
+ mManager->getDirectPlaybackSupport(&attr, &nonDirectConfig));
+ ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
+ mManager->getDirectPlaybackSupport(&attr, &nonExistentConfig));
+ // after releasing MSD patches the direct MSD configs return AUDIO_DIRECT_NOT_SUPPORTED
+ ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
+ mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig1));
+ ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
+ mManager->getDirectPlaybackSupport(&attr, &msdDirectConfig2));
+ ASSERT_EQ(AUDIO_DIRECT_NOT_SUPPORTED,
+ mManager->getDirectPlaybackSupport(&attr, &msdNonDirectConfig));
+}
+
class AudioPolicyManagerTestWithConfigurationFile : public AudioPolicyManagerTest {
protected:
void SetUpManagerConfig() override;
diff --git a/services/camera/libcameraservice/api2/CompositeStream.h b/services/camera/libcameraservice/api2/CompositeStream.h
index 600bd28..d32b71c 100644
--- a/services/camera/libcameraservice/api2/CompositeStream.h
+++ b/services/camera/libcameraservice/api2/CompositeStream.h
@@ -117,6 +117,41 @@
// Composite streams should behave accordingly.
void enableErrorState();
+ // Utility class to lock and unlock a GraphicBuffer
+ class GraphicBufferLocker {
+ public:
+ GraphicBufferLocker(sp<GraphicBuffer> buffer) : _buffer(buffer) {}
+
+ status_t lockAsync(void** dstBuffer, int fenceFd) {
+ if (_buffer == nullptr) return BAD_VALUE;
+
+ status_t res = OK;
+ if (!_locked) {
+ status_t res = _buffer->lockAsync(GRALLOC_USAGE_SW_WRITE_OFTEN,
+ dstBuffer, fenceFd);
+ if (res == OK) {
+ _locked = true;
+ }
+ }
+ return res;
+ }
+
+ ~GraphicBufferLocker() {
+ if (_locked && _buffer != nullptr) {
+ auto res = _buffer->unlock();
+ if (res != OK) {
+ ALOGE("%s: Error trying to unlock buffer: %s (%d)", __FUNCTION__,
+ strerror(-res), res);
+ }
+ }
+ }
+
+ private:
+ sp<GraphicBuffer> _buffer;
+ bool _locked = false;
+ };
+
+
wp<CameraDeviceBase> mDevice;
wp<camera3::StatusTracker> mStatusTracker;
wp<hardware::camera2::ICameraDeviceCallbacks> mRemoteCallback;
diff --git a/services/camera/libcameraservice/api2/DepthCompositeStream.cpp b/services/camera/libcameraservice/api2/DepthCompositeStream.cpp
index a66a592..aa057c7 100644
--- a/services/camera/libcameraservice/api2/DepthCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/DepthCompositeStream.cpp
@@ -297,7 +297,8 @@
}
sp<GraphicBuffer> gb = GraphicBuffer::from(anb);
- res = gb->lockAsync(GRALLOC_USAGE_SW_WRITE_OFTEN, &dstBuffer, fenceFd);
+ GraphicBufferLocker gbLocker(gb);
+ res = gbLocker.lockAsync(&dstBuffer, fenceFd);
if (res != OK) {
ALOGE("%s: Error trying to lock output buffer fence: %s (%d)", __FUNCTION__,
strerror(-res), res);
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
index a73ffb9..6058429 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
@@ -1130,7 +1130,8 @@
// Copy the content of the file to memory.
sp<GraphicBuffer> gb = GraphicBuffer::from(inputFrame.anb);
void* dstBuffer;
- auto res = gb->lockAsync(GRALLOC_USAGE_SW_WRITE_OFTEN, &dstBuffer, inputFrame.fenceFd);
+ GraphicBufferLocker gbLocker(gb);
+ auto res = gbLocker.lockAsync(&dstBuffer, inputFrame.fenceFd);
if (res != OK) {
ALOGE("%s: Error trying to lock output buffer fence: %s (%d)", __FUNCTION__,
strerror(-res), res);