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

Commit cbb44d47 authored by Kevin Rocard's avatar Kevin Rocard Committed by android-build-merger
Browse files

Merge "Revert "Audio V4: Send volume and duplicated track attr in update...

Merge "Revert "Audio V4: Send volume and duplicated track attr in update metadata"" into pi-dev am: ec84cede
am: f180c134

Change-Id: If2e03ce40b8a603215828cc55da4c07a4325e37a
parents 9a045343 f180c134
Loading
Loading
Loading
Loading
+0 −3
Original line number Original line Diff line number Diff line
@@ -19,11 +19,8 @@
#define ANDROID_AUDIO_FLINGER_H
#define ANDROID_AUDIO_FLINGER_H


#include "Configuration.h"
#include "Configuration.h"
#include <atomic>
#include <mutex>
#include <deque>
#include <deque>
#include <map>
#include <map>
#include <vector>
#include <stdint.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/types.h>
#include <limits.h>
#include <limits.h>
+1 −40
Original line number Original line Diff line number Diff line
@@ -93,23 +93,6 @@ public:
                                const sp<media::VolumeShaper::Operation>& operation);
                                const sp<media::VolumeShaper::Operation>& operation);
    sp<media::VolumeShaper::State> getVolumeShaperState(int id);
    sp<media::VolumeShaper::State> getVolumeShaperState(int id);
    sp<media::VolumeHandler>   getVolumeHandler() { return mVolumeHandler; }
    sp<media::VolumeHandler>   getVolumeHandler() { return mVolumeHandler; }
    /** Set the computed normalized final volume of the track.
     * !masterMute * masterVolume * streamVolume * averageLRVolume */
    void                setFinalVolume(float volume);
    float               getFinalVolume() const { return mFinalVolume; }

    /** @return true if the track has changed (metadata or volume) since
     *          the last time this function was called,
     *          true if this function was never called since the track creation,
     *          false otherwise.
     *  Thread safe.
     */
    bool            readAndClearHasChanged() { return !mChangeNotified.test_and_set(); }

    using SourceMetadatas = std::vector<playback_track_metadata_t>;
    using MetadataInserter = std::back_insert_iterator<SourceMetadatas>;
    /** Copy the track metadata in the provided iterator. Thread safe. */
    virtual void    copyMetadataTo(MetadataInserter& backInserter) const;


protected:
protected:
    // for numerous
    // for numerous
@@ -150,8 +133,6 @@ protected:
    bool presentationComplete(int64_t framesWritten, size_t audioHalFrames);
    bool presentationComplete(int64_t framesWritten, size_t audioHalFrames);
    void signalClientFlag(int32_t flag);
    void signalClientFlag(int32_t flag);


    /** Set that a metadata has changed and needs to be notified to backend. Thread safe. */
    void setMetadataHasChanged() { mChangeNotified.clear(); }
public:
public:
    void triggerEvents(AudioSystem::sync_event_t type);
    void triggerEvents(AudioSystem::sync_event_t type);
    virtual void invalidate();
    virtual void invalidate();
@@ -201,13 +182,10 @@ private:
    volatile float      mCachedVolume;  // combined master volume and stream type volume;
    volatile float      mCachedVolume;  // combined master volume and stream type volume;
                                        // 'volatile' means accessed without lock or
                                        // 'volatile' means accessed without lock or
                                        // barrier, but is read/written atomically
                                        // barrier, but is read/written atomically
    float               mFinalVolume; // combine master volume, stream type volume and track volume
    sp<AudioTrackServerProxy>  mAudioTrackServerProxy;
    sp<AudioTrackServerProxy>  mAudioTrackServerProxy;
    bool                mResumeToStopping; // track was paused in stopping state.
    bool                mResumeToStopping; // track was paused in stopping state.
    bool                mFlushHwPending; // track requests for thread flush
    bool                mFlushHwPending; // track requests for thread flush
    audio_output_flags_t mFlags;
    audio_output_flags_t mFlags;
    // If the last track change was notified to the client with readAndClearHasChanged
    std::atomic_flag     mChangeNotified = ATOMIC_FLAG_INIT;
};  // end of Track
};  // end of Track




