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

Commit 1a9ed11a authored by Eric Laurent's avatar Eric Laurent
Browse files

audio policy: add configuration file

removed outputs to stream mapping cache in audio system: the output for a
given stream type must always be queried from audio policy manager as the cache
is not always updated fast enough by audioflinger callback.

removed AudioFlinger::PlaybackThread::setStreamValid() not used anymore if
stream to output mapping is not cached.

Change-Id: Ieca720c0b292181f81247259c8a44359bc74c66b
parent 290ca3a7
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -88,6 +88,19 @@ public:
    static status_t getOutputSamplingRate(int* samplingRate, audio_stream_type_t stream = AUDIO_STREAM_DEFAULT);
    static status_t getOutputFrameCount(int* frameCount, audio_stream_type_t stream = AUDIO_STREAM_DEFAULT);
    static status_t getOutputLatency(uint32_t* latency, audio_stream_type_t stream = AUDIO_STREAM_DEFAULT);
    static status_t getSamplingRate(audio_io_handle_t output,
                                          audio_stream_type_t streamType,
                                          int* samplingRate);
    // returns the number of frames per audio HAL write buffer. Corresponds to
    // audio_stream->get_buffer_size()/audio_stream_frame_size()
    static status_t getFrameCount(audio_io_handle_t output,
                                  audio_stream_type_t stream,
                                  int* frameCount);
    // returns the audio output stream latency in ms. Corresponds to
    // audio_stream_out->get_latency()
    static status_t getLatency(audio_io_handle_t output,
                               audio_stream_type_t stream,
                               uint32_t* latency);

    // DEPRECATED
    static status_t getOutputSamplingRate(int* samplingRate, int stream = AUDIO_STREAM_DEFAULT);
+33 −47
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient;
audio_error_callback AudioSystem::gAudioErrorCallback = NULL;
// Cached values

DefaultKeyedVector<audio_stream_type_t, audio_io_handle_t> AudioSystem::gStreamOutputMap(0);
DefaultKeyedVector<audio_io_handle_t, AudioSystem::OutputDescriptor *> AudioSystem::gOutputs(0);

