Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a2c5ddf9 authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

audio: Cleanups and refactorings

Added utility functions for operating on positional
bit flags.

Moved retrieval of offload mix ports to ModuleConfig
utility class.

Clarify the names of read/write tests.

Bug: 205884982
Test: atest VtsHalAudioCoreTargetTest
Change-Id: Id20881c2e62bc1b95d8fc3c268f99e36337dce7a
parent 7b6acb3f
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -16,8 +16,13 @@

#pragma once

#include <initializer_list>
#include <type_traits>

#include <aidl/android/media/audio/common/AudioChannelLayout.h>
#include <aidl/android/media/audio/common/AudioFormatDescription.h>
#include <aidl/android/media/audio/common/AudioInputFlags.h>
#include <aidl/android/media/audio/common/AudioOutputFlags.h>
#include <aidl/android/media/audio/common/PcmType.h>

namespace android::hardware::audio::common {
@@ -78,4 +83,34 @@ constexpr size_t getFrameSizeInBytes(
    return 0;
}

// The helper functions defined below are only applicable to the case when an enum type
// specifies zero-based bit positions, not bit masks themselves. This is why instantiation
// is restricted to certain enum types.
template <typename E>
using is_bit_position_enum = std::integral_constant<
        bool, std::is_same_v<E, ::aidl::android::media::audio::common::AudioInputFlags> ||
                      std::is_same_v<E, ::aidl::android::media::audio::common::AudioOutputFlags>>;

template <typename E, typename U = std::underlying_type_t<E>,
          typename = std::enable_if_t<is_bit_position_enum<E>::value>>
constexpr U makeBitPositionFlagMask(E flag) {
    return 1 << static_cast<U>(flag);
}

template <typename E, typename U = std::underlying_type_t<E>,
          typename = std::enable_if_t<is_bit_position_enum<E>::value>>
constexpr bool isBitPositionFlagSet(U mask, E flag) {
    return (mask & makeBitPositionFlagMask(flag)) != 0;
}

template <typename E, typename U = std::underlying_type_t<E>,
          typename = std::enable_if_t<is_bit_position_enum<E>::value>>
constexpr U makeBitPositionFlagMask(std::initializer_list<E> flags) {
    U result = 0;
    for (const auto flag : flags) {
        result |= makeBitPositionFlagMask(flag);
    }
    return result;
}

}  // namespace android::hardware::audio::common
+6 −4
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
 * limitations under the License.
 */

#include <Utils.h>
#include <aidl/android/media/audio/common/AudioChannelLayout.h>
#include <aidl/android/media/audio/common/AudioDeviceType.h>
#include <aidl/android/media/audio/common/AudioFormatDescription.h>
@@ -40,6 +41,7 @@ using aidl::android::media::audio::common::AudioPortMixExt;
using aidl::android::media::audio::common::AudioProfile;
using aidl::android::media::audio::common::Int;
using aidl::android::media::audio::common::PcmType;
using android::hardware::audio::common::makeBitPositionFlagMask;

