audio: Add support for compressed offload
- Add compressed offload mix port into default implementation.
- Require AudioOffloadInfo to be passed to IModule.openOutputStream
for compressed offload port configs.
- Update VTS to handle compressed offload.
Bug: 205884982
Test: atest VtsHalAudioCoreTargetTest
Merged-In: I118b2c04bff12b64a7cac4dc2c88217a6a270046
Change-Id: I118b2c04bff12b64a7cac4dc2c88217a6a270046
(cherry picked from commit 975ea3ae8959b1d9502290ebd5c71fba68645c64)
diff --git a/audio/aidl/vts/ModuleConfig.cpp b/audio/aidl/vts/ModuleConfig.cpp
index 0e76d9a..969b0e9 100644
--- a/audio/aidl/vts/ModuleConfig.cpp
+++ b/audio/aidl/vts/ModuleConfig.cpp
@@ -15,6 +15,7 @@
*/
#include <algorithm>
+#include <chrono>
#include <aidl/android/media/audio/common/AudioIoFlags.h>
#include <aidl/android/media/audio/common/AudioOutputFlags.h>
@@ -22,19 +23,43 @@
#include "ModuleConfig.h"
using namespace android;
+using namespace std::chrono_literals;
using aidl::android::hardware::audio::core::IModule;
using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioEncapsulationMode;
using aidl::android::media::audio::common::AudioFormatDescription;
using aidl::android::media::audio::common::AudioFormatType;
using aidl::android::media::audio::common::AudioIoFlags;
+using aidl::android::media::audio::common::AudioOffloadInfo;
using aidl::android::media::audio::common::AudioOutputFlags;
using aidl::android::media::audio::common::AudioPort;
using aidl::android::media::audio::common::AudioPortConfig;
using aidl::android::media::audio::common::AudioPortExt;
using aidl::android::media::audio::common::AudioProfile;
+using aidl::android::media::audio::common::AudioUsage;
using aidl::android::media::audio::common::Int;
+// static
+std::optional<AudioOffloadInfo> ModuleConfig::generateOffloadInfoIfNeeded(
+ const AudioPortConfig& portConfig) {
+ if (portConfig.flags.has_value() &&
+ portConfig.flags.value().getTag() == AudioIoFlags::Tag::output &&
+ (portConfig.flags.value().get<AudioIoFlags::Tag::output>() &
+ 1 << static_cast<int>(AudioOutputFlags::COMPRESS_OFFLOAD)) != 0) {
+ AudioOffloadInfo offloadInfo;
+ offloadInfo.base.sampleRate = portConfig.sampleRate.value().value;
+ offloadInfo.base.channelMask = portConfig.channelMask.value();
+ offloadInfo.base.format = portConfig.format.value();
+ offloadInfo.bitRatePerSecond = 256; // Arbitrary value.
+ offloadInfo.durationUs = std::chrono::microseconds(1min).count(); // Arbitrary value.
+ offloadInfo.usage = AudioUsage::MEDIA;
+ offloadInfo.encapsulationMode = AudioEncapsulationMode::NONE;
+ return offloadInfo;
+ }
+ return {};
+}
+
template <typename T>
auto findById(const std::vector<T>& v, int32_t id) {
return std::find_if(v.begin(), v.end(), [&](const auto& p) { return p.id == id; });
@@ -264,10 +289,10 @@
return result;
}
-static std::vector<AudioPortConfig> combineAudioConfigs(const AudioPort& port,
- const AudioProfile& profile) {
- std::vector<AudioPortConfig> configs;
- configs.reserve(profile.channelMasks.size() * profile.sampleRates.size());
+static size_t combineAudioConfigs(const AudioPort& port, const AudioProfile& profile,
+ std::vector<AudioPortConfig>* result) {
+ const size_t newConfigCount = profile.channelMasks.size() * profile.sampleRates.size();
+ result->reserve(result->capacity() + newConfigCount);
for (auto channelMask : profile.channelMasks) {
for (auto sampleRate : profile.sampleRates) {
AudioPortConfig config{};
@@ -277,66 +302,32 @@
config.sampleRate = sr;
config.channelMask = channelMask;
config.format = profile.format;
+ config.flags = port.flags;
config.ext = port.ext;
- configs.push_back(config);
+ result->push_back(std::move(config));
}
}
- return configs;
+ return newConfigCount;
}
-std::vector<AudioPortConfig> ModuleConfig::generateInputAudioMixPortConfigs(
- const std::vector<AudioPort>& ports, bool singleProfile) const {
+static bool isDynamicProfile(const AudioProfile& profile) {
+ return (profile.format.type == AudioFormatType::DEFAULT && profile.format.encoding.empty()) ||
+ profile.sampleRates.empty() || profile.channelMasks.empty();
+}
+
+std::vector<AudioPortConfig> ModuleConfig::generateAudioMixPortConfigs(
+ const std::vector<AudioPort>& ports, bool isInput, bool singleProfile) const {
std::vector<AudioPortConfig> result;
for (const auto& mixPort : ports) {
- if (getAttachedSourceDevicesPortsForMixPort(mixPort).empty()) {
- continue; // no attached devices
+ if (getAttachedDevicesPortsForMixPort(isInput, mixPort).empty()) {
+ continue;
}
for (const auto& profile : mixPort.profiles) {
- if (profile.format.type == AudioFormatType::DEFAULT || profile.sampleRates.empty() ||
- profile.channelMasks.empty()) {
- continue; // dynamic profile
- }
- auto configs = combineAudioConfigs(mixPort, profile);
- for (auto& config : configs) {
- config.flags = mixPort.flags;
- result.push_back(config);
- if (singleProfile) return result;
- }
- }
- }
- return result;
-}
-
-static std::tuple<AudioIoFlags, bool> generateOutFlags(const AudioPort& mixPort) {
- static const AudioIoFlags offloadFlags = AudioIoFlags::make<AudioIoFlags::Tag::output>(
- (1 << static_cast<int>(AudioOutputFlags::COMPRESS_OFFLOAD)) |
- (1 << static_cast<int>(AudioOutputFlags::DIRECT)));
- const bool isOffload = (mixPort.flags.get<AudioIoFlags::Tag::output>() &
- (1 << static_cast<int>(AudioOutputFlags::COMPRESS_OFFLOAD))) != 0;
- return {isOffload ? offloadFlags : mixPort.flags, isOffload};
-}
-
-std::vector<AudioPortConfig> ModuleConfig::generateOutputAudioMixPortConfigs(
- const std::vector<AudioPort>& ports, bool singleProfile) const {
- std::vector<AudioPortConfig> result;
- for (const auto& mixPort : ports) {
- if (getAttachedSinkDevicesPortsForMixPort(mixPort).empty()) {
- continue; // no attached devices
- }
- auto [flags, isOffload] = generateOutFlags(mixPort);
- (void)isOffload;
- for (const auto& profile : mixPort.profiles) {
- if (profile.format.type == AudioFormatType::DEFAULT) continue;
- auto configs = combineAudioConfigs(mixPort, profile);
- for (auto& config : configs) {
- // Some combinations of flags declared in the config file require special
- // treatment.
- // if (isOffload) {
- // config.offloadInfo.info(generateOffloadInfo(config.base));
- // }
- config.flags = flags;
- result.push_back(config);
- if (singleProfile) return result;
+ if (isDynamicProfile(profile)) continue;
+ combineAudioConfigs(mixPort, profile, &result);
+ if (singleProfile && !result.empty()) {
+ result.resize(1);
+ return result;
}
}
}
@@ -349,9 +340,11 @@
for (const auto& devicePort : ports) {
const size_t resultSizeBefore = result.size();
for (const auto& profile : devicePort.profiles) {
- auto configs = combineAudioConfigs(devicePort, profile);
- result.insert(result.end(), configs.begin(), configs.end());
- if (singleProfile && !result.empty()) return result;
+ combineAudioConfigs(devicePort, profile, &result);
+ if (singleProfile && !result.empty()) {
+ result.resize(1);
+ return result;
+ }
}
if (resultSizeBefore == result.size()) {
std::copy_if(mInitialConfigs.begin(), mInitialConfigs.end(), std::back_inserter(result),