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