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