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