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