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

Commit fa95b402 authored by Andy Hung's avatar Andy Hung Committed by Automerger Merge Worker
Browse files

Merge "TrackMetrics: Add device-based statistics for audio" into rvc-dev am: 31300b43

Change-Id: Ia82b2e288104e6c255f470ff19bd58c2b1aadd1a
parents 7eeb4aa4 31300b43
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -614,6 +614,8 @@ public:
    // and thus which resulted in an underrun.
    virtual uint32_t    getUnderrunFrames() const { return mCblk->u.mStreaming.mUnderrunFrames; }

    virtual uint32_t    getUnderrunCount() const { return mCblk->u.mStreaming.mUnderrunCount; }

    // Return the playback speed and pitch read atomically. Not multi-thread safe on server side.
    AudioPlaybackRate getPlaybackRate();

+18 −0
Original line number Diff line number Diff line
@@ -37,6 +37,11 @@
// They must be appended with another value to make a key.
#define AMEDIAMETRICS_KEY_PREFIX_AUDIO "audio."

// The AudioMmap key appends the "trackId" to the prefix.
// This is the AudioFlinger equivalent of the AAudio Stream.
// TODO: unify with AMEDIAMETRICS_KEY_PREFIX_AUDIO_STREAM
#define AMEDIAMETRICS_KEY_PREFIX_AUDIO_MMAP  AMEDIAMETRICS_KEY_PREFIX_AUDIO "mmap."

// The AudioRecord key appends the "trackId" to the prefix.
#define AMEDIAMETRICS_KEY_PREFIX_AUDIO_RECORD AMEDIAMETRICS_KEY_PREFIX_AUDIO "record."

@@ -95,6 +100,14 @@
#define AMEDIAMETRICS_PROP_CHANNELCOUNT   "channelCount"   // int32
#define AMEDIAMETRICS_PROP_CHANNELMASK    "channelMask"    // int32
#define AMEDIAMETRICS_PROP_CONTENTTYPE    "contentType"    // string attributes (AudioTrack)
#define AMEDIAMETRICS_PROP_CUMULATIVETIMENS "cumulativeTimeNs" // int64_t playback/record time
                                                           // since start
// DEVICE values are averaged since starting on device
#define AMEDIAMETRICS_PROP_DEVICELATENCYMS "deviceLatencyMs" // double - avg latency time
#define AMEDIAMETRICS_PROP_DEVICESTARTUPMS "deviceStartupMs" // double - avg startup time
#define AMEDIAMETRICS_PROP_DEVICETIMENS   "deviceTimeNs"   // int64_t playback/record time
#define AMEDIAMETRICS_PROP_DEVICEVOLUME   "deviceVolume"   // double - average device volume

#define AMEDIAMETRICS_PROP_DIRECTION      "direction"      // string AAudio input or output
#define AMEDIAMETRICS_PROP_DURATIONNS     "durationNs"     // int64 duration time span
#define AMEDIAMETRICS_PROP_ENCODING       "encoding"       // string value of format
@@ -105,7 +118,9 @@

#define AMEDIAMETRICS_PROP_FRAMECOUNT     "frameCount"     // int32
#define AMEDIAMETRICS_PROP_INPUTDEVICES   "inputDevices"   // string value
#define AMEDIAMETRICS_PROP_INTERVALCOUNT  "intervalCount"  // int32
#define AMEDIAMETRICS_PROP_LATENCYMS      "latencyMs"      // double value
#define AMEDIAMETRICS_PROP_NAME           "name"           // string value
#define AMEDIAMETRICS_PROP_ORIGINALFLAGS  "originalFlags"  // int32
#define AMEDIAMETRICS_PROP_OUTPUTDEVICES  "outputDevices"  // string value
#define AMEDIAMETRICS_PROP_PERFORMANCEMODE "performanceMode"    // string value, "none", lowLatency"
@@ -129,6 +144,7 @@
#define AMEDIAMETRICS_PROP_TRACKID        "trackId"        // int32 port id of track/record
#define AMEDIAMETRICS_PROP_TYPE           "type"           // string (thread type)
#define AMEDIAMETRICS_PROP_UNDERRUN       "underrun"       // int32
#define AMEDIAMETRICS_PROP_UNDERRUNFRAMES "underrunFrames" // int64_t from Thread
#define AMEDIAMETRICS_PROP_USAGE          "usage"          // string attributes (ATrack)
#define AMEDIAMETRICS_PROP_VOLUME_LEFT    "volume.left"    // double (AudioTrack)
#define AMEDIAMETRICS_PROP_VOLUME_RIGHT   "volume.right"   // double (AudioTrack)
@@ -140,12 +156,14 @@
// Values are strings accepted for a given property.

