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 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 68 AudioRecord::AudioRecord() 69 : mStatus(NO_INIT), mSessionId(AUDIO_SESSION_ALLOCATE), 70 mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT) 71 { 72 } 73 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 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 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 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 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 338 bool AudioRecord::stopped() const 339 { 340 AutoMutex lock(mLock); 341 return !mActive; 342 } 343 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 358 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 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 384 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 396 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 408 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 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 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 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 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 707 audio_io_handle_t AudioRecord::getInput() const 708 { 709 AutoMutex lock(mLock); 710 return mInput; 711 } 712 713 // ------------------------------------------------------------------------- 714 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 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 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 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 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 1035 AudioRecord::AudioRecordThread::~AudioRecordThread() 1036 { 1037 } 1038 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 1082 void AudioRecord::AudioRecordThread::requestExit() 1083 { 1084 // must be in this order to avoid a race condition 1085 Thread::requestExit(); 1086 resume(); 1087 } 1088 1089 void AudioRecord::AudioRecordThread::pause() 1090 { 1091 AutoMutex _l(mMyLock); 1092 mPaused = true; 1093 } 1094 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 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