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