// An event is a general description, which often is a function name.
#define AMEDIAMETRICS_PROP_EVENT_VALUE_BEGINAUDIOINTERVALGROUP "beginAudioIntervalGroup"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_CLOSE      "close"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_CREATE     "create"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_CREATEAUDIOPATCH "createAudioPatch"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_CTOR       "ctor"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_DISCONNECT "disconnect"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_DTOR       "dtor"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_ENDAUDIOINTERVALGROUP "endAudioIntervalGroup"
#define AMEDIAMETRICS_PROP_EVENT_VALUE_FLUSH      "flush"  // AudioTrack
#define AMEDIAMETRICS_PROP_EVENT_VALUE_INVALIDATE "invalidate" // server track, record
#define AMEDIAMETRICS_PROP_EVENT_VALUE_OPEN       "open"
+1 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@
#include "SpdifStreamOut.h"
#include "AudioHwDevice.h"
#include "NBAIO_Tee.h"
#include "TrackMetrics.h"

#include <powermanager/IPowerManager.h>

+10 −0
Original line number Diff line number Diff line
@@ -171,6 +171,16 @@ public:

            void    setTeePatches(TeePatches teePatches);

    void tallyUnderrunFrames(size_t frames) override {
       if (isOut()) { // we expect this from output tracks only
           mAudioTrackServerProxy->tallyUnderrunFrames(frames);
           // Fetch absolute numbers from AudioTrackShared as it counts
           // contiguous underruns as a one -- we want a consistent number.
           // TODO: isolate this counting into a class.
           mTrackMetrics.logUnderruns(mAudioTrackServerProxy->getUnderrunCount(),
                   mAudioTrackServerProxy->getUnderrunFrames());
       }
    }
protected:
    // for numerous
    friend class PlaybackThread;
+52 −19
Original line number Diff line number Diff line
@@ -220,6 +220,9 @@ static std::string patchSinksToString(const struct audio_patch *patch)
{
    std::stringstream ss;
    for (size_t i = 0; i < patch->num_sinks; ++i) {
        if (i > 0) {
            ss << "|";
        }
        ss << "(" << toString(patch->sinks[i].ext.device.type)
            << ", " << patch->sinks[i].ext.device.address << ")";
    }
@@ -230,6 +233,9 @@ static std::string patchSourcesToString(const struct audio_patch *patch)
{
    std::stringstream ss;
    for (size_t i = 0; i < patch->num_sources; ++i) {
        if (i > 0) {
            ss << "|";
        }
        ss << "(" << toString(patch->sources[i].ext.device.type)
            << ", " << patch->sources[i].ext.device.address << ")";
    }
@@ -1686,6 +1692,7 @@ ssize_t AudioFlinger::ThreadBase::ActiveTracks<T>::remove(const sp<T> &track) {
#ifdef TEE_SINK
    track->dumpTee(-1 /* fd */, "_REMOVE");
#endif
    track->logEndInterval(); // log to MediaMetrics
    return index;
}

@@ -2553,6 +2560,7 @@ status_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track)
            chain->incActiveTrackCnt();
        }

        track->logBeginInterval(patchSinksToString(&mPatch)); // log to MediaMetrics
        status = NO_ERROR;
    }

@@ -4256,10 +4264,16 @@ status_t AudioFlinger::PlaybackThread::createAudioPatch_l(const struct audio_pat
        status = mOutput->stream->setParameters(param.toString());
        *handle = AUDIO_PATCH_HANDLE_NONE;
    }
    mediametrics::LogItem(mMetricsId)
        .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_CREATEAUDIOPATCH)
        .set(AMEDIAMETRICS_PROP_OUTPUTDEVICES, patchSinksToString(patch).c_str())
    const std::string patchSinksAsString = patchSinksToString(patch);
    mediametrics::LogItem item(mMetricsId);
    item.set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_CREATEAUDIOPATCH)
        .set(AMEDIAMETRICS_PROP_OUTPUTDEVICES, patchSinksAsString.c_str())
        .record();
    // also dispatch to active AudioTracks for MediaMetrics
    for (const auto &track : mActiveTracks) {
        track->logEndInterval();
        track->logBeginInterval(patchSinksAsString);
    }

    if (configChanged) {
        sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED);
