AudioRecord.cpp revision 38e905b3cbba4da443d799b16999989781afc6d8
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 <binder/IPCThreadState.h>
23#include <media/AudioRecord.h>
24#include <utils/Log.h>
25#include <private/media/AudioTrackShared.h>
26#include <media/IAudioFlinger.h>
27
28#define WAIT_PERIOD_MS          10
29
30namespace android {
31// ---------------------------------------------------------------------------
32
33// static
34status_t AudioRecord::getMinFrameCount(
35        size_t* frameCount,
36        uint32_t sampleRate,
37        audio_format_t format,
38        audio_channel_mask_t channelMask)
39{
40    if (frameCount == NULL) {
41        return BAD_VALUE;
42    }
43
44    // default to 0 in case of error
45    *frameCount = 0;
46
47    size_t size = 0;
48    status_t status = AudioSystem::getInputBufferSize(sampleRate, format, channelMask, &size);
49    if (status != NO_ERROR) {
50        ALOGE("AudioSystem could not query the input buffer size; status %d", status);
51        return NO_INIT;
52    }
53
54    if (size == 0) {
55        ALOGE("Unsupported configuration: sampleRate %u, format %d, channelMask %#x",
56            sampleRate, format, channelMask);
57        return BAD_VALUE;
58    }
59
60    // We double the size of input buffer for ping pong use of record buffer.
61    size <<= 1;
62
63    // Assumes audio_is_linear_pcm(format)
64    uint32_t channelCount = popcount(channelMask);
65    size /= channelCount * audio_bytes_per_sample(format);
66
67    *frameCount = size;
68    return NO_ERROR;
69}
70
71// ---------------------------------------------------------------------------
72
73AudioRecord::AudioRecord()
74    : mStatus(NO_INIT), mSessionId(AUDIO_SESSION_ALLOCATE),
75      mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT)
76{
77}
78
79AudioRecord::AudioRecord(
80        audio_source_t inputSource,
81        uint32_t sampleRate,
82        audio_format_t format,
83        audio_channel_mask_t channelMask,
84        int frameCount,
85        callback_t cbf,
86        void* user,
87        int notificationFrames,
88        int sessionId,
89        transfer_type transferType,
90        audio_input_flags_t flags)
91    : mStatus(NO_INIT), mSessionId(AUDIO_SESSION_ALLOCATE),
92      mPreviousPriority(ANDROID_PRIORITY_NORMAL),
93      mPreviousSchedulingGroup(SP_DEFAULT),
94      mProxy(NULL)
95{
96    mStatus = set(inputSource, sampleRate, format, channelMask, frameCount, cbf, user,
97            notificationFrames, false /*threadCanCallJava*/, sessionId, transferType);
98}
99
100AudioRecord::~AudioRecord()
101{
102    if (mStatus == NO_ERROR) {
103        // Make sure that callback function exits in the case where
104        // it is looping on buffer empty condition in obtainBuffer().
105        // Otherwise the callback thread will never exit.
106        stop();
107        if (mAudioRecordThread != 0) {
108            mProxy->interrupt();
109            mAudioRecordThread->requestExit();  // see comment in AudioRecord.h
110            mAudioRecordThread->requestExitAndWait();
111            mAudioRecordThread.clear();
112        }
113        if (mAudioRecord != 0) {
114            mAudioRecord->asBinder()->unlinkToDeath(mDeathNotifier, this);
115            mAudioRecord.clear();
116        }
117        IPCThreadState::self()->flushCommands();
118        AudioSystem::releaseAudioSessionId(mSessionId);
119    }
120}
121
122status_t AudioRecord::set(
123        audio_source_t inputSource,
124        uint32_t sampleRate,
125        audio_format_t format,
126        audio_channel_mask_t channelMask,
127        int frameCountInt,
128        callback_t cbf,
129        void* user,
130        int notificationFrames,
131        bool threadCanCallJava,
132        int sessionId,
133        transfer_type transferType,
134        audio_input_flags_t flags)
135{
136    switch (transferType) {
137    case TRANSFER_DEFAULT:
138        if (cbf == NULL || threadCanCallJava) {
139            transferType = TRANSFER_SYNC;
140        } else {
141            transferType = TRANSFER_CALLBACK;
142        }
143        break;
144    case TRANSFER_CALLBACK:
145        if (cbf == NULL) {
146            ALOGE("Transfer type TRANSFER_CALLBACK but cbf == NULL");
147            return BAD_VALUE;
148        }
149        break;
150    case TRANSFER_OBTAIN:
151    case TRANSFER_SYNC:
152        break;
153    default:
154        ALOGE("Invalid transfer type %d", transferType);
155        return BAD_VALUE;
156    }
157    mTransfer = transferType;
158
159    // FIXME "int" here is legacy and will be replaced by size_t later
160    if (frameCountInt < 0) {
161        ALOGE("Invalid frame count %d", frameCountInt);
162        return BAD_VALUE;
163    }
164    size_t frameCount = frameCountInt;
165
166    ALOGV("set(): sampleRate %u, channelMask %#x, frameCount %u", sampleRate, channelMask,
167            frameCount);
168
169    AutoMutex lock(mLock);
170
171    if (mAudioRecord != 0) {
172        ALOGE("Track already in use");
173        return INVALID_OPERATION;
174    }
175
176    if (inputSource == AUDIO_SOURCE_DEFAULT) {
177        inputSource = AUDIO_SOURCE_MIC;
178    }
179    mInputSource = inputSource;
180
181    if (sampleRate == 0) {
182        ALOGE("Invalid sample rate %u", sampleRate);
183        return BAD_VALUE;
184    }
185    mSampleRate = sampleRate;
186
187    // these below should probably come from the audioFlinger too...
188    if (format == AUDIO_FORMAT_DEFAULT) {
189        format = AUDIO_FORMAT_PCM_16_BIT;
190    }
191
192    // validate parameters
193    if (!audio_is_valid_format(format)) {
194        ALOGE("Invalid format %d", format);
195        return BAD_VALUE;
196    }
197    // Temporary restriction: AudioFlinger currently supports 16-bit PCM only
198    if (format != AUDIO_FORMAT_PCM_16_BIT) {
199        ALOGE("Format %d is not supported", format);
200        return BAD_VALUE;
201    }
202    mFormat = format;
203
204    if (!audio_is_input_channel(channelMask)) {
205        ALOGE("Invalid channel mask %#x", channelMask);
206        return BAD_VALUE;
207    }
208    mChannelMask = channelMask;
209    uint32_t channelCount = popcount(channelMask);
210    mChannelCount = channelCount;
211
212    // Assumes audio_is_linear_pcm(format), else sizeof(uint8_t)
213    mFrameSize = channelCount * audio_bytes_per_sample(format);
214
215    // validate framecount
216    size_t minFrameCount = 0;
217    status_t status = AudioRecord::getMinFrameCount(&minFrameCount,
218            sampleRate, format, channelMask);
219    if (status != NO_ERROR) {
220        ALOGE("getMinFrameCount() failed; status %d", status);
221        return status;
222    }
223    ALOGV("AudioRecord::set() minFrameCount = %d", minFrameCount);
224
225    if (frameCount == 0) {
226        frameCount = minFrameCount;
227    } else if (frameCount < minFrameCount) {
228        ALOGE("frameCount %u < minFrameCount %u", frameCount, minFrameCount);
229        return BAD_VALUE;
230    }
231    mFrameCount = frameCount;
232
233    mNotificationFramesReq = notificationFrames;
234    mNotificationFramesAct = 0;
235
236    if (sessionId == AUDIO_SESSION_ALLOCATE) {
237        mSessionId = AudioSystem::newAudioSessionId();
238    } else {
239        mSessionId = sessionId;
240    }
241    ALOGV("set(): mSessionId %d", mSessionId);
242
243    mFlags = flags;
244
245    // create the IAudioRecord
246    status = openRecord_l(0 /*epoch*/);
247    if (status != NO_ERROR) {
248        return status;
249    }
250
251    if (cbf != NULL) {
252        mAudioRecordThread = new AudioRecordThread(*this, threadCanCallJava);
253        mAudioRecordThread->run("AudioRecord", ANDROID_PRIORITY_AUDIO);
254    }
255
256    mStatus = NO_ERROR;
257
258    mActive = false;
259    mCbf = cbf;
260    mRefreshRemaining = true;
261    mUserData = user;
262    // TODO: add audio hardware input latency here
263    mLatency = (1000*mFrameCount) / sampleRate;
264    mMarkerPosition = 0;
265    mMarkerReached = false;
266    mNewPosition = 0;
267    mUpdatePeriod = 0;
268    AudioSystem::acquireAudioSessionId(mSessionId);
269    mSequence = 1;
270    mObservedSequence = mSequence;
271    mInOverrun = false;
272
273    return NO_ERROR;
274}
275
276// -------------------------------------------------------------------------
277
278status_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession)
279{
280    ALOGV("start, sync event %d trigger session %d", event, triggerSession);
281
282    AutoMutex lock(mLock);
283    if (mActive) {
284        return NO_ERROR;
285    }
286
287    // reset current position as seen by client to 0
288    mProxy->setEpoch(mProxy->getEpoch() - mProxy->getPosition());
289    // force refresh of remaining frames by processAudioBuffer() as last
290    // read before stop could be partial.
291    mRefreshRemaining = true;
292
293    mNewPosition = mProxy->getPosition() + mUpdatePeriod;
294    int32_t flags = android_atomic_acquire_load(&mCblk->mFlags);
295
296    status_t status = NO_ERROR;
297    if (!(flags & CBLK_INVALID)) {
298        ALOGV("mAudioRecord->start()");
299        status = mAudioRecord->start(event, triggerSession);
300        if (status == DEAD_OBJECT) {
301            flags |= CBLK_INVALID;
302        }
303    }
304    if (flags & CBLK_INVALID) {
305        status = restoreRecord_l("start");
306    }
307
308    if (status != NO_ERROR) {
309        ALOGE("start() status %d", status);
310    } else {
311        mActive = true;
312        sp<AudioRecordThread> t = mAudioRecordThread;
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    }
321
322    return status;
323}
324
325void AudioRecord::stop()
326{
327    AutoMutex lock(mLock);
328    if (!mActive) {
329        return;
330    }
331
332    mActive = false;
333    mProxy->interrupt();
334    mAudioRecord->stop();
335    // the record head position will reset to 0, so if a marker is set, we need
336    // to activate it again
337    mMarkerReached = false;
338    sp<AudioRecordThread> t = mAudioRecordThread;
339    if (t != 0) {
340        t->pause();
341    } else {
342        setpriority(PRIO_PROCESS, 0, mPreviousPriority);
343        set_sched_policy(0, mPreviousSchedulingGroup);
344    }
345}
346
347bool AudioRecord::stopped() const
348{
349    AutoMutex lock(mLock);
350    return !mActive;
351}
352
353status_t AudioRecord::setMarkerPosition(uint32_t marker)
354{
355    // The only purpose of setting marker position is to get a callback
356    if (mCbf == NULL) {
357        return INVALID_OPERATION;
358    }
359
360    AutoMutex lock(mLock);
361    mMarkerPosition = marker;
362    mMarkerReached = false;
363
364    return NO_ERROR;
365}
366
367status_t AudioRecord::getMarkerPosition(uint32_t *marker) const
368{
369    if (marker == NULL) {
370        return BAD_VALUE;
371    }
372
373    AutoMutex lock(mLock);
374    *marker = mMarkerPosition;
375
376    return NO_ERROR;
377}
378
379status_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod)
380{
381    // The only purpose of setting position update period is to get a callback
382    if (mCbf == NULL) {
383        return INVALID_OPERATION;
384    }
385
386    AutoMutex lock(mLock);
387    mNewPosition = mProxy->getPosition() + updatePeriod;
388    mUpdatePeriod = updatePeriod;
389
390    return NO_ERROR;
391}
392
393status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) const
394{
395    if (updatePeriod == NULL) {
396        return BAD_VALUE;
397    }
398
399    AutoMutex lock(mLock);
400    *updatePeriod = mUpdatePeriod;
401
402    return NO_ERROR;
403}
404
405status_t AudioRecord::getPosition(uint32_t *position) const
406{
407    if (position == NULL) {
408        return BAD_VALUE;
409    }
410
411    AutoMutex lock(mLock);
412    *position = mProxy->getPosition();
413
414    return NO_ERROR;
415}
416
417uint32_t 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(getInput());
421}
422
423// -------------------------------------------------------------------------
424
425// must be called with mLock held
426status_t AudioRecord::openRecord_l(size_t epoch)
427{
428    status_t status;
429    const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
430    if (audioFlinger == 0) {
431        ALOGE("Could not get audioflinger");
432        return NO_INIT;
433    }
434
435    IAudioFlinger::track_flags_t trackFlags = IAudioFlinger::TRACK_DEFAULT;
436    pid_t tid = -1;
437
438    // Client can only express a preference for FAST.  Server will perform additional tests.
439    // The only supported use case for FAST is callback transfer mode.
440    if (mFlags & AUDIO_INPUT_FLAG_FAST) {
441        if ((mTransfer != TRANSFER_CALLBACK) || (mAudioRecordThread == 0)) {
442            ALOGW("AUDIO_INPUT_FLAG_FAST denied by client");
443            // once denied, do not request again if IAudioRecord is re-created
444            mFlags = (audio_input_flags_t) (mFlags & ~AUDIO_INPUT_FLAG_FAST);
445        } else {
446            trackFlags |= IAudioFlinger::TRACK_FAST;
447            tid = mAudioRecordThread->getTid();
448        }
449    }
450
451    mNotificationFramesAct = mNotificationFramesReq;
452
453    if (!(mFlags & AUDIO_INPUT_FLAG_FAST)) {
454        // Make sure that application is notified with sufficient margin before overrun
455        if (mNotificationFramesAct == 0 || mNotificationFramesAct > mFrameCount/2) {
456            mNotificationFramesAct = mFrameCount/2;
457        }
458    }
459
460    audio_io_handle_t input = AudioSystem::getInput(mInputSource, mSampleRate, mFormat,
461            mChannelMask, mSessionId);
462    if (input == 0) {
463        ALOGE("Could not get audio input for record source %d", mInputSource);
464        return BAD_VALUE;
465    }
466    {
467    // Now that we have a reference to an I/O handle and have not yet handed it off to AudioFlinger,
468    // we must release it ourselves if anything goes wrong.
469
470    size_t temp = mFrameCount;  // temp may be replaced by a revised value of frameCount,
471                                // but we will still need the original value also
472    int originalSessionId = mSessionId;
473    sp<IAudioRecord> record = audioFlinger->openRecord(input,
474                                                       mSampleRate, mFormat,
475                                                       mChannelMask,
476                                                       &temp,
477                                                       &trackFlags,
478                                                       tid,
479                                                       &mSessionId,
480                                                       &status);
481    ALOGE_IF(originalSessionId != AUDIO_SESSION_ALLOCATE && mSessionId != originalSessionId,
482            "session ID changed from %d to %d", originalSessionId, mSessionId);
483
484    if (record == 0 || status != NO_ERROR) {
485        ALOGE("AudioFlinger could not create record track, status: %d", status);
486        goto release;
487    }
488    // AudioFlinger now owns the reference to the I/O handle,
489    // so we are no longer responsible for releasing it.
490
491    sp<IMemory> iMem = record->getCblk();
492    if (iMem == 0) {
493        ALOGE("Could not get control block");
494        return NO_INIT;
495    }
496    void *iMemPointer = iMem->pointer();
497    if (iMemPointer == NULL) {
498        ALOGE("Could not get control block pointer");
499        return NO_INIT;
500    }
501    if (mAudioRecord != 0) {
502        mAudioRecord->asBinder()->unlinkToDeath(mDeathNotifier, this);
503        mDeathNotifier.clear();
504    }
505
506    // We retain a copy of the I/O handle, but don't own the reference
507    mInput = input;
508    mAudioRecord = record;
509    mCblkMemory = iMem;
510    audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMemPointer);
511    mCblk = cblk;
512    // note that temp is the (possibly revised) value of mFrameCount
513    if (temp < mFrameCount || (mFrameCount == 0 && temp == 0)) {
514        ALOGW("Requested frameCount %u but received frameCount %u", mFrameCount, temp);
515    }
516    mFrameCount = temp;
517
518    // FIXME missing fast track frameCount logic
519    mAwaitBoost = false;
520    if (mFlags & AUDIO_INPUT_FLAG_FAST) {
521        if (trackFlags & IAudioFlinger::TRACK_FAST) {
522            ALOGV("AUDIO_INPUT_FLAG_FAST successful; frameCount %u", mFrameCount);
523            mAwaitBoost = true;
524            // double-buffering is not required for fast tracks, due to tighter scheduling
525            if (mNotificationFramesAct == 0 || mNotificationFramesAct > mFrameCount) {
526                mNotificationFramesAct = mFrameCount;
527            }
528        } else {
529            ALOGV("AUDIO_INPUT_FLAG_FAST denied by server; frameCount %u", mFrameCount);
530            // once denied, do not request again if IAudioRecord is re-created
531            mFlags = (audio_input_flags_t) (mFlags & ~AUDIO_INPUT_FLAG_FAST);
532            if (mNotificationFramesAct == 0 || mNotificationFramesAct > mFrameCount/2) {
533                mNotificationFramesAct = mFrameCount/2;
534            }
535        }
536    }
537
538    // starting address of buffers in shared memory
539    void *buffers = (char*)cblk + sizeof(audio_track_cblk_t);
540
541    // update proxy
542    mProxy = new AudioRecordClientProxy(cblk, buffers, mFrameCount, mFrameSize);
543    mProxy->setEpoch(epoch);
544    mProxy->setMinimum(mNotificationFramesAct);
545
546    mDeathNotifier = new DeathNotifier(this);
547    mAudioRecord->asBinder()->linkToDeath(mDeathNotifier, this);
548
549    return NO_ERROR;
550    }
551
552release:
553    AudioSystem::releaseInput(input);
554    if (status == NO_ERROR) {
555        status = NO_INIT;
556    }
557    return status;
558}
559
560status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
561{
562    if (audioBuffer == NULL) {
563        return BAD_VALUE;
564    }
565    if (mTransfer != TRANSFER_OBTAIN) {
566        audioBuffer->frameCount = 0;
567        audioBuffer->size = 0;
568        audioBuffer->raw = NULL;
569        return INVALID_OPERATION;
570    }
571
572    const struct timespec *requested;
573    if (waitCount == -1) {
574        requested = &ClientProxy::kForever;
575    } else if (waitCount == 0) {
576        requested = &ClientProxy::kNonBlocking;
577    } else if (waitCount > 0) {
578        long long ms = WAIT_PERIOD_MS * (long long) waitCount;
579        struct timespec timeout;
580        timeout.tv_sec = ms / 1000;
581        timeout.tv_nsec = (int) (ms % 1000) * 1000000;
582        requested = &timeout;
583    } else {
584        ALOGE("%s invalid waitCount %d", __func__, waitCount);
585        requested = NULL;
586    }
587    return obtainBuffer(audioBuffer, requested);
588}
589
590status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, const struct timespec *requested,
591        struct timespec *elapsed, size_t *nonContig)
592{
593    // previous and new IAudioRecord sequence numbers are used to detect track re-creation
594    uint32_t oldSequence = 0;
595    uint32_t newSequence;
596
597    Proxy::Buffer buffer;
598    status_t status = NO_ERROR;
599
600    static const int32_t kMaxTries = 5;
601    int32_t tryCounter = kMaxTries;
602
603    do {
604        // obtainBuffer() is called with mutex unlocked, so keep extra references to these fields to
605        // keep them from going away if another thread re-creates the track during obtainBuffer()
606        sp<AudioRecordClientProxy> proxy;
607        sp<IMemory> iMem;
608        {
609            // start of lock scope
610            AutoMutex lock(mLock);
611
612            newSequence = mSequence;
613            // did previous obtainBuffer() fail due to media server death or voluntary invalidation?
614            if (status == DEAD_OBJECT) {
615                // re-create track, unless someone else has already done so
616                if (newSequence == oldSequence) {
617                    status = restoreRecord_l("obtainBuffer");
618                    if (status != NO_ERROR) {
619                        buffer.mFrameCount = 0;
620                        buffer.mRaw = NULL;
621                        buffer.mNonContig = 0;
622                        break;
623                    }
624                }
625            }
626            oldSequence = newSequence;
627
628            // Keep the extra references
629            proxy = mProxy;
630            iMem = mCblkMemory;
631
632            // Non-blocking if track is stopped
633            if (!mActive) {
634                requested = &ClientProxy::kNonBlocking;
635            }
636
637        }   // end of lock scope
638
639        buffer.mFrameCount = audioBuffer->frameCount;
640        // FIXME starts the requested timeout and elapsed over from scratch
641        status = proxy->obtainBuffer(&buffer, requested, elapsed);
642
643    } while ((status == DEAD_OBJECT) && (tryCounter-- > 0));
644
645    audioBuffer->frameCount = buffer.mFrameCount;
646    audioBuffer->size = buffer.mFrameCount * mFrameSize;
647    audioBuffer->raw = buffer.mRaw;
648    if (nonContig != NULL) {
649        *nonContig = buffer.mNonContig;
650    }
651    return status;
652}
653
654void AudioRecord::releaseBuffer(Buffer* audioBuffer)
655{
656    // all TRANSFER_* are valid
657
658    size_t stepCount = audioBuffer->size / mFrameSize;
659    if (stepCount == 0) {
660        return;
661    }
662
663    Proxy::Buffer buffer;
664    buffer.mFrameCount = stepCount;
665    buffer.mRaw = audioBuffer->raw;
666
667    AutoMutex lock(mLock);
668    mInOverrun = false;
669    mProxy->releaseBuffer(&buffer);
670
671    // the server does not automatically disable recorder on overrun, so no need to restart
672}
673
674audio_io_handle_t AudioRecord::getInput() const
675{
676    AutoMutex lock(mLock);
677    return mInput;
678}
679
680// -------------------------------------------------------------------------
681
682ssize_t AudioRecord::read(void* buffer, size_t userSize)
683{
684    if (mTransfer != TRANSFER_SYNC) {
685        return INVALID_OPERATION;
686    }
687
688    if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) {
689        // sanity-check. user is most-likely passing an error code, and it would
690        // make the return value ambiguous (actualSize vs error).
691        ALOGE("AudioRecord::read(buffer=%p, size=%u (%d)", buffer, userSize, userSize);
692        return BAD_VALUE;
693    }
694
695    ssize_t read = 0;
696    Buffer audioBuffer;
697
698    while (userSize >= mFrameSize) {
699        audioBuffer.frameCount = userSize / mFrameSize;
700
701        status_t err = obtainBuffer(&audioBuffer, &ClientProxy::kForever);
702        if (err < 0) {
703            if (read > 0) {
704                break;
705            }
706            return ssize_t(err);
707        }
708
709        size_t bytesRead = audioBuffer.size;
710        memcpy(buffer, audioBuffer.i8, bytesRead);
711        buffer = ((char *) buffer) + bytesRead;
712        userSize -= bytesRead;
713        read += bytesRead;
714
715        releaseBuffer(&audioBuffer);
716    }
717
718    return read;
719}
720
721// -------------------------------------------------------------------------
722
723nsecs_t AudioRecord::processAudioBuffer()
724{
725    mLock.lock();
726    if (mAwaitBoost) {
727        mAwaitBoost = false;
728        mLock.unlock();
729        static const int32_t kMaxTries = 5;
730        int32_t tryCounter = kMaxTries;
731        uint32_t pollUs = 10000;
732        do {
733            int policy = sched_getscheduler(0);
734            if (policy == SCHED_FIFO || policy == SCHED_RR) {
735                break;
736            }
737            usleep(pollUs);
738            pollUs <<= 1;
739        } while (tryCounter-- > 0);
740        if (tryCounter < 0) {
741            ALOGE("did not receive expected priority boost on time");
742        }
743        // Run again immediately
744        return 0;
745    }
746
747    // Can only reference mCblk while locked
748    int32_t flags = android_atomic_and(~CBLK_OVERRUN, &mCblk->mFlags);
749
750    // Check for track invalidation
751    if (flags & CBLK_INVALID) {
752        (void) restoreRecord_l("processAudioBuffer");
753        mLock.unlock();
754        // Run again immediately, but with a new IAudioRecord
755        return 0;
756    }
757
758    bool active = mActive;
759
760    // Manage overrun callback, must be done under lock to avoid race with releaseBuffer()
761    bool newOverrun = false;
762    if (flags & CBLK_OVERRUN) {
763        if (!mInOverrun) {
764            mInOverrun = true;
765            newOverrun = true;
766        }
767    }
768
769    // Get current position of server
770    size_t position = mProxy->getPosition();
771
772    // Manage marker callback
773    bool markerReached = false;
774    size_t markerPosition = mMarkerPosition;
775    // FIXME fails for wraparound, need 64 bits
776    if (!mMarkerReached && (markerPosition > 0) && (position >= markerPosition)) {
777        mMarkerReached = markerReached = true;
778    }
779
780    // Determine the number of new position callback(s) that will be needed, while locked
781    size_t newPosCount = 0;
782    size_t newPosition = mNewPosition;
783    uint32_t updatePeriod = mUpdatePeriod;
784    // FIXME fails for wraparound, need 64 bits
785    if (updatePeriod > 0 && position >= newPosition) {
786        newPosCount = ((position - newPosition) / updatePeriod) + 1;
787        mNewPosition += updatePeriod * newPosCount;
788    }
789
790    // Cache other fields that will be needed soon
791    size_t notificationFrames = mNotificationFramesAct;
792    if (mRefreshRemaining) {
793        mRefreshRemaining = false;
794        mRemainingFrames = notificationFrames;
795        mRetryOnPartialBuffer = false;
796    }
797    size_t misalignment = mProxy->getMisalignment();
798    uint32_t sequence = mSequence;
799
800    // These fields don't need to be cached, because they are assigned only by set():
801    //      mTransfer, mCbf, mUserData, mSampleRate, mFrameSize
802
803    mLock.unlock();
804
805    // perform callbacks while unlocked
806    if (newOverrun) {
807        mCbf(EVENT_OVERRUN, mUserData, NULL);
808    }
809    if (markerReached) {
810        mCbf(EVENT_MARKER, mUserData, &markerPosition);
811    }
812    while (newPosCount > 0) {
813        size_t temp = newPosition;
814        mCbf(EVENT_NEW_POS, mUserData, &temp);
815        newPosition += updatePeriod;
816        newPosCount--;
817    }
818    if (mObservedSequence != sequence) {
819        mObservedSequence = sequence;
820        mCbf(EVENT_NEW_IAUDIORECORD, mUserData, NULL);
821    }
822
823    // if inactive, then don't run me again until re-started
824    if (!active) {
825        return NS_INACTIVE;
826    }
827
828    // Compute the estimated time until the next timed event (position, markers)
829    uint32_t minFrames = ~0;
830    if (!markerReached && position < markerPosition) {
831        minFrames = markerPosition - position;
832    }
833    if (updatePeriod > 0 && updatePeriod < minFrames) {
834        minFrames = updatePeriod;
835    }
836
837    // If > 0, poll periodically to recover from a stuck server.  A good value is 2.
838    static const uint32_t kPoll = 0;
839    if (kPoll > 0 && mTransfer == TRANSFER_CALLBACK && kPoll * notificationFrames < minFrames) {
840        minFrames = kPoll * notificationFrames;
841    }
842
843    // Convert frame units to time units
844    nsecs_t ns = NS_WHENEVER;
845    if (minFrames != (uint32_t) ~0) {
846        // This "fudge factor" avoids soaking CPU, and compensates for late progress by server
847        static const nsecs_t kFudgeNs = 10000000LL; // 10 ms
848        ns = ((minFrames * 1000000000LL) / mSampleRate) + kFudgeNs;
849    }
850
851    // If not supplying data by EVENT_MORE_DATA, then we're done
852    if (mTransfer != TRANSFER_CALLBACK) {
853        return ns;
854    }
855
856    struct timespec timeout;
857    const struct timespec *requested = &ClientProxy::kForever;
858    if (ns != NS_WHENEVER) {
859        timeout.tv_sec = ns / 1000000000LL;
860        timeout.tv_nsec = ns % 1000000000LL;
861        ALOGV("timeout %ld.%03d", timeout.tv_sec, (int) timeout.tv_nsec / 1000000);
862        requested = &timeout;
863    }
864
865    while (mRemainingFrames > 0) {
866
867        Buffer audioBuffer;
868        audioBuffer.frameCount = mRemainingFrames;
869        size_t nonContig;
870        status_t err = obtainBuffer(&audioBuffer, requested, NULL, &nonContig);
871        LOG_ALWAYS_FATAL_IF((err != NO_ERROR) != (audioBuffer.frameCount == 0),
872                "obtainBuffer() err=%d frameCount=%u", err, audioBuffer.frameCount);
873        requested = &ClientProxy::kNonBlocking;
874        size_t avail = audioBuffer.frameCount + nonContig;
875        ALOGV("obtainBuffer(%u) returned %u = %u + %u err %d",
876                mRemainingFrames, avail, audioBuffer.frameCount, nonContig, err);
877        if (err != NO_ERROR) {
878            if (err == TIMED_OUT || err == WOULD_BLOCK || err == -EINTR) {
879                break;
880            }
881            ALOGE("Error %d obtaining an audio buffer, giving up.", err);
882            return NS_NEVER;
883        }
884
885        if (mRetryOnPartialBuffer) {
886            mRetryOnPartialBuffer = false;
887            if (avail < mRemainingFrames) {
888                int64_t myns = ((mRemainingFrames - avail) *
889                        1100000000LL) / mSampleRate;
890                if (ns < 0 || myns < ns) {
891                    ns = myns;
892                }
893                return ns;
894            }
895        }
896
897        size_t reqSize = audioBuffer.size;
898        mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer);
899        size_t readSize = audioBuffer.size;
900
901        // Sanity check on returned size
902        if (ssize_t(readSize) < 0 || readSize > reqSize) {
903            ALOGE("EVENT_MORE_DATA requested %u bytes but callback returned %d bytes",
904                    reqSize, (int) readSize);
905            return NS_NEVER;
906        }
907
908        if (readSize == 0) {
909            // The callback is done consuming buffers
910            // Keep this thread going to handle timed events and
911            // still try to provide more data in intervals of WAIT_PERIOD_MS
912            // but don't just loop and block the CPU, so wait
913            return WAIT_PERIOD_MS * 1000000LL;
914        }
915
916        size_t releasedFrames = readSize / mFrameSize;
917        audioBuffer.frameCount = releasedFrames;
918        mRemainingFrames -= releasedFrames;
919        if (misalignment >= releasedFrames) {
920            misalignment -= releasedFrames;
921        } else {
922            misalignment = 0;
923        }
924
925        releaseBuffer(&audioBuffer);
926
927        // FIXME here is where we would repeat EVENT_MORE_DATA again on same advanced buffer
928        // if callback doesn't like to accept the full chunk
929        if (readSize < reqSize) {
930            continue;
931        }
932
933        // There could be enough non-contiguous frames available to satisfy the remaining request
934        if (mRemainingFrames <= nonContig) {
935            continue;
936        }
937
938#if 0
939        // This heuristic tries to collapse a series of EVENT_MORE_DATA that would total to a
940        // sum <= notificationFrames.  It replaces that series by at most two EVENT_MORE_DATA
941        // that total to a sum == notificationFrames.
942        if (0 < misalignment && misalignment <= mRemainingFrames) {
943            mRemainingFrames = misalignment;
944            return (mRemainingFrames * 1100000000LL) / mSampleRate;
945        }
946#endif
947
948    }
949    mRemainingFrames = notificationFrames;
950    mRetryOnPartialBuffer = true;
951
952    // A lot has transpired since ns was calculated, so run again immediately and re-calculate
953    return 0;
954}
955
956status_t AudioRecord::restoreRecord_l(const char *from)
957{
958    ALOGW("dead IAudioRecord, creating a new one from %s()", from);
959    ++mSequence;
960    status_t result;
961
962    // if the new IAudioRecord is created, openRecord_l() will modify the
963    // following member variables: mAudioRecord, mCblkMemory and mCblk.
964    // It will also delete the strong references on previous IAudioRecord and IMemory
965    size_t position = mProxy->getPosition();
966    mNewPosition = position + mUpdatePeriod;
967    result = openRecord_l(position);
968    if (result == NO_ERROR) {
969        if (mActive) {
970            // callback thread or sync event hasn't changed
971            // FIXME this fails if we have a new AudioFlinger instance
972            result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0);
973        }
974    }
975    if (result != NO_ERROR) {
976        ALOGW("restoreRecord_l() failed status %d", result);
977        mActive = false;
978    }
979
980    return result;
981}
982
983// =========================================================================
984
985void AudioRecord::DeathNotifier::binderDied(const wp<IBinder>& who __unused)
986{
987    sp<AudioRecord> audioRecord = mAudioRecord.promote();
988    if (audioRecord != 0) {
989        AutoMutex lock(audioRecord->mLock);
990        audioRecord->mProxy->binderDied();
991    }
992}
993
994// =========================================================================
995
996AudioRecord::AudioRecordThread::AudioRecordThread(AudioRecord& receiver, bool bCanCallJava)
997    : Thread(bCanCallJava), mReceiver(receiver), mPaused(true), mPausedInt(false), mPausedNs(0LL),
998      mIgnoreNextPausedInt(false)
999{
1000}
1001
1002AudioRecord::AudioRecordThread::~AudioRecordThread()
1003{
1004}
1005
1006bool AudioRecord::AudioRecordThread::threadLoop()
1007{
1008    {
1009        AutoMutex _l(mMyLock);
1010        if (mPaused) {
1011            mMyCond.wait(mMyLock);
1012            // caller will check for exitPending()
1013            return true;
1014        }
1015        if (mIgnoreNextPausedInt) {
1016            mIgnoreNextPausedInt = false;
1017            mPausedInt = false;
1018        }
1019        if (mPausedInt) {
1020            if (mPausedNs > 0) {
1021                (void) mMyCond.waitRelative(mMyLock, mPausedNs);
1022            } else {
1023                mMyCond.wait(mMyLock);
1024            }
1025            mPausedInt = false;
1026            return true;
1027        }
1028    }
1029    nsecs_t ns =  mReceiver.processAudioBuffer();
1030    switch (ns) {
1031    case 0:
1032        return true;
1033    case NS_INACTIVE:
1034        pauseInternal();
1035        return true;
1036    case NS_NEVER:
1037        return false;
1038    case NS_WHENEVER:
1039        // FIXME increase poll interval, or make event-driven
1040        ns = 1000000000LL;
1041        // fall through
1042    default:
1043        LOG_ALWAYS_FATAL_IF(ns < 0, "processAudioBuffer() returned %lld", ns);
1044        pauseInternal(ns);
1045        return true;
1046    }
1047}
1048
1049void AudioRecord::AudioRecordThread::requestExit()
1050{
1051    // must be in this order to avoid a race condition
1052    Thread::requestExit();
1053    resume();
1054}
1055
1056void AudioRecord::AudioRecordThread::pause()
1057{
1058    AutoMutex _l(mMyLock);
1059    mPaused = true;
1060}
1061
1062void AudioRecord::AudioRecordThread::resume()
1063{
1064    AutoMutex _l(mMyLock);
1065    mIgnoreNextPausedInt = true;
1066    if (mPaused || mPausedInt) {
1067        mPaused = false;
1068        mPausedInt = false;
1069        mMyCond.signal();
1070    }
1071}
1072
1073void AudioRecord::AudioRecordThread::pauseInternal(nsecs_t ns)
1074{
1075    AutoMutex _l(mMyLock);
1076    mPausedInt = true;
1077    mPausedNs = ns;
1078}
1079
1080// -------------------------------------------------------------------------
1081
1082}; // namespace android
1083