Merge "C2: Generate CSD in vp9 encoder" into main
diff --git a/media/codec2/components/avc/Android.bp b/media/codec2/components/avc/Android.bp
index a7ae85b..8ccb9ac 100644
--- a/media/codec2/components/avc/Android.bp
+++ b/media/codec2/components/avc/Android.bp
@@ -17,6 +17,10 @@
static_libs: ["libavcdec"],
+ cflags: [
+ "-DKEEP_THREADS_ACTIVE=1",
+ ],
+
srcs: ["C2SoftAvcDec.cpp"],
export_include_dirs: ["."],
diff --git a/media/codec2/components/avc/C2SoftAvcDec.cpp b/media/codec2/components/avc/C2SoftAvcDec.cpp
index 3385b95..77fdeb9 100644
--- a/media/codec2/components/avc/C2SoftAvcDec.cpp
+++ b/media/codec2/components/avc/C2SoftAvcDec.cpp
@@ -16,6 +16,9 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "C2SoftAvcDec"
+#ifndef KEEP_THREADS_ACTIVE
+#define KEEP_THREADS_ACTIVE 0
+#endif
#include <log/log.h>
#include <media/stagefright/foundation/MediaDefs.h>
@@ -416,7 +419,7 @@
ivdext_create_op_t s_create_op = {};
s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ivdext_create_ip_t);
- s_create_ip.u4_keep_threads_active = 1;
+ s_create_ip.u4_keep_threads_active = KEEP_THREADS_ACTIVE;
s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
s_create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 0;
s_create_ip.s_ivd_create_ip_t.e_output_format = mIvColorFormat;
diff --git a/media/codec2/components/hevc/Android.bp b/media/codec2/components/hevc/Android.bp
index d1388b9..cb9c2ae 100644
--- a/media/codec2/components/hevc/Android.bp
+++ b/media/codec2/components/hevc/Android.bp
@@ -15,6 +15,10 @@
"libcodec2_soft_sanitize_cfi-defaults",
],
+ cflags: [
+ "-DKEEP_THREADS_ACTIVE=1",
+ ],
+
srcs: ["C2SoftHevcDec.cpp"],
static_libs: ["libhevcdec"],
diff --git a/media/codec2/components/hevc/C2SoftHevcDec.cpp b/media/codec2/components/hevc/C2SoftHevcDec.cpp
index 81db2a1..64aa7a4 100644
--- a/media/codec2/components/hevc/C2SoftHevcDec.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcDec.cpp
@@ -16,6 +16,9 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "C2SoftHevcDec"
+#ifndef KEEP_THREADS_ACTIVE
+#define KEEP_THREADS_ACTIVE 0
+#endif
#include <log/log.h>
#include <media/stagefright/foundation/MediaDefs.h>
@@ -407,7 +410,7 @@
ivdext_create_op_t s_create_op = {};
s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ivdext_create_ip_t);
- s_create_ip.u4_keep_threads_active = 1;
+ s_create_ip.u4_keep_threads_active = KEEP_THREADS_ACTIVE;
s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
s_create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 0;
s_create_ip.s_ivd_create_ip_t.e_output_format = mIvColorformat;
diff --git a/media/codec2/hal/client/Android.bp b/media/codec2/hal/client/Android.bp
index af6f4ae..864eeb8 100644
--- a/media/codec2/hal/client/Android.bp
+++ b/media/codec2/hal/client/Android.bp
@@ -33,6 +33,13 @@
"libcodec2-aidl-client-defaults",
],
+ // http://b/343951602#comment4 Explicitly set cpp_std to gnu++20. The
+ // default inherited from libcodec2-impl-defaults sets it to gnu++17 which
+ // causes a segfault when mixing global std::string symbols built with
+ // gnu++17 and gnu++20. TODO(b/343951602): clean this after
+ // libcodec2-impl-defaults opt into gnu++17 is removed.
+ cpp_std: "gnu++20",
+
header_libs: [
"libcodec2_internal", // private
],
diff --git a/media/codec2/sfplugin/C2AidlNode.cpp b/media/codec2/sfplugin/C2AidlNode.cpp
index 0f23205..4e46ad6 100644
--- a/media/codec2/sfplugin/C2AidlNode.cpp
+++ b/media/codec2/sfplugin/C2AidlNode.cpp
@@ -68,10 +68,15 @@
}
::ndk::ScopedAStatus C2AidlNode::submitBuffer(
- int32_t buffer, const ::aidl::android::hardware::HardwareBuffer& hBuffer,
+ int32_t buffer,
+ const std::optional<::aidl::android::hardware::HardwareBuffer>& hBuffer,
int32_t flags, int64_t timestamp, const ::ndk::ScopedFileDescriptor& fence) {
sp<GraphicBuffer> gBuf;
- AHardwareBuffer *ahwb = hBuffer.get();
+ AHardwareBuffer *ahwb = nullptr;
+ if (hBuffer.has_value()) {
+ ahwb = hBuffer.value().get();
+ }
+
if (ahwb) {
gBuf = AHardwareBuffer_to_GraphicBuffer(ahwb);
}
diff --git a/media/codec2/sfplugin/C2AidlNode.h b/media/codec2/sfplugin/C2AidlNode.h
index 9dd3504..95290fd 100644
--- a/media/codec2/sfplugin/C2AidlNode.h
+++ b/media/codec2/sfplugin/C2AidlNode.h
@@ -49,7 +49,7 @@
::ndk::ScopedAStatus submitBuffer(
int32_t buffer,
- const ::aidl::android::hardware::HardwareBuffer& hBuffer,
+ const std::optional<::aidl::android::hardware::HardwareBuffer>& hBuffer,
int32_t flags,
int64_t timestampUs,
const ::ndk::ScopedFileDescriptor& fence) override;
diff --git a/media/module/aidlpersistentsurface/aidl/android/media/IAidlNode.aidl b/media/module/aidlpersistentsurface/aidl/android/media/IAidlNode.aidl
index cf880c2..fe3caf3 100644
--- a/media/module/aidlpersistentsurface/aidl/android/media/IAidlNode.aidl
+++ b/media/module/aidlpersistentsurface/aidl/android/media/IAidlNode.aidl
@@ -44,7 +44,7 @@
void setInputSurface(IAidlBufferSource bufferSource);
void submitBuffer(
int buffer,
- in HardwareBuffer hBuffer,
+ in @nullable HardwareBuffer hBuffer,
int flags,
long timestampUs,
in @nullable ParcelFileDescriptor fence);
diff --git a/media/module/aidlpersistentsurface/wrapper/WAidlGraphicBufferSource.cpp b/media/module/aidlpersistentsurface/wrapper/WAidlGraphicBufferSource.cpp
index 5526b10..a5c72d6 100644
--- a/media/module/aidlpersistentsurface/wrapper/WAidlGraphicBufferSource.cpp
+++ b/media/module/aidlpersistentsurface/wrapper/WAidlGraphicBufferSource.cpp
@@ -51,19 +51,24 @@
int32_t bufferId, uint32_t flags,
const sp<GraphicBuffer> &buffer,
int64_t timestamp, int fenceFd) override {
- AHardwareBuffer *ahwBuffer = nullptr;
- ::aidl::android::hardware::HardwareBuffer hBuffer;
+ ::ndk::ScopedFileDescriptor fence(fenceFd);
if (buffer.get()) {
- ahwBuffer = AHardwareBuffer_from_GraphicBuffer(buffer.get());
+ ::aidl::android::hardware::HardwareBuffer hBuffer;
+ AHardwareBuffer *ahwBuffer = AHardwareBuffer_from_GraphicBuffer(buffer.get());
AHardwareBuffer_acquire(ahwBuffer);
hBuffer.reset(ahwBuffer);
- }
- ::ndk::ScopedFileDescriptor fence(fenceFd);
+ return fromAidlStatus(mNode->submitBuffer(
+ bufferId,
+ std::move(hBuffer),
+ flags,
+ timestamp,
+ fence));
+ }
return fromAidlStatus(mNode->submitBuffer(
bufferId,
- hBuffer,
+ {},
flags,
timestamp,
fence));
diff --git a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
index f3a9518..688772c 100644
--- a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
+++ b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
@@ -70,10 +70,17 @@
return mMixerBehaviors;
}
+ enum CompatibilityScore{
+ NO_MATCH = 0,
+ PARTIAL_MATCH = 1,
+ EXACT_MATCH = 2
+ };
+
/**
- * @brief isCompatibleProfile: This method is used for input and direct output,
+ * @brief compatibilityScore: This method is used for input and direct output,
* and is not used for other output.
- * Checks if the IO profile is compatible with specified parameters.
+ * Return the compatibility score to measure how much the IO profile is compatible
+ * with specified parameters.
* For input, flags is interpreted as audio_input_flags_t.
* TODO: merge audio_output_flags_t and audio_input_flags_t.
*
@@ -86,18 +93,18 @@
* @param updatedChannelMask if non-NULL, it is assigned the actual channel mask
* @param flags to be checked for compatibility
* @param exactMatchRequiredForInputFlags true if exact match is required on flags
- * @return true if the profile is compatible, false otherwise.
+ * @return how the IO profile is compatible with the given parameters.
*/
- bool isCompatibleProfile(const DeviceVector &devices,
- uint32_t samplingRate,
- uint32_t *updatedSamplingRate,
- audio_format_t format,
- audio_format_t *updatedFormat,
- audio_channel_mask_t channelMask,
- audio_channel_mask_t *updatedChannelMask,
- // FIXME parameter type
- uint32_t flags,
- bool exactMatchRequiredForInputFlags = false) const;
+ CompatibilityScore getCompatibilityScore(const DeviceVector &devices,
+ uint32_t samplingRate,
+ uint32_t *updatedSamplingRate,
+ audio_format_t format,
+ audio_format_t *updatedFormat,
+ audio_channel_mask_t channelMask,
+ audio_channel_mask_t *updatedChannelMask,
+ // FIXME parameter type
+ uint32_t flags,
+ bool exactMatchRequiredForInputFlags = false) const;
/**
* @brief areAllDevicesSupported: Checks if the given devices are supported by the IO profile.
diff --git a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
index c7d2e6b..d9fbd89 100644
--- a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
@@ -33,17 +33,17 @@
}
}
-bool IOProfile::isCompatibleProfile(const DeviceVector &devices,
- uint32_t samplingRate,
- uint32_t *updatedSamplingRate,
- audio_format_t format,
- audio_format_t *updatedFormat,
- audio_channel_mask_t channelMask,
- audio_channel_mask_t *updatedChannelMask,
- // FIXME type punning here
- uint32_t flags,
- bool exactMatchRequiredForInputFlags) const
-{
+IOProfile::CompatibilityScore IOProfile::getCompatibilityScore(
+ const android::DeviceVector &devices,
+ uint32_t samplingRate,
+ uint32_t *updatedSamplingRate,
+ audio_format_t format,
+ audio_format_t *updatedFormat,
+ audio_channel_mask_t channelMask,
+ audio_channel_mask_t *updatedChannelMask,
+ // FIXME type punning here
+ uint32_t flags,
+ bool exactMatchRequiredForInputFlags) const {
const bool isPlaybackThread =
getType() == AUDIO_PORT_TYPE_MIX && getRole() == AUDIO_PORT_ROLE_SOURCE;
const bool isRecordThread =
@@ -51,13 +51,13 @@
ALOG_ASSERT(isPlaybackThread != isRecordThread);
if (!areAllDevicesSupported(devices) ||
!isCompatibleProfileForFlags(flags, exactMatchRequiredForInputFlags)) {
- return false;
+ return NO_MATCH;
}
if (!audio_is_valid_format(format) ||
(isPlaybackThread && (samplingRate == 0 || !audio_is_output_channel(channelMask))) ||
(isRecordThread && (!audio_is_input_channel(channelMask)))) {
- return false;
+ return NO_MATCH;
}
audio_format_t myUpdatedFormat = format;
@@ -69,32 +69,40 @@
.channel_mask = channelMask,
.format = format,
};
+ auto result = NO_MATCH;
if (isRecordThread)
{
if ((flags & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0) {
if (checkExactAudioProfile(&config) != NO_ERROR) {
- return false;
+ return result;
}
- } else if (checkExactAudioProfile(&config) != NO_ERROR && checkCompatibleAudioProfile(
- myUpdatedSamplingRate, myUpdatedChannelMask, myUpdatedFormat) != NO_ERROR) {
- return false;
+ result = EXACT_MATCH;
+ } else if (checkExactAudioProfile(&config) == NO_ERROR) {
+ result = EXACT_MATCH;
+ } else if (checkCompatibleAudioProfile(
+ myUpdatedSamplingRate, myUpdatedChannelMask, myUpdatedFormat) == NO_ERROR) {
+ result = PARTIAL_MATCH;
+ } else {
+ return result;
}
} else {
- if (checkExactAudioProfile(&config) != NO_ERROR) {
- return false;
+ if (checkExactAudioProfile(&config) == NO_ERROR) {
+ result = EXACT_MATCH;
+ } else {
+ return result;
}
}
- if (updatedSamplingRate != NULL) {
+ if (updatedSamplingRate != nullptr) {
*updatedSamplingRate = myUpdatedSamplingRate;
}
- if (updatedFormat != NULL) {
+ if (updatedFormat != nullptr) {
*updatedFormat = myUpdatedFormat;
}
- if (updatedChannelMask != NULL) {
+ if (updatedChannelMask != nullptr) {
*updatedChannelMask = myUpdatedChannelMask;
}
- return true;
+ return result;
}
bool IOProfile::areAllDevicesSupported(const DeviceVector &devices) const {
diff --git a/services/audiopolicy/engine/config/src/EngineConfig.cpp b/services/audiopolicy/engine/config/src/EngineConfig.cpp
index ca78ce7..3f9ae19 100644
--- a/services/audiopolicy/engine/config/src/EngineConfig.cpp
+++ b/services/audiopolicy/engine/config/src/EngineConfig.cpp
@@ -22,6 +22,7 @@
#include <string>
#include <string>
#include <vector>
+#include <unordered_map>
#define LOG_TAG "APM::AudioPolicyEngine/Config"
//#define LOG_NDEBUG 0
@@ -51,6 +52,27 @@
namespace {
+ConversionResult<std::string> aidl2legacy_AudioHalProductStrategy_ProductStrategyType(int id) {
+ using AudioProductStrategyType = media::audio::common::AudioProductStrategyType;
+
+#define STRATEGY_ENTRY(name) {static_cast<int>(AudioProductStrategyType::name), "STRATEGY_" #name}
+ static const std::unordered_map<int, std::string> productStrategyMap = {STRATEGY_ENTRY(MEDIA),
+ STRATEGY_ENTRY(PHONE),
+ STRATEGY_ENTRY(SONIFICATION),
+ STRATEGY_ENTRY(SONIFICATION_RESPECTFUL),
+ STRATEGY_ENTRY(DTMF),
+ STRATEGY_ENTRY(ENFORCED_AUDIBLE),
+ STRATEGY_ENTRY(TRANSMITTED_THROUGH_SPEAKER),
+ STRATEGY_ENTRY(ACCESSIBILITY)};
+#undef STRATEGY_ENTRY
+
+ auto it = productStrategyMap.find(id);
+ if (it == productStrategyMap.end()) {
+ return base::unexpected(BAD_VALUE);
+ }
+ return it->second;
+}
+
ConversionResult<AttributesGroup> aidl2legacy_AudioHalAttributeGroup_AttributesGroup(
const media::audio::common::AudioHalAttributesGroup& aidl) {
AttributesGroup legacy;
@@ -65,7 +87,8 @@
ConversionResult<ProductStrategy> aidl2legacy_AudioHalProductStrategy_ProductStrategy(
const media::audio::common::AudioHalProductStrategy& aidl) {
ProductStrategy legacy;
- legacy.name = "strategy_" + std::to_string(aidl.id);
+ legacy.name = VALUE_OR_RETURN(
+ aidl2legacy_AudioHalProductStrategy_ProductStrategyType(aidl.id));
legacy.attributesGroups = VALUE_OR_RETURN(convertContainer<AttributesGroups>(
aidl.attributesGroups,
aidl2legacy_AudioHalAttributeGroup_AttributesGroup));
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 5c4ab7b..6a10469 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -390,8 +390,12 @@
// Before checking intputs, broadcast connect event to allow HAL to retrieve dynamic
// parameters on newly connected devices (instead of opening the inputs...)
broadcastDeviceConnectionState(device, media::DeviceConnectedState::CONNECTED);
+ // Propagate device availability to Engine
+ setEngineDeviceConnectionState(device, state);
if (checkInputsForDevice(device, state) != NO_ERROR) {
+ setEngineDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE);
+
mAvailableInputDevices.remove(device);
broadcastDeviceConnectionState(device, media::DeviceConnectedState::DISCONNECTED);
@@ -425,6 +429,9 @@
// remove device from mReportedFormatsMap cache
mReportedFormatsMap.erase(device);
+
+ // Propagate device availability to Engine
+ setEngineDeviceConnectionState(device, state);
} break;
default:
@@ -432,9 +439,6 @@
return BAD_VALUE;
}
- // Propagate device availability to Engine
- setEngineDeviceConnectionState(device, state);
-
checkCloseInputs();
// As the input device list can impact the output device selection, update
// getDeviceForStrategy() cache
@@ -1043,11 +1047,11 @@
sp<IOProfile> profile;
for (const auto& hwModule : hwModules) {
for (const auto& curProfile : hwModule->getOutputProfiles()) {
- if (!curProfile->isCompatibleProfile(devices,
+ if (curProfile->getCompatibilityScore(devices,
samplingRate, NULL /*updatedSamplingRate*/,
format, NULL /*updatedFormat*/,
channelMask, NULL /*updatedChannelMask*/,
- flags)) {
+ flags) == IOProfile::NO_MATCH) {
continue;
}
// reject profiles not corresponding to a device currently available
@@ -3175,6 +3179,23 @@
releaseInput(portId);
}
+bool AudioPolicyManager::checkCloseInput(const sp<AudioInputDescriptor>& input) {
+ if (input->clientsList().size() == 0
+ || !mAvailableInputDevices.containsAtLeastOne(input->supportedDevices())) {
+ return true;
+ }
+ for (const auto& client : input->clientsList()) {
+ sp<DeviceDescriptor> device =
+ mEngine->getInputDeviceForAttributes(client->attributes(), client->uid(),
+ client->session());
+ if (!input->supportedDevices().contains(device)) {
+ return true;
+ }
+ }
+ setInputDevice(input->mIoHandle, getNewInputDevice(input));
+ return false;
+}
+
void AudioPolicyManager::checkCloseInputs() {
// After connecting or disconnecting an input device, close input if:
// - it has no client (was just opened to check profile) OR
@@ -3183,29 +3204,10 @@
// devices anymore. Otherwise update device selection
std::vector<audio_io_handle_t> inputsToClose;
for (size_t i = 0; i < mInputs.size(); i++) {
- const sp<AudioInputDescriptor> input = mInputs.valueAt(i);
- if (input->clientsList().size() == 0
- || !mAvailableInputDevices.containsAtLeastOne(input->supportedDevices())) {
+ if (checkCloseInput(mInputs.valueAt(i))) {
inputsToClose.push_back(mInputs.keyAt(i));
- } else {
- bool close = false;
- for (const auto& client : input->clientsList()) {
- sp<DeviceDescriptor> device =
- mEngine->getInputDeviceForAttributes(client->attributes(), client->uid(),
- client->session());
- if (!input->supportedDevices().contains(device)) {
- close = true;
- break;
- }
- }
- if (close) {
- inputsToClose.push_back(mInputs.keyAt(i));
- } else {
- setInputDevice(input->mIoHandle, getNewInputDevice(input));
- }
}
}
-
for (const audio_io_handle_t handle : inputsToClose) {
ALOGV("%s closing input %d", __func__, handle);
closeInput(handle);
@@ -4463,11 +4465,11 @@
outputDevices = getMsdAudioOutDevices();
}
for (const auto& curProfile : hwModule->getOutputProfiles()) {
- if (!curProfile->isCompatibleProfile(outputDevices,
+ if (curProfile->getCompatibilityScore(outputDevices,
config->sample_rate, nullptr /*updatedSamplingRate*/,
config->format, nullptr /*updatedFormat*/,
config->channel_mask, nullptr /*updatedChannelMask*/,
- flags)) {
+ flags) == IOProfile::NO_MATCH) {
continue;
}
// reject profiles not corresponding to a device currently available
@@ -4573,15 +4575,17 @@
for (const auto& hwModule : mHwModules) {
for (const auto& curProfile : hwModule->getOutputProfiles()) {
if (curProfile->hasDynamicAudioProfile()
- && curProfile->isCompatibleProfile(devices,
- mixerAttributes->config.sample_rate,
- nullptr /*updatedSamplingRate*/,
- mixerAttributes->config.format,
- nullptr /*updatedFormat*/,
- mixerAttributes->config.channel_mask,
- nullptr /*updatedChannelMask*/,
- flags,
- false /*exactMatchRequiredForInputFlags*/)) {
+ && curProfile->getCompatibilityScore(
+ devices,
+ mixerAttributes->config.sample_rate,
+ nullptr /*updatedSamplingRate*/,
+ mixerAttributes->config.format,
+ nullptr /*updatedFormat*/,
+ mixerAttributes->config.channel_mask,
+ nullptr /*updatedChannelMask*/,
+ flags,
+ false /*exactMatchRequiredForInputFlags*/)
+ != IOProfile::NO_MATCH) {
profile = curProfile;
break;
}
@@ -4984,14 +4988,15 @@
return BAD_VALUE;
}
- if (!outputDesc->mProfile->isCompatibleProfile(DeviceVector(devDesc),
- patch->sources[0].sample_rate,
- NULL, // updatedSamplingRate
- patch->sources[0].format,
- NULL, // updatedFormat
- patch->sources[0].channel_mask,
- NULL, // updatedChannelMask
- AUDIO_OUTPUT_FLAG_NONE /*FIXME*/)) {
+ if (outputDesc->mProfile->getCompatibilityScore(
+ DeviceVector(devDesc),
+ patch->sources[0].sample_rate,
+ nullptr, // updatedSamplingRate
+ patch->sources[0].format,
+ nullptr, // updatedFormat
+ patch->sources[0].channel_mask,
+ nullptr, // updatedChannelMask
+ AUDIO_OUTPUT_FLAG_NONE /*FIXME*/) == IOProfile::NO_MATCH) {
ALOGV("%s profile not supported for device %08x", __func__, devDesc->type());
return INVALID_OPERATION;
}
@@ -5039,17 +5044,18 @@
return BAD_VALUE;
}
- if (!inputDesc->mProfile->isCompatibleProfile(DeviceVector(device),
- patch->sinks[0].sample_rate,
- NULL, /*updatedSampleRate*/
- patch->sinks[0].format,
- NULL, /*updatedFormat*/
- patch->sinks[0].channel_mask,
- NULL, /*updatedChannelMask*/
- // FIXME for the parameter type,
- // and the NONE
- (audio_output_flags_t)
- AUDIO_INPUT_FLAG_NONE)) {
+ if (inputDesc->mProfile->getCompatibilityScore(
+ DeviceVector(device),
+ patch->sinks[0].sample_rate,
+ nullptr, /*updatedSampleRate*/
+ patch->sinks[0].format,
+ nullptr, /*updatedFormat*/
+ patch->sinks[0].channel_mask,
+ nullptr, /*updatedChannelMask*/
+ // FIXME for the parameter type,
+ // and the NONE
+ (audio_output_flags_t)
+ AUDIO_INPUT_FLAG_NONE) == IOProfile::NO_MATCH) {
return INVALID_OPERATION;
}
// TODO: reconfigure output format and channels here
@@ -6606,14 +6612,14 @@
status_t AudioPolicyManager::checkInputsForDevice(const sp<DeviceDescriptor>& device,
audio_policy_dev_state_t state)
{
- sp<AudioInputDescriptor> desc;
-
if (audio_device_is_digital(device->type())) {
// erase all current sample rates, formats and channel masks
device->clearAudioProfiles();
}
if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
+ sp<AudioInputDescriptor> desc;
+
// first call getAudioPort to get the supported attributes from the HAL
struct audio_port_v7 port = {};
device->toAudioPort(&port);
@@ -6704,6 +6710,11 @@
device->importAudioPortAndPickAudioProfile(profile);
}
ALOGV("checkInputsForDevice(): adding input %d", input);
+
+ if (checkCloseInput(desc)) {
+ ALOGV("%s closing input %d", __func__, input);
+ closeInput(input);
+ }
}
} // end scan profiles
@@ -7675,9 +7686,6 @@
// Choose an input profile based on the requested capture parameters: select the first available
// profile supporting all requested parameters.
// The flags can be ignored if it doesn't contain a much match flag.
- //
- // TODO: perhaps isCompatibleProfile should return a "matching" score so we can return
- // the best matching profile, not the first one.
using underlying_input_flag_t = std::underlying_type_t<audio_input_flags_t>;
const underlying_input_flag_t mustMatchFlag = AUDIO_INPUT_FLAG_MMAP_NOIRQ |
@@ -7694,27 +7702,35 @@
for (const auto& profile : hwModule->getInputProfiles()) {
// profile->log();
//updatedFormat = format;
- if (profile->isCompatibleProfile(DeviceVector(device), samplingRate,
- &samplingRate /*updatedSamplingRate*/,
- format,
- &format, /*updatedFormat*/
- channelMask,
- &channelMask /*updatedChannelMask*/,
- // FIXME ugly cast
- (audio_output_flags_t) flags,
- true /*exactMatchRequiredForInputFlags*/)) {
+ if (profile->getCompatibilityScore(
+ DeviceVector(device),
+ samplingRate,
+ &updatedSamplingRate,
+ format,
+ &updatedFormat,
+ channelMask,
+ &updatedChannelMask,
+ // FIXME ugly cast
+ (audio_output_flags_t) flags,
+ true /*exactMatchRequiredForInputFlags*/) == IOProfile::EXACT_MATCH) {
+ samplingRate = updatedSamplingRate;
+ format = updatedFormat;
+ channelMask = updatedChannelMask;
return profile;
}
- if (firstInexact == nullptr && profile->isCompatibleProfile(DeviceVector(device),
- samplingRate,
- &updatedSamplingRate,
- format,
- &updatedFormat,
- channelMask,
- &updatedChannelMask,
- // FIXME ugly cast
- (audio_output_flags_t) flags,
- false /*exactMatchRequiredForInputFlags*/)) {
+ if (firstInexact == nullptr
+ && profile->getCompatibilityScore(
+ DeviceVector(device),
+ samplingRate,
+ &updatedSamplingRate,
+ format,
+ &updatedFormat,
+ channelMask,
+ &updatedChannelMask,
+ // FIXME ugly cast
+ (audio_output_flags_t) flags,
+ false /*exactMatchRequiredForInputFlags*/)
+ != IOProfile::NO_MATCH) {
firstInexact = profile;
}
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 61be09f..7513952 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -526,6 +526,7 @@
void addOutput(audio_io_handle_t output, const sp<SwAudioOutputDescriptor>& outputDesc);
void removeOutput(audio_io_handle_t output);
void addInput(audio_io_handle_t input, const sp<AudioInputDescriptor>& inputDesc);
+ bool checkCloseInput(const sp<AudioInputDescriptor>& input);
/**
* @brief setOutputDevices change the route of the specified output.
diff --git a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
index 7ef0266..072d9c0 100644
--- a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
@@ -70,6 +70,22 @@
return BAD_VALUE;
}
*input = mNextIoHandle++;
+ mOpenedInputs.insert(*input);
+ ALOGD("%s: opened input %d", __func__, *input);
+ return NO_ERROR;
+ }
+
+ status_t closeInput(audio_io_handle_t input) override {
+ if (mOpenedInputs.erase(input) != 1) {
+ if (input >= mNextIoHandle) {
+ ALOGE("%s: I/O handle %d has not been allocated yet (next is %d)",
+ __func__, input, mNextIoHandle);
+ } else {
+ ALOGE("%s: Attempt to close input %d twice", __func__, input);
+ }
+ return BAD_VALUE;
+ }
+ ALOGD("%s: closed input %d", __func__, input);
return NO_ERROR;
}
@@ -124,6 +140,8 @@
return &it->second;
};
+ size_t getOpenedInputsCount() const { return mOpenedInputs.size(); }
+
audio_module_handle_t peekNextModuleHandle() const { return mNextModuleHandle; }
void swapAllowedModuleNames(std::set<std::string>&& names = {}) {
@@ -241,6 +259,7 @@
std::vector<struct audio_port_v7> mDisconnectedDevicePorts;
std::set<audio_format_t> mSupportedFormats;
std::set<audio_channel_mask_t> mSupportedChannelMasks;
+ std::set<audio_io_handle_t> mOpenedInputs;
};
} // namespace android
diff --git a/services/audiopolicy/tests/AudioPolicyTestManager.h b/services/audiopolicy/tests/AudioPolicyTestManager.h
index 31ee252..34ceeab 100644
--- a/services/audiopolicy/tests/AudioPolicyTestManager.h
+++ b/services/audiopolicy/tests/AudioPolicyTestManager.h
@@ -31,8 +31,10 @@
using AudioPolicyManager::getConfig;
using AudioPolicyManager::initialize;
using AudioPolicyManager::getOutputs;
+ using AudioPolicyManager::getInputs;
using AudioPolicyManager::getAvailableOutputDevices;
using AudioPolicyManager::getAvailableInputDevices;
+ using AudioPolicyManager::checkInputsForDevice;
using AudioPolicyManager::setSurroundFormatEnabled;
using AudioPolicyManager::releaseMsdOutputPatches;
using AudioPolicyManager::setMsdOutputPatches;
@@ -43,6 +45,7 @@
using AudioPolicyManager::deviceToAudioPort;
using AudioPolicyManager::handleDeviceConfigChange;
uint32_t getAudioPortGeneration() const { return mAudioPortGeneration; }
+ HwModuleCollection getHwModules() const { return mHwModules; }
};
} // namespace android
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index 8642fd4..4d9d87c 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -92,6 +92,12 @@
return attributionSourceState;
}
+bool equals(const audio_config_base_t& config1, const audio_config_base_t& config2) {
+ return config1.format == config2.format
+ && config1.sample_rate == config2.sample_rate
+ && config1.channel_mask == config2.channel_mask;
+}
+
} // namespace
TEST(AudioPolicyConfigTest, DefaultConfigForTestsIsEmpty) {
@@ -1266,6 +1272,82 @@
"", "", AUDIO_FORMAT_LDAC));
}
+TEST_F(AudioPolicyManagerTestWithConfigurationFile, PreferExactConfigForInput) {
+ const audio_channel_mask_t deviceChannelMask = AUDIO_CHANNEL_IN_3POINT1;
+ mClient->addSupportedFormat(AUDIO_FORMAT_PCM_16_BIT);
+ mClient->addSupportedChannelMask(deviceChannelMask);
+ ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_IN_USB_DEVICE,
+ AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
+ "", "", AUDIO_FORMAT_DEFAULT));
+
+ audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ audio_attributes_t attr = {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN,
+ AUDIO_SOURCE_VOICE_COMMUNICATION,AUDIO_FLAG_NONE, ""};
+ AudioPolicyInterface::input_type_t inputType;
+ audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
+ AttributionSourceState attributionSource = createAttributionSourceState(/*uid=*/ 0);
+ audio_config_base_t requestedConfig = {
+ .channel_mask = AUDIO_CHANNEL_IN_STEREO,
+ .format = AUDIO_FORMAT_PCM_16_BIT,
+ .sample_rate = 48000
+ };
+ audio_config_base_t config = requestedConfig;
+ audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
+ ASSERT_EQ(OK, mManager->getInputForAttr(
+ &attr, &input, 1 /*riid*/, AUDIO_SESSION_NONE, attributionSource, &config,
+ AUDIO_INPUT_FLAG_NONE,
+ &selectedDeviceId, &inputType, &portId));
+ ASSERT_NE(AUDIO_PORT_HANDLE_NONE, portId);
+ ASSERT_TRUE(equals(requestedConfig, config));
+
+ attr = {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN,
+ AUDIO_SOURCE_VOICE_COMMUNICATION, AUDIO_FLAG_NONE, ""};
+ requestedConfig.channel_mask = deviceChannelMask;
+ config = requestedConfig;
+ selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ input = AUDIO_PORT_HANDLE_NONE;
+ portId = AUDIO_PORT_HANDLE_NONE;
+ ASSERT_EQ(OK, mManager->getInputForAttr(
+ &attr, &input, 1 /*riid*/, AUDIO_SESSION_NONE, attributionSource, &config,
+ AUDIO_INPUT_FLAG_NONE,
+ &selectedDeviceId, &inputType, &portId));
+ ASSERT_NE(AUDIO_PORT_HANDLE_NONE, portId);
+ ASSERT_TRUE(equals(requestedConfig, config));
+
+ ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_IN_USB_DEVICE,
+ AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+ "", "", AUDIO_FORMAT_DEFAULT));
+}
+
+TEST_F(AudioPolicyManagerTestWithConfigurationFile, CheckInputsForDeviceClosesStreams) {
+ mClient->addSupportedFormat(AUDIO_FORMAT_PCM_16_BIT);
+ mClient->addSupportedFormat(AUDIO_FORMAT_PCM_24_BIT_PACKED);
+ mClient->addSupportedChannelMask(AUDIO_CHANNEL_IN_MONO);
+ mClient->addSupportedChannelMask(AUDIO_CHANNEL_IN_STEREO);
+ // Since 'checkInputsForDevice' is called as part of the 'setDeviceConnectionState',
+ // call it directly here, as we need to ensure that it does not keep all intermediate
+ // streams opened, as it may cause a rejection from the HAL based on the cap.
+ const size_t streamCountBefore = mClient->getOpenedInputsCount();
+ sp<DeviceDescriptor> device = mManager->getHwModules().getDeviceDescriptor(
+ AUDIO_DEVICE_IN_USB_DEVICE, "", "", AUDIO_FORMAT_DEFAULT, true /*allowToCreate*/);
+ ASSERT_NE(nullptr, device.get());
+ EXPECT_EQ(NO_ERROR,
+ mManager->checkInputsForDevice(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE));
+ EXPECT_EQ(streamCountBefore, mClient->getOpenedInputsCount());
+}
+
+TEST_F(AudioPolicyManagerTestWithConfigurationFile, SetDeviceConnectionStateClosesStreams) {
+ mClient->addSupportedFormat(AUDIO_FORMAT_PCM_16_BIT);
+ mClient->addSupportedFormat(AUDIO_FORMAT_PCM_24_BIT_PACKED);
+ mClient->addSupportedChannelMask(AUDIO_CHANNEL_IN_MONO);
+ mClient->addSupportedChannelMask(AUDIO_CHANNEL_IN_STEREO);
+ const size_t streamCountBefore = mClient->getOpenedInputsCount();
+ EXPECT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_IN_USB_DEVICE,
+ AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
+ "", "", AUDIO_FORMAT_DEFAULT));
+ EXPECT_EQ(streamCountBefore, mClient->getOpenedInputsCount());
+}
+
class AudioPolicyManagerTestDynamicPolicy : public AudioPolicyManagerTestWithConfigurationFile {
protected:
void TearDown() override;
diff --git a/services/audiopolicy/tests/resources/test_audio_policy_configuration.xml b/services/audiopolicy/tests/resources/test_audio_policy_configuration.xml
index 4efdf8a..bbc19fa 100644
--- a/services/audiopolicy/tests/resources/test_audio_policy_configuration.xml
+++ b/services/audiopolicy/tests/resources/test_audio_policy_configuration.xml
@@ -65,6 +65,7 @@
samplingRates="48000"
channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
</mixPort>
+ <mixPort name="hifi_input" role="sink" />
</mixPorts>
<devicePorts>
<devicePort tagName="Speaker" type="AUDIO_DEVICE_OUT_SPEAKER" role="sink">
@@ -98,7 +99,7 @@
<route type="mix" sink="primary input"
sources="Built-In Mic,Hdmi-In Mic,USB Device In"/>
<route type="mix" sink="voip_tx"
- sources="Built-In Mic"/>
+ sources="Built-In Mic,USB Device In"/>
<route type="mix" sink="Hdmi"
sources="primary output"/>
<route type="mix" sink="BT SCO"
@@ -111,6 +112,8 @@
sources="primary output,hifi_output,mmap_no_irq_out"/>
<route type="mix" sink="mixport_bus_input"
sources="BUS Device In"/>
+ <route type="mix" sink="hifi_input"
+ sources="USB Device In" />
</routes>
</module>