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

Commit 251789f3 authored by Mikhail Naganov's avatar Mikhail Naganov Committed by Gerrit Code Review
Browse files

Merge changes from topic "e-ac3-joc remote submix take2" into main

* changes:
  Return HAL config in datapath for SwAudioOutputDescriptor
  Propagate AudioFlinger open output flags to audio policy
  Support remote submix for 44.1kHz
parents 15aca8c9 d27bbb9c
Loading
Loading
Loading
Loading
+21 −3
Original line number Diff line number Diff line
@@ -86,7 +86,18 @@ TEST(AudioTrackTest, TestPerformanceMode) {
    }
}

TEST(AudioTrackTest, DefaultRoutingTest) {
class AudioTrackTest
        : public ::testing::TestWithParam<int> {

public:
    AudioTrackTest()
            : mSampleRate(GetParam()){};

    const uint32_t mSampleRate;

};

TEST_P(AudioTrackTest, DefaultRoutingTest) {
    audio_port_v7 port;
    if (OK != getPortByAttributes(AUDIO_PORT_ROLE_SOURCE, AUDIO_PORT_TYPE_DEVICE,
                                  AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0", port)) {
@@ -95,7 +106,8 @@ TEST(AudioTrackTest, DefaultRoutingTest) {

    // create record instance
    sp<AudioCapture> capture = sp<AudioCapture>::make(
            AUDIO_SOURCE_REMOTE_SUBMIX, 48000, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO);
            AUDIO_SOURCE_REMOTE_SUBMIX, mSampleRate, AUDIO_FORMAT_PCM_16_BIT,
            AUDIO_CHANNEL_IN_STEREO);
    ASSERT_NE(nullptr, capture);
    ASSERT_EQ(OK, capture->create()) << "record creation failed";
    sp<OnAudioDeviceUpdateNotifier> cbCapture = sp<OnAudioDeviceUpdateNotifier>::make();
@@ -103,7 +115,7 @@ TEST(AudioTrackTest, DefaultRoutingTest) {

    // create playback instance
    sp<AudioPlayback> playback = sp<AudioPlayback>::make(
            48000 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
            mSampleRate, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
            AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE);
    ASSERT_NE(nullptr, playback);
    ASSERT_EQ(OK, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"))
@@ -133,6 +145,12 @@ TEST(AudioTrackTest, DefaultRoutingTest) {
    playback->stop();
}

INSTANTIATE_TEST_SUITE_P(
        AudioTrackParameterizedTest,
        AudioTrackTest,
        ::testing::Values(44100, 48000)
);

class AudioRoutingTest : public ::testing::Test {
  public:
    void SetUp() override {
+42 −6
Original line number Diff line number Diff line
@@ -368,16 +368,21 @@ status_t Hal2AidlMapper::findOrCreateMixPortConfig(
        const AudioConfig& config, const std::optional<AudioIoFlags>& flags, int32_t ioHandle,
        AudioSource source, const std::set<int32_t>& destinationPortIds,
        AudioPortConfig* portConfig, bool* created) {
    // These flags get removed one by one in this order when retrying port finding.
    static const std::vector<AudioInputFlags> kOptionalInputFlags{
        AudioInputFlags::FAST, AudioInputFlags::RAW, AudioInputFlags::VOIP_TX };
    if (auto portConfigIt = findPortConfig(config, flags, ioHandle);
            portConfigIt == mPortConfigs.end() && flags.has_value()) {
        auto optionalInputFlagsIt = kOptionalInputFlags.begin();
        // These input flags get removed one by one in this order when retrying port finding.
        std::vector<AudioInputFlags> optionalInputFlags {
            AudioInputFlags::FAST, AudioInputFlags::RAW, AudioInputFlags::VOIP_TX };
        // For remote submix input, retry with direct input flag removed as the remote submix
        // input is not expected to manipulate the contents of the audio stream.
        if (mRemoteSubmixIn.has_value()) {
            optionalInputFlags.push_back(AudioInputFlags::DIRECT);
        }
        auto optionalInputFlagsIt = optionalInputFlags.begin();
        AudioIoFlags matchFlags = flags.value();
        auto portsIt = findPort(config, matchFlags, destinationPortIds);
        while (portsIt == mPorts.end() && matchFlags.getTag() == AudioIoFlags::Tag::input
                && optionalInputFlagsIt != kOptionalInputFlags.end()) {
                && optionalInputFlagsIt != optionalInputFlags.end()) {
            if (!isBitPositionFlagSet(
                            matchFlags.get<AudioIoFlags::Tag::input>(), *optionalInputFlagsIt)) {
                ++optionalInputFlagsIt;
@@ -392,6 +397,36 @@ status_t Hal2AidlMapper::findOrCreateMixPortConfig(
                        config.toString().c_str(), flags.value().toString().c_str(),
                        matchFlags.toString().c_str());
        }
        // These output flags get removed one by one in this order when retrying port finding.
        std::vector<AudioOutputFlags> optionalOutputFlags { };
        // For remote submix output, retry with these output flags removed one by one:
        // 1. DIRECT: remote submix outputs are expected not to manipulate the contents of the
        //            audio stream.
        // 2. IEC958_NONAUDIO: remote submix outputs are not connected to ALSA and do not require
        //                     non audio signalling.
        if (mRemoteSubmixOut.has_value()) {
            optionalOutputFlags.push_back(AudioOutputFlags::DIRECT);
            optionalOutputFlags.push_back(AudioOutputFlags::IEC958_NONAUDIO);
        }
        auto optionalOutputFlagsIt = optionalOutputFlags.begin();
        matchFlags = flags.value();
        while (portsIt == mPorts.end() && matchFlags.getTag() == AudioIoFlags::Tag::output
                && optionalOutputFlagsIt != optionalOutputFlags.end()) {
            if (!isBitPositionFlagSet(
                            matchFlags.get<AudioIoFlags::Tag::output>(),*optionalOutputFlagsIt)) {
                ++optionalOutputFlagsIt;
                continue;
            }
            matchFlags.set<AudioIoFlags::Tag::output>(matchFlags.get<AudioIoFlags::Tag::output>() &
                    ~makeBitPositionFlagMask(*optionalOutputFlagsIt++));
            portsIt = findPort(config, matchFlags, destinationPortIds);
            AUGMENT_LOG(I,
                        "mix port for config %s, flags %s was not found"
                        "retried with flags %s",
                        config.toString().c_str(), flags.value().toString().c_str(),
                        matchFlags.toString().c_str());
        }

        if (portsIt == mPorts.end()) {
            AUGMENT_LOG(E, "mix port for config %s, flags %s is not found",
                        config.toString().c_str(), matchFlags.toString().c_str());
@@ -792,7 +827,8 @@ status_t Hal2AidlMapper::prepareToOpenStream(
    status_t status = prepareToOpenStreamHelper(ioHandle, devicePortConfig.portId,
            devicePortConfig.id, flags, source, initialConfig, cleanups, config,
            mixPortConfig, patch);
    if (status != OK) {
    if (status != OK && !(mRemoteSubmixOut.has_value() &&
                initialConfig.base.format.type != AudioFormatType::PCM)) {
        // If using the client-provided config did not work out for establishing a mix port config
        // or patching, try with the device port config. Note that in general device port config and
        // mix port config are not required to be the same, however they must match if the HAL
+7 −7
Original line number Diff line number Diff line
@@ -2923,7 +2923,7 @@ sp<IAfThreadBase> AudioFlinger::openOutput_l(audio_module_handle_t module,
                                                        audio_config_base_t *mixerConfig,
                                                        audio_devices_t deviceType,
                                                        const String8& address,
                                                        audio_output_flags_t flags,
                                                        audio_output_flags_t *flags,
                                                        const audio_attributes_t attributes)
{
    AudioHwDevice *outHwDev = findSuitableHwDev_l(module, deviceType);
@@ -2958,7 +2958,7 @@ sp<IAfThreadBase> AudioFlinger::openOutput_l(audio_module_handle_t module,
    mHardwareStatus = AUDIO_HW_IDLE;

    if (status == NO_ERROR) {
        if (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) {
        if (*flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) {
            const sp<IAfMmapPlaybackThread> thread = IAfMmapPlaybackThread::create(
                    this, *output, outHwDev, outputStream, mSystemReady);
            mMmapThreads.add(*output, thread);
@@ -2967,22 +2967,22 @@ sp<IAfThreadBase> AudioFlinger::openOutput_l(audio_module_handle_t module,
            return thread;
        } else {
            sp<IAfPlaybackThread> thread;
            if (flags & AUDIO_OUTPUT_FLAG_BIT_PERFECT) {
            if (*flags & AUDIO_OUTPUT_FLAG_BIT_PERFECT) {
                thread = IAfPlaybackThread::createBitPerfectThread(
                        this, outputStream, *output, mSystemReady);
                ALOGV("%s() created bit-perfect output: ID %d thread %p",
                      __func__, *output, thread.get());
            } else if (flags & AUDIO_OUTPUT_FLAG_SPATIALIZER) {
            } else if (*flags & AUDIO_OUTPUT_FLAG_SPATIALIZER) {
                thread = IAfPlaybackThread::createSpatializerThread(this, outputStream, *output,
                                                    mSystemReady, mixerConfig);
                ALOGV("openOutput_l() created spatializer output: ID %d thread %p",
                      *output, thread.get());
            } else if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
            } else if (*flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
                thread = IAfPlaybackThread::createOffloadThread(this, outputStream, *output,
                        mSystemReady, halConfig->offload_info);
                ALOGV("openOutput_l() created offload output: ID %d thread %p",
                      *output, thread.get());
            } else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT)
            } else if ((*flags & AUDIO_OUTPUT_FLAG_DIRECT)
                    || !IAfThreadBase::isValidPcmSinkFormat(halConfig->format)
                    || !IAfThreadBase::isValidPcmSinkChannelMask(halConfig->channel_mask)) {
                thread = IAfPlaybackThread::createDirectOutputThread(this, outputStream, *output,
@@ -3046,7 +3046,7 @@ status_t AudioFlinger::openOutput(const media::OpenOutputRequest& request,
    audio_utils::lock_guard _l(mutex());

    const sp<IAfThreadBase> thread = openOutput_l(module, &output, &halConfig,
            &mixerConfig, deviceType, address, flags, attributes);
            &mixerConfig, deviceType, address, &flags, attributes);
    if (thread != 0) {
        uint32_t latencyMs = 0;
        if ((flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) == 0) {
+1 −1
Original line number Diff line number Diff line
@@ -337,7 +337,7 @@ private:
            audio_config_base_t* mixerConfig,
            audio_devices_t deviceType,
            const String8& address,
            audio_output_flags_t flags,
            audio_output_flags_t* flags,
            audio_attributes_t attributes) final REQUIRES(mutex());
    const DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>&
            getAudioHwDevs_l() const final REQUIRES(mutex(), hardwareMutex()) {
+1 −1
Original line number Diff line number Diff line
@@ -82,7 +82,7 @@ public:
            audio_config_base_t* mixerConfig,
            audio_devices_t deviceType,
            const String8& address,
            audio_output_flags_t flags,
            audio_output_flags_t* flags,
            audio_attributes_t attributes) REQUIRES(mutex()) = 0;
    virtual audio_utils::mutex& mutex() const
            RETURN_CAPABILITY(audio_utils::AudioFlinger_Mutex) = 0;
Loading