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

Commit fe231127 authored by Eric Laurent's avatar Eric Laurent
Browse files

audio policy: refactor output and input opening

Refactor the way input and output streams are open so that common
logic is centralized in AudioOutputDescriptor and AudioInputDescriptor
classes.

This is in preparation of adding reference counting for ouputs and inputs
opened for a given profile.

Test: Manual
Change-Id: Id806e23077eb41f6398400ab40aeaa694c7d5603
parent a221a7c8
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -34,8 +34,8 @@ class AudioMix;
class AudioInputDescriptor: public AudioPortConfig, public AudioSessionInfoProvider
{
public:
    explicit AudioInputDescriptor(const sp<IOProfile>& profile);
    void setIoHandle(audio_io_handle_t ioHandle);
    explicit AudioInputDescriptor(const sp<IOProfile>& profile,
                                  AudioPolicyClientInterface *clientInterface);
    audio_port_handle_t getId() const;
    audio_module_handle_t getModuleHandle() const;
    uint32_t getOpenRefCount() const;
@@ -73,6 +73,14 @@ public:

    void setPatchHandle(audio_patch_handle_t handle);

    status_t open(const audio_config_t *config,
                  audio_devices_t device,
                  const String8& address,
                  audio_source_t source,
                  audio_input_flags_t flags,
                  audio_io_handle_t *input);
    void close();

private:
    audio_patch_handle_t          mPatchHandle;
    audio_port_handle_t           mId;
@@ -85,6 +93,7 @@ private:
    // a particular input started and prevent preemption of this active input by this session.
    // We also inherit sessions from the preempted input to avoid a 3 way preemption loop etc...
    SortedVector<audio_session_t> mPreemptedSessions;
    AudioPolicyClientInterface *mClientInterface;
};

class AudioInputCollection :
+8 −2
Original line number Diff line number Diff line
@@ -101,8 +101,6 @@ public:

    status_t    dump(int fd);

    void setIoHandle(audio_io_handle_t ioHandle);

    virtual audio_devices_t device() const;
    virtual bool sharesHwModuleWith(const sp<AudioOutputDescriptor>& outputDesc);
    virtual audio_devices_t supportedDevices();
@@ -122,6 +120,14 @@ public:
                           const struct audio_port_config *srcConfig = NULL) const;
    virtual void toAudioPort(struct audio_port *port) const;

            status_t open(const audio_config_t *config,
                          audio_devices_t device,
                          const String8& address,
                          audio_stream_type_t stream,
                          audio_output_flags_t flags,
                          audio_io_handle_t *output);
            void close();

    const sp<IOProfile> mProfile;          // I/O profile this output derives from
    audio_io_handle_t mIoHandle;           // output handle
    uint32_t mLatency;                  //
+65 −8
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#define LOG_TAG "APM::AudioInputDescriptor"
//#define LOG_NDEBUG 0

#include <AudioPolicyInterface.h>
#include "AudioInputDescriptor.h"
#include "IOProfile.h"
#include "AudioGain.h"
@@ -26,10 +27,12 @@

namespace android {

AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile)
AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile,
                                           AudioPolicyClientInterface *clientInterface)
    : mIoHandle(0),
      mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL),
      mProfile(profile), mPatchHandle(AUDIO_PATCH_HANDLE_NONE), mId(0)
      mProfile(profile), mPatchHandle(AUDIO_PATCH_HANDLE_NONE), mId(0),
      mClientInterface(clientInterface)
{
    if (profile != NULL) {
        profile->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
@@ -39,12 +42,6 @@ AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile)
    }
}

void AudioInputDescriptor::setIoHandle(audio_io_handle_t ioHandle)
{
    mId = AudioPort::getNextUniqueId();
    mIoHandle = ioHandle;
}

