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

Commit 6490d84c authored by Andy Hung's avatar Andy Hung Committed by Gerrit Code Review
Browse files

Merge "Add SpdifStreamIn data path" into main

parents 55f2814b 6c00951f
Loading
Loading
Loading
Loading
+11 −33
Original line number Diff line number Diff line
@@ -3196,41 +3196,19 @@ sp<IAfThreadBase> AudioFlinger::openInput_l(audio_module_handle_t module,
        return 0;
    }

    audio_config_t halconfig = *config;
    sp<DeviceHalInterface> inHwHal = inHwDev->hwDevice();
    sp<StreamInHalInterface> inStream;
    status_t status = inHwHal->openInputStream(
            *input, devices, &halconfig, flags, address, source,
            outputDevice, outputDeviceAddress, &inStream);
    ALOGV("openInput_l() openInputStream returned input %p, devices %#x, SamplingRate %d"
           ", Format %#x, Channels %#x, flags %#x, status %d addr %s",
            inStream.get(),
    AudioStreamIn *inputStream = nullptr;
    status_t status = inHwDev->openInputStream(
            &inputStream,
            *input,
            devices,
            halconfig.sample_rate,
            halconfig.format,
            halconfig.channel_mask,
            flags,
            status, address);

    // If the input could not be opened with the requested parameters and we can handle the
    // conversion internally, try to open again with the proposed parameters.
    if (status == BAD_VALUE &&
        audio_is_linear_pcm(config->format) &&
        audio_is_linear_pcm(halconfig.format) &&
        (halconfig.sample_rate <= AUDIO_RESAMPLER_DOWN_RATIO_MAX * config->sample_rate) &&
        (audio_channel_count_from_in_mask(halconfig.channel_mask) <= FCC_LIMIT) &&
        (audio_channel_count_from_in_mask(config->channel_mask) <= FCC_LIMIT)) {
        // FIXME describe the change proposed by HAL (save old values so we can log them here)
        ALOGV("openInput_l() reopening with proposed sampling rate and channel mask");
        inStream.clear();
        status = inHwHal->openInputStream(
                *input, devices, &halconfig, flags, address, source,
                outputDevice, outputDeviceAddress, &inStream);
        // FIXME log this new status; HAL should not propose any further changes
    }

    if (status == NO_ERROR && inStream != 0) {
        AudioStreamIn *inputStream = new AudioStreamIn(inHwDev, inStream, flags);
            config,
            address,
            source,
            outputDevice,
            outputDeviceAddress.c_str());

    if (status == NO_ERROR) {
        if ((flags & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0) {
            const sp<IAfMmapCaptureThread> thread =
                    IAfMmapCaptureThread::create(this, *input, inHwDev, inputStream, mSystemReady);
+18 −5
Original line number Diff line number Diff line
@@ -9544,10 +9544,24 @@ void RecordThread::ioConfigChanged_l(audio_io_config_event_t event, pid_t pid,

void RecordThread::readInputParameters_l()
{
    status_t result = mInput->stream->getAudioProperties(&mSampleRate, &mChannelMask, &mHALFormat);
    LOG_ALWAYS_FATAL_IF(result != OK, "Error retrieving audio properties from HAL: %d", result);
    mFormat = mHALFormat;
    const audio_config_base_t audioConfig = mInput->getAudioProperties();
    mSampleRate = audioConfig.sample_rate;
    mChannelMask = audioConfig.channel_mask;
    if (!audio_is_input_channel(mChannelMask)) {
        LOG_ALWAYS_FATAL("Channel mask %#x not valid for input", mChannelMask);
    }

    mChannelCount = audio_channel_count_from_in_mask(mChannelMask);

    // Get actual HAL format.
    status_t result = mInput->stream->getAudioProperties(nullptr, nullptr, &mHALFormat);
    LOG_ALWAYS_FATAL_IF(result != OK, "Error when retrieving input stream format: %d", result);
    // Get format from the shim, which will be different than the HAL format
    // if recording compressed audio from IEC61937 wrapped sources.
    mFormat = audioConfig.format;
    if (!audio_is_valid_format(mFormat)) {
        LOG_ALWAYS_FATAL("Format %#x not valid for input", mFormat);
    }
    if (audio_is_linear_pcm(mFormat)) {
        LOG_ALWAYS_FATAL_IF(mChannelCount > FCC_LIMIT, "HAL channel count %d > %d",
                mChannelCount, FCC_LIMIT);
@@ -9555,8 +9569,7 @@ void RecordThread::readInputParameters_l()
        // Can have more that FCC_LIMIT channels in encoded streams.
        ALOGI("HAL format %#x is not linear pcm", mFormat);
    }
    result = mInput->stream->getFrameSize(&mFrameSize);
    LOG_ALWAYS_FATAL_IF(result != OK, "Error retrieving frame size from HAL: %d", result);
    mFrameSize = mInput->getFrameSize();
    LOG_ALWAYS_FATAL_IF(mFrameSize <= 0, "Error frame size was %zu but must be greater than zero",
            mFrameSize);
    result = mInput->stream->getBufferSize(&mBufferSize);
+3 −0
Original line number Diff line number Diff line
@@ -43,11 +43,14 @@ cc_library {

    srcs: [
        "AudioHwDevice.cpp",
        "AudioStreamIn.cpp",
        "AudioStreamOut.cpp",
        "SpdifStreamIn.cpp",
        "SpdifStreamOut.cpp",
    ],

    header_libs: [
        "libaudioclient_headers",
        "libaudiohal_headers",
        "liberror_headers",
    ],
+95 −28
Original line number Diff line number Diff line
/*
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
 *
 * Copyright 2007, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "AudioHwDevice"
@@ -21,10 +21,13 @@
#include <system/audio.h>
#include <utils/Log.h>

#include <audio_utils/spdif/SPDIFDecoder.h>
#include <audio_utils/spdif/SPDIFEncoder.h>
#include <media/AudioResamplerPublic.h>

#include "AudioHwDevice.h"
#include "AudioStreamOut.h"
#include "SpdifStreamIn.h"
#include "SpdifStreamOut.h"

namespace android {
@@ -47,12 +50,8 @@ status_t AudioHwDevice::openOutputStream(
    auto outputStream = new AudioStreamOut(this, flags);

    // Try to open the HAL first using the current format.
    ALOGV("openOutputStream(), try "
            " sampleRate %d, Format %#x, "
            "channelMask %#x",
            config->sample_rate,
            config->format,
            config->channel_mask);
    ALOGV("openOutputStream(), try sampleRate %d, format %#x, channelMask %#x", config->sample_rate,
            config->format, config->channel_mask);
    status_t status = outputStream->open(handle, deviceType, config, address);

    if (status != NO_ERROR) {
@@ -62,13 +61,8 @@ status_t AudioHwDevice::openOutputStream(
        // FIXME Look at any modification to the config.
        // The HAL might modify the config to suggest a wrapped format.
        // Log this so we can see what the HALs are doing.
        ALOGI("openOutputStream(), HAL returned"
            " sampleRate %d, Format %#x, "
            "channelMask %#x, status %d",
            config->sample_rate,
            config->format,
            config->channel_mask,
            status);
        ALOGI("openOutputStream(), HAL returned sampleRate %d, format %#x, channelMask %#x,"
                " status %d", config->sample_rate, config->format, config->channel_mask, status);

        // If the data is encoded then try again using wrapped PCM.
        const bool wrapperNeeded = !audio_has_proportional_frames(originalConfig.format)
@@ -96,6 +90,79 @@ status_t AudioHwDevice::openOutputStream(
    return status;
}

status_t AudioHwDevice::openInputStream(
        AudioStreamIn **ppStreamIn,
        audio_io_handle_t handle,
        audio_devices_t deviceType,
        audio_input_flags_t flags,
        struct audio_config *config,
        const char *address,
        audio_source_t source,
        audio_devices_t outputDevice,
        const char *outputDeviceAddress) {

    struct audio_config originalConfig = *config;
    auto inputStream = new AudioStreamIn(this, flags);

    // Try to open the HAL first using the current format.
    ALOGV("openInputStream(), try sampleRate %d, format %#x, channelMask %#x", config->sample_rate,
            config->format, config->channel_mask);
    status_t status = inputStream->open(handle, deviceType, config, address, source, outputDevice,
                                        outputDeviceAddress);

    // If the input could not be opened with the requested parameters and we can handle the
    // conversion internally, try to open again with the proposed parameters.
    if (status == BAD_VALUE &&
        audio_is_linear_pcm(originalConfig.format) &&
        audio_is_linear_pcm(config->format) &&
        (config->sample_rate <= AUDIO_RESAMPLER_DOWN_RATIO_MAX * config->sample_rate) &&
        (audio_channel_count_from_in_mask(config->channel_mask) <= FCC_LIMIT) &&
        (audio_channel_count_from_in_mask(originalConfig.channel_mask) <= FCC_LIMIT)) {
        // FIXME describe the change proposed by HAL (save old values so we can log them here)
        ALOGV("openInputStream() reopening with proposed sampling rate and channel mask");
        status = inputStream->open(handle, deviceType, config, address, source,
                outputDevice, outputDeviceAddress);
        // FIXME log this new status; HAL should not propose any further changes
        if (status != NO_ERROR) {
            delete inputStream;
            inputStream = nullptr;
        }
    } else if (status != NO_ERROR) {
        delete inputStream;
        inputStream = nullptr;

        // FIXME Look at any modification to the config.
        // The HAL might modify the config to suggest a wrapped format.
        // Log this so we can see what the HALs are doing.
        ALOGI("openInputStream(), HAL returned sampleRate %d, format %#x, channelMask %#x,"
                " status %d", config->sample_rate, config->format, config->channel_mask, status);

        // If the data is encoded then try again using wrapped PCM.
        const bool unwrapperNeeded = !audio_has_proportional_frames(originalConfig.format)
                && ((flags & AUDIO_INPUT_FLAG_DIRECT) != 0);

        if (unwrapperNeeded) {
            if (SPDIFDecoder::isFormatSupported(originalConfig.format)) {
                inputStream = new SpdifStreamIn(this, flags, originalConfig.format);
                status = inputStream->open(handle, deviceType, &originalConfig, address, source,
                        outputDevice, outputDeviceAddress);
                if (status != NO_ERROR) {
                    ALOGE("ERROR - openInputStream(), SPDIF open returned %d",
                        status);
                    delete inputStream;
                    inputStream = nullptr;
                }
            } else {
                ALOGE("ERROR - openInputStream(), SPDIFDecoder does not support format 0x%08x",
                    originalConfig.format);
            }
        }
    }

    *ppStreamIn = inputStream;
    return status;
}

bool AudioHwDevice::supportsAudioPatches() const {
    bool result;
    return mHwDevice->supportsAudioPatches(&result) == OK ? result : false;
+29 −20
Original line number Diff line number Diff line
/*
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
 *
 * Copyright 2007, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_AUDIO_HW_DEVICE_H
#define ANDROID_AUDIO_HW_DEVICE_H
#pragma once

#include <stdint.h>
#include <stdlib.h>
@@ -30,6 +29,7 @@

namespace android {

class AudioStreamIn;
class AudioStreamOut;

class AudioHwDevice {
@@ -89,6 +89,17 @@ public:
            struct audio_config *config,
            const char *address);

    status_t openInputStream(
            AudioStreamIn **ppStreamIn,
            audio_io_handle_t handle,
            audio_devices_t deviceType,
            audio_input_flags_t flags,
            struct audio_config *config,
            const char *address,
            audio_source_t source,
            audio_devices_t outputDevice,
            const char *outputDeviceAddress);

    [[nodiscard]] bool supportsAudioPatches() const;

    [[nodiscard]] status_t getAudioPort(struct audio_port_v7 *port) const;
@@ -112,5 +123,3 @@ private:
};

} // namespace android

#endif // ANDROID_AUDIO_HW_DEVICE_H
Loading