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

Commit 5bd3f386 authored by Jean-Michel Trivi's avatar Jean-Michel Trivi
Browse files

AudioPolicyManager: return output for audio attributes

In AudioPolicyManager, support querying an output
 or playback strategy for audio attributes,
 instead of a stream type,
In AudioTrack creation, use the output returned
 for the track's attributes.

Change-Id: I0fef05845ba676404775e2e338c10e6a96237268
parent faabb51c
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -99,6 +99,8 @@ public:
    // to be non-zero if status == NO_ERROR
    static status_t getOutputSamplingRate(uint32_t* samplingRate,
            audio_stream_type_t stream);
    static status_t getOutputSamplingRateForAttr(uint32_t* samplingRate,
                const audio_attributes_t *attr);
    static status_t getOutputFrameCount(size_t* frameCount,
            audio_stream_type_t stream);
    static status_t getOutputLatency(uint32_t* latency,
@@ -212,7 +214,12 @@ public:
                                        audio_channel_mask_t channelMask = AUDIO_CHANNEL_OUT_STEREO,
                                        audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
                                        const audio_offload_info_t *offloadInfo = NULL);

    static audio_io_handle_t getOutputForAttr(const audio_attributes_t *attr,
                                        uint32_t samplingRate = 0,
                                        audio_format_t format = AUDIO_FORMAT_DEFAULT,
                                        audio_channel_mask_t channelMask = AUDIO_CHANNEL_OUT_STEREO,
                                        audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
                                        const audio_offload_info_t *offloadInfo = NULL);
    static status_t startOutput(audio_io_handle_t output,
                                audio_stream_type_t stream,
                                int session);
+6 −0
Original line number Diff line number Diff line
@@ -56,6 +56,12 @@ public:
                                        audio_channel_mask_t channelMask = 0,
                                        audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
                                        const audio_offload_info_t *offloadInfo = NULL) = 0;
    virtual audio_io_handle_t getOutputForAttr(const audio_attributes_t *attr,
                                            uint32_t samplingRate = 0,
                                            audio_format_t format = AUDIO_FORMAT_DEFAULT,
                                            audio_channel_mask_t channelMask = 0,
                                            audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
                                            const audio_offload_info_t *offloadInfo = NULL) = 0;
    virtual status_t startOutput(audio_io_handle_t output,
                                 audio_stream_type_t stream,
                                 int session = 0) = 0;
+26 −0
Original line number Diff line number Diff line
@@ -245,6 +245,19 @@ status_t AudioSystem::getOutputSamplingRate(uint32_t* samplingRate, audio_stream
    return getSamplingRate(output, samplingRate);
}

status_t AudioSystem::getOutputSamplingRateForAttr(uint32_t* samplingRate,
        const audio_attributes_t *attr)
{
    if (attr == NULL) {
        return BAD_VALUE;
    }
    audio_io_handle_t output = getOutputForAttr(attr);
    if (output == 0) {
        return PERMISSION_DENIED;
    }
    return getSamplingRate(output, samplingRate);
}

