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