Home | History | Annotate | Download | only in libmedia
      1 /*
      2 **
      3 ** Copyright 2008, 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 //#define LOG_NDEBUG 0
     19 #define LOG_TAG "AudioRecord"
     20 
     21 #include <stdint.h>
     22 #include <sys/types.h>
     23 
     24 #include <sched.h>
     25 #include <sys/resource.h>
     26 
     27 #include <private/media/AudioTrackShared.h>
     28 
     29 #include <media/AudioSystem.h>
     30 #include <media/AudioRecord.h>
     31 #include <media/mediarecorder.h>
     32 
     33 #include <binder/IServiceManager.h>
     34 #include <utils/Log.h>
     35 #include <binder/Parcel.h>
     36 #include <binder/IPCThreadState.h>
     37 #include <utils/Timers.h>
     38 #include <utils/Atomic.h>
     39 
     40 #include <system/audio.h>
     41 #include <cutils/bitops.h>
     42 #include <cutils/compiler.h>
     43 
     44 namespace android {
     45 // ---------------------------------------------------------------------------
     46 
     47 // static
     48 status_t AudioRecord::getMinFrameCount(
     49         int* frameCount,
     50         uint32_t sampleRate,
     51         audio_format_t format,
     52         int channelCount)
     53 {
     54     size_t size = 0;
     55     if (AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &size)
     56             != NO_ERROR) {
     57         ALOGE("AudioSystem could not query the input buffer size.");
     58         return NO_INIT;
     59     }
     60 
     61     if (size == 0) {
     62         ALOGE("Unsupported configuration: sampleRate %d, format %d, channelCount %d",
     63             sampleRate, format, channelCount);
     64         return BAD_VALUE;
     65     }
     66 
     67     // We double the size of input buffer for ping pong use of record buffer.
     68     size <<= 1;
     69 
     70     if (audio_is_linear_pcm(format)) {
     71         size /= channelCount * audio_bytes_per_sample(format);
     72     }
     73 
     74     *frameCount = size;
     75     return NO_ERROR;
     76 }
     77 
     78 // ---------------------------------------------------------------------------
     79 
     80 AudioRecord::AudioRecord()
     81     : mStatus(NO_INIT), mSessionId(0),
     82       mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT)
     83 {
     84 }
     85 
     86 AudioRecord::AudioRecord(
     87         audio_source_t inputSource,
     88         uint32_t sampleRate,
     89         audio_format_t format,
     90         uint32_t channelMask,
     91         int frameCount,
     92         record_flags flags,
     93         callback_t cbf,
     94         void* user,
     95         int notificationFrames,
     96         int sessionId)
     97     : mStatus(NO_INIT), mSessionId(0),
     98       mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT)
     99 {
    100     mStatus = set(inputSource, sampleRate, format, channelMask,
    101             frameCount, flags, cbf, user, notificationFrames, sessionId);
    102 }
    103 
    104 AudioRecord::~AudioRecord()
    105 {
    106     if (mStatus == NO_ERROR) {
    107         // Make sure that callback function exits in the case where
    108         // it is looping on buffer empty condition in obtainBuffer().
    109         // Otherwise the callback thread will never exit.
    110         stop();
    111         if (mClientRecordThread != 0) {
    112             mClientRecordThread->requestExitAndWait();
    113             mClientRecordThread.clear();
    114         }
    115         mAudioRecord.clear();
    116         IPCThreadState::self()->flushCommands();
    117         AudioSystem::releaseAudioSessionId(mSessionId);
    118     }
    119 }
    120 
    121 status_t AudioRecord::set(
    122         audio_source_t inputSource,
    123         uint32_t sampleRate,
    124         audio_format_t format,
    125         uint32_t channelMask,
    126         int frameCount,
    127         record_flags flags,
    128         callback_t cbf,
    129         void* user,
    130         int notificationFrames,
    131         bool threadCanCallJava,
    132         int sessionId)
    133 {
    134 
    135     ALOGV("set(): sampleRate %d, channelMask %d, frameCount %d",sampleRate, channelMask, frameCount);
    136 
    137     AutoMutex lock(mLock);
    138 
    139     if (mAudioRecord != 0) {
    140         return INVALID_OPERATION;
    141     }
    142 
    143     if (inputSource == AUDIO_SOURCE_DEFAULT) {
    144         inputSource = AUDIO_SOURCE_MIC;
    145     }
    146 
    147     if (sampleRate == 0) {
    148         sampleRate = DEFAULT_SAMPLE_RATE;
    149     }
    150     // these below should probably come from the audioFlinger too...
    151     if (format == AUDIO_FORMAT_DEFAULT) {
    152         format = AUDIO_FORMAT_PCM_16_BIT;
    153     }
    154     // validate parameters
    155     if (!audio_is_valid_format(format)) {
    156         ALOGE("Invalid format");
    157         return BAD_VALUE;
    158     }
    159 
    160     if (!audio_is_input_channel(channelMask)) {
    161         return BAD_VALUE;
    162     }
    163 
    164     int channelCount = popcount(channelMask);
    165 
    166     if (sessionId == 0 ) {
    167         mSessionId = AudioSystem::newAudioSessionId();
    168     } else {
    169         mSessionId = sessionId;
    170     }
    171     ALOGV("set(): mSessionId %d", mSessionId);
    172 
    173     audio_io_handle_t input = AudioSystem::getInput(inputSource,
    174                                                     sampleRate,
    175                                                     format,
    176                                                     channelMask,
    177                                                     (audio_in_acoustics_t)flags,
    178                                                     mSessionId);
    179     if (input == 0) {
    180         ALOGE("Could not get audio input for record source %d", inputSource);
    181         return BAD_VALUE;
    182     }
    183 
    184     // validate framecount
    185     int minFrameCount = 0;
    186     status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelCount);
    187     if (status != NO_ERROR) {
    188         return status;
    189     }
    190     ALOGV("AudioRecord::set() minFrameCount = %d", minFrameCount);
    191 
    192     if (frameCount == 0) {
    193         frameCount = minFrameCount;
    194     } else if (frameCount < minFrameCount) {
    195         return BAD_VALUE;
    196     }
    197 
    198     if (notificationFrames == 0) {
    199         notificationFrames = frameCount/2;
    200     }
    201 
    202     // create the IAudioRecord
    203     status = openRecord_l(sampleRate, format, channelMask,
    204                         frameCount, input);
    205     if (status != NO_ERROR) {
    206         return status;
    207     }
    208 
    209     if (cbf != NULL) {
    210         mClientRecordThread = new ClientRecordThread(*this, threadCanCallJava);
    211     }
    212 
    213     mStatus = NO_ERROR;
    214 
    215     mFormat = format;
    216     // Update buffer size in case it has been limited by AudioFlinger during track creation
    217     mFrameCount = mCblk->frameCount;
    218     mChannelCount = (uint8_t)channelCount;
    219     mChannelMask = channelMask;
    220     mActive = 0;
    221     mCbf = cbf;
    222     mNotificationFrames = notificationFrames;
    223     mRemainingFrames = notificationFrames;
    224     mUserData = user;
    225     // TODO: add audio hardware input latency here
    226     mLatency = (1000*mFrameCount) / sampleRate;
    227     mMarkerPosition = 0;
    228     mMarkerReached = false;
    229     mNewPosition = 0;
    230     mUpdatePeriod = 0;
    231     mInputSource = inputSource;
    232     mFlags = flags;
    233     mInput = input;
    234     AudioSystem::acquireAudioSessionId(mSessionId);
    235 
    236     return NO_ERROR;
    237 }
    238 
    239 status_t AudioRecord::initCheck() const
    240 {
    241     return mStatus;
    242 }
    243 
    244 // -------------------------------------------------------------------------
    245 
    246 uint32_t AudioRecord::latency() const
    247 {
    248     return mLatency;
    249 }
    250 
    251 audio_format_t AudioRecord::format() const
    252 {
    253     return mFormat;
    254 }
    255 
    256 int AudioRecord::channelCount() const
    257 {
    258     return mChannelCount;
    259 }
    260 
    261 uint32_t AudioRecord::frameCount() const
    262 {
    263     return mFrameCount;
    264 }
    265 
    266 size_t AudioRecord::frameSize() const
    267 {
    268     if (audio_is_linear_pcm(mFormat)) {
    269         return channelCount()*audio_bytes_per_sample(mFormat);
    270     } else {
    271         return sizeof(uint8_t);
    272     }
    273 }
    274 
    275 audio_source_t AudioRecord::inputSource() const
    276 {
    277     return mInputSource;
    278 }
    279 
    280 // -------------------------------------------------------------------------
    281 
    282 status_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession)
    283 {
    284     status_t ret = NO_ERROR;
    285     sp<ClientRecordThread> t = mClientRecordThread;
    286 
    287     ALOGV("start, sync event %d trigger session %d", event, triggerSession);
    288 
    289     if (t != 0) {
    290         if (t->exitPending()) {
    291             if (t->requestExitAndWait() == WOULD_BLOCK) {
    292                 ALOGE("AudioRecord::start called from thread");
    293                 return WOULD_BLOCK;
    294             }
    295         }
    296     }
    297 
    298     AutoMutex lock(mLock);
    299     // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed
    300     // while we are accessing the cblk
    301     sp<IAudioRecord> audioRecord = mAudioRecord;
    302     sp<IMemory> iMem = mCblkMemory;
    303     audio_track_cblk_t* cblk = mCblk;
    304     if (mActive == 0) {
    305         mActive = 1;
    306 
    307         pid_t tid;
    308         if (t != 0) {
    309             mReadyToRun = WOULD_BLOCK;
    310             t->run("AudioRecord", ANDROID_PRIORITY_AUDIO);
    311             tid = t->getTid();  // pid_t is unknown until run()
    312             ALOGV("getTid=%d", tid);
    313             if (tid == -1) {
    314                 tid = 0;
    315             }
    316             // thread blocks in readyToRun()
    317         } else {
    318             tid = 0;    // not gettid()
    319         }
    320 
    321         cblk->lock.lock();
    322         if (!(cblk->flags & CBLK_INVALID_MSK)) {
    323             cblk->lock.unlock();
    324             ALOGV("mAudioRecord->start()");
    325             ret = mAudioRecord->start(event, triggerSession);
    326             cblk->lock.lock();
    327             if (ret == DEAD_OBJECT) {
    328                 android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
    329             }
    330         }
    331         if (cblk->flags & CBLK_INVALID_MSK) {
    332             ret = restoreRecord_l(cblk);
    333         }
    334         cblk->lock.unlock();
    335         if (ret == NO_ERROR) {
    336             mNewPosition = cblk->user + mUpdatePeriod;
    337             cblk->bufferTimeoutMs = (event == AudioSystem::SYNC_EVENT_NONE) ? MAX_RUN_TIMEOUT_MS :
    338                                             AudioSystem::kSyncRecordStartTimeOutMs;
    339             cblk->waitTimeMs = 0;
    340             if (t != 0) {
    341                 // thread unblocks in readyToRun() and returns NO_ERROR
    342                 mReadyToRun = NO_ERROR;
    343                 mCondition.signal();
    344             } else {
    345                 mPreviousPriority = getpriority(PRIO_PROCESS, 0);
    346                 get_sched_policy(0, &mPreviousSchedulingGroup);
    347                 androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO);
    348             }
    349         } else {
    350             mActive = 0;
    351             // thread unblocks in readyToRun() and returns NO_INIT
    352             mReadyToRun = NO_INIT;
    353             mCondition.signal();
    354         }
    355     }
    356 
    357     return ret;
    358 }
    359 
    360 status_t AudioRecord::stop()
    361 {
    362     sp<ClientRecordThread> t = mClientRecordThread;
    363 
    364     ALOGV("stop");
    365 
    366     AutoMutex lock(mLock);
    367     if (mActive == 1) {
    368         mActive = 0;
    369         mCblk->cv.signal();
    370         mAudioRecord->stop();
    371         // the record head position will reset to 0, so if a marker is set, we need
    372         // to activate it again
    373         mMarkerReached = false;
    374         if (t != 0) {
    375             t->requestExit();
    376         } else {
    377             setpriority(PRIO_PROCESS, 0, mPreviousPriority);
    378             set_sched_policy(0, mPreviousSchedulingGroup);
    379         }
    380     }
    381 
    382     return NO_ERROR;
    383 }
    384 
    385 bool AudioRecord::stopped() const
    386 {
    387     return !mActive;
    388 }
    389 
    390 uint32_t AudioRecord::getSampleRate() const
    391 {
    392     AutoMutex lock(mLock);
    393     return mCblk->sampleRate;
    394 }
    395 
    396 status_t AudioRecord::setMarkerPosition(uint32_t marker)
    397 {
    398     if (mCbf == NULL) return INVALID_OPERATION;
    399 
    400     mMarkerPosition = marker;
    401     mMarkerReached = false;
    402 
    403     return NO_ERROR;
    404 }
    405 
    406 status_t AudioRecord::getMarkerPosition(uint32_t *marker) const
    407 {
    408     if (marker == NULL) return BAD_VALUE;
    409 
    410     *marker = mMarkerPosition;
    411 
    412     return NO_ERROR;
    413 }
    414 
    415 status_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod)
    416 {
    417     if (mCbf == NULL) return INVALID_OPERATION;
    418 
    419     uint32_t curPosition;
    420     getPosition(&curPosition);
    421     mNewPosition = curPosition + updatePeriod;
    422     mUpdatePeriod = updatePeriod;
    423 
    424     return NO_ERROR;
    425 }
    426 
    427 status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) const
    428 {
    429     if (updatePeriod == NULL) return BAD_VALUE;
    430 
    431     *updatePeriod = mUpdatePeriod;
    432 
    433     return NO_ERROR;
    434 }
    435 
    436 status_t AudioRecord::getPosition(uint32_t *position) const
    437 {
    438     if (position == NULL) return BAD_VALUE;
    439 
    440     AutoMutex lock(mLock);
    441     *position = mCblk->user;
    442 
    443     return NO_ERROR;
    444 }
    445 
    446 unsigned int AudioRecord::getInputFramesLost() const
    447 {
    448     if (mActive)
    449         return AudioSystem::getInputFramesLost(mInput);
    450     else
    451         return 0;
    452 }
    453 
    454 // -------------------------------------------------------------------------
    455 
    456 // must be called with mLock held
    457 status_t AudioRecord::openRecord_l(
    458         uint32_t sampleRate,
    459         audio_format_t format,
    460         uint32_t channelMask,
    461         int frameCount,
    462         audio_io_handle_t input)
    463 {
    464     status_t status;
    465     const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
    466     if (audioFlinger == 0) {
    467         return NO_INIT;
    468     }
    469 
    470     sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), input,
    471                                                        sampleRate, format,
    472                                                        channelMask,
    473                                                        frameCount,
    474                                                        IAudioFlinger::TRACK_DEFAULT,
    475                                                        &mSessionId,
    476                                                        &status);
    477 
    478     if (record == 0) {
    479         ALOGE("AudioFlinger could not create record track, status: %d", status);
    480         return status;
    481     }
    482     sp<IMemory> cblk = record->getCblk();
    483     if (cblk == 0) {
    484         ALOGE("Could not get control block");
    485         return NO_INIT;
    486     }
    487     mAudioRecord.clear();
    488     mAudioRecord = record;
    489     mCblkMemory.clear();
    490     mCblkMemory = cblk;
    491     mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
    492     mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
    493     android_atomic_and(~CBLK_DIRECTION_MSK, &mCblk->flags);
    494     mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
    495     mCblk->waitTimeMs = 0;
    496     return NO_ERROR;
    497 }
    498 
    499 status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
    500 {
    501     AutoMutex lock(mLock);
    502     int active;
    503     status_t result = NO_ERROR;
    504     audio_track_cblk_t* cblk = mCblk;
    505     uint32_t framesReq = audioBuffer->frameCount;
    506     uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS;
    507 
    508     audioBuffer->frameCount  = 0;
    509     audioBuffer->size        = 0;
    510 
    511     uint32_t framesReady = cblk->framesReady();
    512 
    513     if (framesReady == 0) {
    514         cblk->lock.lock();
    515         goto start_loop_here;
    516         while (framesReady == 0) {
    517             active = mActive;
    518             if (CC_UNLIKELY(!active)) {
    519                 cblk->lock.unlock();
    520                 return NO_MORE_BUFFERS;
    521             }
    522             if (CC_UNLIKELY(!waitCount)) {
    523                 cblk->lock.unlock();
    524                 return WOULD_BLOCK;
    525             }
    526             if (!(cblk->flags & CBLK_INVALID_MSK)) {
    527                 mLock.unlock();
    528                 result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
    529                 cblk->lock.unlock();
    530                 mLock.lock();
    531                 if (mActive == 0) {
    532                     return status_t(STOPPED);
    533                 }
    534                 cblk->lock.lock();
    535             }
    536             if (cblk->flags & CBLK_INVALID_MSK) {
    537                 goto create_new_record;
    538             }
    539             if (CC_UNLIKELY(result != NO_ERROR)) {
    540                 cblk->waitTimeMs += waitTimeMs;
    541                 if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) {
    542                     ALOGW(   "obtainBuffer timed out (is the CPU pegged?) "
    543                             "user=%08x, server=%08x", cblk->user, cblk->server);
    544                     cblk->lock.unlock();
    545                     // callback thread or sync event hasn't changed
    546                     result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0);
    547                     cblk->lock.lock();
    548                     if (result == DEAD_OBJECT) {
    549                         android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
    550 create_new_record:
    551                         result = AudioRecord::restoreRecord_l(cblk);
    552                     }
    553                     if (result != NO_ERROR) {
    554                         ALOGW("obtainBuffer create Track error %d", result);
    555                         cblk->lock.unlock();
    556                         return result;
    557                     }
    558                     cblk->waitTimeMs = 0;
    559                 }
    560                 if (--waitCount == 0) {
    561                     cblk->lock.unlock();
    562                     return TIMED_OUT;
    563                 }
    564             }
    565             // read the server count again
    566         start_loop_here:
    567             framesReady = cblk->framesReady();
    568         }
    569         cblk->lock.unlock();
    570     }
    571 
    572     cblk->waitTimeMs = 0;
    573     // reset time out to running value after obtaining a buffer
    574     cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
    575 
    576     if (framesReq > framesReady) {
    577         framesReq = framesReady;
    578     }
    579 
    580     uint32_t u = cblk->user;
    581     uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
    582 
    583     if (framesReq > bufferEnd - u) {
    584         framesReq = bufferEnd - u;
    585     }
    586 
    587     audioBuffer->flags       = 0;
    588     audioBuffer->channelCount= mChannelCount;
    589     audioBuffer->format      = mFormat;
    590     audioBuffer->frameCount  = framesReq;
    591     audioBuffer->size        = framesReq*cblk->frameSize;
    592     audioBuffer->raw         = (int8_t*)cblk->buffer(u);
    593     active = mActive;
    594     return active ? status_t(NO_ERROR) : status_t(STOPPED);
    595 }
    596 
    597 void AudioRecord::releaseBuffer(Buffer* audioBuffer)
    598 {
    599     AutoMutex lock(mLock);
    600     mCblk->stepUser(audioBuffer->frameCount);
    601 }
    602 
    603 audio_io_handle_t AudioRecord::getInput() const
    604 {
    605     AutoMutex lock(mLock);
    606     return mInput;
    607 }
    608 
    609 // must be called with mLock held
    610 audio_io_handle_t AudioRecord::getInput_l()
    611 {
    612     mInput = AudioSystem::getInput(mInputSource,
    613                                 mCblk->sampleRate,
    614                                 mFormat,
    615                                 mChannelMask,
    616                                 (audio_in_acoustics_t)mFlags,
    617                                 mSessionId);
    618     return mInput;
    619 }
    620 
    621 int AudioRecord::getSessionId() const
    622 {
    623     return mSessionId;
    624 }
    625 
    626 // -------------------------------------------------------------------------
    627 
    628 ssize_t AudioRecord::read(void* buffer, size_t userSize)
    629 {
    630     ssize_t read = 0;
    631     Buffer audioBuffer;
    632     int8_t *dst = static_cast<int8_t*>(buffer);
    633 
    634     if (ssize_t(userSize) < 0) {
    635         // sanity-check. user is most-likely passing an error code.
    636         ALOGE("AudioRecord::read(buffer=%p, size=%u (%d)",
    637                 buffer, userSize, userSize);
    638         return BAD_VALUE;
    639     }
    640 
    641     mLock.lock();
    642     // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed
    643     // while we are accessing the cblk
    644     sp<IAudioRecord> audioRecord = mAudioRecord;
    645     sp<IMemory> iMem = mCblkMemory;
    646     mLock.unlock();
    647 
    648     do {
    649 
    650         audioBuffer.frameCount = userSize/frameSize();
    651 
    652         // By using a wait count corresponding to twice the timeout period in
    653         // obtainBuffer() we give a chance to recover once for a read timeout
    654         // (if media_server crashed for instance) before returning a length of
    655         // 0 bytes read to the client
    656         status_t err = obtainBuffer(&audioBuffer, ((2 * MAX_RUN_TIMEOUT_MS) / WAIT_PERIOD_MS));
    657         if (err < 0) {
    658             // out of buffers, return #bytes written
    659             if (err == status_t(NO_MORE_BUFFERS))
    660                 break;
    661             if (err == status_t(TIMED_OUT))
    662                 err = 0;
    663             return ssize_t(err);
    664         }
    665 
    666         size_t bytesRead = audioBuffer.size;
    667         memcpy(dst, audioBuffer.i8, bytesRead);
    668 
    669         dst += bytesRead;
    670         userSize -= bytesRead;
    671         read += bytesRead;
    672 
    673         releaseBuffer(&audioBuffer);
    674     } while (userSize);
    675 
    676     return read;
    677 }
    678 
    679 // -------------------------------------------------------------------------
    680 
    681 bool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread)
    682 {
    683     Buffer audioBuffer;
    684     uint32_t frames = mRemainingFrames;
    685     size_t readSize;
    686 
    687     mLock.lock();
    688     // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed
    689     // while we are accessing the cblk
    690     sp<IAudioRecord> audioRecord = mAudioRecord;
    691     sp<IMemory> iMem = mCblkMemory;
    692     audio_track_cblk_t* cblk = mCblk;
    693     mLock.unlock();
    694 
    695     // Manage marker callback
    696     if (!mMarkerReached && (mMarkerPosition > 0)) {
    697         if (cblk->user >= mMarkerPosition) {
    698             mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition);
    699             mMarkerReached = true;
    700         }
    701     }
    702 
    703     // Manage new position callback
    704     if (mUpdatePeriod > 0) {
    705         while (cblk->user >= mNewPosition) {
    706             mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition);
    707             mNewPosition += mUpdatePeriod;
    708         }
    709     }
    710 
    711     do {
    712         audioBuffer.frameCount = frames;
    713         // Calling obtainBuffer() with a wait count of 1
    714         // limits wait time to WAIT_PERIOD_MS. This prevents from being
    715         // stuck here not being able to handle timed events (position, markers).
    716         status_t err = obtainBuffer(&audioBuffer, 1);
    717         if (err < NO_ERROR) {
    718             if (err != TIMED_OUT) {
    719                 ALOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up.");
    720                 return false;
    721             }
    722             break;
    723         }
    724         if (err == status_t(STOPPED)) return false;
    725 
    726         size_t reqSize = audioBuffer.size;
    727         mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer);
    728         readSize = audioBuffer.size;
    729 
    730         // Sanity check on returned size
    731         if (ssize_t(readSize) <= 0) {
    732             // The callback is done filling buffers
    733             // Keep this thread going to handle timed events and
    734             // still try to get more data in intervals of WAIT_PERIOD_MS
    735             // but don't just loop and block the CPU, so wait
    736             usleep(WAIT_PERIOD_MS*1000);
    737             break;
    738         }
    739         if (readSize > reqSize) readSize = reqSize;
    740 
    741         audioBuffer.size = readSize;
    742         audioBuffer.frameCount = readSize/frameSize();
    743         frames -= audioBuffer.frameCount;
    744 
    745         releaseBuffer(&audioBuffer);
    746 
    747     } while (frames);
    748 
    749 
    750     // Manage overrun callback
    751     if (mActive && (cblk->framesAvailable() == 0)) {
    752         ALOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags);
    753         if (!(android_atomic_or(CBLK_UNDERRUN_ON, &cblk->flags) & CBLK_UNDERRUN_MSK)) {
    754             mCbf(EVENT_OVERRUN, mUserData, 0);
    755         }
    756     }
    757 
    758     if (frames == 0) {
    759         mRemainingFrames = mNotificationFrames;
    760     } else {
    761         mRemainingFrames = frames;
    762     }
    763     return true;
    764 }
    765 
    766 // must be called with mLock and cblk.lock held. Callers must also hold strong references on
    767 // the IAudioRecord and IMemory in case they are recreated here.
    768 // If the IAudioRecord is successfully restored, the cblk pointer is updated
    769 status_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& cblk)
    770 {
    771     status_t result;
    772 
    773     if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) {
    774         ALOGW("dead IAudioRecord, creating a new one");
    775         // signal old cblk condition so that other threads waiting for available buffers stop
    776         // waiting now
    777         cblk->cv.broadcast();
    778         cblk->lock.unlock();
    779 
    780         // if the new IAudioRecord is created, openRecord_l() will modify the
    781         // following member variables: mAudioRecord, mCblkMemory and mCblk.
    782         // It will also delete the strong references on previous IAudioRecord and IMemory
    783         result = openRecord_l(cblk->sampleRate, mFormat, mChannelMask,
    784                 mFrameCount, getInput_l());
    785         if (result == NO_ERROR) {
    786             // callback thread or sync event hasn't changed
    787             result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0);
    788         }
    789         if (result != NO_ERROR) {
    790             mActive = false;
    791         }
    792 
    793         // signal old cblk condition for other threads waiting for restore completion
    794         android_atomic_or(CBLK_RESTORED_ON, &cblk->flags);
    795         cblk->cv.broadcast();
    796     } else {
    797         if (!(cblk->flags & CBLK_RESTORED_MSK)) {
    798             ALOGW("dead IAudioRecord, waiting for a new one to be created");
    799             mLock.unlock();
    800             result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS));
    801             cblk->lock.unlock();
    802             mLock.lock();
    803         } else {
    804             ALOGW("dead IAudioRecord, already restored");
    805             result = NO_ERROR;
    806             cblk->lock.unlock();
    807         }
    808         if (result != NO_ERROR || mActive == 0) {
    809             result = status_t(STOPPED);
    810         }
    811     }
    812     ALOGV("restoreRecord_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x",
    813         result, mActive, mCblk, cblk, mCblk->flags, cblk->flags);
    814 
    815     if (result == NO_ERROR) {
    816         // from now on we switch to the newly created cblk
    817         cblk = mCblk;
    818     }
    819     cblk->lock.lock();
    820 
    821     ALOGW_IF(result != NO_ERROR, "restoreRecord_l() error %d", result);
    822 
    823     return result;
    824 }
    825 
    826 // =========================================================================
    827 
    828 AudioRecord::ClientRecordThread::ClientRecordThread(AudioRecord& receiver, bool bCanCallJava)
    829     : Thread(bCanCallJava), mReceiver(receiver)
    830 {
    831 }
    832 
    833 bool AudioRecord::ClientRecordThread::threadLoop()
    834 {
    835     return mReceiver.processAudioBuffer(this);
    836 }
    837 
    838 status_t AudioRecord::ClientRecordThread::readyToRun()
    839 {
    840     AutoMutex(mReceiver.mLock);
    841     while (mReceiver.mReadyToRun == WOULD_BLOCK) {
    842         mReceiver.mCondition.wait(mReceiver.mLock);
    843     }
    844     return mReceiver.mReadyToRun;
    845 }
    846 
    847 // -------------------------------------------------------------------------
    848 
    849 }; // namespace android
    850