audio_module_handle_t AudioInputDescriptor::getModuleHandle() const
{
    if (mProfile == 0) {
@@ -192,6 +189,66 @@ audio_config_base_t AudioInputDescriptor::getConfig() const
    return config;
}

status_t AudioInputDescriptor::open(const audio_config_t *config,
                                       audio_devices_t device,
                                       const String8& address,
                                       audio_source_t source,
                                       audio_input_flags_t flags,
                                       audio_io_handle_t *input)
{
    audio_config_t lConfig;
    if (config == nullptr) {
        lConfig = AUDIO_CONFIG_INITIALIZER;
        lConfig.sample_rate = mSamplingRate;
        lConfig.channel_mask = mChannelMask;
        lConfig.format = mFormat;
    } else {
        lConfig = *config;
    }

    String8 lAddress = address;
    if (lAddress == "") {
        const DeviceVector& supportedDevices = mProfile->getSupportedDevices();
        const DeviceVector& devicesForType = supportedDevices.getDevicesFromType(device);
        lAddress = devicesForType.size() > 0 ? devicesForType.itemAt(0)->mAddress
                  : String8("");
    }

    mDevice = device;

    ALOGV("opening input for device %08x address %s profile %p name %s",
          mDevice, lAddress.string(), mProfile.get(), mProfile->getName().string());

    status_t status = mClientInterface->openInput(mProfile->getModuleHandle(),
                                                  input,
                                                  &lConfig,
                                                  &mDevice,
                                                  lAddress,
                                                  source,
                                                  flags);
    LOG_ALWAYS_FATAL_IF(mDevice != device,
                        "%s openInput returned device %08x when given device %08x",
                        __FUNCTION__, mDevice, device);

    if (status == NO_ERROR) {
        mSamplingRate = lConfig.sample_rate;
        mChannelMask = lConfig.channel_mask;
        mFormat = lConfig.format;
        mId = AudioPort::getNextUniqueId();
        mIoHandle = *input;
    }

    return status;
}


void AudioInputDescriptor::close()
{
    if (mIoHandle != AUDIO_IO_HANDLE_NONE) {
        mClientInterface->closeInput(mIoHandle);
    }
}

status_t AudioInputDescriptor::dump(int fd)
{
    const size_t SIZE = 256;
+82 −7
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include "AudioGain.h"
#include "Volume.h"
#include "HwModule.h"
#include <media/AudioParameter.h>
#include <media/AudioPolicy.h>

// A device mask for all audio output devices that are considered "remote" when evaluating
@@ -231,13 +232,6 @@ SwAudioOutputDescriptor::SwAudioOutputDescriptor(const sp<IOProfile>& profile,
    }
}

void SwAudioOutputDescriptor::setIoHandle(audio_io_handle_t ioHandle)
{
    mId = AudioPort::getNextUniqueId();
    mIoHandle = ioHandle;
}


status_t SwAudioOutputDescriptor::dump(int fd)
{
    const size_t SIZE = 256;
@@ -387,6 +381,87 @@ bool SwAudioOutputDescriptor::setVolume(float volume,
    return changed;
}

status_t SwAudioOutputDescriptor::open(const audio_config_t *config,
                                       audio_devices_t device,
                                       const String8& address,
                                       audio_stream_type_t stream,
                                       audio_output_flags_t flags,
                                       audio_io_handle_t *output)
{
    audio_config_t lConfig;
    if (config == nullptr) {
        lConfig = AUDIO_CONFIG_INITIALIZER;
        lConfig.sample_rate = mSamplingRate;
        lConfig.channel_mask = mChannelMask;
        lConfig.format = mFormat;
    } else {
        lConfig = *config;
    }

    String8 lAddress = address;
    if (lAddress == "") {
        const DeviceVector& supportedDevices = mProfile->getSupportedDevices();
        const DeviceVector& devicesForType = supportedDevices.getDevicesFromType(device);
        lAddress = devicesForType.size() > 0 ? devicesForType.itemAt(0)->mAddress
                  : String8("");
    }

    mDevice = device;
    // if the selected profile is offloaded and no offload info was specified,
    // create a default one
    if ((mProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
            lConfig.offload_info.format == AUDIO_FORMAT_DEFAULT) {
        flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
        lConfig.offload_info = AUDIO_INFO_INITIALIZER;
        lConfig.offload_info.sample_rate = lConfig.sample_rate;
        lConfig.offload_info.channel_mask = lConfig.channel_mask;
        lConfig.offload_info.format = lConfig.format;
        lConfig.offload_info.stream_type = stream;
        lConfig.offload_info.duration_us = -1;
        lConfig.offload_info.has_video = true; // conservative
        lConfig.offload_info.is_streaming = true; // likely
    }

    mFlags = (audio_output_flags_t)(mFlags | flags);

    ALOGV("opening output for device %08x address %s profile %p name %s",
          mDevice, lAddress.string(), mProfile.get(), mProfile->getName().string());

    status_t status = mClientInterface->openOutput(mProfile->getModuleHandle(),
                                                   output,
                                                   &lConfig,
                                                   &mDevice,
                                                   lAddress,
                                                   &mLatency,
                                                   mFlags);
    LOG_ALWAYS_FATAL_IF(mDevice != device,
                        "%s openOutput returned device %08x when given device %08x",
                        __FUNCTION__, mDevice, device);

    if (status == NO_ERROR) {
        mSamplingRate = lConfig.sample_rate;
        mChannelMask = lConfig.channel_mask;
        mFormat = lConfig.format;
        mId = AudioPort::getNextUniqueId();
        mIoHandle = *output;
    }

    return status;
}


void SwAudioOutputDescriptor::close()
{
    if (mIoHandle != AUDIO_IO_HANDLE_NONE) {
        AudioParameter param;
        param.add(String8("closing"), String8("true"));
        mClientInterface->setParameters(mIoHandle, param.toString());

        mClientInterface->closeOutput(mIoHandle);
    }
}


// HwAudioOutputDescriptor implementation
HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<AudioSourceDescriptor>& source,
                                                 AudioPolicyClientInterface *clientInterface)
Loading