status_t AudioSystem::getSamplingRate(audio_io_handle_t output,
                                      uint32_t* samplingRate)
{
@@ -633,6 +646,19 @@ audio_io_handle_t AudioSystem::getOutput(audio_stream_type_t stream,
    return aps->getOutput(stream, samplingRate, format, channelMask, flags, offloadInfo);
}

audio_io_handle_t AudioSystem::getOutputForAttr(const audio_attributes_t *attr,
                                    uint32_t samplingRate,
                                    audio_format_t format,
                                    audio_channel_mask_t channelMask,
                                    audio_output_flags_t flags,
                                    const audio_offload_info_t *offloadInfo)
{
    if (attr == NULL) return 0;
    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
    if (aps == 0) return 0;
    return aps->getOutputForAttr(attr, samplingRate, format, channelMask, flags, offloadInfo);
}

status_t AudioSystem::startOutput(audio_io_handle_t output,
                                  audio_stream_type_t stream,
                                  int session)
+6 −9
Original line number Diff line number Diff line
@@ -287,8 +287,7 @@ status_t AudioTrack::set(

    status_t status;
    if (sampleRate == 0) {
        // TODO replace with new APM method with support for audio_attributes_t
        status = AudioSystem::getOutputSamplingRate(&sampleRate, mStreamType);
        status = AudioSystem::getOutputSamplingRateForAttr(&sampleRate, &mAttributes);
        if (status != NO_ERROR) {
            ALOGE("Could not get output sample rate for stream type %d; status %d",
                    mStreamType, status);
@@ -641,8 +640,7 @@ status_t AudioTrack::setSampleRate(uint32_t rate)
    }

    uint32_t afSamplingRate;
    // TODO replace with new APM method with support for audio_attributes_t
    if (AudioSystem::getOutputSamplingRate(&afSamplingRate, mStreamType) != NO_ERROR) {
    if (AudioSystem::getOutputSamplingRateForAttr(&afSamplingRate, &mAttributes) != NO_ERROR) {
        return NO_INIT;
    }
    // Resampler implementation limits input sampling rate to 2 x output sampling rate.
@@ -889,13 +887,12 @@ status_t AudioTrack::createTrack_l(size_t epoch)
        return NO_INIT;
    }

    // TODO replace with new APM method with support for audio_attributes_t
    audio_io_handle_t output = AudioSystem::getOutput(mStreamType, mSampleRate, mFormat,
    audio_io_handle_t output = AudioSystem::getOutputForAttr(&mAttributes, mSampleRate, mFormat,
            mChannelMask, mFlags, mOffloadInfo);
    if (output == AUDIO_IO_HANDLE_NONE) {
        ALOGE("Could not get audio output for stream type %d, sample rate %u, format %#x, "
        ALOGE("Could not get audio output for stream type %d, usage %d, sample rate %u, format %#x,"
              " channel mask %#x, flags %#x",
              mStreamType, mSampleRate, mFormat, mChannelMask, mFlags);
              mStreamType, mAttributes.usage, mSampleRate, mFormat, mChannelMask, mFlags);
        return BAD_VALUE;
    }
    {
+56 −1
Original line number Diff line number Diff line
@@ -64,7 +64,8 @@ enum {
    RELEASE_AUDIO_PATCH,
    LIST_AUDIO_PATCHES,
    SET_AUDIO_PORT_CONFIG,
    REGISTER_CLIENT
    REGISTER_CLIENT,
    GET_OUTPUT_FOR_ATTR
};

class BpAudioPolicyService : public BpInterface<IAudioPolicyService>
@@ -155,6 +156,36 @@ public:
        return static_cast <audio_io_handle_t> (reply.readInt32());
    }

    virtual audio_io_handle_t getOutputForAttr(
                                            const audio_attributes_t *attr,
                                            uint32_t samplingRate,
                                            audio_format_t format,
                                            audio_channel_mask_t channelMask,
                                            audio_output_flags_t flags,
                                            const audio_offload_info_t *offloadInfo)
        {
            Parcel data, reply;
            data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
            if (attr == NULL) {
                ALOGE("Writing NULL audio attributes - shouldn't happen");
                return (audio_io_handle_t) 0;
            }
            data.write(attr, sizeof(audio_attributes_t));
            data.writeInt32(samplingRate);
            data.writeInt32(static_cast <uint32_t>(format));
            data.writeInt32(channelMask);
            data.writeInt32(static_cast <uint32_t>(flags));
            // hasOffloadInfo
            if (offloadInfo == NULL) {
                data.writeInt32(0);
            } else {
                data.writeInt32(1);
                data.write(offloadInfo, sizeof(audio_offload_info_t));
            }
            remote()->transact(GET_OUTPUT_FOR_ATTR, data, &reply);
            return static_cast <audio_io_handle_t> (reply.readInt32());
        }

    virtual status_t startOutput(audio_io_handle_t output,
                                 audio_stream_type_t stream,
                                 int session)
@@ -614,6 +645,30 @@ status_t BnAudioPolicyService::onTransact(
            return NO_ERROR;
        } break;

        case GET_OUTPUT_FOR_ATTR: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_attributes_t *attr = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
            data.read(attr, sizeof(audio_attributes_t));
            uint32_t samplingRate = data.readInt32();
            audio_format_t format = (audio_format_t) data.readInt32();
            audio_channel_mask_t channelMask = data.readInt32();
            audio_output_flags_t flags =
                    static_cast <audio_output_flags_t>(data.readInt32());
            bool hasOffloadInfo = data.readInt32() != 0;
            audio_offload_info_t offloadInfo;
            if (hasOffloadInfo) {
                data.read(&offloadInfo, sizeof(audio_offload_info_t));
            }
            audio_io_handle_t output = getOutputForAttr(attr,
                    samplingRate,
                    format,
                    channelMask,
                    flags,
                    hasOffloadInfo ? &offloadInfo : NULL);
            reply->writeInt32(static_cast <int>(output));
            return NO_ERROR;
        } break;

        case START_OUTPUT: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32());
Loading