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