Use HAL-provided config for getInputBufferSize
Since getInputBufferSize is essentially the same
operation as opening a stream, it can also suggest
a config if the provided one is not supported.
Modify AudioFlinger::getInputBufferSize implementation
to retry with HAL-provided config.
Bug: 318423731
Test: run `atest audioeffect_tests` on cf_x86_64_auto-trunk_staging-userdebug
Change-Id: I0eb14966ce816674d631bfef097d243a0445c83b
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
index 1d8fec0..af06581 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -271,15 +271,16 @@
return parseAndGetVendorParameters(mVendorExt, mModule, parameterKeys, values);
}
-status_t DeviceHalAidl::getInputBufferSize(const struct audio_config* config, size_t* size) {
+status_t DeviceHalAidl::getInputBufferSize(struct audio_config* config, size_t* size) {
ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
TIME_CHECK();
if (mModule == nullptr) return NO_INIT;
if (config == nullptr || size == nullptr) {
return BAD_VALUE;
}
+ constexpr bool isInput = true;
AudioConfig aidlConfig = VALUE_OR_RETURN_STATUS(
- ::aidl::android::legacy2aidl_audio_config_t_AudioConfig(*config, true /*isInput*/));
+ ::aidl::android::legacy2aidl_audio_config_t_AudioConfig(*config, isInput));
AudioDevice aidlDevice;
aidlDevice.type.type = AudioDeviceType::IN_DEFAULT;
AudioSource aidlSource = AudioSource::DEFAULT;
@@ -293,6 +294,9 @@
0 /*handle*/, aidlDevice, aidlFlags, aidlSource,
&cleanups, &aidlConfig, &mixPortConfig, &aidlPatch));
}
+ *config = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::aidl2legacy_AudioConfig_audio_config_t(aidlConfig, isInput));
+ if (mixPortConfig.id == 0) return BAD_VALUE; // HAL suggests a different config.
*size = aidlConfig.frameCount *
getFrameSizeInBytes(aidlConfig.base.format, aidlConfig.base.channelMask);
// Do not disarm cleanups to release temporary port configs.
diff --git a/media/libaudiohal/impl/DeviceHalAidl.h b/media/libaudiohal/impl/DeviceHalAidl.h
index 9493e47..6f8afe5 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.h
+++ b/media/libaudiohal/impl/DeviceHalAidl.h
@@ -113,7 +113,7 @@
status_t getParameters(const String8& keys, String8 *values) override;
// Returns audio input buffer size according to parameters passed.
- status_t getInputBufferSize(const struct audio_config* config, size_t* size) override;
+ status_t getInputBufferSize(struct audio_config* config, size_t* size) override;
// Creates and opens the audio hardware output stream. The stream is closed
// by releasing all references to the returned object.
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index e8e1f46..478e0f0 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -236,7 +236,7 @@
}
status_t DeviceHalHidl::getInputBufferSize(
- const struct audio_config *config, size_t *size) {
+ struct audio_config *config, size_t *size) {
TIME_CHECK();
if (mDevice == 0) return NO_INIT;
AudioConfig hidlConfig;
diff --git a/media/libaudiohal/impl/DeviceHalHidl.h b/media/libaudiohal/impl/DeviceHalHidl.h
index 7a712df..1362dab 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.h
+++ b/media/libaudiohal/impl/DeviceHalHidl.h
@@ -67,7 +67,7 @@
status_t getParameters(const String8& keys, String8 *values) override;
// Returns audio input buffer size according to parameters passed.
- status_t getInputBufferSize(const struct audio_config* config, size_t* size) override;
+ status_t getInputBufferSize(struct audio_config* config, size_t* size) override;
// Creates and opens the audio hardware output stream. The stream is closed
// by releasing all references to the returned object.
diff --git a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
index bb5f851..7f6c1fb 100644
--- a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
@@ -78,8 +78,9 @@
virtual status_t getParameters(const String8& keys, String8 *values) = 0;
// Returns audio input buffer size according to parameters passed.
- virtual status_t getInputBufferSize(const struct audio_config *config,
- size_t *size) = 0;
+ // If there is no possibility for the HAL to open an input with the provided
+ // parameters, the method will return BAD_VALUE and modify the provided `config`.
+ virtual status_t getInputBufferSize(struct audio_config *config, size_t *size) = 0;
// Creates and opens the audio hardware output stream. The stream is closed
// by releasing all references to the returned object.
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 7d63afb..c78e98e 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1933,7 +1933,7 @@
mHardwareStatus = AUDIO_HW_IDLE;
// Change parameters of the configuration each iteration until we find a
- // configuration that the device will support.
+ // configuration that the device will support, or HAL suggests what it supports.
audio_config_t config = AUDIO_CONFIG_INITIALIZER;
for (auto testChannelMask : channelMasks) {
config.channel_mask = testChannelMask;
@@ -1943,11 +1943,16 @@
config.sample_rate = testSampleRate;
size_t bytes = 0;
+ audio_config_t loopConfig = config;
status_t result = dev->getInputBufferSize(&config, &bytes);
+ if (result == BAD_VALUE) {
+ // Retry with the config suggested by the HAL.
+ result = dev->getInputBufferSize(&config, &bytes);
+ }
if (result != OK || bytes == 0) {
+ config = loopConfig;
continue;
}
-
if (config.sample_rate != sampleRate || config.channel_mask != channelMask ||
config.format != format) {
uint32_t dstChannelCount = audio_channel_count_from_in_mask(channelMask);