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