@@ -238,11 +216,8 @@ public:
            bool        isActive() const { return mActive; }
            bool        isActive() const { return mActive; }
    const wp<ThreadBase>& thread() const { return mThread; }
    const wp<ThreadBase>& thread() const { return mThread; }


            void        copyMetadataTo(MetadataInserter& backInserter) const override;
    /** Set the metadatas of the upstream tracks. Thread safe. */
            void        setMetadatas(const SourceMetadatas& metadatas);

private:
private:

    status_t            obtainBuffer(AudioBufferProvider::Buffer* buffer,
    status_t            obtainBuffer(AudioBufferProvider::Buffer* buffer,
                                     uint32_t waitTimeMs);
                                     uint32_t waitTimeMs);
    void                clearBufferQueue();
    void                clearBufferQueue();
@@ -257,20 +232,6 @@ private:
    bool                        mActive;
    bool                        mActive;
    DuplicatingThread* const    mSourceThread; // for waitTimeMs() in write()
    DuplicatingThread* const    mSourceThread; // for waitTimeMs() in write()
    sp<AudioTrackClientProxy>   mClientProxy;
    sp<AudioTrackClientProxy>   mClientProxy;
    /** Attributes of the source tracks.
     *
     * This member must be accessed with mTrackMetadatasMutex taken.
     * There is one writer (duplicating thread) and one reader (downstream mixer).
     *
     * That means that the duplicating thread can block the downstream mixer
     * thread and vice versa for the time of the copy.
     * If this becomes an issue, the metadata could be stored in an atomic raw pointer,
     * and a exchange with nullptr and delete can be used.
     * Alternatively a read-copy-update might be implemented.
     */
    SourceMetadatas mTrackMetadatas;
    /** Protects mTrackMetadatas against concurrent access. */
    mutable std::mutex mTrackMetadatasMutex;
};  // end of OutputTrack
};  // end of OutputTrack


// playback track, used by PatchPanel
// playback track, used by PatchPanel
+23 −36
Original line number Original line Diff line number Diff line
@@ -2623,32 +2623,26 @@ void AudioFlinger::PlaybackThread::readOutputParameters_l()


void AudioFlinger::PlaybackThread::updateMetadata_l()
void AudioFlinger::PlaybackThread::updateMetadata_l()
{
{
    if (mOutput == nullptr || mOutput->stream == nullptr ) {
    // TODO: add volume support
        return; // That should not happen
    if (mOutput == nullptr || mOutput->stream == nullptr ||
    }
            !mActiveTracks.readAndClearHasChanged()) {
    bool hasChanged = mActiveTracks.readAndClearHasChanged();
        return;
    for (const sp<Track> &track : mActiveTracks) {
        // Do not short-circuit as all hasChanged states must be reset
        // as all the metadata are going to be sent
        hasChanged |= track->readAndClearHasChanged();
    }
    if (!hasChanged) {
        return; // nothing to do
    }
    }
    StreamOutHalInterface::SourceMetadata metadata;
    StreamOutHalInterface::SourceMetadata metadata;
    auto backInserter = std::back_inserter(metadata.tracks);
    for (const sp<Track> &track : mActiveTracks) {
    for (const sp<Track> &track : mActiveTracks) {
        // No track is invalid as this is called after prepareTrack_l in the same critical section
        // No track is invalid as this is called after prepareTrack_l in the same critical section
        track->copyMetadataTo(backInserter);
        if (track->isOutputTrack()) {
            // TODO: OutputTrack (used for duplication) are currently not supported
            continue;
        }
        }
    sendMetadataToBackend_l(metadata);
        metadata.tracks.push_back({
                .usage = track->attributes().usage,
                .content_type = track->attributes().content_type,
                .gain = 1,
        });
    }
    }

void AudioFlinger::PlaybackThread::sendMetadataToBackend_l(
        const StreamOutHalInterface::SourceMetadata& metadata)
{
    mOutput->stream->updateSourceMetadata(metadata);
    mOutput->stream->updateSourceMetadata(metadata);
};
}


