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