FastCapture.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*
  2. * Copyright (C) 2014 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 "FastCapture"
  17. //#define LOG_NDEBUG 0
  18. #define ATRACE_TAG ATRACE_TAG_AUDIO
  19. #include "Configuration.h"
  20. #include <audio_utils/format.h>
  21. #include <linux/futex.h>
  22. #include <sys/syscall.h>
  23. #include <media/AudioBufferProvider.h>
  24. #include <utils/Log.h>
  25. #include <utils/Trace.h>
  26. #include "FastCapture.h"
  27. namespace android {
  28. /*static*/ const FastCaptureState FastCapture::sInitial;
  29. FastCapture::FastCapture() : FastThread("cycleC_ms", "loadC_us"),
  30. mInputSource(NULL), mInputSourceGen(0), mPipeSink(NULL), mPipeSinkGen(0),
  31. mReadBuffer(NULL), mReadBufferState(-1), mFormat(Format_Invalid), mSampleRate(0),
  32. // mDummyDumpState
  33. mTotalNativeFramesRead(0)
  34. {
  35. mPrevious = &sInitial;
  36. mCurrent = &sInitial;
  37. mDummyDumpState = &mDummyFastCaptureDumpState;
  38. }
  39. FastCapture::~FastCapture()
  40. {
  41. }
  42. FastCaptureStateQueue* FastCapture::sq()
  43. {
  44. return &mSQ;
  45. }
  46. const FastThreadState *FastCapture::poll()
  47. {
  48. return mSQ.poll();
  49. }
  50. void FastCapture::setNBLogWriter(NBLog::Writer *logWriter __unused)
  51. {
  52. }
  53. void FastCapture::onIdle()
  54. {
  55. mPreIdle = *(const FastCaptureState *)mCurrent;
  56. mCurrent = &mPreIdle;
  57. }
  58. void FastCapture::onExit()
  59. {
  60. free(mReadBuffer);
  61. }
  62. bool FastCapture::isSubClassCommand(FastThreadState::Command command)
  63. {
  64. switch ((FastCaptureState::Command) command) {
  65. case FastCaptureState::READ:
  66. case FastCaptureState::WRITE:
  67. case FastCaptureState::READ_WRITE:
  68. return true;
  69. default:
  70. return false;
  71. }
  72. }
  73. void FastCapture::onStateChange()
  74. {
  75. const FastCaptureState * const current = (const FastCaptureState *) mCurrent;
  76. const FastCaptureState * const previous = (const FastCaptureState *) mPrevious;
  77. FastCaptureDumpState * const dumpState = (FastCaptureDumpState *) mDumpState;
  78. const size_t frameCount = current->mFrameCount;
  79. bool eitherChanged = false;
  80. // check for change in input HAL configuration
  81. NBAIO_Format previousFormat = mFormat;
  82. if (current->mInputSourceGen != mInputSourceGen) {
  83. mInputSource = current->mInputSource;
  84. mInputSourceGen = current->mInputSourceGen;
  85. if (mInputSource == NULL) {
  86. mFormat = Format_Invalid;
  87. mSampleRate = 0;
  88. } else {
  89. mFormat = mInputSource->format();
  90. mSampleRate = Format_sampleRate(mFormat);
  91. #if !LOG_NDEBUG
  92. unsigned channelCount = Format_channelCount(mFormat);
  93. ALOG_ASSERT(channelCount >= 1 && channelCount <= FCC_8);
  94. #endif
  95. }
  96. dumpState->mSampleRate = mSampleRate;
  97. eitherChanged = true;
  98. }
  99. // check for change in pipe
  100. if (current->mPipeSinkGen != mPipeSinkGen) {
  101. mPipeSink = current->mPipeSink;
  102. mPipeSinkGen = current->mPipeSinkGen;
  103. eitherChanged = true;
  104. }
  105. // input source and pipe sink must be compatible
  106. if (eitherChanged && mInputSource != NULL && mPipeSink != NULL) {
  107. ALOG_ASSERT(Format_isEqual(mFormat, mPipeSink->format()));
  108. }
  109. if ((!Format_isEqual(mFormat, previousFormat)) || (frameCount != previous->mFrameCount)) {
  110. // FIXME to avoid priority inversion, don't free here
  111. free(mReadBuffer);
  112. mReadBuffer = NULL;
  113. if (frameCount > 0 && mSampleRate > 0) {
  114. // FIXME new may block for unbounded time at internal mutex of the heap
  115. // implementation; it would be better to have normal capture thread allocate for
  116. // us to avoid blocking here and to prevent possible priority inversion
  117. size_t bufferSize = frameCount * Format_frameSize(mFormat);
  118. (void)posix_memalign(&mReadBuffer, 32, bufferSize);
  119. memset(mReadBuffer, 0, bufferSize); // if posix_memalign fails, will segv here.
  120. mPeriodNs = (frameCount * 1000000000LL) / mSampleRate; // 1.00
  121. mUnderrunNs = (frameCount * 1750000000LL) / mSampleRate; // 1.75
  122. mOverrunNs = (frameCount * 500000000LL) / mSampleRate; // 0.50
  123. mForceNs = (frameCount * 950000000LL) / mSampleRate; // 0.95
  124. mWarmupNsMin = (frameCount * 750000000LL) / mSampleRate; // 0.75
  125. mWarmupNsMax = (frameCount * 1250000000LL) / mSampleRate; // 1.25
  126. } else {
  127. mPeriodNs = 0;
  128. mUnderrunNs = 0;
  129. mOverrunNs = 0;
  130. mForceNs = 0;
  131. mWarmupNsMin = 0;
  132. mWarmupNsMax = LONG_MAX;
  133. }
  134. mReadBufferState = -1;
  135. dumpState->mFrameCount = frameCount;
  136. }
  137. }
  138. void FastCapture::onWork()
  139. {
  140. const FastCaptureState * const current = (const FastCaptureState *) mCurrent;
  141. FastCaptureDumpState * const dumpState = (FastCaptureDumpState *) mDumpState;
  142. const FastCaptureState::Command command = mCommand;
  143. size_t frameCount = current->mFrameCount;
  144. AudioBufferProvider* fastPatchRecordBufferProvider = current->mFastPatchRecordBufferProvider;
  145. AudioBufferProvider::Buffer patchBuffer;
  146. if (fastPatchRecordBufferProvider != 0) {
  147. patchBuffer.frameCount = ~0;
  148. status_t status = fastPatchRecordBufferProvider->getNextBuffer(&patchBuffer);
  149. if (status != NO_ERROR) {
  150. frameCount = 0;
  151. } else if (patchBuffer.frameCount < frameCount) {
  152. // TODO: Make sure that it doesn't cause any issues if we just get a small available
  153. // buffer from the buffer provider.
  154. frameCount = patchBuffer.frameCount;
  155. }
  156. }
  157. if ((command & FastCaptureState::READ) /*&& isWarm*/) {
  158. ALOG_ASSERT(mInputSource != NULL);
  159. ALOG_ASSERT(mReadBuffer != NULL);
  160. dumpState->mReadSequence++;
  161. ATRACE_BEGIN("read");
  162. ssize_t framesRead = mInputSource->read(mReadBuffer, frameCount);
  163. ATRACE_END();
  164. dumpState->mReadSequence++;
  165. if (framesRead >= 0) {
  166. LOG_ALWAYS_FATAL_IF((size_t) framesRead > frameCount);
  167. mTotalNativeFramesRead += framesRead;
  168. dumpState->mFramesRead = mTotalNativeFramesRead;
  169. mReadBufferState = framesRead;
  170. patchBuffer.frameCount = framesRead;
  171. } else {
  172. dumpState->mReadErrors++;
  173. mReadBufferState = 0;
  174. }
  175. // FIXME rename to attemptedIO
  176. mAttemptedWrite = true;
  177. }
  178. if (command & FastCaptureState::WRITE) {
  179. ALOG_ASSERT(mPipeSink != NULL);
  180. ALOG_ASSERT(mReadBuffer != NULL);
  181. if (mReadBufferState < 0) {
  182. memset(mReadBuffer, 0, frameCount * Format_frameSize(mFormat));
  183. mReadBufferState = frameCount;
  184. }
  185. if (mReadBufferState > 0) {
  186. ssize_t framesWritten = mPipeSink->write(mReadBuffer, mReadBufferState);
  187. audio_track_cblk_t* cblk = current->mCblk;
  188. if (fastPatchRecordBufferProvider != 0) {
  189. // This indicates the fast track is a patch record, update the cblk by
  190. // calling releaseBuffer().
  191. memcpy_by_audio_format(patchBuffer.raw, current->mFastPatchRecordFormat,
  192. mReadBuffer, mFormat.mFormat, framesWritten * mFormat.mChannelCount);
  193. patchBuffer.frameCount = framesWritten;
  194. fastPatchRecordBufferProvider->releaseBuffer(&patchBuffer);
  195. } else if (cblk != NULL && framesWritten > 0) {
  196. // FIXME This supports at most one fast capture client.
  197. // To handle multiple clients this could be converted to an array,
  198. // or with a lot more work the control block could be shared by all clients.
  199. int32_t rear = cblk->u.mStreaming.mRear;
  200. android_atomic_release_store(framesWritten + rear, &cblk->u.mStreaming.mRear);
  201. cblk->mServer += framesWritten;
  202. int32_t old = android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex);
  203. if (!(old & CBLK_FUTEX_WAKE)) {
  204. // client is never in server process, so don't use FUTEX_WAKE_PRIVATE
  205. (void) syscall(__NR_futex, &cblk->mFutex, FUTEX_WAKE, 1);
  206. }
  207. }
  208. }
  209. }
  210. }
  211. } // namespace android