status_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames)
status_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames)
{
{
@@ -4387,19 +4381,13 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
                    didModify = true;
                    didModify = true;
                    // no acknowledgement required for newly active tracks
                    // no acknowledgement required for newly active tracks
                }
                }
                sp<AudioTrackServerProxy> proxy = track->mAudioTrackServerProxy;
                // cache the combined master volume and stream type volume for fast mixer; this
                // cache the combined master volume and stream type volume for fast mixer; this
                // lacks any synchronization or barrier so VolumeProvider may read a stale value
                // lacks any synchronization or barrier so VolumeProvider may read a stale value
                const float vh = track->getVolumeHandler()->getVolume(
                const float vh = track->getVolumeHandler()->getVolume(
                        proxy->framesReleased()).first;
                        track->mAudioTrackServerProxy->framesReleased()).first;
                float volume = masterVolume
                track->mCachedVolume = masterVolume
                        * mStreamTypes[track->streamType()].volume
                        * mStreamTypes[track->streamType()].volume
                        * vh;
                        * vh;
                track->mCachedVolume = masterVolume;
                gain_minifloat_packed_t vlr = proxy->getVolumeLR();
                float vlf = volume * float_from_gain(gain_minifloat_unpack_left(vlr));
                float vrf = volume * float_from_gain(gain_minifloat_unpack_right(vlr));
                track->setFinalVolume((vlf + vrf) / 2.f);
                ++fastTracks;
                ++fastTracks;
            } else {
            } else {
                // was it previously active?
                // was it previously active?
@@ -4576,8 +4564,6 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
                vaf = v * sendLevel * (1. / MAX_GAIN_INT);
                vaf = v * sendLevel * (1. / MAX_GAIN_INT);
            }
            }


            track->setFinalVolume((vrf + vlf) / 2.f);

            // Delegate volume control to effect in track effect chain if needed
            // Delegate volume control to effect in track effect chain if needed
            if (chain != 0 && chain->setVolume_l(&vl, &vr)) {
            if (chain != 0 && chain->setVolume_l(&vl, &vr)) {
                // Do not ramp volume if volume is controlled by effect
                // Do not ramp volume if volume is controlled by effect
@@ -5122,7 +5108,6 @@ void AudioFlinger::DirectOutputThread::processVolume_l(Track *track, bool lastTr
    }
    }


    if (lastTrack) {
    if (lastTrack) {
        track->setFinalVolume((left + right) / 2.f);
        if (left != mLeftVolFloat || right != mRightVolFloat) {
        if (left != mLeftVolFloat || right != mRightVolFloat) {
            mLeftVolFloat = left;
            mLeftVolFloat = left;
            mRightVolFloat = right;
            mRightVolFloat = right;
@@ -6180,12 +6165,14 @@ bool AudioFlinger::DuplicatingThread::outputsReady(
    return true;
    return true;
}
}


void AudioFlinger::DuplicatingThread::sendMetadataToBackend_l(
void AudioFlinger::DuplicatingThread::updateMetadata_l()
        const StreamOutHalInterface::SourceMetadata& metadata)
{
{
    for (auto& outputTrack : outputTracks) { // not mOutputTracks
    // TODO: The duplicated track metadata needs to be pushed to downstream
        outputTrack->setMetadatas(metadata.tracks);
    // but this information can be read at any time by the downstream threads.
    }
    // Taking the lock of any downstream threads is no possible due to cross deadlock risks
    // (eg: during effect move).
    // A lock-free structure needs to be used to shared the metadata, probably an atomic
    // pointer to a metadata vector in each output tracks.
}
}


uint32_t AudioFlinger::DuplicatingThread::activeSleepTimeUs() const
uint32_t AudioFlinger::DuplicatingThread::activeSleepTimeUs() const
+5 −7
Original line number Original line Diff line number Diff line
@@ -566,8 +566,8 @@ protected:
                    // periodically called in the threadLoop() to update power state uids.
                    // periodically called in the threadLoop() to update power state uids.
                    void            updatePowerState(sp<ThreadBase> thread, bool force = false);
                    void            updatePowerState(sp<ThreadBase> thread, bool force = false);


                    /** @return true if one or move active tracks was added or removed since the
                    /** @return true if the active tracks have changed since the last time
                     *          last time this function was called or the vector was created. */
                     *          this function was called or the vector was created. */
                    bool            readAndClearHasChanged();
                    bool            readAndClearHasChanged();


                private:
                private:
@@ -588,7 +588,7 @@ protected:
                    int                 mLastActiveTracksGeneration;
                    int                 mLastActiveTracksGeneration;
                    wp<T>               mLatestActiveTrack; // latest track added to ActiveTracks
                    wp<T>               mLatestActiveTrack; // latest track added to ActiveTracks
                    SimpleLog * const   mLocalLog;
                    SimpleLog * const   mLocalLog;
                    // If the vector has changed since last call to readAndClearHasChanged
                    // If the active tracks have changed since last call to readAndClearHasChanged
                    bool                mHasChanged = false;
                    bool                mHasChanged = false;
                };
                };


@@ -927,8 +927,7 @@ private:
    void        removeTrack_l(const sp<Track>& track);
    void        removeTrack_l(const sp<Track>& track);


    void        readOutputParameters_l();
    void        readOutputParameters_l();
    void        updateMetadata_l() final;
    void        updateMetadata_l() override;
    virtual void sendMetadataToBackend_l(const StreamOutHalInterface::SourceMetadata& metadata);


    virtual void dumpInternals(int fd, const Vector<String16>& args);
    virtual void dumpInternals(int fd, const Vector<String16>& args);
    void        dumpTracks(int fd, const Vector<String16>& args);
    void        dumpTracks(int fd, const Vector<String16>& args);
@@ -1288,8 +1287,7 @@ public:
                void        removeOutputTrack(MixerThread* thread);
                void        removeOutputTrack(MixerThread* thread);
                uint32_t    waitTimeMs() const { return mWaitTimeMs; }
                uint32_t    waitTimeMs() const { return mWaitTimeMs; }


                void        sendMetadataToBackend_l(
                void        updateMetadata_l() override;
                        const StreamOutHalInterface::SourceMetadata& metadata) override;
protected:
protected:
    virtual     uint32_t    activeSleepTimeUs() const;
    virtual     uint32_t    activeSleepTimeUs() const;


+0 −35
Original line number Original line Diff line number Diff line
@@ -407,9 +407,6 @@ AudioFlinger::PlaybackThread::Track::Track(
    // mSinkTimestamp
    // mSinkTimestamp
    mFastIndex(-1),
    mFastIndex(-1),
    mCachedVolume(1.0),
    mCachedVolume(1.0),
    /* The track might not play immediately after being active, similarly as if its volume was 0.
     * When the track starts playing, its volume will be computed. */
    mFinalVolume(0.f),
    mResumeToStopping(false),
    mResumeToStopping(false),
    mFlushHwPending(false),
    mFlushHwPending(false),
    mFlags(flags)
    mFlags(flags)
@@ -1000,23 +997,6 @@ sp<VolumeShaper::State> AudioFlinger::PlaybackThread::Track::getVolumeShaperStat
    return mVolumeHandler->getVolumeShaperState(id);
    return mVolumeHandler->getVolumeShaperState(id);
}
}


void AudioFlinger::PlaybackThread::Track::setFinalVolume(float volume)
{
    if (mFinalVolume != volume) { // Compare to an epsilon if too many meaningless updates
        mFinalVolume = volume;
        setMetadataHasChanged();
    }
}

void AudioFlinger::PlaybackThread::Track::copyMetadataTo(MetadataInserter& backInserter) const
{
    *backInserter++ = {
            .usage = mAttr.usage,
            .content_type = mAttr.content_type,
            .gain = mFinalVolume,
    };
}

status_t AudioFlinger::PlaybackThread::Track::getTimestamp(AudioTimestamp& timestamp)
status_t AudioFlinger::PlaybackThread::Track::getTimestamp(AudioTimestamp& timestamp)
{
{
    if (!isOffloaded() && !isDirect()) {
    if (!isOffloaded() && !isDirect()) {
@@ -1447,21 +1427,6 @@ bool AudioFlinger::PlaybackThread::OutputTrack::write(void* data, uint32_t frame
    return outputBufferFull;
    return outputBufferFull;
}
}


void AudioFlinger::PlaybackThread::OutputTrack::copyMetadataTo(MetadataInserter& backInserter) const
{
    std::lock_guard<std::mutex> lock(mTrackMetadatasMutex);
    backInserter = std::copy(mTrackMetadatas.begin(), mTrackMetadatas.end(), backInserter);
}

void AudioFlinger::PlaybackThread::OutputTrack::setMetadatas(const SourceMetadatas& metadatas) {
    {
        std::lock_guard<std::mutex> lock(mTrackMetadatasMutex);
        mTrackMetadatas = metadatas;
    }
    // No need to adjust metadata track volumes as OutputTrack volumes are always 0dBFS.
    setMetadataHasChanged();
}

status_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(
status_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(
        AudioBufferProvider::Buffer* buffer, uint32_t waitTimeMs)
        AudioBufferProvider::Buffer* buffer, uint32_t waitTimeMs)
{
{