@@ -4812,19 +4826,9 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
            // because that is when the underrun occurs.
            // We do not distinguish between FastTracks and NormalTracks here.
            if (*mMixerStatus == MIXER_TRACKS_READY && mUnderrunFrames.size() > 0) {
                mediametrics::LogItem item(mMetricsId);

                item.set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_UNDERRUN);
                for (const auto &underrun : mUnderrunFrames) {
                    underrun.first->mAudioTrackServerProxy->tallyUnderrunFrames(
                            underrun.second);

                    item.set(std::string("[" AMEDIAMETRICS_KEY_PREFIX_AUDIO_TRACK)
                            + std::to_string(underrun.first->portId())
                            + "]" AMEDIAMETRICS_PROP_UNDERRUN,
                            (int32_t)underrun.second);
                    underrun.first->tallyUnderrunFrames(underrun.second);
                }
                item.record();
            }
        }

@@ -4837,7 +4841,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac

    private:
        const mixer_state * const mMixerStatus;
        const std::string& mMetricsId;
        const std::string& __unused mMetricsId;
        std::vector<std::pair<sp<Track>, size_t>> mUnderrunFrames;
    } deferredOperations(&mixerStatus, mMetricsId);
    // implicit nested scope for variable capture
@@ -7881,6 +7885,9 @@ status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrac
            sendIoConfigEvent_l(
                AUDIO_CLIENT_STARTED, recordTrack->creatorPid(), recordTrack->portId());
        }

        recordTrack->logBeginInterval(patchSourcesToString(&mPatch)); // log to MediaMetrics

        // Catch up with current buffer indices if thread is already running.
        // This is what makes a new client discard all buffered data.  If the track's mRsmpInFront
        // was initialized to some value closer to the thread's mRsmpInFront, then the track could
@@ -8545,12 +8552,17 @@ status_t AudioFlinger::RecordThread::createAudioPatch_l(const struct audio_patch
        mPatch = *patch;
    }

    mediametrics::LogItem(mMetricsId)
        .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_CREATEAUDIOPATCH)
        .set(AMEDIAMETRICS_PROP_INPUTDEVICES, patchSourcesToString(patch).c_str())
    const std::string pathSourcesAsString = patchSourcesToString(patch);
    mediametrics::LogItem item(mMetricsId);
    item.set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_CREATEAUDIOPATCH)
        .set(AMEDIAMETRICS_PROP_INPUTDEVICES, pathSourcesAsString.c_str())
        .set(AMEDIAMETRICS_PROP_SOURCE, toString(mAudioSource).c_str())
        .record();

    // also dispatch to active AudioRecords
    for (const auto &track : mActiveTracks) {
        track->logEndInterval();
        track->logBeginInterval(pathSourcesAsString);
    }
    return status;
}

@@ -8861,6 +8873,7 @@ status_t AudioFlinger::MmapThread::start(const AudioClient& client,
        chain->incActiveTrackCnt();
    }

    track->logBeginInterval(patchSinksToString(&mPatch)); // log to MediaMetrics
    *handle = portId;
    broadcast_l();

@@ -8946,6 +8959,26 @@ void AudioFlinger::MmapThread::readHalParameters_l()
    result = mHalStream->getBufferSize(&mBufferSize);
    LOG_ALWAYS_FATAL_IF(result != OK, "Error retrieving buffer size from HAL: %d", result);
    mFrameCount = mBufferSize / mFrameSize;

    mediametrics::LogItem item(mMetricsId);
    item.set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_READPARAMETERS)
        .set(AMEDIAMETRICS_PROP_ENCODING, formatToString(mFormat).c_str())
        .set(AMEDIAMETRICS_PROP_SAMPLERATE, (int32_t)mSampleRate)
        .set(AMEDIAMETRICS_PROP_CHANNELMASK, (int32_t)mChannelMask)
        .set(AMEDIAMETRICS_PROP_CHANNELCOUNT, (int32_t)mChannelCount)
        .set(AMEDIAMETRICS_PROP_FRAMECOUNT, (int32_t)mFrameCount)
        /*
        .set(AMEDIAMETRICS_PROP_FLAGS, toString(flags).c_str())
        .set(AMEDIAMETRICS_PROP_PREFIX_HAPTIC AMEDIAMETRICS_PROP_CHANNELMASK,
                (int32_t)mHapticChannelMask)
        .set(AMEDIAMETRICS_PROP_PREFIX_HAPTIC AMEDIAMETRICS_PROP_CHANNELCOUNT,
                (int32_t)mHapticChannelCount)
        */
        .set(AMEDIAMETRICS_PROP_PREFIX_HAL    AMEDIAMETRICS_PROP_ENCODING,
                formatToString(mHALFormat).c_str())
        .set(AMEDIAMETRICS_PROP_PREFIX_HAL    AMEDIAMETRICS_PROP_FRAMECOUNT,
                (int32_t)mFrameCount) // sic - added HAL
        .record();
}

bool AudioFlinger::MmapThread::threadLoop()
Loading