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