• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <stdint.h>
22 #include <sys/types.h>
23 
24 #include <sched.h>
25 #include <sys/resource.h>
26 
27 #include <private/media/AudioTrackShared.h>
28 
29 #include <media/AudioSystem.h>
30 #include <media/AudioRecord.h>
31 #include <media/mediarecorder.h>
32 
33 #include <binder/IServiceManager.h>
34 #include <utils/Log.h>
35 #include <binder/Parcel.h>
36 #include <binder/IPCThreadState.h>
37 #include <utils/Timers.h>
38 #include <utils/Atomic.h>
39 
40 #include <system/audio.h>
41 #include <cutils/bitops.h>
42 
43 #define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
44 #define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
45 
46 namespace android {
47 // ---------------------------------------------------------------------------
48 
49 // static
getMinFrameCount(int * frameCount,uint32_t sampleRate,int format,int channelCount)50 status_t AudioRecord::getMinFrameCount(
51         int* frameCount,
52         uint32_t sampleRate,
53         int format,
54         int channelCount)
55 {
56     size_t size = 0;
57     if (AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &size)
58             != NO_ERROR) {
59         LOGE("AudioSystem could not query the input buffer size.");
60         return NO_INIT;
61     }
62 
63     if (size == 0) {
64         LOGE("Unsupported configuration: sampleRate %d, format %d, channelCount %d",
65             sampleRate, format, channelCount);
66         return BAD_VALUE;
67     }
68 
69     // We double the size of input buffer for ping pong use of record buffer.
70     size <<= 1;
71 
72     if (audio_is_linear_pcm(format)) {
73         size /= channelCount * audio_bytes_per_sample(format);
74     }
75 
76     *frameCount = size;
77     return NO_ERROR;
78 }
79 
80 // ---------------------------------------------------------------------------
81 
AudioRecord()82 AudioRecord::AudioRecord()
83     : mStatus(NO_INIT), mSessionId(0)
84 {
85 }
86 
AudioRecord(int inputSource,uint32_t sampleRate,int format,uint32_t channelMask,int frameCount,uint32_t flags,callback_t cbf,void * user,int notificationFrames,int sessionId)87 AudioRecord::AudioRecord(
88         int inputSource,
89         uint32_t sampleRate,
90         int format,
91         uint32_t channelMask,
92         int frameCount,
93         uint32_t flags,
94         callback_t cbf,
95         void* user,
96         int notificationFrames,
97         int sessionId)
98     : mStatus(NO_INIT), mSessionId(0)
99 {
100     mStatus = set(inputSource, sampleRate, format, channelMask,
101             frameCount, flags, cbf, user, notificationFrames, sessionId);
102 }
103 
~AudioRecord()104 AudioRecord::~AudioRecord()
105 {
106     if (mStatus == NO_ERROR) {
107         // Make sure that callback function exits in the case where
108         // it is looping on buffer empty condition in obtainBuffer().
109         // Otherwise the callback thread will never exit.
110         stop();
111         if (mClientRecordThread != 0) {
112             mClientRecordThread->requestExitAndWait();
113             mClientRecordThread.clear();
114         }
115         mAudioRecord.clear();
116         IPCThreadState::self()->flushCommands();
117         AudioSystem::releaseAudioSessionId(mSessionId);
118     }
119 }
120 
set(int inputSource,uint32_t sampleRate,int format,uint32_t channelMask,int frameCount,uint32_t flags,callback_t cbf,void * user,int notificationFrames,bool threadCanCallJava,int sessionId)121 status_t AudioRecord::set(
122         int inputSource,
123         uint32_t sampleRate,
124         int format,
125         uint32_t channelMask,
126         int frameCount,
127         uint32_t flags,
128         callback_t cbf,
129         void* user,
130         int notificationFrames,
131         bool threadCanCallJava,
132         int sessionId)
133 {
134 
135     LOGV("set(): sampleRate %d, channelMask %d, frameCount %d",sampleRate, channelMask, frameCount);
136 
137     AutoMutex lock(mLock);
138 
139     if (mAudioRecord != 0) {
140         return INVALID_OPERATION;
141     }
142 
143     if (inputSource == AUDIO_SOURCE_DEFAULT) {
144         inputSource = AUDIO_SOURCE_MIC;
145     }
146 
147     if (sampleRate == 0) {
148         sampleRate = DEFAULT_SAMPLE_RATE;
149     }
150     // these below should probably come from the audioFlinger too...
151     if (format == 0) {
152         format = AUDIO_FORMAT_PCM_16_BIT;
153     }
154     // validate parameters
155     if (!audio_is_valid_format(format)) {
156         LOGE("Invalid format");
157         return BAD_VALUE;
158     }
159 
160     if (!audio_is_input_channel(channelMask)) {
161         return BAD_VALUE;
162     }
163 
164     int channelCount = popcount(channelMask);
165 
166     if (sessionId == 0 ) {
167         mSessionId = AudioSystem::newAudioSessionId();
168     } else {
169         mSessionId = sessionId;
170     }
171     LOGV("set(): mSessionId %d", mSessionId);
172 
173     audio_io_handle_t input = AudioSystem::getInput(inputSource,
174                                                     sampleRate,
175                                                     format,
176                                                     channelMask,
177                                                     (audio_in_acoustics_t)flags,
178                                                     mSessionId);
179     if (input == 0) {
180         LOGE("Could not get audio input for record source %d", inputSource);
181         return BAD_VALUE;
182     }
183 
184     // validate framecount
185     int minFrameCount = 0;
186     status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelCount);
187     if (status != NO_ERROR) {
188         return status;
189     }
190     LOGV("AudioRecord::set() minFrameCount = %d", minFrameCount);
191 
192     if (frameCount == 0) {
193         frameCount = minFrameCount;
194     } else if (frameCount < minFrameCount) {
195         return BAD_VALUE;
196     }
197 
198     if (notificationFrames == 0) {
199         notificationFrames = frameCount/2;
200     }
201 
202     // create the IAudioRecord
203     status = openRecord_l(sampleRate, format, channelMask,
204                         frameCount, flags, input);
205     if (status != NO_ERROR) {
206         return status;
207     }
208 
209     if (cbf != 0) {
210         mClientRecordThread = new ClientRecordThread(*this, threadCanCallJava);
211         if (mClientRecordThread == 0) {
212             return NO_INIT;
213         }
214     }
215 
216     mStatus = NO_ERROR;
217 
218     mFormat = format;
219     // Update buffer size in case it has been limited by AudioFlinger during track creation
220     mFrameCount = mCblk->frameCount;
221     mChannelCount = (uint8_t)channelCount;
222     mChannelMask = channelMask;
223     mActive = 0;
224     mCbf = cbf;
225     mNotificationFrames = notificationFrames;
226     mRemainingFrames = notificationFrames;
227     mUserData = user;
228     // TODO: add audio hardware input latency here
229     mLatency = (1000*mFrameCount) / sampleRate;
230     mMarkerPosition = 0;
231     mMarkerReached = false;
232     mNewPosition = 0;
233     mUpdatePeriod = 0;
234     mInputSource = (uint8_t)inputSource;
235     mFlags = flags;
236     mInput = input;
237     AudioSystem::acquireAudioSessionId(mSessionId);
238 
239     return NO_ERROR;
240 }
241 
initCheck() const242 status_t AudioRecord::initCheck() const
243 {
244     return mStatus;
245 }
246 
247 // -------------------------------------------------------------------------
248 
latency() const249 uint32_t AudioRecord::latency() const
250 {
251     return mLatency;
252 }
253 
format() const254 int AudioRecord::format() const
255 {
256     return mFormat;
257 }
258 
channelCount() const259 int AudioRecord::channelCount() const
260 {
261     return mChannelCount;
262 }
263 
frameCount() const264 uint32_t AudioRecord::frameCount() const
265 {
266     return mFrameCount;
267 }
268 
frameSize() const269 int AudioRecord::frameSize() const
270 {
271     if (audio_is_linear_pcm(mFormat)) {
272         return channelCount()*audio_bytes_per_sample(mFormat);
273     } else {
274         return sizeof(uint8_t);
275     }
276 }
277 
inputSource() const278 int AudioRecord::inputSource() const
279 {
280     return (int)mInputSource;
281 }
282 
283 // -------------------------------------------------------------------------
284 
start()285 status_t AudioRecord::start()
286 {
287     status_t ret = NO_ERROR;
288     sp<ClientRecordThread> t = mClientRecordThread;
289 
290     LOGV("start");
291 
292     if (t != 0) {
293         if (t->exitPending()) {
294             if (t->requestExitAndWait() == WOULD_BLOCK) {
295                 LOGE("AudioRecord::start called from thread");
296                 return WOULD_BLOCK;
297             }
298         }
299         t->mLock.lock();
300      }
301 
302     AutoMutex lock(mLock);
303     // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed
304     // while we are accessing the cblk
305     sp <IAudioRecord> audioRecord = mAudioRecord;
306     sp <IMemory> iMem = mCblkMemory;
307     audio_track_cblk_t* cblk = mCblk;
308     if (mActive == 0) {
309         mActive = 1;
310 
311         cblk->lock.lock();
312         if (!(cblk->flags & CBLK_INVALID_MSK)) {
313             cblk->lock.unlock();
314             ret = mAudioRecord->start();
315             cblk->lock.lock();
316             if (ret == DEAD_OBJECT) {
317                 android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
318             }
319         }
320         if (cblk->flags & CBLK_INVALID_MSK) {
321             ret = restoreRecord_l(cblk);
322         }
323         cblk->lock.unlock();
324         if (ret == NO_ERROR) {
325             mNewPosition = cblk->user + mUpdatePeriod;
326             cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
327             cblk->waitTimeMs = 0;
328             if (t != 0) {
329                t->run("ClientRecordThread", ANDROID_PRIORITY_AUDIO);
330             } else {
331                 setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO);
332             }
333         } else {
334             mActive = 0;
335         }
336     }
337 
338     if (t != 0) {
339         t->mLock.unlock();
340     }
341 
342     return ret;
343 }
344 
stop()345 status_t AudioRecord::stop()
346 {
347     sp<ClientRecordThread> t = mClientRecordThread;
348 
349     LOGV("stop");
350 
351     if (t != 0) {
352         t->mLock.lock();
353     }
354 
355     AutoMutex lock(mLock);
356     if (mActive == 1) {
357         mActive = 0;
358         mCblk->cv.signal();
359         mAudioRecord->stop();
360         // the record head position will reset to 0, so if a marker is set, we need
361         // to activate it again
362         mMarkerReached = false;
363         if (t != 0) {
364             t->requestExit();
365         } else {
366             setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL);
367         }
368     }
369 
370     if (t != 0) {
371         t->mLock.unlock();
372     }
373 
374     return NO_ERROR;
375 }
376 
stopped() const377 bool AudioRecord::stopped() const
378 {
379     return !mActive;
380 }
381 
getSampleRate()382 uint32_t AudioRecord::getSampleRate()
383 {
384     AutoMutex lock(mLock);
385     return mCblk->sampleRate;
386 }
387 
setMarkerPosition(uint32_t marker)388 status_t AudioRecord::setMarkerPosition(uint32_t marker)
389 {
390     if (mCbf == 0) return INVALID_OPERATION;
391 
392     mMarkerPosition = marker;
393     mMarkerReached = false;
394 
395     return NO_ERROR;
396 }
397 
getMarkerPosition(uint32_t * marker)398 status_t AudioRecord::getMarkerPosition(uint32_t *marker)
399 {
400     if (marker == 0) return BAD_VALUE;
401 
402     *marker = mMarkerPosition;
403 
404     return NO_ERROR;
405 }
406 
setPositionUpdatePeriod(uint32_t updatePeriod)407 status_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod)
408 {
409     if (mCbf == 0) return INVALID_OPERATION;
410 
411     uint32_t curPosition;
412     getPosition(&curPosition);
413     mNewPosition = curPosition + updatePeriod;
414     mUpdatePeriod = updatePeriod;
415 
416     return NO_ERROR;
417 }
418 
getPositionUpdatePeriod(uint32_t * updatePeriod)419 status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod)
420 {
421     if (updatePeriod == 0) return BAD_VALUE;
422 
423     *updatePeriod = mUpdatePeriod;
424 
425     return NO_ERROR;
426 }
427 
getPosition(uint32_t * position)428 status_t AudioRecord::getPosition(uint32_t *position)
429 {
430     if (position == 0) return BAD_VALUE;
431 
432     AutoMutex lock(mLock);
433     *position = mCblk->user;
434 
435     return NO_ERROR;
436 }
437 
getInputFramesLost()438 unsigned int AudioRecord::getInputFramesLost()
439 {
440     if (mActive)
441         return AudioSystem::getInputFramesLost(mInput);
442     else
443         return 0;
444 }
445 
446 // -------------------------------------------------------------------------
447 
448 // must be called with mLock held
openRecord_l(uint32_t sampleRate,uint32_t format,uint32_t channelMask,int frameCount,uint32_t flags,audio_io_handle_t input)449 status_t AudioRecord::openRecord_l(
450         uint32_t sampleRate,
451         uint32_t format,
452         uint32_t channelMask,
453         int frameCount,
454         uint32_t flags,
455         audio_io_handle_t input)
456 {
457     status_t status;
458     const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
459     if (audioFlinger == 0) {
460         return NO_INIT;
461     }
462 
463     sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), input,
464                                                        sampleRate, format,
465                                                        channelMask,
466                                                        frameCount,
467                                                        ((uint16_t)flags) << 16,
468                                                        &mSessionId,
469                                                        &status);
470 
471     if (record == 0) {
472         LOGE("AudioFlinger could not create record track, status: %d", status);
473         return status;
474     }
475     sp<IMemory> cblk = record->getCblk();
476     if (cblk == 0) {
477         LOGE("Could not get control block");
478         return NO_INIT;
479     }
480     mAudioRecord.clear();
481     mAudioRecord = record;
482     mCblkMemory.clear();
483     mCblkMemory = cblk;
484     mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
485     mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
486     android_atomic_and(~CBLK_DIRECTION_MSK, &mCblk->flags);
487     mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
488     mCblk->waitTimeMs = 0;
489     return NO_ERROR;
490 }
491 
obtainBuffer(Buffer * audioBuffer,int32_t waitCount)492 status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
493 {
494     AutoMutex lock(mLock);
495     int active;
496     status_t result = NO_ERROR;
497     audio_track_cblk_t* cblk = mCblk;
498     uint32_t framesReq = audioBuffer->frameCount;
499     uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS;
500 
501     audioBuffer->frameCount  = 0;
502     audioBuffer->size        = 0;
503 
504     uint32_t framesReady = cblk->framesReady();
505 
506     if (framesReady == 0) {
507         cblk->lock.lock();
508         goto start_loop_here;
509         while (framesReady == 0) {
510             active = mActive;
511             if (UNLIKELY(!active)) {
512                 cblk->lock.unlock();
513                 return NO_MORE_BUFFERS;
514             }
515             if (UNLIKELY(!waitCount)) {
516                 cblk->lock.unlock();
517                 return WOULD_BLOCK;
518             }
519             if (!(cblk->flags & CBLK_INVALID_MSK)) {
520                 mLock.unlock();
521                 result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
522                 cblk->lock.unlock();
523                 mLock.lock();
524                 if (mActive == 0) {
525                     return status_t(STOPPED);
526                 }
527                 cblk->lock.lock();
528             }
529             if (cblk->flags & CBLK_INVALID_MSK) {
530                 goto create_new_record;
531             }
532             if (__builtin_expect(result!=NO_ERROR, false)) {
533                 cblk->waitTimeMs += waitTimeMs;
534                 if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) {
535                     LOGW(   "obtainBuffer timed out (is the CPU pegged?) "
536                             "user=%08x, server=%08x", cblk->user, cblk->server);
537                     cblk->lock.unlock();
538                     result = mAudioRecord->start();
539                     cblk->lock.lock();
540                     if (result == DEAD_OBJECT) {
541                         android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
542 create_new_record:
543                         result = AudioRecord::restoreRecord_l(cblk);
544                     }
545                     if (result != NO_ERROR) {
546                         LOGW("obtainBuffer create Track error %d", result);
547                         cblk->lock.unlock();
548                         return result;
549                     }
550                     cblk->waitTimeMs = 0;
551                 }
552                 if (--waitCount == 0) {
553                     cblk->lock.unlock();
554                     return TIMED_OUT;
555                 }
556             }
557             // read the server count again
558         start_loop_here:
559             framesReady = cblk->framesReady();
560         }
561         cblk->lock.unlock();
562     }
563 
564     cblk->waitTimeMs = 0;
565 
566     if (framesReq > framesReady) {
567         framesReq = framesReady;
568     }
569 
570     uint32_t u = cblk->user;
571     uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
572 
573     if (u + framesReq > bufferEnd) {
574         framesReq = bufferEnd - u;
575     }
576 
577     audioBuffer->flags       = 0;
578     audioBuffer->channelCount= mChannelCount;
579     audioBuffer->format      = mFormat;
580     audioBuffer->frameCount  = framesReq;
581     audioBuffer->size        = framesReq*cblk->frameSize;
582     audioBuffer->raw         = (int8_t*)cblk->buffer(u);
583     active = mActive;
584     return active ? status_t(NO_ERROR) : status_t(STOPPED);
585 }
586 
releaseBuffer(Buffer * audioBuffer)587 void AudioRecord::releaseBuffer(Buffer* audioBuffer)
588 {
589     AutoMutex lock(mLock);
590     mCblk->stepUser(audioBuffer->frameCount);
591 }
592 
getInput()593 audio_io_handle_t AudioRecord::getInput()
594 {
595     AutoMutex lock(mLock);
596     return mInput;
597 }
598 
599 // must be called with mLock held
getInput_l()600 audio_io_handle_t AudioRecord::getInput_l()
601 {
602     mInput = AudioSystem::getInput(mInputSource,
603                                 mCblk->sampleRate,
604                                 mFormat,
605                                 mChannelMask,
606                                 (audio_in_acoustics_t)mFlags,
607                                 mSessionId);
608     return mInput;
609 }
610 
getSessionId()611 int AudioRecord::getSessionId()
612 {
613     return mSessionId;
614 }
615 
616 // -------------------------------------------------------------------------
617 
read(void * buffer,size_t userSize)618 ssize_t AudioRecord::read(void* buffer, size_t userSize)
619 {
620     ssize_t read = 0;
621     Buffer audioBuffer;
622     int8_t *dst = static_cast<int8_t*>(buffer);
623 
624     if (ssize_t(userSize) < 0) {
625         // sanity-check. user is most-likely passing an error code.
626         LOGE("AudioRecord::read(buffer=%p, size=%u (%d)",
627                 buffer, userSize, userSize);
628         return BAD_VALUE;
629     }
630 
631     mLock.lock();
632     // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed
633     // while we are accessing the cblk
634     sp <IAudioRecord> audioRecord = mAudioRecord;
635     sp <IMemory> iMem = mCblkMemory;
636     mLock.unlock();
637 
638     do {
639 
640         audioBuffer.frameCount = userSize/frameSize();
641 
642         // By using a wait count corresponding to twice the timeout period in
643         // obtainBuffer() we give a chance to recover once for a read timeout
644         // (if media_server crashed for instance) before returning a length of
645         // 0 bytes read to the client
646         status_t err = obtainBuffer(&audioBuffer, ((2 * MAX_RUN_TIMEOUT_MS) / WAIT_PERIOD_MS));
647         if (err < 0) {
648             // out of buffers, return #bytes written
649             if (err == status_t(NO_MORE_BUFFERS))
650                 break;
651             if (err == status_t(TIMED_OUT))
652                 err = 0;
653             return ssize_t(err);
654         }
655 
656         size_t bytesRead = audioBuffer.size;
657         memcpy(dst, audioBuffer.i8, bytesRead);
658 
659         dst += bytesRead;
660         userSize -= bytesRead;
661         read += bytesRead;
662 
663         releaseBuffer(&audioBuffer);
664     } while (userSize);
665 
666     return read;
667 }
668 
669 // -------------------------------------------------------------------------
670 
processAudioBuffer(const sp<ClientRecordThread> & thread)671 bool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread)
672 {
673     Buffer audioBuffer;
674     uint32_t frames = mRemainingFrames;
675     size_t readSize;
676 
677     mLock.lock();
678     // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed
679     // while we are accessing the cblk
680     sp <IAudioRecord> audioRecord = mAudioRecord;
681     sp <IMemory> iMem = mCblkMemory;
682     audio_track_cblk_t* cblk = mCblk;
683     mLock.unlock();
684 
685     // Manage marker callback
686     if (!mMarkerReached && (mMarkerPosition > 0)) {
687         if (cblk->user >= mMarkerPosition) {
688             mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition);
689             mMarkerReached = true;
690         }
691     }
692 
693     // Manage new position callback
694     if (mUpdatePeriod > 0) {
695         while (cblk->user >= mNewPosition) {
696             mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition);
697             mNewPosition += mUpdatePeriod;
698         }
699     }
700 
701     do {
702         audioBuffer.frameCount = frames;
703         // Calling obtainBuffer() with a wait count of 1
704         // limits wait time to WAIT_PERIOD_MS. This prevents from being
705         // stuck here not being able to handle timed events (position, markers).
706         status_t err = obtainBuffer(&audioBuffer, 1);
707         if (err < NO_ERROR) {
708             if (err != TIMED_OUT) {
709                 LOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up.");
710                 return false;
711             }
712             break;
713         }
714         if (err == status_t(STOPPED)) return false;
715 
716         size_t reqSize = audioBuffer.size;
717         mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer);
718         readSize = audioBuffer.size;
719 
720         // Sanity check on returned size
721         if (ssize_t(readSize) <= 0) {
722             // The callback is done filling buffers
723             // Keep this thread going to handle timed events and
724             // still try to get more data in intervals of WAIT_PERIOD_MS
725             // but don't just loop and block the CPU, so wait
726             usleep(WAIT_PERIOD_MS*1000);
727             break;
728         }
729         if (readSize > reqSize) readSize = reqSize;
730 
731         audioBuffer.size = readSize;
732         audioBuffer.frameCount = readSize/frameSize();
733         frames -= audioBuffer.frameCount;
734 
735         releaseBuffer(&audioBuffer);
736 
737     } while (frames);
738 
739 
740     // Manage overrun callback
741     if (mActive && (cblk->framesAvailable() == 0)) {
742         LOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags);
743         if (!(android_atomic_or(CBLK_UNDERRUN_ON, &cblk->flags) & CBLK_UNDERRUN_MSK)) {
744             mCbf(EVENT_OVERRUN, mUserData, 0);
745         }
746     }
747 
748     if (frames == 0) {
749         mRemainingFrames = mNotificationFrames;
750     } else {
751         mRemainingFrames = frames;
752     }
753     return true;
754 }
755 
756 // must be called with mLock and cblk.lock held. Callers must also hold strong references on
757 // the IAudioRecord and IMemory in case they are recreated here.
758 // If the IAudioRecord is successfully restored, the cblk pointer is updated
restoreRecord_l(audio_track_cblk_t * & cblk)759 status_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& cblk)
760 {
761     status_t result;
762 
763     if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) {
764         LOGW("dead IAudioRecord, creating a new one");
765         // signal old cblk condition so that other threads waiting for available buffers stop
766         // waiting now
767         cblk->cv.broadcast();
768         cblk->lock.unlock();
769 
770         // if the new IAudioRecord is created, openRecord_l() will modify the
771         // following member variables: mAudioRecord, mCblkMemory and mCblk.
772         // It will also delete the strong references on previous IAudioRecord and IMemory
773         result = openRecord_l(cblk->sampleRate, mFormat, mChannelMask,
774                 mFrameCount, mFlags, getInput_l());
775         if (result == NO_ERROR) {
776             result = mAudioRecord->start();
777         }
778         if (result != NO_ERROR) {
779             mActive = false;
780         }
781 
782         // signal old cblk condition for other threads waiting for restore completion
783         android_atomic_or(CBLK_RESTORED_ON, &cblk->flags);
784         cblk->cv.broadcast();
785     } else {
786         if (!(cblk->flags & CBLK_RESTORED_MSK)) {
787             LOGW("dead IAudioRecord, waiting for a new one to be created");
788             mLock.unlock();
789             result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS));
790             cblk->lock.unlock();
791             mLock.lock();
792         } else {
793             LOGW("dead IAudioRecord, already restored");
794             result = NO_ERROR;
795             cblk->lock.unlock();
796         }
797         if (result != NO_ERROR || mActive == 0) {
798             result = status_t(STOPPED);
799         }
800     }
801     LOGV("restoreRecord_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x",
802          result, mActive, mCblk, cblk, mCblk->flags, cblk->flags);
803 
804     if (result == NO_ERROR) {
805         // from now on we switch to the newly created cblk
806         cblk = mCblk;
807     }
808     cblk->lock.lock();
809 
810     LOGW_IF(result != NO_ERROR, "restoreRecord_l() error %d", result);
811 
812     return result;
813 }
814 
815 // =========================================================================
816 
ClientRecordThread(AudioRecord & receiver,bool bCanCallJava)817 AudioRecord::ClientRecordThread::ClientRecordThread(AudioRecord& receiver, bool bCanCallJava)
818     : Thread(bCanCallJava), mReceiver(receiver)
819 {
820 }
821 
threadLoop()822 bool AudioRecord::ClientRecordThread::threadLoop()
823 {
824     return mReceiver.processAudioBuffer(this);
825 }
826 
827 // -------------------------------------------------------------------------
828 
829 }; // namespace android
830 
831