AudioTrackShared.cpp 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254
  1. /*
  2. * Copyright (C) 2007 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #define LOG_TAG "AudioTrackShared"
  17. //#define LOG_NDEBUG 0
  18. #include <android-base/macros.h>
  19. #include <private/media/AudioTrackShared.h>
  20. #include <utils/Log.h>
  21. #include <audio_utils/safe_math.h>
  22. #include <linux/futex.h>
  23. #include <sys/syscall.h>
  24. namespace android {
  25. // used to clamp a value to size_t. TODO: move to another file.
  26. template <typename T>
  27. size_t clampToSize(T x) {
  28. return sizeof(T) > sizeof(size_t) && x > (T) SIZE_MAX ? SIZE_MAX : x < 0 ? 0 : (size_t) x;
  29. }
  30. // incrementSequence is used to determine the next sequence value
  31. // for the loop and position sequence counters. It should return
  32. // a value between "other" + 1 and "other" + INT32_MAX, the choice of
  33. // which needs to be the "least recently used" sequence value for "self".
  34. // In general, this means (new_self) returned is max(self, other) + 1.
  35. __attribute__((no_sanitize("integer")))
  36. static uint32_t incrementSequence(uint32_t self, uint32_t other) {
  37. int32_t diff = (int32_t) self - (int32_t) other;
  38. if (diff >= 0 && diff < INT32_MAX) {
  39. return self + 1; // we're already ahead of other.
  40. }
  41. return other + 1; // we're behind, so move just ahead of other.
  42. }
  43. audio_track_cblk_t::audio_track_cblk_t()
  44. : mServer(0), mFutex(0), mMinimum(0)
  45. , mVolumeLR(GAIN_MINIFLOAT_PACKED_UNITY), mSampleRate(0), mSendLevel(0)
  46. , mBufferSizeInFrames(0)
  47. , mFlags(0)
  48. {
  49. memset(&u, 0, sizeof(u));
  50. }
  51. // ---------------------------------------------------------------------------
  52. Proxy::Proxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize,
  53. bool isOut, bool clientInServer)
  54. : mCblk(cblk), mBuffers(buffers), mFrameCount(frameCount), mFrameSize(frameSize),
  55. mFrameCountP2(roundup(frameCount)), mIsOut(isOut), mClientInServer(clientInServer),
  56. mIsShutdown(false), mUnreleased(0)
  57. {
  58. }
  59. // ---------------------------------------------------------------------------
  60. ClientProxy::ClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
  61. size_t frameSize, bool isOut, bool clientInServer)
  62. : Proxy(cblk, buffers, frameCount, frameSize, isOut, clientInServer)
  63. , mEpoch(0)
  64. , mTimestampObserver(&cblk->mExtendedTimestampQueue)
  65. {
  66. setBufferSizeInFrames(frameCount);
  67. }
  68. const struct timespec ClientProxy::kForever = {INT_MAX /*tv_sec*/, 0 /*tv_nsec*/};
  69. const struct timespec ClientProxy::kNonBlocking = {0 /*tv_sec*/, 0 /*tv_nsec*/};
  70. #define MEASURE_NS 10000000 // attempt to provide accurate timeouts if requested >= MEASURE_NS
  71. // To facilitate quicker recovery from server failure, this value limits the timeout per each futex
  72. // wait. However it does not protect infinite timeouts. If defined to be zero, there is no limit.
  73. // FIXME May not be compatible with audio tunneling requirements where timeout should be in the
  74. // order of minutes.
  75. #define MAX_SEC 5
  76. uint32_t ClientProxy::setBufferSizeInFrames(uint32_t size)
  77. {
  78. // The minimum should be greater than zero and less than the size
  79. // at which underruns will occur.
  80. const uint32_t minimum = 16; // based on AudioMixer::BLOCKSIZE
  81. const uint32_t maximum = frameCount();
  82. uint32_t clippedSize = size;
  83. if (maximum < minimum) {
  84. clippedSize = maximum;
  85. } else if (clippedSize < minimum) {
  86. clippedSize = minimum;
  87. } else if (clippedSize > maximum) {
  88. clippedSize = maximum;
  89. }
  90. // for server to read
  91. android_atomic_release_store(clippedSize, (int32_t *)&mCblk->mBufferSizeInFrames);
  92. // for client to read
  93. mBufferSizeInFrames = clippedSize;
  94. return clippedSize;
  95. }
  96. __attribute__((no_sanitize("integer")))
  97. status_t ClientProxy::obtainBuffer(Buffer* buffer, const struct timespec *requested,
  98. struct timespec *elapsed)
  99. {
  100. LOG_ALWAYS_FATAL_IF(buffer == NULL || buffer->mFrameCount == 0,
  101. "%s: null or zero frame buffer, buffer:%p", __func__, buffer);
  102. struct timespec total; // total elapsed time spent waiting
  103. total.tv_sec = 0;
  104. total.tv_nsec = 0;
  105. bool measure = elapsed != NULL; // whether to measure total elapsed time spent waiting
  106. status_t status;
  107. enum {
  108. TIMEOUT_ZERO, // requested == NULL || *requested == 0
  109. TIMEOUT_INFINITE, // *requested == infinity
  110. TIMEOUT_FINITE, // 0 < *requested < infinity
  111. TIMEOUT_CONTINUE, // additional chances after TIMEOUT_FINITE
  112. } timeout;
  113. if (requested == NULL) {
  114. timeout = TIMEOUT_ZERO;
  115. } else if (requested->tv_sec == 0 && requested->tv_nsec == 0) {
  116. timeout = TIMEOUT_ZERO;
  117. } else if (requested->tv_sec == INT_MAX) {
  118. timeout = TIMEOUT_INFINITE;
  119. } else {
  120. timeout = TIMEOUT_FINITE;
  121. if (requested->tv_sec > 0 || requested->tv_nsec >= MEASURE_NS) {
  122. measure = true;
  123. }
  124. }
  125. struct timespec before;
  126. bool beforeIsValid = false;
  127. audio_track_cblk_t* cblk = mCblk;
  128. bool ignoreInitialPendingInterrupt = true;
  129. // check for shared memory corruption
  130. if (mIsShutdown) {
  131. status = NO_INIT;
  132. goto end;
  133. }
  134. for (;;) {
  135. int32_t flags = android_atomic_and(~CBLK_INTERRUPT, &cblk->mFlags);
  136. // check for track invalidation by server, or server death detection
  137. if (flags & CBLK_INVALID) {
  138. ALOGV("Track invalidated");
  139. status = DEAD_OBJECT;
  140. goto end;
  141. }
  142. if (flags & CBLK_DISABLED) {
  143. ALOGV("Track disabled");
  144. status = NOT_ENOUGH_DATA;
  145. goto end;
  146. }
  147. // check for obtainBuffer interrupted by client
  148. if (!ignoreInitialPendingInterrupt && (flags & CBLK_INTERRUPT)) {
  149. ALOGV("obtainBuffer() interrupted by client");
  150. status = -EINTR;
  151. goto end;
  152. }
  153. ignoreInitialPendingInterrupt = false;
  154. // compute number of frames available to write (AudioTrack) or read (AudioRecord)
  155. int32_t front;
  156. int32_t rear;
  157. if (mIsOut) {
  158. // The barrier following the read of mFront is probably redundant.
  159. // We're about to perform a conditional branch based on 'filled',
  160. // which will force the processor to observe the read of mFront
  161. // prior to allowing data writes starting at mRaw.
  162. // However, the processor may support speculative execution,
  163. // and be unable to undo speculative writes into shared memory.
  164. // The barrier will prevent such speculative execution.
  165. front = android_atomic_acquire_load(&cblk->u.mStreaming.mFront);
  166. rear = cblk->u.mStreaming.mRear;
  167. } else {
  168. // On the other hand, this barrier is required.
  169. rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear);
  170. front = cblk->u.mStreaming.mFront;
  171. }
  172. // write to rear, read from front
  173. ssize_t filled = audio_utils::safe_sub_overflow(rear, front);
  174. // pipe should not be overfull
  175. if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
  176. if (mIsOut) {
  177. ALOGE("Shared memory control block is corrupt (filled=%zd, mFrameCount=%zu); "
  178. "shutting down", filled, mFrameCount);
  179. mIsShutdown = true;
  180. status = NO_INIT;
  181. goto end;
  182. }
  183. // for input, sync up on overrun
  184. filled = 0;
  185. cblk->u.mStreaming.mFront = rear;
  186. (void) android_atomic_or(CBLK_OVERRUN, &cblk->mFlags);
  187. }
  188. // Don't allow filling pipe beyond the user settable size.
  189. // The calculation for avail can go negative if the buffer size
  190. // is suddenly dropped below the amount already in the buffer.
  191. // So use a signed calculation to prevent a numeric overflow abort.
  192. ssize_t adjustableSize = (ssize_t) getBufferSizeInFrames();
  193. ssize_t avail = (mIsOut) ? adjustableSize - filled : filled;
  194. if (avail < 0) {
  195. avail = 0;
  196. } else if (avail > 0) {
  197. // 'avail' may be non-contiguous, so return only the first contiguous chunk
  198. size_t part1;
  199. if (mIsOut) {
  200. rear &= mFrameCountP2 - 1;
  201. part1 = mFrameCountP2 - rear;
  202. } else {
  203. front &= mFrameCountP2 - 1;
  204. part1 = mFrameCountP2 - front;
  205. }
  206. if (part1 > (size_t)avail) {
  207. part1 = avail;
  208. }
  209. if (part1 > buffer->mFrameCount) {
  210. part1 = buffer->mFrameCount;
  211. }
  212. buffer->mFrameCount = part1;
  213. buffer->mRaw = part1 > 0 ?
  214. &((char *) mBuffers)[(mIsOut ? rear : front) * mFrameSize] : NULL;
  215. buffer->mNonContig = avail - part1;
  216. mUnreleased = part1;
  217. status = NO_ERROR;
  218. break;
  219. }
  220. struct timespec remaining;
  221. const struct timespec *ts;
  222. switch (timeout) {
  223. case TIMEOUT_ZERO:
  224. status = WOULD_BLOCK;
  225. goto end;
  226. case TIMEOUT_INFINITE:
  227. ts = NULL;
  228. break;
  229. case TIMEOUT_FINITE:
  230. timeout = TIMEOUT_CONTINUE;
  231. if (MAX_SEC == 0) {
  232. ts = requested;
  233. break;
  234. }
  235. FALLTHROUGH_INTENDED;
  236. case TIMEOUT_CONTINUE:
  237. // FIXME we do not retry if requested < 10ms? needs documentation on this state machine
  238. if (!measure || requested->tv_sec < total.tv_sec ||
  239. (requested->tv_sec == total.tv_sec && requested->tv_nsec <= total.tv_nsec)) {
  240. status = TIMED_OUT;
  241. goto end;
  242. }
  243. remaining.tv_sec = requested->tv_sec - total.tv_sec;
  244. if ((remaining.tv_nsec = requested->tv_nsec - total.tv_nsec) < 0) {
  245. remaining.tv_nsec += 1000000000;
  246. remaining.tv_sec++;
  247. }
  248. if (0 < MAX_SEC && MAX_SEC < remaining.tv_sec) {
  249. remaining.tv_sec = MAX_SEC;
  250. remaining.tv_nsec = 0;
  251. }
  252. ts = &remaining;
  253. break;
  254. default:
  255. LOG_ALWAYS_FATAL("obtainBuffer() timeout=%d", timeout);
  256. ts = NULL;
  257. break;
  258. }
  259. int32_t old = android_atomic_and(~CBLK_FUTEX_WAKE, &cblk->mFutex);
  260. if (!(old & CBLK_FUTEX_WAKE)) {
  261. if (measure && !beforeIsValid) {
  262. clock_gettime(CLOCK_MONOTONIC, &before);
  263. beforeIsValid = true;
  264. }
  265. errno = 0;
  266. (void) syscall(__NR_futex, &cblk->mFutex,
  267. mClientInServer ? FUTEX_WAIT_PRIVATE : FUTEX_WAIT, old & ~CBLK_FUTEX_WAKE, ts);
  268. status_t error = errno; // clock_gettime can affect errno
  269. // update total elapsed time spent waiting
  270. if (measure) {
  271. struct timespec after;
  272. clock_gettime(CLOCK_MONOTONIC, &after);
  273. total.tv_sec += after.tv_sec - before.tv_sec;
  274. // Use auto instead of long to avoid the google-runtime-int warning.
  275. auto deltaNs = after.tv_nsec - before.tv_nsec;
  276. if (deltaNs < 0) {
  277. deltaNs += 1000000000;
  278. total.tv_sec--;
  279. }
  280. if ((total.tv_nsec += deltaNs) >= 1000000000) {
  281. total.tv_nsec -= 1000000000;
  282. total.tv_sec++;
  283. }
  284. before = after;
  285. beforeIsValid = true;
  286. }
  287. switch (error) {
  288. case 0: // normal wakeup by server, or by binderDied()
  289. case EWOULDBLOCK: // benign race condition with server
  290. case EINTR: // wait was interrupted by signal or other spurious wakeup
  291. case ETIMEDOUT: // time-out expired
  292. // FIXME these error/non-0 status are being dropped
  293. break;
  294. default:
  295. status = error;
  296. ALOGE("%s unexpected error %s", __func__, strerror(status));
  297. goto end;
  298. }
  299. }
  300. }
  301. end:
  302. if (status != NO_ERROR) {
  303. buffer->mFrameCount = 0;
  304. buffer->mRaw = NULL;
  305. buffer->mNonContig = 0;
  306. mUnreleased = 0;
  307. }
  308. if (elapsed != NULL) {
  309. *elapsed = total;
  310. }
  311. if (requested == NULL) {
  312. requested = &kNonBlocking;
  313. }
  314. if (measure) {
  315. ALOGV("requested %ld.%03ld elapsed %ld.%03ld",
  316. requested->tv_sec, requested->tv_nsec / 1000000,
  317. total.tv_sec, total.tv_nsec / 1000000);
  318. }
  319. return status;
  320. }
  321. __attribute__((no_sanitize("integer")))
  322. void ClientProxy::releaseBuffer(Buffer* buffer)
  323. {
  324. LOG_ALWAYS_FATAL_IF(buffer == NULL);
  325. size_t stepCount = buffer->mFrameCount;
  326. if (stepCount == 0 || mIsShutdown) {
  327. // prevent accidental re-use of buffer
  328. buffer->mFrameCount = 0;
  329. buffer->mRaw = NULL;
  330. buffer->mNonContig = 0;
  331. return;
  332. }
  333. LOG_ALWAYS_FATAL_IF(!(stepCount <= mUnreleased && mUnreleased <= mFrameCount),
  334. "%s: mUnreleased out of range, "
  335. "!(stepCount:%zu <= mUnreleased:%zu <= mFrameCount:%zu), BufferSizeInFrames:%u",
  336. __func__, stepCount, mUnreleased, mFrameCount, getBufferSizeInFrames());
  337. mUnreleased -= stepCount;
  338. audio_track_cblk_t* cblk = mCblk;
  339. // Both of these barriers are required
  340. if (mIsOut) {
  341. int32_t rear = cblk->u.mStreaming.mRear;
  342. android_atomic_release_store(stepCount + rear, &cblk->u.mStreaming.mRear);
  343. } else {
  344. int32_t front = cblk->u.mStreaming.mFront;
  345. android_atomic_release_store(stepCount + front, &cblk->u.mStreaming.mFront);
  346. }
  347. }
  348. void ClientProxy::binderDied()
  349. {
  350. audio_track_cblk_t* cblk = mCblk;
  351. if (!(android_atomic_or(CBLK_INVALID, &cblk->mFlags) & CBLK_INVALID)) {
  352. android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex);
  353. // it seems that a FUTEX_WAKE_PRIVATE will not wake a FUTEX_WAIT, even within same process
  354. (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,
  355. 1);
  356. }
  357. }
  358. void ClientProxy::interrupt()
  359. {
  360. audio_track_cblk_t* cblk = mCblk;
  361. if (!(android_atomic_or(CBLK_INTERRUPT, &cblk->mFlags) & CBLK_INTERRUPT)) {
  362. android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex);
  363. (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,
  364. 1);
  365. }
  366. }
  367. __attribute__((no_sanitize("integer")))
  368. size_t ClientProxy::getMisalignment()
  369. {
  370. audio_track_cblk_t* cblk = mCblk;
  371. return (mFrameCountP2 - (mIsOut ? cblk->u.mStreaming.mRear : cblk->u.mStreaming.mFront)) &
  372. (mFrameCountP2 - 1);
  373. }
  374. // ---------------------------------------------------------------------------
  375. void AudioTrackClientProxy::flush()
  376. {
  377. sendStreamingFlushStop(true /* flush */);
  378. }
  379. void AudioTrackClientProxy::stop()
  380. {
  381. sendStreamingFlushStop(false /* flush */);
  382. }
  383. // Sets the client-written mFlush and mStop positions, which control server behavior.
  384. //
  385. // @param flush indicates whether the operation is a flush or stop.
  386. // A client stop sets mStop to the current write position;
  387. // the server will not read past this point until start() or subsequent flush().
  388. // A client flush sets both mStop and mFlush to the current write position.
  389. // This advances the server read limit (if previously set) and on the next
  390. // server read advances the server read position to this limit.
  391. //
  392. void AudioTrackClientProxy::sendStreamingFlushStop(bool flush)
  393. {
  394. // TODO: Replace this by 64 bit counters - avoids wrap complication.
  395. // This works for mFrameCountP2 <= 2^30
  396. // mFlush is 32 bits concatenated as [ flush_counter ] [ newfront_offset ]
  397. // Should newFlush = cblk->u.mStreaming.mRear? Only problem is
  398. // if you want to flush twice to the same rear location after a 32 bit wrap.
  399. const size_t increment = mFrameCountP2 << 1;
  400. const size_t mask = increment - 1;
  401. // No need for client atomic synchronization on mRear, mStop, mFlush
  402. // as AudioTrack client only read/writes to them under client lock. Server only reads.
  403. const int32_t rearMasked = mCblk->u.mStreaming.mRear & mask;
  404. // update stop before flush so that the server front
  405. // never advances beyond a (potential) previous stop's rear limit.
  406. int32_t stopBits; // the following add can overflow
  407. __builtin_add_overflow(mCblk->u.mStreaming.mStop & ~mask, increment, &stopBits);
  408. android_atomic_release_store(rearMasked | stopBits, &mCblk->u.mStreaming.mStop);
  409. if (flush) {
  410. int32_t flushBits; // the following add can overflow
  411. __builtin_add_overflow(mCblk->u.mStreaming.mFlush & ~mask, increment, &flushBits);
  412. android_atomic_release_store(rearMasked | flushBits, &mCblk->u.mStreaming.mFlush);
  413. }
  414. }
  415. bool AudioTrackClientProxy::clearStreamEndDone() {
  416. return (android_atomic_and(~CBLK_STREAM_END_DONE, &mCblk->mFlags) & CBLK_STREAM_END_DONE) != 0;
  417. }
  418. bool AudioTrackClientProxy::getStreamEndDone() const {
  419. return (mCblk->mFlags & CBLK_STREAM_END_DONE) != 0;
  420. }
  421. status_t AudioTrackClientProxy::waitStreamEndDone(const struct timespec *requested)
  422. {
  423. struct timespec total; // total elapsed time spent waiting
  424. total.tv_sec = 0;
  425. total.tv_nsec = 0;
  426. audio_track_cblk_t* cblk = mCblk;
  427. status_t status;
  428. enum {
  429. TIMEOUT_ZERO, // requested == NULL || *requested == 0
  430. TIMEOUT_INFINITE, // *requested == infinity
  431. TIMEOUT_FINITE, // 0 < *requested < infinity
  432. TIMEOUT_CONTINUE, // additional chances after TIMEOUT_FINITE
  433. } timeout;
  434. if (requested == NULL) {
  435. timeout = TIMEOUT_ZERO;
  436. } else if (requested->tv_sec == 0 && requested->tv_nsec == 0) {
  437. timeout = TIMEOUT_ZERO;
  438. } else if (requested->tv_sec == INT_MAX) {
  439. timeout = TIMEOUT_INFINITE;
  440. } else {
  441. timeout = TIMEOUT_FINITE;
  442. }
  443. for (;;) {
  444. int32_t flags = android_atomic_and(~(CBLK_INTERRUPT|CBLK_STREAM_END_DONE), &cblk->mFlags);
  445. // check for track invalidation by server, or server death detection
  446. if (flags & CBLK_INVALID) {
  447. ALOGV("Track invalidated");
  448. status = DEAD_OBJECT;
  449. goto end;
  450. }
  451. // a track is not supposed to underrun at this stage but consider it done
  452. if (flags & (CBLK_STREAM_END_DONE | CBLK_DISABLED)) {
  453. ALOGV("stream end received");
  454. status = NO_ERROR;
  455. goto end;
  456. }
  457. // check for obtainBuffer interrupted by client
  458. if (flags & CBLK_INTERRUPT) {
  459. ALOGV("waitStreamEndDone() interrupted by client");
  460. status = -EINTR;
  461. goto end;
  462. }
  463. struct timespec remaining;
  464. const struct timespec *ts;
  465. switch (timeout) {
  466. case TIMEOUT_ZERO:
  467. status = WOULD_BLOCK;
  468. goto end;
  469. case TIMEOUT_INFINITE:
  470. ts = NULL;
  471. break;
  472. case TIMEOUT_FINITE:
  473. timeout = TIMEOUT_CONTINUE;
  474. if (MAX_SEC == 0) {
  475. ts = requested;
  476. break;
  477. }
  478. FALLTHROUGH_INTENDED;
  479. case TIMEOUT_CONTINUE:
  480. // FIXME we do not retry if requested < 10ms? needs documentation on this state machine
  481. if (requested->tv_sec < total.tv_sec ||
  482. (requested->tv_sec == total.tv_sec && requested->tv_nsec <= total.tv_nsec)) {
  483. status = TIMED_OUT;
  484. goto end;
  485. }
  486. remaining.tv_sec = requested->tv_sec - total.tv_sec;
  487. if ((remaining.tv_nsec = requested->tv_nsec - total.tv_nsec) < 0) {
  488. remaining.tv_nsec += 1000000000;
  489. remaining.tv_sec++;
  490. }
  491. if (0 < MAX_SEC && MAX_SEC < remaining.tv_sec) {
  492. remaining.tv_sec = MAX_SEC;
  493. remaining.tv_nsec = 0;
  494. }
  495. ts = &remaining;
  496. break;
  497. default:
  498. LOG_ALWAYS_FATAL("waitStreamEndDone() timeout=%d", timeout);
  499. ts = NULL;
  500. break;
  501. }
  502. int32_t old = android_atomic_and(~CBLK_FUTEX_WAKE, &cblk->mFutex);
  503. if (!(old & CBLK_FUTEX_WAKE)) {
  504. errno = 0;
  505. (void) syscall(__NR_futex, &cblk->mFutex,
  506. mClientInServer ? FUTEX_WAIT_PRIVATE : FUTEX_WAIT, old & ~CBLK_FUTEX_WAKE, ts);
  507. switch (errno) {
  508. case 0: // normal wakeup by server, or by binderDied()
  509. case EWOULDBLOCK: // benign race condition with server
  510. case EINTR: // wait was interrupted by signal or other spurious wakeup
  511. case ETIMEDOUT: // time-out expired
  512. break;
  513. default:
  514. status = errno;
  515. ALOGE("%s unexpected error %s", __func__, strerror(status));
  516. goto end;
  517. }
  518. }
  519. }
  520. end:
  521. if (requested == NULL) {
  522. requested = &kNonBlocking;
  523. }
  524. return status;
  525. }
  526. // ---------------------------------------------------------------------------
  527. StaticAudioTrackClientProxy::StaticAudioTrackClientProxy(audio_track_cblk_t* cblk, void *buffers,
  528. size_t frameCount, size_t frameSize)
  529. : AudioTrackClientProxy(cblk, buffers, frameCount, frameSize),
  530. mMutator(&cblk->u.mStatic.mSingleStateQueue),
  531. mPosLoopObserver(&cblk->u.mStatic.mPosLoopQueue)
  532. {
  533. memset(&mState, 0, sizeof(mState));
  534. memset(&mPosLoop, 0, sizeof(mPosLoop));
  535. }
  536. void StaticAudioTrackClientProxy::flush()
  537. {
  538. LOG_ALWAYS_FATAL("static flush");
  539. }
  540. void StaticAudioTrackClientProxy::stop()
  541. {
  542. ; // no special handling required for static tracks.
  543. }
  544. void StaticAudioTrackClientProxy::setLoop(size_t loopStart, size_t loopEnd, int loopCount)
  545. {
  546. // This can only happen on a 64-bit client
  547. if (loopStart > UINT32_MAX || loopEnd > UINT32_MAX) {
  548. // FIXME Should return an error status
  549. return;
  550. }
  551. mState.mLoopStart = (uint32_t) loopStart;
  552. mState.mLoopEnd = (uint32_t) loopEnd;
  553. mState.mLoopCount = loopCount;
  554. mState.mLoopSequence = incrementSequence(mState.mLoopSequence, mState.mPositionSequence);
  555. // set patch-up variables until the mState is acknowledged by the ServerProxy.
  556. // observed buffer position and loop count will freeze until then to give the
  557. // illusion of a synchronous change.
  558. getBufferPositionAndLoopCount(NULL, NULL);
  559. // preserve behavior to restart at mState.mLoopStart if position exceeds mState.mLoopEnd.
  560. if (mState.mLoopCount != 0 && mPosLoop.mBufferPosition >= mState.mLoopEnd) {
  561. mPosLoop.mBufferPosition = mState.mLoopStart;
  562. }
  563. mPosLoop.mLoopCount = mState.mLoopCount;
  564. (void) mMutator.push(mState);
  565. }
  566. void StaticAudioTrackClientProxy::setBufferPosition(size_t position)
  567. {
  568. // This can only happen on a 64-bit client
  569. if (position > UINT32_MAX) {
  570. // FIXME Should return an error status
  571. return;
  572. }
  573. mState.mPosition = (uint32_t) position;
  574. mState.mPositionSequence = incrementSequence(mState.mPositionSequence, mState.mLoopSequence);
  575. // set patch-up variables until the mState is acknowledged by the ServerProxy.
  576. // observed buffer position and loop count will freeze until then to give the
  577. // illusion of a synchronous change.
  578. if (mState.mLoopCount > 0) { // only check if loop count is changing
  579. getBufferPositionAndLoopCount(NULL, NULL); // get last position
  580. }
  581. mPosLoop.mBufferPosition = position;
  582. if (position >= mState.mLoopEnd) {
  583. // no ongoing loop is possible if position is greater than loopEnd.
  584. mPosLoop.mLoopCount = 0;
  585. }
  586. (void) mMutator.push(mState);
  587. }
  588. void StaticAudioTrackClientProxy::setBufferPositionAndLoop(size_t position, size_t loopStart,
  589. size_t loopEnd, int loopCount)
  590. {
  591. setLoop(loopStart, loopEnd, loopCount);
  592. setBufferPosition(position);
  593. }
  594. size_t StaticAudioTrackClientProxy::getBufferPosition()
  595. {
  596. getBufferPositionAndLoopCount(NULL, NULL);
  597. return mPosLoop.mBufferPosition;
  598. }
  599. void StaticAudioTrackClientProxy::getBufferPositionAndLoopCount(
  600. size_t *position, int *loopCount)
  601. {
  602. if (mMutator.ack() == StaticAudioTrackSingleStateQueue::SSQ_DONE) {
  603. if (mPosLoopObserver.poll(mPosLoop)) {
  604. ; // a valid mPosLoop should be available if ackDone is true.
  605. }
  606. }
  607. if (position != NULL) {
  608. *position = mPosLoop.mBufferPosition;
  609. }
  610. if (loopCount != NULL) {
  611. *loopCount = mPosLoop.mLoopCount;
  612. }
  613. }
  614. // ---------------------------------------------------------------------------
  615. ServerProxy::ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
  616. size_t frameSize, bool isOut, bool clientInServer)
  617. : Proxy(cblk, buffers, frameCount, frameSize, isOut, clientInServer),
  618. mAvailToClient(0), mFlush(0), mReleased(0), mFlushed(0)
  619. , mTimestampMutator(&cblk->mExtendedTimestampQueue)
  620. {
  621. cblk->mBufferSizeInFrames = frameCount;
  622. }
  623. __attribute__((no_sanitize("integer")))
  624. void ServerProxy::flushBufferIfNeeded()
  625. {
  626. audio_track_cblk_t* cblk = mCblk;
  627. // The acquire_load is not really required. But since the write is a release_store in the
  628. // client, using acquire_load here makes it easier for people to maintain the code,
  629. // and the logic for communicating ipc variables seems somewhat standard,
  630. // and there really isn't much penalty for 4 or 8 byte atomics.
  631. int32_t flush = android_atomic_acquire_load(&cblk->u.mStreaming.mFlush);
  632. if (flush != mFlush) {
  633. ALOGV("ServerProxy::flushBufferIfNeeded() mStreaming.mFlush = 0x%x, mFlush = 0x%0x",
  634. flush, mFlush);
  635. // shouldn't matter, but for range safety use mRear instead of getRear().
  636. int32_t rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear);
  637. int32_t front = cblk->u.mStreaming.mFront;
  638. // effectively obtain then release whatever is in the buffer
  639. const size_t overflowBit = mFrameCountP2 << 1;
  640. const size_t mask = overflowBit - 1;
  641. int32_t newFront = (front & ~mask) | (flush & mask);
  642. ssize_t filled = audio_utils::safe_sub_overflow(rear, newFront);
  643. if (filled >= (ssize_t)overflowBit) {
  644. // front and rear offsets span the overflow bit of the p2 mask
  645. // so rebasing newFront on the front offset is off by the overflow bit.
  646. // adjust newFront to match rear offset.
  647. ALOGV("flush wrap: filled %zx >= overflowBit %zx", filled, overflowBit);
  648. newFront += overflowBit;
  649. filled -= overflowBit;
  650. }
  651. // Rather than shutting down on a corrupt flush, just treat it as a full flush
  652. if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
  653. ALOGE("mFlush %#x -> %#x, front %#x, rear %#x, mask %#x, newFront %#x, "
  654. "filled %zd=%#x",
  655. mFlush, flush, front, rear,
  656. (unsigned)mask, newFront, filled, (unsigned)filled);
  657. newFront = rear;
  658. }
  659. mFlush = flush;
  660. android_atomic_release_store(newFront, &cblk->u.mStreaming.mFront);
  661. // There is no danger from a false positive, so err on the side of caution
  662. if (true /*front != newFront*/) {
  663. int32_t old = android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex);
  664. if (!(old & CBLK_FUTEX_WAKE)) {
  665. (void) syscall(__NR_futex, &cblk->mFutex,
  666. mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, 1);
  667. }
  668. }
  669. mFlushed += (newFront - front) & mask;
  670. }
  671. }
  672. __attribute__((no_sanitize("integer")))
  673. int32_t AudioTrackServerProxy::getRear() const
  674. {
  675. const int32_t stop = android_atomic_acquire_load(&mCblk->u.mStreaming.mStop);
  676. const int32_t rear = android_atomic_acquire_load(&mCblk->u.mStreaming.mRear);
  677. const int32_t stopLast = mStopLast.load(std::memory_order_acquire);
  678. if (stop != stopLast) {
  679. const int32_t front = mCblk->u.mStreaming.mFront;
  680. const size_t overflowBit = mFrameCountP2 << 1;
  681. const size_t mask = overflowBit - 1;
  682. int32_t newRear = (rear & ~mask) | (stop & mask);
  683. ssize_t filled = audio_utils::safe_sub_overflow(newRear, front);
  684. // overflowBit is unsigned, so cast to signed for comparison.
  685. if (filled >= (ssize_t)overflowBit) {
  686. // front and rear offsets span the overflow bit of the p2 mask
  687. // so rebasing newRear on the rear offset is off by the overflow bit.
  688. ALOGV("stop wrap: filled %zx >= overflowBit %zx", filled, overflowBit);
  689. newRear -= overflowBit;
  690. filled -= overflowBit;
  691. }
  692. if (0 <= filled && (size_t) filled <= mFrameCount) {
  693. // we're stopped, return the stop level as newRear
  694. return newRear;
  695. }
  696. // A corrupt stop. Log error and ignore.
  697. ALOGE("mStopLast %#x -> stop %#x, front %#x, rear %#x, mask %#x, newRear %#x, "
  698. "filled %zd=%#x",
  699. stopLast, stop, front, rear,
  700. (unsigned)mask, newRear, filled, (unsigned)filled);
  701. // Don't reset mStopLast as this is const.
  702. }
  703. return rear;
  704. }
  705. void AudioTrackServerProxy::start()
  706. {
  707. mStopLast = android_atomic_acquire_load(&mCblk->u.mStreaming.mStop);
  708. }
  709. __attribute__((no_sanitize("integer")))
  710. status_t ServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush)
  711. {
  712. LOG_ALWAYS_FATAL_IF(buffer == NULL || buffer->mFrameCount == 0,
  713. "%s: null or zero frame buffer, buffer:%p", __func__, buffer);
  714. if (mIsShutdown) {
  715. goto no_init;
  716. }
  717. {
  718. audio_track_cblk_t* cblk = mCblk;
  719. // compute number of frames available to write (AudioTrack) or read (AudioRecord),
  720. // or use previous cached value from framesReady(), with added barrier if it omits.
  721. int32_t front;
  722. int32_t rear;
  723. // See notes on barriers at ClientProxy::obtainBuffer()
  724. if (mIsOut) {
  725. flushBufferIfNeeded(); // might modify mFront
  726. rear = getRear();
  727. front = cblk->u.mStreaming.mFront;
  728. } else {
  729. front = android_atomic_acquire_load(&cblk->u.mStreaming.mFront);
  730. rear = cblk->u.mStreaming.mRear;
  731. }
  732. ssize_t filled = audio_utils::safe_sub_overflow(rear, front);
  733. // pipe should not already be overfull
  734. if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
  735. ALOGE("Shared memory control block is corrupt (filled=%zd, mFrameCount=%zu); shutting down",
  736. filled, mFrameCount);
  737. mIsShutdown = true;
  738. }
  739. if (mIsShutdown) {
  740. goto no_init;
  741. }
  742. // don't allow filling pipe beyond the nominal size
  743. size_t availToServer;
  744. if (mIsOut) {
  745. availToServer = filled;
  746. mAvailToClient = mFrameCount - filled;
  747. } else {
  748. availToServer = mFrameCount - filled;
  749. mAvailToClient = filled;
  750. }
  751. // 'availToServer' may be non-contiguous, so return only the first contiguous chunk
  752. size_t part1;
  753. if (mIsOut) {
  754. front &= mFrameCountP2 - 1;
  755. part1 = mFrameCountP2 - front;
  756. } else {
  757. rear &= mFrameCountP2 - 1;
  758. part1 = mFrameCountP2 - rear;
  759. }
  760. if (part1 > availToServer) {
  761. part1 = availToServer;
  762. }
  763. size_t ask = buffer->mFrameCount;
  764. if (part1 > ask) {
  765. part1 = ask;
  766. }
  767. // is assignment redundant in some cases?
  768. buffer->mFrameCount = part1;
  769. buffer->mRaw = part1 > 0 ?
  770. &((char *) mBuffers)[(mIsOut ? front : rear) * mFrameSize] : NULL;
  771. buffer->mNonContig = availToServer - part1;
  772. // After flush(), allow releaseBuffer() on a previously obtained buffer;
  773. // see "Acknowledge any pending flush()" in audioflinger/Tracks.cpp.
  774. if (!ackFlush) {
  775. mUnreleased = part1;
  776. }
  777. return part1 > 0 ? NO_ERROR : WOULD_BLOCK;
  778. }
  779. no_init:
  780. buffer->mFrameCount = 0;
  781. buffer->mRaw = NULL;
  782. buffer->mNonContig = 0;
  783. mUnreleased = 0;
  784. return NO_INIT;
  785. }
  786. __attribute__((no_sanitize("integer")))
  787. void ServerProxy::releaseBuffer(Buffer* buffer)
  788. {
  789. LOG_ALWAYS_FATAL_IF(buffer == NULL);
  790. size_t stepCount = buffer->mFrameCount;
  791. if (stepCount == 0 || mIsShutdown) {
  792. // prevent accidental re-use of buffer
  793. buffer->mFrameCount = 0;
  794. buffer->mRaw = NULL;
  795. buffer->mNonContig = 0;
  796. return;
  797. }
  798. LOG_ALWAYS_FATAL_IF(!(stepCount <= mUnreleased && mUnreleased <= mFrameCount),
  799. "%s: mUnreleased out of range, "
  800. "!(stepCount:%zu <= mUnreleased:%zu <= mFrameCount:%zu)",
  801. __func__, stepCount, mUnreleased, mFrameCount);
  802. mUnreleased -= stepCount;
  803. audio_track_cblk_t* cblk = mCblk;
  804. if (mIsOut) {
  805. int32_t front = cblk->u.mStreaming.mFront;
  806. android_atomic_release_store(stepCount + front, &cblk->u.mStreaming.mFront);
  807. } else {
  808. int32_t rear = cblk->u.mStreaming.mRear;
  809. android_atomic_release_store(stepCount + rear, &cblk->u.mStreaming.mRear);
  810. }
  811. cblk->mServer += stepCount;
  812. mReleased += stepCount;
  813. size_t half = mFrameCount / 2;
  814. if (half == 0) {
  815. half = 1;
  816. }
  817. size_t minimum = (size_t) cblk->mMinimum;
  818. if (minimum == 0) {
  819. minimum = mIsOut ? half : 1;
  820. } else if (minimum > half) {
  821. minimum = half;
  822. }
  823. // FIXME AudioRecord wakeup needs to be optimized; it currently wakes up client every time
  824. if (!mIsOut || (mAvailToClient + stepCount >= minimum)) {
  825. ALOGV("mAvailToClient=%zu stepCount=%zu minimum=%zu", mAvailToClient, stepCount, minimum);
  826. int32_t old = android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex);
  827. if (!(old & CBLK_FUTEX_WAKE)) {
  828. (void) syscall(__NR_futex, &cblk->mFutex,
  829. mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, 1);
  830. }
  831. }
  832. buffer->mFrameCount = 0;
  833. buffer->mRaw = NULL;
  834. buffer->mNonContig = 0;
  835. }
  836. // ---------------------------------------------------------------------------
  837. __attribute__((no_sanitize("integer")))
  838. size_t AudioTrackServerProxy::framesReady()
  839. {
  840. LOG_ALWAYS_FATAL_IF(!mIsOut);
  841. if (mIsShutdown) {
  842. return 0;
  843. }
  844. audio_track_cblk_t* cblk = mCblk;
  845. int32_t flush = cblk->u.mStreaming.mFlush;
  846. if (flush != mFlush) {
  847. // FIXME should return an accurate value, but over-estimate is better than under-estimate
  848. return mFrameCount;
  849. }
  850. const int32_t rear = getRear();
  851. ssize_t filled = audio_utils::safe_sub_overflow(rear, cblk->u.mStreaming.mFront);
  852. // pipe should not already be overfull
  853. if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
  854. ALOGE("Shared memory control block is corrupt (filled=%zd, mFrameCount=%zu); shutting down",
  855. filled, mFrameCount);
  856. mIsShutdown = true;
  857. return 0;
  858. }
  859. // cache this value for later use by obtainBuffer(), with added barrier
  860. // and racy if called by normal mixer thread
  861. // ignores flush(), so framesReady() may report a larger mFrameCount than obtainBuffer()
  862. return filled;
  863. }
  864. __attribute__((no_sanitize("integer")))
  865. size_t AudioTrackServerProxy::framesReadySafe() const
  866. {
  867. if (mIsShutdown) {
  868. return 0;
  869. }
  870. const audio_track_cblk_t* cblk = mCblk;
  871. const int32_t flush = android_atomic_acquire_load(&cblk->u.mStreaming.mFlush);
  872. if (flush != mFlush) {
  873. return mFrameCount;
  874. }
  875. const int32_t rear = getRear();
  876. const ssize_t filled = audio_utils::safe_sub_overflow(rear, cblk->u.mStreaming.mFront);
  877. if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
  878. return 0; // error condition, silently return 0.
  879. }
  880. return filled;
  881. }
  882. bool AudioTrackServerProxy::setStreamEndDone() {
  883. audio_track_cblk_t* cblk = mCblk;
  884. bool old =
  885. (android_atomic_or(CBLK_STREAM_END_DONE, &cblk->mFlags) & CBLK_STREAM_END_DONE) != 0;
  886. if (!old) {
  887. (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,
  888. 1);
  889. }
  890. return old;
  891. }
  892. __attribute__((no_sanitize("integer")))
  893. void AudioTrackServerProxy::tallyUnderrunFrames(uint32_t frameCount)
  894. {
  895. audio_track_cblk_t* cblk = mCblk;
  896. if (frameCount > 0) {
  897. cblk->u.mStreaming.mUnderrunFrames += frameCount;
  898. if (!mUnderrunning) { // start of underrun?
  899. mUnderrunCount++;
  900. cblk->u.mStreaming.mUnderrunCount = mUnderrunCount;
  901. mUnderrunning = true;
  902. ALOGV("tallyUnderrunFrames(%3u) at uf = %u, bump mUnderrunCount = %u",
  903. frameCount, cblk->u.mStreaming.mUnderrunFrames, mUnderrunCount);
  904. }
  905. // FIXME also wake futex so that underrun is noticed more quickly
  906. (void) android_atomic_or(CBLK_UNDERRUN, &cblk->mFlags);
  907. } else {
  908. ALOGV_IF(mUnderrunning,
  909. "tallyUnderrunFrames(%3u) at uf = %u, underrun finished",
  910. frameCount, cblk->u.mStreaming.mUnderrunFrames);
  911. mUnderrunning = false; // so we can detect the next edge
  912. }
  913. }
  914. AudioPlaybackRate AudioTrackServerProxy::getPlaybackRate()
  915. { // do not call from multiple threads without holding lock
  916. mPlaybackRateObserver.poll(mPlaybackRate);
  917. return mPlaybackRate;
  918. }
  919. // ---------------------------------------------------------------------------
  920. StaticAudioTrackServerProxy::StaticAudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers,
  921. size_t frameCount, size_t frameSize)
  922. : AudioTrackServerProxy(cblk, buffers, frameCount, frameSize),
  923. mObserver(&cblk->u.mStatic.mSingleStateQueue),
  924. mPosLoopMutator(&cblk->u.mStatic.mPosLoopQueue),
  925. mFramesReadySafe(frameCount), mFramesReady(frameCount),
  926. mFramesReadyIsCalledByMultipleThreads(false)
  927. {
  928. memset(&mState, 0, sizeof(mState));
  929. }
  930. void StaticAudioTrackServerProxy::framesReadyIsCalledByMultipleThreads()
  931. {
  932. mFramesReadyIsCalledByMultipleThreads = true;
  933. }
  934. size_t StaticAudioTrackServerProxy::framesReady()
  935. {
  936. // Can't call pollPosition() from multiple threads.
  937. if (!mFramesReadyIsCalledByMultipleThreads) {
  938. (void) pollPosition();
  939. }
  940. return mFramesReadySafe;
  941. }
  942. size_t StaticAudioTrackServerProxy::framesReadySafe() const
  943. {
  944. return mFramesReadySafe;
  945. }
  946. status_t StaticAudioTrackServerProxy::updateStateWithLoop(
  947. StaticAudioTrackState *localState, const StaticAudioTrackState &update) const
  948. {
  949. if (localState->mLoopSequence != update.mLoopSequence) {
  950. bool valid = false;
  951. const size_t loopStart = update.mLoopStart;
  952. const size_t loopEnd = update.mLoopEnd;
  953. size_t position = localState->mPosition;
  954. if (update.mLoopCount == 0) {
  955. valid = true;
  956. } else if (update.mLoopCount >= -1) {
  957. if (loopStart < loopEnd && loopEnd <= mFrameCount &&
  958. loopEnd - loopStart >= MIN_LOOP) {
  959. // If the current position is greater than the end of the loop
  960. // we "wrap" to the loop start. This might cause an audible pop.
  961. if (position >= loopEnd) {
  962. position = loopStart;
  963. }
  964. valid = true;
  965. }
  966. }
  967. if (!valid || position > mFrameCount) {
  968. return NO_INIT;
  969. }
  970. localState->mPosition = position;
  971. localState->mLoopCount = update.mLoopCount;
  972. localState->mLoopEnd = loopEnd;
  973. localState->mLoopStart = loopStart;
  974. localState->mLoopSequence = update.mLoopSequence;
  975. }
  976. return OK;
  977. }
  978. status_t StaticAudioTrackServerProxy::updateStateWithPosition(
  979. StaticAudioTrackState *localState, const StaticAudioTrackState &update) const
  980. {
  981. if (localState->mPositionSequence != update.mPositionSequence) {
  982. if (update.mPosition > mFrameCount) {
  983. return NO_INIT;
  984. } else if (localState->mLoopCount != 0 && update.mPosition >= localState->mLoopEnd) {
  985. localState->mLoopCount = 0; // disable loop count if position is beyond loop end.
  986. }
  987. localState->mPosition = update.mPosition;
  988. localState->mPositionSequence = update.mPositionSequence;
  989. }
  990. return OK;
  991. }
  992. ssize_t StaticAudioTrackServerProxy::pollPosition()
  993. {
  994. StaticAudioTrackState state;
  995. if (mObserver.poll(state)) {
  996. StaticAudioTrackState trystate = mState;
  997. bool result;
  998. const int32_t diffSeq = (int32_t) state.mLoopSequence - (int32_t) state.mPositionSequence;
  999. if (diffSeq < 0) {
  1000. result = updateStateWithLoop(&trystate, state) == OK &&
  1001. updateStateWithPosition(&trystate, state) == OK;
  1002. } else {
  1003. result = updateStateWithPosition(&trystate, state) == OK &&
  1004. updateStateWithLoop(&trystate, state) == OK;
  1005. }
  1006. if (!result) {
  1007. mObserver.done();
  1008. // caution: no update occurs so server state will be inconsistent with client state.
  1009. ALOGE("%s client pushed an invalid state, shutting down", __func__);
  1010. mIsShutdown = true;
  1011. return (ssize_t) NO_INIT;
  1012. }
  1013. mState = trystate;
  1014. if (mState.mLoopCount == -1) {
  1015. mFramesReady = INT64_MAX;
  1016. } else if (mState.mLoopCount == 0) {
  1017. mFramesReady = mFrameCount - mState.mPosition;
  1018. } else if (mState.mLoopCount > 0) {
  1019. // TODO: Later consider fixing overflow, but does not seem needed now
  1020. // as will not overflow if loopStart and loopEnd are Java "ints".
  1021. mFramesReady = int64_t(mState.mLoopCount) * (mState.mLoopEnd - mState.mLoopStart)
  1022. + mFrameCount - mState.mPosition;
  1023. }
  1024. mFramesReadySafe = clampToSize(mFramesReady);
  1025. // This may overflow, but client is not supposed to rely on it
  1026. StaticAudioTrackPosLoop posLoop;
  1027. posLoop.mLoopCount = (int32_t) mState.mLoopCount;
  1028. posLoop.mBufferPosition = (uint32_t) mState.mPosition;
  1029. mPosLoopMutator.push(posLoop);
  1030. mObserver.done(); // safe to read mStatic variables.
  1031. }
  1032. return (ssize_t) mState.mPosition;
  1033. }
  1034. __attribute__((no_sanitize("integer")))
  1035. status_t StaticAudioTrackServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush)
  1036. {
  1037. if (mIsShutdown) {
  1038. buffer->mFrameCount = 0;
  1039. buffer->mRaw = NULL;
  1040. buffer->mNonContig = 0;
  1041. mUnreleased = 0;
  1042. return NO_INIT;
  1043. }
  1044. ssize_t positionOrStatus = pollPosition();
  1045. if (positionOrStatus < 0) {
  1046. buffer->mFrameCount = 0;
  1047. buffer->mRaw = NULL;
  1048. buffer->mNonContig = 0;
  1049. mUnreleased = 0;
  1050. return (status_t) positionOrStatus;
  1051. }
  1052. size_t position = (size_t) positionOrStatus;
  1053. size_t end = mState.mLoopCount != 0 ? mState.mLoopEnd : mFrameCount;
  1054. size_t avail;
  1055. if (position < end) {
  1056. avail = end - position;
  1057. size_t wanted = buffer->mFrameCount;
  1058. if (avail < wanted) {
  1059. buffer->mFrameCount = avail;
  1060. } else {
  1061. avail = wanted;
  1062. }
  1063. buffer->mRaw = &((char *) mBuffers)[position * mFrameSize];
  1064. } else {
  1065. avail = 0;
  1066. buffer->mFrameCount = 0;
  1067. buffer->mRaw = NULL;
  1068. }
  1069. // As mFramesReady is the total remaining frames in the static audio track,
  1070. // it is always larger or equal to avail.
  1071. LOG_ALWAYS_FATAL_IF(mFramesReady < (int64_t) avail,
  1072. "%s: mFramesReady out of range, mFramesReady:%lld < avail:%zu",
  1073. __func__, (long long)mFramesReady, avail);
  1074. buffer->mNonContig = mFramesReady == INT64_MAX ? SIZE_MAX : clampToSize(mFramesReady - avail);
  1075. if (!ackFlush) {
  1076. mUnreleased = avail;
  1077. }
  1078. return NO_ERROR;
  1079. }
  1080. __attribute__((no_sanitize("integer")))
  1081. void StaticAudioTrackServerProxy::releaseBuffer(Buffer* buffer)
  1082. {
  1083. size_t stepCount = buffer->mFrameCount;
  1084. LOG_ALWAYS_FATAL_IF(!((int64_t) stepCount <= mFramesReady),
  1085. "%s: stepCount out of range, "
  1086. "!(stepCount:%zu <= mFramesReady:%lld)",
  1087. __func__, stepCount, (long long)mFramesReady);
  1088. LOG_ALWAYS_FATAL_IF(!(stepCount <= mUnreleased),
  1089. "%s: stepCount out of range, "
  1090. "!(stepCount:%zu <= mUnreleased:%zu)",
  1091. __func__, stepCount, mUnreleased);
  1092. if (stepCount == 0) {
  1093. // prevent accidental re-use of buffer
  1094. buffer->mRaw = NULL;
  1095. buffer->mNonContig = 0;
  1096. return;
  1097. }
  1098. mUnreleased -= stepCount;
  1099. audio_track_cblk_t* cblk = mCblk;
  1100. size_t position = mState.mPosition;
  1101. size_t newPosition = position + stepCount;
  1102. int32_t setFlags = 0;
  1103. if (!(position <= newPosition && newPosition <= mFrameCount)) {
  1104. ALOGW("%s newPosition %zu outside [%zu, %zu]", __func__, newPosition, position,
  1105. mFrameCount);
  1106. newPosition = mFrameCount;
  1107. } else if (mState.mLoopCount != 0 && newPosition == mState.mLoopEnd) {
  1108. newPosition = mState.mLoopStart;
  1109. if (mState.mLoopCount == -1 || --mState.mLoopCount != 0) {
  1110. setFlags = CBLK_LOOP_CYCLE;
  1111. } else {
  1112. setFlags = CBLK_LOOP_FINAL;
  1113. }
  1114. }
  1115. if (newPosition == mFrameCount) {
  1116. setFlags |= CBLK_BUFFER_END;
  1117. }
  1118. mState.mPosition = newPosition;
  1119. if (mFramesReady != INT64_MAX) {
  1120. mFramesReady -= stepCount;
  1121. }
  1122. mFramesReadySafe = clampToSize(mFramesReady);
  1123. cblk->mServer += stepCount;
  1124. mReleased += stepCount;
  1125. // This may overflow, but client is not supposed to rely on it
  1126. StaticAudioTrackPosLoop posLoop;
  1127. posLoop.mBufferPosition = mState.mPosition;
  1128. posLoop.mLoopCount = mState.mLoopCount;
  1129. mPosLoopMutator.push(posLoop);
  1130. if (setFlags != 0) {
  1131. (void) android_atomic_or(setFlags, &cblk->mFlags);
  1132. // this would be a good place to wake a futex
  1133. }
  1134. buffer->mFrameCount = 0;
  1135. buffer->mRaw = NULL;
  1136. buffer->mNonContig = 0;
  1137. }
  1138. void StaticAudioTrackServerProxy::tallyUnderrunFrames(uint32_t frameCount)
  1139. {
  1140. // Unlike AudioTrackServerProxy::tallyUnderrunFrames() used for streaming tracks,
  1141. // we don't have a location to count underrun frames. The underrun frame counter
  1142. // only exists in AudioTrackSharedStreaming. Fortunately, underruns are not
  1143. // possible for static buffer tracks other than at end of buffer, so this is not a loss.
  1144. // FIXME also wake futex so that underrun is noticed more quickly
  1145. if (frameCount > 0) {
  1146. (void) android_atomic_or(CBLK_UNDERRUN, &mCblk->mFlags);
  1147. }
  1148. }
  1149. int32_t StaticAudioTrackServerProxy::getRear() const
  1150. {
  1151. LOG_ALWAYS_FATAL("getRear() not permitted for static tracks");
  1152. return 0;
  1153. }
  1154. __attribute__((no_sanitize("integer")))
  1155. size_t AudioRecordServerProxy::framesReadySafe() const
  1156. {
  1157. if (mIsShutdown) {
  1158. return 0;
  1159. }
  1160. const int32_t front = android_atomic_acquire_load(&mCblk->u.mStreaming.mFront);
  1161. const int32_t rear = mCblk->u.mStreaming.mRear;
  1162. const ssize_t filled = audio_utils::safe_sub_overflow(rear, front);
  1163. if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
  1164. return 0; // error condition, silently return 0.
  1165. }
  1166. return filled;
  1167. }
  1168. // ---------------------------------------------------------------------------
  1169. } // namespace android