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