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

Commit ec84cede authored by Kevin Rocard's avatar Kevin Rocard Committed by Android (Google) Code Review
Browse files

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

parents f592b938 80ee2722
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -19,11 +19,8 @@
#define ANDROID_AUDIO_FLINGER_H

#include "Configuration.h"
#include <atomic>
#include <mutex>
#include <deque>
#include <map>
#include <vector>
#include <stdint.h>
#include <sys/types.h>
#include <limits.h>
+1 −40
Original line number Diff line number Diff line
@@ -93,23 +93,6 @@ public:
                                const sp<media::VolumeShaper::Operation>& operation);
    sp<media::VolumeShaper::State> getVolumeShaperState(int id);
    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:
    // for numerous
@@ -150,8 +133,6 @@ protected:
    bool presentationComplete(int64_t framesWritten, size_t audioHalFrames);
    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:
    void triggerEvents(AudioSystem::sync_event_t type);
    virtual void invalidate();
@@ -201,13 +182,10 @@ private:
    volatile float      mCachedVolume;  // combined master volume and stream type volume;
                                        // 'volatile' means accessed without lock or
                                        // barrier, but is read/written atomically
    float               mFinalVolume; // combine master volume, stream type volume and track volume
    sp<AudioTrackServerProxy>  mAudioTrackServerProxy;
    bool                mResumeToStopping; // track was paused in stopping state.
    bool                mFlushHwPending; // track requests for thread flush
    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


@@ -238,11 +216,8 @@ public:
            bool        isActive() const { return mActive; }
    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:

    status_t            obtainBuffer(AudioBufferProvider::Buffer* buffer,
                                     uint32_t waitTimeMs);
    void                clearBufferQueue();
@@ -257,20 +232,6 @@ private:
    bool                        mActive;
    DuplicatingThread* const    mSourceThread; // for waitTimeMs() in write()
    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

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

void AudioFlinger::PlaybackThread::updateMetadata_l()
{
    if (mOutput == nullptr || mOutput->stream == nullptr ) {
        return; // That should not happen
    }
    bool hasChanged = mActiveTracks.readAndClearHasChanged();
    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
    // TODO: add volume support
    if (mOutput == nullptr || mOutput->stream == nullptr ||
            !mActiveTracks.readAndClearHasChanged()) {
        return;
    }
    StreamOutHalInterface::SourceMetadata metadata;
    auto backInserter = std::back_inserter(metadata.tracks);
    for (const sp<Track> &track : mActiveTracks) {
        // 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);
};
}

status_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames)
{
@@ -4387,19 +4381,13 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
                    didModify = true;
                    // 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
                // lacks any synchronization or barrier so VolumeProvider may read a stale value
                const float vh = track->getVolumeHandler()->getVolume(
                        proxy->framesReleased()).first;
                float volume = masterVolume
                        track->mAudioTrackServerProxy->framesReleased()).first;
                track->mCachedVolume = masterVolume
                        * mStreamTypes[track->streamType()].volume
                        * 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;
            } else {
                // was it previously active?
@@ -4576,8 +4564,6 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
                vaf = v * sendLevel * (1. / MAX_GAIN_INT);
            }

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

            // Delegate volume control to effect in track effect chain if needed
            if (chain != 0 && chain->setVolume_l(&vl, &vr)) {
                // 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) {
        track->setFinalVolume((left + right) / 2.f);
        if (left != mLeftVolFloat || right != mRightVolFloat) {
            mLeftVolFloat = left;
            mRightVolFloat = right;
@@ -6180,12 +6165,14 @@ bool AudioFlinger::DuplicatingThread::outputsReady(
    return true;
}

void AudioFlinger::DuplicatingThread::sendMetadataToBackend_l(
        const StreamOutHalInterface::SourceMetadata& metadata)
void AudioFlinger::DuplicatingThread::updateMetadata_l()
{
    for (auto& outputTrack : outputTracks) { // not mOutputTracks
        outputTrack->setMetadatas(metadata.tracks);
    }
    // TODO: The duplicated track metadata needs to be pushed to downstream
    // 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
+5 −7
Original line number Diff line number Diff line
@@ -566,8 +566,8 @@ protected:
                    // periodically called in the threadLoop() to update power state uids.
                    void            updatePowerState(sp<ThreadBase> thread, bool force = false);

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

                private:
@@ -588,7 +588,7 @@ protected:
                    int                 mLastActiveTracksGeneration;
                    wp<T>               mLatestActiveTrack; // latest track added to ActiveTracks
                    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;
                };

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

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

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

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

+0 −35
Original line number Diff line number Diff line
@@ -407,9 +407,6 @@ AudioFlinger::PlaybackThread::Track::Track(
    // mSinkTimestamp
    mFastIndex(-1),
    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),
    mFlushHwPending(false),
    mFlags(flags)
@@ -1000,23 +997,6 @@ sp<VolumeShaper::State> AudioFlinger::PlaybackThread::Track::getVolumeShaperStat
    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)
{
    if (!isOffloaded() && !isDirect()) {
@@ -1447,21 +1427,6 @@ bool AudioFlinger::PlaybackThread::OutputTrack::write(void* data, uint32_t frame
    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(
        AudioBufferProvider::Buffer* buffer, uint32_t waitTimeMs)
{