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 <datapath/TrackMetrics.h> 26 #include <mediautils/BatteryNotifier.h> 27 28 #include <atomic> // avoid transitive dependency 29 #include <list> // avoid transitive dependency 30 #include <optional> // avoid transitive dependency 31 32 namespace android { 33 34 // base for record and playback 35 class TrackBase : public ExtendedAudioBufferProvider, public virtual IAfTrackBase { 36 public: 37 TrackBase(IAfThreadBase* thread, 38 const sp<Client>& client, 39 const audio_attributes_t& mAttr, 40 uint32_t sampleRate, 41 audio_format_t format, 42 audio_channel_mask_t channelMask, 43 size_t frameCount, 44 void *buffer, 45 size_t bufferSize, 46 audio_session_t sessionId, 47 pid_t creatorPid, 48 uid_t uid, 49 bool isOut, 50 const alloc_type alloc = ALLOC_CBLK, 51 track_type type = TYPE_DEFAULT, 52 audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE, 53 std::string metricsId = {}); 54 ~TrackBase() override; 55 status_t initCheck() const override; getCblk()56 sp<IMemory> getCblk() const final { return mCblkMemory; } cblk()57 audio_track_cblk_t* cblk() const final { return mCblk; } sessionId()58 audio_session_t sessionId() const final { return mSessionId; } uid()59 uid_t uid() const final { return mUid; } creatorPid()60 pid_t creatorPid() const final { return mCreatorPid; } portId()61 audio_port_handle_t portId() const final { return mPortId; } 62 status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) override; state()63 track_state state() const final { return mState; } setState(track_state state)64 void setState(track_state state) final { mState = state; } getBuffers()65 sp<IMemory> getBuffers() const final { return mBufferMemory; } buffer()66 void* buffer() const final { return mBuffer; } bufferSize()67 size_t bufferSize() const final { return mBufferSize; } 68 isOutputTrack()69 bool isOutputTrack() const final { return (mType == TYPE_OUTPUT); } isPatchTrack()70 bool isPatchTrack() const final { return (mType == TYPE_PATCH); } isExternalTrack()71 bool isExternalTrack() const final { return !isOutputTrack() && !isPatchTrack(); } invalidate()72 void invalidate() override { 73 if (mIsInvalid) return; 74 mTrackMetrics.logInvalidate(); 75 mIsInvalid = true; 76 } isInvalid()77 bool isInvalid() const final { return mIsInvalid; } terminate()78 void terminate() final { mTerminated = true; } isTerminated()79 bool isTerminated() const final { return mTerminated; } attributes()80 audio_attributes_t attributes() const final { return mAttr; } isSpatialized()81 bool isSpatialized() const override { return false; } isBitPerfect()82 bool isBitPerfect() const override { return false; } 83 thread()84 wp<IAfThreadBase> thread() const final { return mThread; } 85 serverProxy()86 const sp<ServerProxy>& serverProxy() const final { return mServerProxy; } 87 88 #ifdef TEE_SINK dumpTee(int fd,const std::string & reason)89 void dumpTee(int fd, const std::string &reason) const final { 90 mTee.dump(fd, reason); 91 } 92 #endif 93 /** returns the buffer contents size converted to time in milliseconds 94 * for PCM Playback or Record streaming tracks. The return value is zero for 95 * PCM static tracks and not defined for non-PCM tracks. 96 * 97 * This may be called without the thread lock. 98 */ bufferLatencyMs()99 double bufferLatencyMs() const override { 100 return mServerProxy->framesReadySafe() * 1000. / sampleRate(); 101 } 102 103 /** returns whether the track supports server latency computation. 104 * This is set in the constructor and constant throughout the track lifetime. 105 */ isServerLatencySupported()106 bool isServerLatencySupported() const final { return mServerLatencySupported; } 107 108 /** computes the server latency for PCM Playback or Record track 109 * to the device sink/source. This is the time for the next frame in the track buffer 110 * written or read from the server thread to the device source or sink. 111 * 112 * This may be called without the thread lock, but latencyMs and fromTrack 113 * may be not be synchronized. For example PatchPanel may not obtain the 114 * thread lock before calling. 115 * 116 * \param latencyMs on success is set to the latency in milliseconds of the 117 * next frame written/read by the server thread to/from the track buffer 118 * from the device source/sink. 119 * \param fromTrack on success is set to true if latency was computed directly 120 * from the track timestamp; otherwise set to false if latency was 121 * estimated from the server timestamp. 122 * fromTrack may be nullptr or omitted if not required. 123 * 124 * \returns OK or INVALID_OPERATION on failure. 125 */ 126 status_t getServerLatencyMs(double* latencyMs, bool* fromTrack = nullptr) const final { 127 if (!isServerLatencySupported()) { 128 return INVALID_OPERATION; 129 } 130 131 // if no thread lock is acquired, these atomics are not 132 // synchronized with each other, considered a benign race. 133 134 const double serverLatencyMs = mServerLatencyMs.load(); 135 if (serverLatencyMs == 0.) { 136 return INVALID_OPERATION; 137 } 138 if (fromTrack != nullptr) { 139 *fromTrack = mServerLatencyFromTrack.load(); 140 } 141 *latencyMs = serverLatencyMs; 142 return OK; 143 } 144 145 /** computes the total client latency for PCM Playback or Record tracks 146 * for the next client app access to the device sink/source; i.e. the 147 * server latency plus the buffer latency. 148 * 149 * This may be called without the thread lock, but latencyMs and fromTrack 150 * may be not be synchronized. For example PatchPanel may not obtain the 151 * thread lock before calling. 152 * 153 * \param latencyMs on success is set to the latency in milliseconds of the 154 * next frame written/read by the client app to/from the track buffer 155 * from the device sink/source. 156 * \param fromTrack on success is set to true if latency was computed directly 157 * from the track timestamp; otherwise set to false if latency was 158 * estimated from the server timestamp. 159 * fromTrack may be nullptr or omitted if not required. 160 * 161 * \returns OK or INVALID_OPERATION on failure. 162 */ 163 status_t getTrackLatencyMs(double* latencyMs, bool* fromTrack = nullptr) const { 164 double serverLatencyMs; 165 status_t status = getServerLatencyMs(&serverLatencyMs, fromTrack); 166 if (status == OK) { 167 *latencyMs = serverLatencyMs + bufferLatencyMs(); 168 } 169 return status; 170 } 171 172 // KernelFrameTime is updated per "mix" period even for non-pcm tracks. getKernelFrameTime(FrameTime * ft)173 void getKernelFrameTime(FrameTime* ft) const final { 174 *ft = mKernelFrameTime.load(); 175 } 176 format()177 audio_format_t format() const final { return mFormat; } id()178 int id() const final { return mId; } 179 getTrackStateAsString()180 const char* getTrackStateAsString() const final { 181 if (isTerminated()) { 182 return "TERMINATED"; 183 } 184 switch (mState) { 185 case IDLE: 186 return "IDLE"; 187 case STOPPING_1: // for Fast and Offload 188 return "STOPPING_1"; 189 case STOPPING_2: // for Fast and Offload 190 return "STOPPING_2"; 191 case STOPPED: 192 return "STOPPED"; 193 case RESUMING: 194 return "RESUMING"; 195 case ACTIVE: 196 return "ACTIVE"; 197 case PAUSING: 198 return "PAUSING"; 199 case PAUSED: 200 return "PAUSED"; 201 case FLUSHED: 202 return "FLUSHED"; 203 case STARTING_1: // for RecordTrack 204 return "STARTING_1"; 205 case STARTING_2: // for RecordTrack 206 return "STARTING_2"; 207 default: 208 return "UNKNOWN"; 209 } 210 } 211 212 // Called by the PlaybackThread to indicate that the track is becoming active 213 // and a new interval should start with a given device list. logBeginInterval(const std::string & devices)214 void logBeginInterval(const std::string& devices) final { 215 mTrackMetrics.logBeginInterval(devices); 216 } 217 218 // Called by the PlaybackThread to indicate the track is no longer active. logEndInterval()219 void logEndInterval() final { 220 mTrackMetrics.logEndInterval(); 221 } 222 223 // Called to tally underrun frames in playback. tallyUnderrunFrames(size_t)224 void tallyUnderrunFrames(size_t /* frames */) override {} 225 channelMask()226 audio_channel_mask_t channelMask() const final { return mChannelMask; } 227 228 /** @return true if the track has changed (metadata or volume) since 229 * the last time this function was called, 230 * true if this function was never called since the track creation, 231 * false otherwise. 232 * Thread safe. 233 */ readAndClearHasChanged()234 bool readAndClearHasChanged() final { return !mChangeNotified.test_and_set(); } 235 236 /** Set that a metadata has changed and needs to be notified to backend. Thread safe. */ setMetadataHasChanged()237 void setMetadataHasChanged() final { mChangeNotified.clear(); } 238 239 /** 240 * Called when a track moves to active state to record its contribution to battery usage. 241 * Track state transitions should eventually be handled within the track class. 242 */ beginBatteryAttribution()243 void beginBatteryAttribution() final { 244 mBatteryStatsHolder.emplace(uid()); 245 } 246 247 /** 248 * Called when a track moves out of the active state to record its contribution 249 * to battery usage. 250 */ endBatteryAttribution()251 void endBatteryAttribution() final { 252 mBatteryStatsHolder.reset(); 253 } 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 const wp<IAfThreadBase> mThread; 337 const alloc_type mAllocType; 338 /*const*/ sp<Client> mClient; // see explanation at ~TrackBase() why not const 339 sp<IMemory> mCblkMemory; 340 audio_track_cblk_t* mCblk; 341 sp<IMemory> mBufferMemory; // currently non-0 for fast RecordTrack only 342 void* mBuffer; // start of track buffer, typically in shared memory 343 // except for OutputTrack when it is in local memory 344 size_t mBufferSize; // size of mBuffer in bytes 345 // we don't really need a lock for these 346 MirroredVariable<track_state> mState; 347 const audio_attributes_t mAttr; 348 const uint32_t mSampleRate; // initial sample rate only; for tracks which 349 // support dynamic rates, the current value is in control block 350 const audio_format_t mFormat; 351 const audio_channel_mask_t mChannelMask; 352 const uint32_t mChannelCount; 353 const size_t mFrameSize; // AudioFlinger's view of frame size in shared memory, 354 // where for AudioTrack (but not AudioRecord), 355 // 8-bit PCM samples are stored as 16-bit 356 const size_t mFrameCount;// size of track buffer given at createTrack() or 357 // createRecord(), and then adjusted as needed 358 359 const audio_session_t mSessionId; 360 uid_t mUid; 361 std::list<sp<audioflinger::SyncEvent>> mSyncEvents; 362 const bool mIsOut; 363 sp<ServerProxy> mServerProxy; 364 const int mId; 365 #ifdef TEE_SINK 366 NBAIO_Tee mTee; 367 #endif 368 bool mTerminated; 369 track_type mType; // must be one of TYPE_DEFAULT, TYPE_OUTPUT, TYPE_PATCH ... 370 audio_io_handle_t mThreadIoHandle; // I/O handle of the thread the track is attached to 371 audio_port_handle_t mPortId; // unique ID for this track used by audio policy 372 bool mIsInvalid; // non-resettable latch, set by invalidate() 373 374 // It typically takes 5 threadloop mix iterations for latency to stabilize. 375 // However, this can be 12+ iterations for BT. 376 // To be sure, we wait for latency to dip (it usually increases at the start) 377 // to assess stability and then log to MediaMetrics. 378 // Rapid start / pause calls may cause inaccurate numbers. 379 static inline constexpr int32_t LOG_START_COUNTDOWN = 12; 380 int32_t mLogStartCountdown = 0; // Mixer period countdown 381 int64_t mLogStartTimeNs = 0; // Monotonic time at start() 382 int64_t mLogStartFrames = 0; // Timestamp frames at start() 383 double mLogLatencyMs = 0.; // Track the last log latency 384 385 bool mLogForceVolumeUpdate = true; // force volume update to TrackMetrics. 386 387 TrackMetrics mTrackMetrics; 388 389 bool mServerLatencySupported = false; 390 std::atomic<bool> mServerLatencyFromTrack{}; // latency from track or server timestamp. 391 std::atomic<double> mServerLatencyMs{}; // last latency pushed from server thread. 392 std::atomic<FrameTime> mKernelFrameTime{}; // last frame time on kernel side. 393 const pid_t mCreatorPid; // can be different from mclient->pid() for instance 394 // when created by NuPlayer on behalf of a client 395 396 // If the last track change was notified to the client with readAndClearHasChanged 397 std::atomic_flag mChangeNotified = ATOMIC_FLAG_INIT; 398 // RAII object for battery stats book-keeping 399 std::optional<mediautils::BatteryStatsAudioHandle> mBatteryStatsHolder; 400 }; 401 402 class PatchTrackBase : public PatchProxyBufferProvider, public virtual IAfPatchTrackBase 403 { 404 public: 405 PatchTrackBase(const sp<ClientProxy>& proxy, 406 IAfThreadBase* thread, 407 const Timeout& timeout); 408 void setPeerTimeout(std::chrono::nanoseconds timeout) final; setPeerProxy(const sp<IAfPatchTrackBase> & proxy,bool holdReference)409 void setPeerProxy(const sp<IAfPatchTrackBase>& proxy, bool holdReference) final { 410 if (proxy) { 411 mPeerReferenceHold = holdReference ? proxy : nullptr; 412 mPeerProxy = proxy->asPatchProxyBufferProvider(); 413 } else { 414 clearPeerProxy(); 415 } 416 } clearPeerProxy()417 void clearPeerProxy() final { 418 mPeerReferenceHold.clear(); 419 mPeerProxy = nullptr; 420 } 421 asPatchProxyBufferProvider()422 PatchProxyBufferProvider* asPatchProxyBufferProvider() final { return this; } 423 producesBufferOnDemand()424 bool producesBufferOnDemand() const override { return false; } 425 426 protected: 427 const sp<ClientProxy> mProxy; 428 sp<RefBase> mPeerReferenceHold; // keeps mPeerProxy alive during access. 429 PatchProxyBufferProvider* mPeerProxy = nullptr; 430 struct timespec mPeerTimeout{}; 431 }; 432 433 } // namespace android 434