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