namespace aidl::android::hardware::audio::core::internal {

@@ -193,7 +195,7 @@ Configuration& getNullPrimaryConfiguration() {
                                 createDeviceExt(AudioDeviceType::OUT_SPEAKER, 0)));

        AudioPort primaryOutMix = createPort(c.nextPortId++, "primary output",
                                             1 << static_cast<int32_t>(AudioOutputFlags::PRIMARY),
                                             makeBitPositionFlagMask(AudioOutputFlags::PRIMARY),
                                             false, createPortMixExt(1, 1));
        primaryOutMix.profiles.insert(primaryOutMix.profiles.begin(),
                                      standardPcmAudioProfiles.begin(),
@@ -202,9 +204,9 @@ Configuration& getNullPrimaryConfiguration() {

        AudioPort compressedOffloadOutMix =
                createPort(c.nextPortId++, "compressed offload",
                           1 << static_cast<int32_t>(AudioOutputFlags::DIRECT) |
                                   1 << static_cast<int32_t>(AudioOutputFlags::COMPRESS_OFFLOAD) |
                                   1 << static_cast<int32_t>(AudioOutputFlags::NON_BLOCKING),
                           makeBitPositionFlagMask({AudioOutputFlags::DIRECT,
                                                    AudioOutputFlags::COMPRESS_OFFLOAD,
                                                    AudioOutputFlags::NON_BLOCKING}),
                           false, createPortMixExt(1, 1));
        compressedOffloadOutMix.profiles.push_back(
                createProfile(::android::MEDIA_MIMETYPE_AUDIO_MPEG,
+8 −7
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ using aidl::android::media::audio::common::AudioProfile;
using aidl::android::media::audio::common::Int;
using aidl::android::media::audio::common::PcmType;
using android::hardware::audio::common::getFrameSizeInBytes;
using android::hardware::audio::common::isBitPositionFlagSet;

namespace aidl::android::hardware::audio::core {

@@ -125,11 +126,11 @@ ndk::ScopedAStatus Module::createStreamContext(int32_t in_portConfigId, int64_t
    }
    const auto& flags = portConfigIt->flags.value();
    if ((flags.getTag() == AudioIoFlags::Tag::input &&
         (flags.get<AudioIoFlags::Tag::input>() &
          1 << static_cast<int32_t>(AudioInputFlags::MMAP_NOIRQ)) == 0) ||
         !isBitPositionFlagSet(flags.get<AudioIoFlags::Tag::input>(),
                               AudioInputFlags::MMAP_NOIRQ)) ||
        (flags.getTag() == AudioIoFlags::Tag::output &&
         (flags.get<AudioIoFlags::Tag::output>() &
          1 << static_cast<int32_t>(AudioOutputFlags::MMAP_NOIRQ)) == 0)) {
         !isBitPositionFlagSet(flags.get<AudioIoFlags::Tag::output>(),
                               AudioOutputFlags::MMAP_NOIRQ))) {
        StreamContext temp(
                std::make_unique<StreamContext::CommandMQ>(1, true /*configureEventFlagWord*/),
                std::make_unique<StreamContext::ReplyMQ>(1, true /*configureEventFlagWord*/),
@@ -478,9 +479,9 @@ ndk::ScopedAStatus Module::openOutputStream(const OpenOutputStreamArguments& in_
                   << " does not correspond to an output mix port";
        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
    }
    if ((port->flags.get<AudioIoFlags::Tag::output>() &
         1 << static_cast<int32_t>(AudioOutputFlags::COMPRESS_OFFLOAD)) != 0 &&
        !in_args.offloadInfo.has_value()) {
    const bool isOffload = isBitPositionFlagSet(port->flags.get<AudioIoFlags::Tag::output>(),
                                                AudioOutputFlags::COMPRESS_OFFLOAD);
    if (isOffload && !in_args.offloadInfo.has_value()) {
        LOG(ERROR) << __func__ << ": port id " << port->id
                   << " has COMPRESS_OFFLOAD flag set, requires offload info";
        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+2 −3
Original line number Diff line number Diff line
@@ -229,10 +229,9 @@ class StreamWrapper {
    }
    void setStreamIsConnected(bool connected) {
        std::visit(
                [&](auto&& ws) -> bool {
                [&](auto&& ws) {
                    auto s = ws.lock();
                    if (s) s->setIsConnected(connected);
                    return !!s;
                },
                mStream);
    }
@@ -253,7 +252,7 @@ class Streams {
    }
    void insert(int32_t portId, int32_t portConfigId, StreamWrapper sw) {
        mStreams.insert(std::pair{portConfigId, sw});
        mStreams.insert(std::pair{portId, sw});
        mStreams.insert(std::pair{portId, std::move(sw)});
    }
    void setStreamIsConnected(int32_t portConfigId, bool connected) {
        if (auto it = mStreams.find(portConfigId); it != mStreams.end()) {
+21 −2
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <algorithm>
#include <chrono>

#include <Utils.h>
#include <aidl/android/media/audio/common/AudioIoFlags.h>
#include <aidl/android/media/audio/common/AudioOutputFlags.h>

@@ -39,14 +40,15 @@ 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;
using android::hardware::audio::common::isBitPositionFlagSet;

// 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) {
        isBitPositionFlagSet(portConfig.flags.value().get<AudioIoFlags::Tag::output>(),
                             AudioOutputFlags::COMPRESS_OFFLOAD)) {
        AudioOffloadInfo offloadInfo;
        offloadInfo.base.sampleRate = portConfig.sampleRate.value().value;
        offloadInfo.base.channelMask = portConfig.channelMask.value();
@@ -123,6 +125,23 @@ std::vector<AudioPort> ModuleConfig::getOutputMixPorts() const {
    return result;
}

std::vector<AudioPort> ModuleConfig::getOffloadMixPorts(bool attachedOnly, bool singlePort) const {
    std::vector<AudioPort> result;
    const auto mixPorts = getMixPorts(false /*isInput*/);
    auto offloadPortIt = mixPorts.begin();
    while (offloadPortIt != mixPorts.end()) {
        offloadPortIt = std::find_if(offloadPortIt, mixPorts.end(), [&](const AudioPort& port) {
            return isBitPositionFlagSet(port.flags.get<AudioIoFlags::Tag::output>(),
                                        AudioOutputFlags::COMPRESS_OFFLOAD) &&
                   (!attachedOnly || !getAttachedSinkDevicesPortsForMixPort(port).empty());
        });
        if (offloadPortIt == mixPorts.end()) break;
        result.push_back(*offloadPortIt++);
        if (singlePort) break;
    }
    return result;
}

std::vector<AudioPort> ModuleConfig::getAttachedDevicesPortsForMixPort(
        bool isInput, const AudioPortConfig& mixPortConfig) const {
    const auto mixPortIt = findById<AudioPort>(mPorts, mixPortConfig.portId);
Loading