1*ec779b8eSAndroid Build Coastguard Worker /* 2*ec779b8eSAndroid Build Coastguard Worker ** 3*ec779b8eSAndroid Build Coastguard Worker ** Copyright 2012, The Android Open Source Project 4*ec779b8eSAndroid Build Coastguard Worker ** 5*ec779b8eSAndroid Build Coastguard Worker ** Licensed under the Apache License, Version 2.0 (the "License"); 6*ec779b8eSAndroid Build Coastguard Worker ** you may not use this file except in compliance with the License. 7*ec779b8eSAndroid Build Coastguard Worker ** You may obtain a copy of the License at 8*ec779b8eSAndroid Build Coastguard Worker ** 9*ec779b8eSAndroid Build Coastguard Worker ** http://www.apache.org/licenses/LICENSE-2.0 10*ec779b8eSAndroid Build Coastguard Worker ** 11*ec779b8eSAndroid Build Coastguard Worker ** Unless required by applicable law or agreed to in writing, software 12*ec779b8eSAndroid Build Coastguard Worker ** distributed under the License is distributed on an "AS IS" BASIS, 13*ec779b8eSAndroid Build Coastguard Worker ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*ec779b8eSAndroid Build Coastguard Worker ** See the License for the specific language governing permissions and 15*ec779b8eSAndroid Build Coastguard Worker ** limitations under the License. 16*ec779b8eSAndroid Build Coastguard Worker */ 17*ec779b8eSAndroid Build Coastguard Worker 18*ec779b8eSAndroid Build Coastguard Worker #pragma once 19*ec779b8eSAndroid Build Coastguard Worker 20*ec779b8eSAndroid Build Coastguard Worker #include "Configuration.h" // TEE_SINK 21*ec779b8eSAndroid Build Coastguard Worker #include "IAfTrack.h" 22*ec779b8eSAndroid Build Coastguard Worker 23*ec779b8eSAndroid Build Coastguard Worker #include <afutils/NBAIO_Tee.h> 24*ec779b8eSAndroid Build Coastguard Worker #include <android-base/macros.h> // DISALLOW_COPY_AND_ASSIGN 25*ec779b8eSAndroid Build Coastguard Worker #include <audio_utils/Trace.h> 26*ec779b8eSAndroid Build Coastguard Worker #include <datapath/TrackMetrics.h> 27*ec779b8eSAndroid Build Coastguard Worker #include <mediautils/BatteryNotifier.h> 28*ec779b8eSAndroid Build Coastguard Worker #include <psh_utils/AudioPowerManager.h> 29*ec779b8eSAndroid Build Coastguard Worker 30*ec779b8eSAndroid Build Coastguard Worker #include <atomic> // avoid transitive dependency 31*ec779b8eSAndroid Build Coastguard Worker #include <list> // avoid transitive dependency 32*ec779b8eSAndroid Build Coastguard Worker #include <optional> // avoid transitive dependency 33*ec779b8eSAndroid Build Coastguard Worker 34*ec779b8eSAndroid Build Coastguard Worker namespace android { 35*ec779b8eSAndroid Build Coastguard Worker 36*ec779b8eSAndroid Build Coastguard Worker // base for record and playback 37*ec779b8eSAndroid Build Coastguard Worker class TrackBase : public ExtendedAudioBufferProvider, public virtual IAfTrackBase { 38*ec779b8eSAndroid Build Coastguard Worker public: 39*ec779b8eSAndroid Build Coastguard Worker TrackBase(IAfThreadBase* thread, 40*ec779b8eSAndroid Build Coastguard Worker const sp<Client>& client, 41*ec779b8eSAndroid Build Coastguard Worker const audio_attributes_t& mAttr, 42*ec779b8eSAndroid Build Coastguard Worker uint32_t sampleRate, 43*ec779b8eSAndroid Build Coastguard Worker audio_format_t format, 44*ec779b8eSAndroid Build Coastguard Worker audio_channel_mask_t channelMask, 45*ec779b8eSAndroid Build Coastguard Worker size_t frameCount, 46*ec779b8eSAndroid Build Coastguard Worker void *buffer, 47*ec779b8eSAndroid Build Coastguard Worker size_t bufferSize, 48*ec779b8eSAndroid Build Coastguard Worker audio_session_t sessionId, 49*ec779b8eSAndroid Build Coastguard Worker pid_t creatorPid, 50*ec779b8eSAndroid Build Coastguard Worker uid_t uid, 51*ec779b8eSAndroid Build Coastguard Worker bool isOut, 52*ec779b8eSAndroid Build Coastguard Worker const alloc_type alloc = ALLOC_CBLK, 53*ec779b8eSAndroid Build Coastguard Worker track_type type = TYPE_DEFAULT, 54*ec779b8eSAndroid Build Coastguard Worker audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE, 55*ec779b8eSAndroid Build Coastguard Worker std::string metricsId = {}); 56*ec779b8eSAndroid Build Coastguard Worker ~TrackBase() override; 57*ec779b8eSAndroid Build Coastguard Worker status_t initCheck() const override; getCblk()58*ec779b8eSAndroid Build Coastguard Worker sp<IMemory> getCblk() const final { return mCblkMemory; } cblk()59*ec779b8eSAndroid Build Coastguard Worker audio_track_cblk_t* cblk() const final { return mCblk; } sessionId()60*ec779b8eSAndroid Build Coastguard Worker audio_session_t sessionId() const final { return mSessionId; } uid()61*ec779b8eSAndroid Build Coastguard Worker uid_t uid() const final { return mUid; } creatorPid()62*ec779b8eSAndroid Build Coastguard Worker pid_t creatorPid() const final { return mCreatorPid; } portId()63*ec779b8eSAndroid Build Coastguard Worker audio_port_handle_t portId() const final { return mPortId; } 64*ec779b8eSAndroid Build Coastguard Worker status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) override; state()65*ec779b8eSAndroid Build Coastguard Worker track_state state() const final { return mState; } setState(track_state state)66*ec779b8eSAndroid Build Coastguard Worker void setState(track_state state) final { mState = state; } getBuffers()67*ec779b8eSAndroid Build Coastguard Worker sp<IMemory> getBuffers() const final { return mBufferMemory; } buffer()68*ec779b8eSAndroid Build Coastguard Worker void* buffer() const final { return mBuffer; } bufferSize()69*ec779b8eSAndroid Build Coastguard Worker size_t bufferSize() const final { return mBufferSize; } 70*ec779b8eSAndroid Build Coastguard Worker isOutputTrack()71*ec779b8eSAndroid Build Coastguard Worker bool isOutputTrack() const final { return (mType == TYPE_OUTPUT); } isPatchTrack()72*ec779b8eSAndroid Build Coastguard Worker bool isPatchTrack() const final { return (mType == TYPE_PATCH); } isExternalTrack()73*ec779b8eSAndroid Build Coastguard Worker bool isExternalTrack() const final { return !isOutputTrack() && !isPatchTrack(); } invalidate()74*ec779b8eSAndroid Build Coastguard Worker void invalidate() override { 75*ec779b8eSAndroid Build Coastguard Worker if (mIsInvalid) return; 76*ec779b8eSAndroid Build Coastguard Worker mTrackMetrics.logInvalidate(); 77*ec779b8eSAndroid Build Coastguard Worker mIsInvalid = true; 78*ec779b8eSAndroid Build Coastguard Worker } isInvalid()79*ec779b8eSAndroid Build Coastguard Worker bool isInvalid() const final { return mIsInvalid; } terminate()80*ec779b8eSAndroid Build Coastguard Worker void terminate() final { mTerminated = true; } isTerminated()81*ec779b8eSAndroid Build Coastguard Worker bool isTerminated() const final { return mTerminated; } attributes()82*ec779b8eSAndroid Build Coastguard Worker audio_attributes_t attributes() const final { return mAttr; } isSpatialized()83*ec779b8eSAndroid Build Coastguard Worker bool isSpatialized() const override { return false; } isBitPerfect()84*ec779b8eSAndroid Build Coastguard Worker bool isBitPerfect() const override { return false; } 85*ec779b8eSAndroid Build Coastguard Worker thread()86*ec779b8eSAndroid Build Coastguard Worker wp<IAfThreadBase> thread() const final { return mThread; } 87*ec779b8eSAndroid Build Coastguard Worker serverProxy()88*ec779b8eSAndroid Build Coastguard Worker const sp<ServerProxy>& serverProxy() const final { return mServerProxy; } 89*ec779b8eSAndroid Build Coastguard Worker 90*ec779b8eSAndroid Build Coastguard Worker #ifdef TEE_SINK dumpTee(int fd,const std::string & reason)91*ec779b8eSAndroid Build Coastguard Worker void dumpTee(int fd, const std::string &reason) const final { 92*ec779b8eSAndroid Build Coastguard Worker mTee.dump(fd, reason); 93*ec779b8eSAndroid Build Coastguard Worker } 94*ec779b8eSAndroid Build Coastguard Worker #endif 95*ec779b8eSAndroid Build Coastguard Worker /** returns the buffer contents size converted to time in milliseconds 96*ec779b8eSAndroid Build Coastguard Worker * for PCM Playback or Record streaming tracks. The return value is zero for 97*ec779b8eSAndroid Build Coastguard Worker * PCM static tracks and not defined for non-PCM tracks. 98*ec779b8eSAndroid Build Coastguard Worker * 99*ec779b8eSAndroid Build Coastguard Worker * This may be called without the thread lock. 100*ec779b8eSAndroid Build Coastguard Worker */ bufferLatencyMs()101*ec779b8eSAndroid Build Coastguard Worker double bufferLatencyMs() const override { 102*ec779b8eSAndroid Build Coastguard Worker return mServerProxy->framesReadySafe() * 1000. / sampleRate(); 103*ec779b8eSAndroid Build Coastguard Worker } 104*ec779b8eSAndroid Build Coastguard Worker 105*ec779b8eSAndroid Build Coastguard Worker /** returns whether the track supports server latency computation. 106*ec779b8eSAndroid Build Coastguard Worker * This is set in the constructor and constant throughout the track lifetime. 107*ec779b8eSAndroid Build Coastguard Worker */ isServerLatencySupported()108*ec779b8eSAndroid Build Coastguard Worker bool isServerLatencySupported() const final { return mServerLatencySupported; } 109*ec779b8eSAndroid Build Coastguard Worker 110*ec779b8eSAndroid Build Coastguard Worker /** computes the server latency for PCM Playback or Record track 111*ec779b8eSAndroid Build Coastguard Worker * to the device sink/source. This is the time for the next frame in the track buffer 112*ec779b8eSAndroid Build Coastguard Worker * written or read from the server thread to the device source or sink. 113*ec779b8eSAndroid Build Coastguard Worker * 114*ec779b8eSAndroid Build Coastguard Worker * This may be called without the thread lock, but latencyMs and fromTrack 115*ec779b8eSAndroid Build Coastguard Worker * may be not be synchronized. For example PatchPanel may not obtain the 116*ec779b8eSAndroid Build Coastguard Worker * thread lock before calling. 117*ec779b8eSAndroid Build Coastguard Worker * 118*ec779b8eSAndroid Build Coastguard Worker * \param latencyMs on success is set to the latency in milliseconds of the 119*ec779b8eSAndroid Build Coastguard Worker * next frame written/read by the server thread to/from the track buffer 120*ec779b8eSAndroid Build Coastguard Worker * from the device source/sink. 121*ec779b8eSAndroid Build Coastguard Worker * \param fromTrack on success is set to true if latency was computed directly 122*ec779b8eSAndroid Build Coastguard Worker * from the track timestamp; otherwise set to false if latency was 123*ec779b8eSAndroid Build Coastguard Worker * estimated from the server timestamp. 124*ec779b8eSAndroid Build Coastguard Worker * fromTrack may be nullptr or omitted if not required. 125*ec779b8eSAndroid Build Coastguard Worker * 126*ec779b8eSAndroid Build Coastguard Worker * \returns OK or INVALID_OPERATION on failure. 127*ec779b8eSAndroid Build Coastguard Worker */ 128*ec779b8eSAndroid Build Coastguard Worker status_t getServerLatencyMs(double* latencyMs, bool* fromTrack = nullptr) const final { 129*ec779b8eSAndroid Build Coastguard Worker if (!isServerLatencySupported()) { 130*ec779b8eSAndroid Build Coastguard Worker return INVALID_OPERATION; 131*ec779b8eSAndroid Build Coastguard Worker } 132*ec779b8eSAndroid Build Coastguard Worker 133*ec779b8eSAndroid Build Coastguard Worker // if no thread lock is acquired, these atomics are not 134*ec779b8eSAndroid Build Coastguard Worker // synchronized with each other, considered a benign race. 135*ec779b8eSAndroid Build Coastguard Worker 136*ec779b8eSAndroid Build Coastguard Worker const double serverLatencyMs = mServerLatencyMs.load(); 137*ec779b8eSAndroid Build Coastguard Worker if (serverLatencyMs == 0.) { 138*ec779b8eSAndroid Build Coastguard Worker return INVALID_OPERATION; 139*ec779b8eSAndroid Build Coastguard Worker } 140*ec779b8eSAndroid Build Coastguard Worker if (fromTrack != nullptr) { 141*ec779b8eSAndroid Build Coastguard Worker *fromTrack = mServerLatencyFromTrack.load(); 142*ec779b8eSAndroid Build Coastguard Worker } 143*ec779b8eSAndroid Build Coastguard Worker *latencyMs = serverLatencyMs; 144*ec779b8eSAndroid Build Coastguard Worker return OK; 145*ec779b8eSAndroid Build Coastguard Worker } 146*ec779b8eSAndroid Build Coastguard Worker 147*ec779b8eSAndroid Build Coastguard Worker /** computes the total client latency for PCM Playback or Record tracks 148*ec779b8eSAndroid Build Coastguard Worker * for the next client app access to the device sink/source; i.e. the 149*ec779b8eSAndroid Build Coastguard Worker * server latency plus the buffer latency. 150*ec779b8eSAndroid Build Coastguard Worker * 151*ec779b8eSAndroid Build Coastguard Worker * This may be called without the thread lock, but latencyMs and fromTrack 152*ec779b8eSAndroid Build Coastguard Worker * may be not be synchronized. For example PatchPanel may not obtain the 153*ec779b8eSAndroid Build Coastguard Worker * thread lock before calling. 154*ec779b8eSAndroid Build Coastguard Worker * 155*ec779b8eSAndroid Build Coastguard Worker * \param latencyMs on success is set to the latency in milliseconds of the 156*ec779b8eSAndroid Build Coastguard Worker * next frame written/read by the client app to/from the track buffer 157*ec779b8eSAndroid Build Coastguard Worker * from the device sink/source. 158*ec779b8eSAndroid Build Coastguard Worker * \param fromTrack on success is set to true if latency was computed directly 159*ec779b8eSAndroid Build Coastguard Worker * from the track timestamp; otherwise set to false if latency was 160*ec779b8eSAndroid Build Coastguard Worker * estimated from the server timestamp. 161*ec779b8eSAndroid Build Coastguard Worker * fromTrack may be nullptr or omitted if not required. 162*ec779b8eSAndroid Build Coastguard Worker * 163*ec779b8eSAndroid Build Coastguard Worker * \returns OK or INVALID_OPERATION on failure. 164*ec779b8eSAndroid Build Coastguard Worker */ 165*ec779b8eSAndroid Build Coastguard Worker status_t getTrackLatencyMs(double* latencyMs, bool* fromTrack = nullptr) const { 166*ec779b8eSAndroid Build Coastguard Worker double serverLatencyMs; 167*ec779b8eSAndroid Build Coastguard Worker status_t status = getServerLatencyMs(&serverLatencyMs, fromTrack); 168*ec779b8eSAndroid Build Coastguard Worker if (status == OK) { 169*ec779b8eSAndroid Build Coastguard Worker *latencyMs = serverLatencyMs + bufferLatencyMs(); 170*ec779b8eSAndroid Build Coastguard Worker } 171*ec779b8eSAndroid Build Coastguard Worker return status; 172*ec779b8eSAndroid Build Coastguard Worker } 173*ec779b8eSAndroid Build Coastguard Worker 174*ec779b8eSAndroid Build Coastguard Worker // KernelFrameTime is updated per "mix" period even for non-pcm tracks. getKernelFrameTime(FrameTime * ft)175*ec779b8eSAndroid Build Coastguard Worker void getKernelFrameTime(FrameTime* ft) const final { 176*ec779b8eSAndroid Build Coastguard Worker *ft = mKernelFrameTime.load(); 177*ec779b8eSAndroid Build Coastguard Worker } 178*ec779b8eSAndroid Build Coastguard Worker format()179*ec779b8eSAndroid Build Coastguard Worker audio_format_t format() const final { return mFormat; } id()180*ec779b8eSAndroid Build Coastguard Worker int id() const final { return mId; } 181*ec779b8eSAndroid Build Coastguard Worker getTrackStateAsString()182*ec779b8eSAndroid Build Coastguard Worker const char* getTrackStateAsString() const final { 183*ec779b8eSAndroid Build Coastguard Worker if (isTerminated()) { 184*ec779b8eSAndroid Build Coastguard Worker return "TERMINATED"; 185*ec779b8eSAndroid Build Coastguard Worker } 186*ec779b8eSAndroid Build Coastguard Worker switch (mState) { 187*ec779b8eSAndroid Build Coastguard Worker case IDLE: 188*ec779b8eSAndroid Build Coastguard Worker return "IDLE"; 189*ec779b8eSAndroid Build Coastguard Worker case STOPPING_1: // for Fast and Offload 190*ec779b8eSAndroid Build Coastguard Worker return "STOPPING_1"; 191*ec779b8eSAndroid Build Coastguard Worker case STOPPING_2: // for Fast and Offload 192*ec779b8eSAndroid Build Coastguard Worker return "STOPPING_2"; 193*ec779b8eSAndroid Build Coastguard Worker case STOPPED: 194*ec779b8eSAndroid Build Coastguard Worker return "STOPPED"; 195*ec779b8eSAndroid Build Coastguard Worker case RESUMING: 196*ec779b8eSAndroid Build Coastguard Worker return "RESUMING"; 197*ec779b8eSAndroid Build Coastguard Worker case ACTIVE: 198*ec779b8eSAndroid Build Coastguard Worker return "ACTIVE"; 199*ec779b8eSAndroid Build Coastguard Worker case PAUSING: 200*ec779b8eSAndroid Build Coastguard Worker return "PAUSING"; 201*ec779b8eSAndroid Build Coastguard Worker case PAUSED: 202*ec779b8eSAndroid Build Coastguard Worker return "PAUSED"; 203*ec779b8eSAndroid Build Coastguard Worker case FLUSHED: 204*ec779b8eSAndroid Build Coastguard Worker return "FLUSHED"; 205*ec779b8eSAndroid Build Coastguard Worker case STARTING_1: // for RecordTrack 206*ec779b8eSAndroid Build Coastguard Worker return "STARTING_1"; 207*ec779b8eSAndroid Build Coastguard Worker case STARTING_2: // for RecordTrack 208*ec779b8eSAndroid Build Coastguard Worker return "STARTING_2"; 209*ec779b8eSAndroid Build Coastguard Worker default: 210*ec779b8eSAndroid Build Coastguard Worker return "UNKNOWN"; 211*ec779b8eSAndroid Build Coastguard Worker } 212*ec779b8eSAndroid Build Coastguard Worker } 213*ec779b8eSAndroid Build Coastguard Worker getTraceSuffix()214*ec779b8eSAndroid Build Coastguard Worker const std::string& getTraceSuffix() const final { return mTraceSuffix; } 215*ec779b8eSAndroid Build Coastguard Worker // Called by the PlaybackThread to indicate that the track is becoming active 216*ec779b8eSAndroid Build Coastguard Worker // and a new interval should start with a given device list. 217*ec779b8eSAndroid Build Coastguard Worker void logBeginInterval(const std::string& devices) final; 218*ec779b8eSAndroid Build Coastguard Worker 219*ec779b8eSAndroid Build Coastguard Worker // Called by the PlaybackThread to indicate the track is no longer active. 220*ec779b8eSAndroid Build Coastguard Worker void logEndInterval() final; 221*ec779b8eSAndroid Build Coastguard Worker 222*ec779b8eSAndroid Build Coastguard Worker // Called by the PlaybackThread when ATRACE is enabled. 223*ec779b8eSAndroid Build Coastguard Worker void logRefreshInterval(const std::string& devices) final; 224*ec779b8eSAndroid Build Coastguard Worker 225*ec779b8eSAndroid Build Coastguard Worker // Called to tally underrun frames in playback. tallyUnderrunFrames(size_t)226*ec779b8eSAndroid Build Coastguard Worker void tallyUnderrunFrames(size_t /* frames */) override {} 227*ec779b8eSAndroid Build Coastguard Worker channelMask()228*ec779b8eSAndroid Build Coastguard Worker audio_channel_mask_t channelMask() const final { return mChannelMask; } 229*ec779b8eSAndroid Build Coastguard Worker 230*ec779b8eSAndroid Build Coastguard Worker /** @return true if the track has changed (metadata or volume) since 231*ec779b8eSAndroid Build Coastguard Worker * the last time this function was called, 232*ec779b8eSAndroid Build Coastguard Worker * true if this function was never called since the track creation, 233*ec779b8eSAndroid Build Coastguard Worker * false otherwise. 234*ec779b8eSAndroid Build Coastguard Worker * Thread safe. 235*ec779b8eSAndroid Build Coastguard Worker */ readAndClearHasChanged()236*ec779b8eSAndroid Build Coastguard Worker bool readAndClearHasChanged() final { return !mChangeNotified.test_and_set(); } 237*ec779b8eSAndroid Build Coastguard Worker 238*ec779b8eSAndroid Build Coastguard Worker /** Set that a metadata has changed and needs to be notified to backend. Thread safe. */ setMetadataHasChanged()239*ec779b8eSAndroid Build Coastguard Worker void setMetadataHasChanged() final { mChangeNotified.clear(); } 240*ec779b8eSAndroid Build Coastguard Worker 241*ec779b8eSAndroid Build Coastguard Worker /** 242*ec779b8eSAndroid Build Coastguard Worker * Called when a track moves to active state to record its contribution to battery usage. 243*ec779b8eSAndroid Build Coastguard Worker * Track state transitions should eventually be handled within the track class. 244*ec779b8eSAndroid Build Coastguard Worker */ 245*ec779b8eSAndroid Build Coastguard Worker void beginBatteryAttribution() final; 246*ec779b8eSAndroid Build Coastguard Worker 247*ec779b8eSAndroid Build Coastguard Worker /** 248*ec779b8eSAndroid Build Coastguard Worker * Called when a track moves out of the active state to record its contribution 249*ec779b8eSAndroid Build Coastguard Worker * to battery usage. 250*ec779b8eSAndroid Build Coastguard Worker */ 251*ec779b8eSAndroid Build Coastguard Worker void endBatteryAttribution() final; 252*ec779b8eSAndroid Build Coastguard Worker 253*ec779b8eSAndroid Build Coastguard Worker protected: 254*ec779b8eSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(TrackBase); 255*ec779b8eSAndroid Build Coastguard Worker releaseCblk()256*ec779b8eSAndroid Build Coastguard Worker void releaseCblk() { 257*ec779b8eSAndroid Build Coastguard Worker if (mCblk != nullptr) { 258*ec779b8eSAndroid Build Coastguard Worker mState.clear(); 259*ec779b8eSAndroid Build Coastguard Worker mCblk->~audio_track_cblk_t(); // destroy our shared-structure. 260*ec779b8eSAndroid Build Coastguard Worker if (mClient == 0) { 261*ec779b8eSAndroid Build Coastguard Worker free(mCblk); 262*ec779b8eSAndroid Build Coastguard Worker } 263*ec779b8eSAndroid Build Coastguard Worker mCblk = nullptr; 264*ec779b8eSAndroid Build Coastguard Worker } 265*ec779b8eSAndroid Build Coastguard Worker } 266*ec779b8eSAndroid Build Coastguard Worker 267*ec779b8eSAndroid Build Coastguard Worker // AudioBufferProvider interface 268*ec779b8eSAndroid Build Coastguard Worker // status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) override; 269*ec779b8eSAndroid Build Coastguard Worker void releaseBuffer(AudioBufferProvider::Buffer* buffer) override; 270*ec779b8eSAndroid Build Coastguard Worker 271*ec779b8eSAndroid Build Coastguard Worker // ExtendedAudioBufferProvider interface is only needed for Track, 272*ec779b8eSAndroid Build Coastguard Worker // but putting it in TrackBase avoids the complexity of virtual inheritance framesReady()273*ec779b8eSAndroid Build Coastguard Worker size_t framesReady() const override { return SIZE_MAX; } // MmapTrack doesn't implement. 274*ec779b8eSAndroid Build Coastguard Worker channelCount()275*ec779b8eSAndroid Build Coastguard Worker uint32_t channelCount() const { return mChannelCount; } 276*ec779b8eSAndroid Build Coastguard Worker frameSize()277*ec779b8eSAndroid Build Coastguard Worker size_t frameSize() const final { return mFrameSize; } 278*ec779b8eSAndroid Build Coastguard Worker sampleRate()279*ec779b8eSAndroid Build Coastguard Worker uint32_t sampleRate() const override { return mSampleRate; } 280*ec779b8eSAndroid Build Coastguard Worker isStopped()281*ec779b8eSAndroid Build Coastguard Worker bool isStopped() const final { 282*ec779b8eSAndroid Build Coastguard Worker return (mState == STOPPED || mState == FLUSHED); 283*ec779b8eSAndroid Build Coastguard Worker } 284*ec779b8eSAndroid Build Coastguard Worker 285*ec779b8eSAndroid Build Coastguard Worker // for fast tracks and offloaded tracks only isStopping()286*ec779b8eSAndroid Build Coastguard Worker bool isStopping() const final { 287*ec779b8eSAndroid Build Coastguard Worker return mState == STOPPING_1 || mState == STOPPING_2; 288*ec779b8eSAndroid Build Coastguard Worker } isStopping_1()289*ec779b8eSAndroid Build Coastguard Worker bool isStopping_1() const final { 290*ec779b8eSAndroid Build Coastguard Worker return mState == STOPPING_1; 291*ec779b8eSAndroid Build Coastguard Worker } isStopping_2()292*ec779b8eSAndroid Build Coastguard Worker bool isStopping_2() const final { 293*ec779b8eSAndroid Build Coastguard Worker return mState == STOPPING_2; 294*ec779b8eSAndroid Build Coastguard Worker } 295*ec779b8eSAndroid Build Coastguard Worker 296*ec779b8eSAndroid Build Coastguard Worker // Upper case characters are final states. 297*ec779b8eSAndroid Build Coastguard Worker // Lower case characters are transitory. getTrackStateAsCodedString()298*ec779b8eSAndroid Build Coastguard Worker const char *getTrackStateAsCodedString() const { 299*ec779b8eSAndroid Build Coastguard Worker if (isTerminated()) { 300*ec779b8eSAndroid Build Coastguard Worker return "T "; 301*ec779b8eSAndroid Build Coastguard Worker } 302*ec779b8eSAndroid Build Coastguard Worker switch (mState) { 303*ec779b8eSAndroid Build Coastguard Worker case IDLE: 304*ec779b8eSAndroid Build Coastguard Worker return "I "; 305*ec779b8eSAndroid Build Coastguard Worker case STOPPING_1: // for Fast and Offload 306*ec779b8eSAndroid Build Coastguard Worker return "s1"; 307*ec779b8eSAndroid Build Coastguard Worker case STOPPING_2: // for Fast and Offload 308*ec779b8eSAndroid Build Coastguard Worker return "s2"; 309*ec779b8eSAndroid Build Coastguard Worker case STOPPED: 310*ec779b8eSAndroid Build Coastguard Worker return "S "; 311*ec779b8eSAndroid Build Coastguard Worker case RESUMING: 312*ec779b8eSAndroid Build Coastguard Worker return "r "; 313*ec779b8eSAndroid Build Coastguard Worker case ACTIVE: 314*ec779b8eSAndroid Build Coastguard Worker return "A "; 315*ec779b8eSAndroid Build Coastguard Worker case PAUSING: 316*ec779b8eSAndroid Build Coastguard Worker return "p "; 317*ec779b8eSAndroid Build Coastguard Worker case PAUSED: 318*ec779b8eSAndroid Build Coastguard Worker return "P "; 319*ec779b8eSAndroid Build Coastguard Worker case FLUSHED: 320*ec779b8eSAndroid Build Coastguard Worker return "F "; 321*ec779b8eSAndroid Build Coastguard Worker case STARTING_1: // for RecordTrack 322*ec779b8eSAndroid Build Coastguard Worker return "r1"; 323*ec779b8eSAndroid Build Coastguard Worker case STARTING_2: // for RecordTrack 324*ec779b8eSAndroid Build Coastguard Worker return "r2"; 325*ec779b8eSAndroid Build Coastguard Worker default: 326*ec779b8eSAndroid Build Coastguard Worker return "? "; 327*ec779b8eSAndroid Build Coastguard Worker } 328*ec779b8eSAndroid Build Coastguard Worker } 329*ec779b8eSAndroid Build Coastguard Worker isOut()330*ec779b8eSAndroid Build Coastguard Worker bool isOut() const { return mIsOut; } 331*ec779b8eSAndroid Build Coastguard Worker // true for Track, false for RecordTrack, 332*ec779b8eSAndroid Build Coastguard Worker // this could be a track type if needed later 333*ec779b8eSAndroid Build Coastguard Worker 334*ec779b8eSAndroid Build Coastguard Worker void deferRestartIfDisabled(); restartIfDisabled()335*ec779b8eSAndroid Build Coastguard Worker virtual void restartIfDisabled() {} 336*ec779b8eSAndroid Build Coastguard Worker 337*ec779b8eSAndroid Build Coastguard Worker virtual std::string trackFlagsAsString() const = 0; 338*ec779b8eSAndroid Build Coastguard Worker 339*ec779b8eSAndroid Build Coastguard Worker audio_utils::trace::Object createDeviceIntervalTrace(const std::string& devices); 340*ec779b8eSAndroid Build Coastguard Worker 341*ec779b8eSAndroid Build Coastguard Worker const wp<IAfThreadBase> mThread; 342*ec779b8eSAndroid Build Coastguard Worker const alloc_type mAllocType; 343*ec779b8eSAndroid Build Coastguard Worker /*const*/ sp<Client> mClient; // see explanation at ~TrackBase() why not const 344*ec779b8eSAndroid Build Coastguard Worker sp<IMemory> mCblkMemory; 345*ec779b8eSAndroid Build Coastguard Worker audio_track_cblk_t* mCblk; 346*ec779b8eSAndroid Build Coastguard Worker sp<IMemory> mBufferMemory; // currently non-0 for fast RecordTrack only 347*ec779b8eSAndroid Build Coastguard Worker void* mBuffer; // start of track buffer, typically in shared memory 348*ec779b8eSAndroid Build Coastguard Worker // except for OutputTrack when it is in local memory 349*ec779b8eSAndroid Build Coastguard Worker size_t mBufferSize; // size of mBuffer in bytes 350*ec779b8eSAndroid Build Coastguard Worker // we don't really need a lock for these 351*ec779b8eSAndroid Build Coastguard Worker MirroredVariable<track_state> mState; 352*ec779b8eSAndroid Build Coastguard Worker audio_attributes_t mAttr; 353*ec779b8eSAndroid Build Coastguard Worker const uint32_t mSampleRate; // initial sample rate only; for tracks which 354*ec779b8eSAndroid Build Coastguard Worker // support dynamic rates, the current value is in control block 355*ec779b8eSAndroid Build Coastguard Worker const audio_format_t mFormat; 356*ec779b8eSAndroid Build Coastguard Worker const audio_channel_mask_t mChannelMask; 357*ec779b8eSAndroid Build Coastguard Worker const uint32_t mChannelCount; 358*ec779b8eSAndroid Build Coastguard Worker const size_t mFrameSize; // AudioFlinger's view of frame size in shared memory, 359*ec779b8eSAndroid Build Coastguard Worker // where for AudioTrack (but not AudioRecord), 360*ec779b8eSAndroid Build Coastguard Worker // 8-bit PCM samples are stored as 16-bit 361*ec779b8eSAndroid Build Coastguard Worker const size_t mFrameCount;// size of track buffer given at createTrack() or 362*ec779b8eSAndroid Build Coastguard Worker // createRecord(), and then adjusted as needed 363*ec779b8eSAndroid Build Coastguard Worker 364*ec779b8eSAndroid Build Coastguard Worker const audio_session_t mSessionId; 365*ec779b8eSAndroid Build Coastguard Worker uid_t mUid; 366*ec779b8eSAndroid Build Coastguard Worker std::list<sp<audioflinger::SyncEvent>> mSyncEvents; 367*ec779b8eSAndroid Build Coastguard Worker const bool mIsOut; 368*ec779b8eSAndroid Build Coastguard Worker sp<ServerProxy> mServerProxy; 369*ec779b8eSAndroid Build Coastguard Worker const int mId; 370*ec779b8eSAndroid Build Coastguard Worker #ifdef TEE_SINK 371*ec779b8eSAndroid Build Coastguard Worker NBAIO_Tee mTee; 372*ec779b8eSAndroid Build Coastguard Worker #endif 373*ec779b8eSAndroid Build Coastguard Worker bool mTerminated; 374*ec779b8eSAndroid Build Coastguard Worker track_type mType; // must be one of TYPE_DEFAULT, TYPE_OUTPUT, TYPE_PATCH ... 375*ec779b8eSAndroid Build Coastguard Worker audio_io_handle_t mThreadIoHandle; // I/O handle of the thread the track is attached to 376*ec779b8eSAndroid Build Coastguard Worker audio_port_handle_t mPortId; // unique ID for this track used by audio policy 377*ec779b8eSAndroid Build Coastguard Worker bool mIsInvalid; // non-resettable latch, set by invalidate() 378*ec779b8eSAndroid Build Coastguard Worker 379*ec779b8eSAndroid Build Coastguard Worker // It typically takes 5 threadloop mix iterations for latency to stabilize. 380*ec779b8eSAndroid Build Coastguard Worker // However, this can be 12+ iterations for BT. 381*ec779b8eSAndroid Build Coastguard Worker // To be sure, we wait for latency to dip (it usually increases at the start) 382*ec779b8eSAndroid Build Coastguard Worker // to assess stability and then log to MediaMetrics. 383*ec779b8eSAndroid Build Coastguard Worker // Rapid start / pause calls may cause inaccurate numbers. 384*ec779b8eSAndroid Build Coastguard Worker static inline constexpr int32_t LOG_START_COUNTDOWN = 12; 385*ec779b8eSAndroid Build Coastguard Worker int32_t mLogStartCountdown = 0; // Mixer period countdown 386*ec779b8eSAndroid Build Coastguard Worker int64_t mLogStartTimeNs = 0; // Monotonic time at start() 387*ec779b8eSAndroid Build Coastguard Worker int64_t mLogStartFrames = 0; // Timestamp frames at start() 388*ec779b8eSAndroid Build Coastguard Worker double mLogLatencyMs = 0.; // Track the last log latency 389*ec779b8eSAndroid Build Coastguard Worker 390*ec779b8eSAndroid Build Coastguard Worker bool mLogForceVolumeUpdate = true; // force volume update to TrackMetrics. 391*ec779b8eSAndroid Build Coastguard Worker 392*ec779b8eSAndroid Build Coastguard Worker audio_utils::trace::Object mLastTrace; // accessed by PlaybackThread or RecordThread 393*ec779b8eSAndroid Build Coastguard Worker TrackMetrics mTrackMetrics; 394*ec779b8eSAndroid Build Coastguard Worker 395*ec779b8eSAndroid Build Coastguard Worker bool mServerLatencySupported = false; 396*ec779b8eSAndroid Build Coastguard Worker std::atomic<bool> mServerLatencyFromTrack{}; // latency from track or server timestamp. 397*ec779b8eSAndroid Build Coastguard Worker std::atomic<double> mServerLatencyMs{}; // last latency pushed from server thread. 398*ec779b8eSAndroid Build Coastguard Worker std::atomic<FrameTime> mKernelFrameTime{}; // last frame time on kernel side. 399*ec779b8eSAndroid Build Coastguard Worker const pid_t mCreatorPid; // can be different from mclient->pid() for instance 400*ec779b8eSAndroid Build Coastguard Worker // when created by NuPlayer on behalf of a client 401*ec779b8eSAndroid Build Coastguard Worker 402*ec779b8eSAndroid Build Coastguard Worker const std::string mTraceSuffix; 403*ec779b8eSAndroid Build Coastguard Worker const std::string mTraceActionId; 404*ec779b8eSAndroid Build Coastguard Worker const std::string mTraceIntervalId; 405*ec779b8eSAndroid Build Coastguard Worker 406*ec779b8eSAndroid Build Coastguard Worker // If the last track change was notified to the client with readAndClearHasChanged 407*ec779b8eSAndroid Build Coastguard Worker std::atomic_flag mChangeNotified = ATOMIC_FLAG_INIT; 408*ec779b8eSAndroid Build Coastguard Worker // RAII object for battery stats book-keeping 409*ec779b8eSAndroid Build Coastguard Worker std::optional<mediautils::BatteryStatsAudioHandle> mBatteryStatsHolder; 410*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<media::psh_utils::Token> mTrackToken; 411*ec779b8eSAndroid Build Coastguard Worker }; 412*ec779b8eSAndroid Build Coastguard Worker 413*ec779b8eSAndroid Build Coastguard Worker class PatchTrackBase : public PatchProxyBufferProvider, public virtual IAfPatchTrackBase 414*ec779b8eSAndroid Build Coastguard Worker { 415*ec779b8eSAndroid Build Coastguard Worker public: 416*ec779b8eSAndroid Build Coastguard Worker PatchTrackBase(const sp<ClientProxy>& proxy, 417*ec779b8eSAndroid Build Coastguard Worker IAfThreadBase* thread, 418*ec779b8eSAndroid Build Coastguard Worker const Timeout& timeout); 419*ec779b8eSAndroid Build Coastguard Worker void setPeerTimeout(std::chrono::nanoseconds timeout) final; setPeerProxy(const sp<IAfPatchTrackBase> & proxy,bool holdReference)420*ec779b8eSAndroid Build Coastguard Worker void setPeerProxy(const sp<IAfPatchTrackBase>& proxy, bool holdReference) final { 421*ec779b8eSAndroid Build Coastguard Worker if (proxy) { 422*ec779b8eSAndroid Build Coastguard Worker mPeerReferenceHold = holdReference ? proxy : nullptr; 423*ec779b8eSAndroid Build Coastguard Worker mPeerProxy = proxy->asPatchProxyBufferProvider(); 424*ec779b8eSAndroid Build Coastguard Worker } else { 425*ec779b8eSAndroid Build Coastguard Worker clearPeerProxy(); 426*ec779b8eSAndroid Build Coastguard Worker } 427*ec779b8eSAndroid Build Coastguard Worker } clearPeerProxy()428*ec779b8eSAndroid Build Coastguard Worker void clearPeerProxy() final { 429*ec779b8eSAndroid Build Coastguard Worker mPeerReferenceHold.clear(); 430*ec779b8eSAndroid Build Coastguard Worker mPeerProxy = nullptr; 431*ec779b8eSAndroid Build Coastguard Worker } 432*ec779b8eSAndroid Build Coastguard Worker asPatchProxyBufferProvider()433*ec779b8eSAndroid Build Coastguard Worker PatchProxyBufferProvider* asPatchProxyBufferProvider() final { return this; } 434*ec779b8eSAndroid Build Coastguard Worker producesBufferOnDemand()435*ec779b8eSAndroid Build Coastguard Worker bool producesBufferOnDemand() const override { return false; } 436*ec779b8eSAndroid Build Coastguard Worker 437*ec779b8eSAndroid Build Coastguard Worker protected: 438*ec779b8eSAndroid Build Coastguard Worker const sp<ClientProxy> mProxy; 439*ec779b8eSAndroid Build Coastguard Worker sp<RefBase> mPeerReferenceHold; // keeps mPeerProxy alive during access. 440*ec779b8eSAndroid Build Coastguard Worker PatchProxyBufferProvider* mPeerProxy = nullptr; 441*ec779b8eSAndroid Build Coastguard Worker struct timespec mPeerTimeout{}; 442*ec779b8eSAndroid Build Coastguard Worker }; 443*ec779b8eSAndroid Build Coastguard Worker 444*ec779b8eSAndroid Build Coastguard Worker } // namespace android 445