// Cached values for recording queries, all protected by gLock
@@ -213,7 +212,6 @@ status_t AudioSystem::getOutputSamplingRate(int* samplingRate, int streamType) {

status_t AudioSystem::getOutputSamplingRate(int* samplingRate, audio_stream_type_t streamType)
{
    OutputDescriptor *outputDesc;
    audio_io_handle_t output;

    if (streamType == AUDIO_STREAM_DEFAULT) {
@@ -225,6 +223,15 @@ status_t AudioSystem::getOutputSamplingRate(int* samplingRate, audio_stream_type
        return PERMISSION_DENIED;
    }

    return getSamplingRate(output, streamType, samplingRate);
}

status_t AudioSystem::getSamplingRate(audio_io_handle_t output,
                                      audio_stream_type_t streamType,
                                      int* samplingRate)
{
    OutputDescriptor *outputDesc;

    gLock.lock();
    outputDesc = AudioSystem::gOutputs.valueFor(output);
    if (outputDesc == NULL) {
@@ -239,7 +246,7 @@ status_t AudioSystem::getOutputSamplingRate(int* samplingRate, audio_stream_type
        gLock.unlock();
    }

    ALOGV("getOutputSamplingRate() streamType %d, output %d, sampling rate %d", streamType, output, *samplingRate);
    ALOGV("getSamplingRate() streamType %d, output %d, sampling rate %d", streamType, output, *samplingRate);

    return NO_ERROR;
}
@@ -251,7 +258,6 @@ status_t AudioSystem::getOutputFrameCount(int* frameCount, int streamType) {

status_t AudioSystem::getOutputFrameCount(int* frameCount, audio_stream_type_t streamType)
{
    OutputDescriptor *outputDesc;
    audio_io_handle_t output;

    if (streamType == AUDIO_STREAM_DEFAULT) {
@@ -263,6 +269,15 @@ status_t AudioSystem::getOutputFrameCount(int* frameCount, audio_stream_type_t s
        return PERMISSION_DENIED;
    }

    return getFrameCount(output, streamType, frameCount);
}

status_t AudioSystem::getFrameCount(audio_io_handle_t output,
                                    audio_stream_type_t streamType,
                                    int* frameCount)
{
    OutputDescriptor *outputDesc;

    gLock.lock();
    outputDesc = AudioSystem::gOutputs.valueFor(output);
    if (outputDesc == NULL) {
@@ -275,14 +290,13 @@ status_t AudioSystem::getOutputFrameCount(int* frameCount, audio_stream_type_t s
        gLock.unlock();
    }

    ALOGV("getOutputFrameCount() streamType %d, output %d, frameCount %d", streamType, output, *frameCount);
    ALOGV("getFrameCount() streamType %d, output %d, frameCount %d", streamType, output, *frameCount);

    return NO_ERROR;
}

status_t AudioSystem::getOutputLatency(uint32_t* latency, audio_stream_type_t streamType)
{
    OutputDescriptor *outputDesc;
    audio_io_handle_t output;

    if (streamType == AUDIO_STREAM_DEFAULT) {
@@ -294,6 +308,15 @@ status_t AudioSystem::getOutputLatency(uint32_t* latency, audio_stream_type_t st
        return PERMISSION_DENIED;
    }

    return getLatency(output, streamType, latency);
}

status_t AudioSystem::getLatency(audio_io_handle_t output,
                                 audio_stream_type_t streamType,
                                 uint32_t* latency)
{
    OutputDescriptor *outputDesc;

    gLock.lock();
    outputDesc = AudioSystem::gOutputs.valueFor(output);
    if (outputDesc == NULL) {
@@ -306,7 +329,7 @@ status_t AudioSystem::getOutputLatency(uint32_t* latency, audio_stream_type_t st
        gLock.unlock();
    }

    ALOGV("getOutputLatency() streamType %d, output %d, latency %d", streamType, output, *latency);
    ALOGV("getLatency() streamType %d, output %d, latency %d", streamType, output, *latency);

    return NO_ERROR;
}
@@ -395,7 +418,6 @@ void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who) {

    AudioSystem::gAudioFlinger.clear();
    // clear output handles and stream to output map caches
    AudioSystem::gStreamOutputMap.clear();
    AudioSystem::gOutputs.clear();

    if (gAudioErrorCallback) {
@@ -416,12 +438,6 @@ void AudioSystem::AudioFlingerClient::ioConfigChanged(int event, audio_io_handle

    switch (event) {
    case STREAM_CONFIG_CHANGED:
        if (param2 == NULL) break;
        stream = *(const audio_stream_type_t *)param2;
        ALOGV("ioConfigChanged() STREAM_CONFIG_CHANGED stream %d, output %d", stream, ioHandle);
        if (gStreamOutputMap.indexOfKey(stream) >= 0) {
            gStreamOutputMap.replaceValueFor(stream, ioHandle);
        }
        break;
    case OUTPUT_OPENED: {
        if (gOutputs.indexOfKey(ioHandle) >= 0) {
@@ -444,11 +460,6 @@ void AudioSystem::AudioFlingerClient::ioConfigChanged(int event, audio_io_handle
        ALOGV("ioConfigChanged() output %d closed", ioHandle);

        gOutputs.removeItem(ioHandle);
        for (int i = gStreamOutputMap.size() - 1; i >= 0 ; i--) {
            if (gStreamOutputMap.valueAt(i) == ioHandle) {
                gStreamOutputMap.removeItemsAt(i);
            }
        }
        } break;

    case OUTPUT_CONFIG_CHANGED: {
@@ -580,33 +591,9 @@ audio_io_handle_t AudioSystem::getOutput(audio_stream_type_t stream,
                                    uint32_t channels,
                                    audio_policy_output_flags_t flags)
{
    audio_io_handle_t output = 0;
    // Do not use stream to output map cache if the direct output
    // flag is set or if we are likely to use a direct output
    // (e.g voice call stream @ 8kHz could use BT SCO device and be routed to
    // a direct output on some platforms).
    // TODO: the output cache and stream to output mapping implementation needs to
    // be reworked for proper operation with direct outputs. This code is too specific
    // to the first use case we want to cover (Voice Recognition and Voice Dialer over
    // Bluetooth SCO
    if ((flags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT) == 0 &&
        ((stream != AUDIO_STREAM_VOICE_CALL && stream != AUDIO_STREAM_BLUETOOTH_SCO) ||
         channels != AUDIO_CHANNEL_OUT_MONO ||
         (samplingRate != 8000 && samplingRate != 16000))) {
        Mutex::Autolock _l(gLock);
        output = AudioSystem::gStreamOutputMap.valueFor(stream);
        ALOGV_IF((output != 0), "getOutput() read %d from cache for stream %d", output, stream);
    }
    if (output == 0) {
    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
    if (aps == 0) return 0;
        output = aps->getOutput(stream, samplingRate, format, channels, flags);
        if ((flags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT) == 0) {
            Mutex::Autolock _l(gLock);
            AudioSystem::gStreamOutputMap.add(stream, output);
        }
    }
    return output;
    return aps->getOutput(stream, samplingRate, format, channels, flags);
}

status_t AudioSystem::startOutput(audio_io_handle_t output,
@@ -754,7 +741,6 @@ void AudioSystem::clearAudioConfigCache()
{
    Mutex::Autolock _l(gLock);
    ALOGV("clearAudioConfigCache()");
    gStreamOutputMap.clear();
    gOutputs.clear();
}

+10 −13
Original line number Diff line number Diff line
@@ -185,27 +185,23 @@ status_t AudioTrack::set(

    ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());

    ALOGV("set() streamType %d frameCount %d flags %04x", streamType, frameCount, flags);

    AutoMutex lock(mLock);
    if (mAudioTrack != 0) {
        ALOGE("Track already in use");
        return INVALID_OPERATION;
    }

    int afSampleRate;
    if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
        return NO_INIT;
    }

    uint32_t afLatency;
    if (AudioSystem::getOutputLatency(&afLatency, streamType) != NO_ERROR) {
        return NO_INIT;
    }

    // handle default values first.
    if (streamType == AUDIO_STREAM_DEFAULT) {
        streamType = AUDIO_STREAM_MUSIC;
    }

    int afSampleRate;
    if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
        return NO_INIT;
    }
    if (sampleRate == 0) {
        sampleRate = afSampleRate;
    }
@@ -751,15 +747,15 @@ status_t AudioTrack::createTrack_l(
    }

    int afSampleRate;
    if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
    if (AudioSystem::getSamplingRate(output, streamType, &afSampleRate) != NO_ERROR) {
        return NO_INIT;
    }
    int afFrameCount;
    if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) {
    if (AudioSystem::getFrameCount(output, streamType, &afFrameCount) != NO_ERROR) {
        return NO_INIT;
    }
    uint32_t afLatency;
    if (AudioSystem::getOutputLatency(&afLatency, streamType) != NO_ERROR) {
    if (AudioSystem::getLatency(output, streamType, &afLatency) != NO_ERROR) {
        return NO_INIT;
    }

@@ -774,6 +770,7 @@ status_t AudioTrack::createTrack_l(
        ALOGW("AUDIO_POLICY_OUTPUT_FLAG_FAST denied");
        flags = (audio_policy_output_flags_t) (flags & ~AUDIO_POLICY_OUTPUT_FLAG_FAST);
    }
    ALOGV("createTrack_l() output %d afFrameCount %d afLatency %d", output, afFrameCount, afLatency);

    mNotificationFramesAct = mNotificationFramesReq;
    if (!audio_is_linear_pcm(format)) {
+3 −25
Original line number Diff line number Diff line
@@ -150,9 +150,9 @@ out:
}

static const char * const audio_interfaces[] = {
    "primary",
    "a2dp",
    "usb",
    AUDIO_HARDWARE_MODULE_ID_PRIMARY,
    AUDIO_HARDWARE_MODULE_ID_A2DP,
    AUDIO_HARDWARE_MODULE_ID_USB,
};
#define ARRAY_SIZE(x) (sizeof((x))/sizeof(((x)[0])))

@@ -1503,8 +1503,6 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge
            stream = (audio_stream_type_t) (stream + 1)) {
        mStreamTypes[stream].volume = mAudioFlinger->streamVolume_l(stream);
        mStreamTypes[stream].mute = mAudioFlinger->streamMute_l(stream);
        // initialized by stream_type_t default constructor
        // mStreamTypes[stream].valid = true;
    }
    // mStreamTypes[AUDIO_STREAM_CNT] exists but isn't explicitly initialized here,
    // because mAudioFlinger doesn't have one to copy from
@@ -1717,14 +1715,6 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac
            chain->setStrategy(AudioSystem::getStrategyForStream(track->streamType()));
            chain->incTrackCnt();
        }

        // invalidate track immediately if the stream type was moved to another thread since
        // createTrack() was called by the client process.
        if (!mStreamTypes[streamType].valid) {
            ALOGW("createTrack_l() on thread %p: invalidating track on stream %d",
                this, streamType);
            android_atomic_or(CBLK_INVALID_ON, &track->mCblk->flags);
        }
    }
    lStatus = NO_ERROR;

@@ -2709,15 +2699,6 @@ void AudioFlinger::MixerThread::invalidateTracks(audio_stream_type_t streamType)
    }
}

void AudioFlinger::PlaybackThread::setStreamValid(audio_stream_type_t streamType, bool valid)
{
    ALOGV ("PlaybackThread::setStreamValid() thread %p, streamType %d, valid %d",
            this,  streamType, valid);
    Mutex::Autolock _l(mLock);

    mStreamTypes[streamType].valid = valid;
}

// getTrackName_l() must be called with ThreadBase::mLock held
int AudioFlinger::MixerThread::getTrackName_l()
{
@@ -5969,13 +5950,10 @@ status_t AudioFlinger::setStreamOutput(audio_stream_type_t stream, audio_io_hand
    ALOGV("setStreamOutput() stream %d to output %d", stream, output);
    audioConfigChanged_l(AudioSystem::STREAM_CONFIG_CHANGED, output, &stream);

    dstThread->setStreamValid(stream, true);

    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
        PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
        if (thread != dstThread && thread->type() != ThreadBase::DIRECT) {
            MixerThread *srcThread = (MixerThread *)thread;
            srcThread->setStreamValid(stream, false);
            srcThread->invalidateTracks(stream);
        }
    }
+1 −4
Original line number Diff line number Diff line
@@ -630,13 +630,11 @@ private:
    struct  stream_type_t {
        stream_type_t()
            :   volume(1.0f),
                mute(false),
                valid(true)
                mute(false)
        {
        }
        float       volume;
        bool        mute;
        bool        valid;
    };

    // --- PlaybackThread ---
@@ -945,7 +943,6 @@ public:
                    virtual uint32_t hasAudioSession(int sessionId);
                    virtual uint32_t getStrategyForSession_l(int sessionId);

                            void setStreamValid(audio_stream_type_t streamType, bool valid);

                    virtual status_t setSyncEvent(const sp<SyncEvent>& event);
                    virtual bool     isValidSyncEvent(const sp<SyncEvent>& event);
Loading