1 /* 2 ** 3 ** Copyright 2008, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 //#define LOG_NDEBUG 0 19 #define LOG_TAG "AudioRecord" 20 21 #include <stdint.h> 22 #include <sys/types.h> 23 24 #include <sched.h> 25 #include <sys/resource.h> 26 27 #include <private/media/AudioTrackShared.h> 28 29 #include <media/AudioSystem.h> 30 #include <media/AudioRecord.h> 31 #include <media/mediarecorder.h> 32 33 #include <binder/IServiceManager.h> 34 #include <utils/Log.h> 35 #include <binder/Parcel.h> 36 #include <binder/IPCThreadState.h> 37 #include <utils/Timers.h> 38 #include <utils/Atomic.h> 39 40 #include <system/audio.h> 41 #include <cutils/bitops.h> 42 #include <cutils/compiler.h> 43 44 namespace android { 45 // --------------------------------------------------------------------------- 46 47 // static 48 status_t AudioRecord::getMinFrameCount( 49 int* frameCount, 50 uint32_t sampleRate, 51 audio_format_t format, 52 int channelCount) 53 { 54 size_t size = 0; 55 if (AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &size) 56 != NO_ERROR) { 57 ALOGE("AudioSystem could not query the input buffer size."); 58 return NO_INIT; 59 } 60 61 if (size == 0) { 62 ALOGE("Unsupported configuration: sampleRate %d, format %d, channelCount %d", 63 sampleRate, format, channelCount); 64 return BAD_VALUE; 65 } 66 67 // We double the size of input buffer for ping pong use of record buffer. 68 size <<= 1; 69 70 if (audio_is_linear_pcm(format)) { 71 size /= channelCount * audio_bytes_per_sample(format); 72 } 73 74 *frameCount = size; 75 return NO_ERROR; 76 } 77 78 // --------------------------------------------------------------------------- 79 80 AudioRecord::AudioRecord() 81 : mStatus(NO_INIT), mSessionId(0), 82 mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT) 83 { 84 } 85 86 AudioRecord::AudioRecord( 87 audio_source_t inputSource, 88 uint32_t sampleRate, 89 audio_format_t format, 90 uint32_t channelMask, 91 int frameCount, 92 record_flags flags, 93 callback_t cbf, 94 void* user, 95 int notificationFrames, 96 int sessionId) 97 : mStatus(NO_INIT), mSessionId(0), 98 mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT) 99 { 100 mStatus = set(inputSource, sampleRate, format, channelMask, 101 frameCount, flags, cbf, user, notificationFrames, sessionId); 102 } 103 104 AudioRecord::~AudioRecord() 105 { 106 if (mStatus == NO_ERROR) { 107 // Make sure that callback function exits in the case where 108 // it is looping on buffer empty condition in obtainBuffer(). 109 // Otherwise the callback thread will never exit. 110 stop(); 111 if (mClientRecordThread != 0) { 112 mClientRecordThread->requestExitAndWait(); 113 mClientRecordThread.clear(); 114 } 115 mAudioRecord.clear(); 116 IPCThreadState::self()->flushCommands(); 117 AudioSystem::releaseAudioSessionId(mSessionId); 118 } 119 } 120 121 status_t AudioRecord::set( 122 audio_source_t inputSource, 123 uint32_t sampleRate, 124 audio_format_t format, 125 uint32_t channelMask, 126 int frameCount, 127 record_flags flags, 128 callback_t cbf, 129 void* user, 130 int notificationFrames, 131 bool threadCanCallJava, 132 int sessionId) 133 { 134 135 ALOGV("set(): sampleRate %d, channelMask %d, frameCount %d",sampleRate, channelMask, frameCount); 136 137 AutoMutex lock(mLock); 138 139 if (mAudioRecord != 0) { 140 return INVALID_OPERATION; 141 } 142 143 if (inputSource == AUDIO_SOURCE_DEFAULT) { 144 inputSource = AUDIO_SOURCE_MIC; 145 } 146 147 if (sampleRate == 0) { 148 sampleRate = DEFAULT_SAMPLE_RATE; 149 } 150 // these below should probably come from the audioFlinger too... 151 if (format == AUDIO_FORMAT_DEFAULT) { 152 format = AUDIO_FORMAT_PCM_16_BIT; 153 } 154 // validate parameters 155 if (!audio_is_valid_format(format)) { 156 ALOGE("Invalid format"); 157 return BAD_VALUE; 158 } 159 160 if (!audio_is_input_channel(channelMask)) { 161 return BAD_VALUE; 162 } 163 164 int channelCount = popcount(channelMask); 165 166 if (sessionId == 0 ) { 167 mSessionId = AudioSystem::newAudioSessionId(); 168 } else { 169 mSessionId = sessionId; 170 } 171 ALOGV("set(): mSessionId %d", mSessionId); 172 173 audio_io_handle_t input = AudioSystem::getInput(inputSource, 174 sampleRate, 175 format, 176 channelMask, 177 (audio_in_acoustics_t)flags, 178 mSessionId); 179 if (input == 0) { 180 ALOGE("Could not get audio input for record source %d", inputSource); 181 return BAD_VALUE; 182 } 183 184 // validate framecount 185 int minFrameCount = 0; 186 status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelCount); 187 if (status != NO_ERROR) { 188 return status; 189 } 190 ALOGV("AudioRecord::set() minFrameCount = %d", minFrameCount); 191 192 if (frameCount == 0) { 193 frameCount = minFrameCount; 194 } else if (frameCount < minFrameCount) { 195 return BAD_VALUE; 196 } 197 198 if (notificationFrames == 0) { 199 notificationFrames = frameCount/2; 200 } 201 202 // create the IAudioRecord 203 status = openRecord_l(sampleRate, format, channelMask, 204 frameCount, input); 205 if (status != NO_ERROR) { 206 return status; 207 } 208 209 if (cbf != NULL) { 210 mClientRecordThread = new ClientRecordThread(*this, threadCanCallJava); 211 } 212 213 mStatus = NO_ERROR; 214 215 mFormat = format; 216 // Update buffer size in case it has been limited by AudioFlinger during track creation 217 mFrameCount = mCblk->frameCount; 218 mChannelCount = (uint8_t)channelCount; 219 mChannelMask = channelMask; 220 mActive = 0; 221 mCbf = cbf; 222 mNotificationFrames = notificationFrames; 223 mRemainingFrames = notificationFrames; 224 mUserData = user; 225 // TODO: add audio hardware input latency here 226 mLatency = (1000*mFrameCount) / sampleRate; 227 mMarkerPosition = 0; 228 mMarkerReached = false; 229 mNewPosition = 0; 230 mUpdatePeriod = 0; 231 mInputSource = inputSource; 232 mFlags = flags; 233 mInput = input; 234 AudioSystem::acquireAudioSessionId(mSessionId); 235 236 return NO_ERROR; 237 } 238 239 status_t AudioRecord::initCheck() const 240 { 241 return mStatus; 242 } 243 244 // ------------------------------------------------------------------------- 245 246 uint32_t AudioRecord::latency() const 247 { 248 return mLatency; 249 } 250 251 audio_format_t AudioRecord::format() const 252 { 253 return mFormat; 254 } 255 256 int AudioRecord::channelCount() const 257 { 258 return mChannelCount; 259 } 260 261 uint32_t AudioRecord::frameCount() const 262 { 263 return mFrameCount; 264 } 265 266 size_t AudioRecord::frameSize() const 267 { 268 if (audio_is_linear_pcm(mFormat)) { 269 return channelCount()*audio_bytes_per_sample(mFormat); 270 } else { 271 return sizeof(uint8_t); 272 } 273 } 274 275 audio_source_t AudioRecord::inputSource() const 276 { 277 return mInputSource; 278 } 279 280 // ------------------------------------------------------------------------- 281 282 status_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession) 283 { 284 status_t ret = NO_ERROR; 285 sp<ClientRecordThread> t = mClientRecordThread; 286 287 ALOGV("start, sync event %d trigger session %d", event, triggerSession); 288 289 if (t != 0) { 290 if (t->exitPending()) { 291 if (t->requestExitAndWait() == WOULD_BLOCK) { 292 ALOGE("AudioRecord::start called from thread"); 293 return WOULD_BLOCK; 294 } 295 } 296 } 297 298 AutoMutex lock(mLock); 299 // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed 300 // while we are accessing the cblk 301 sp<IAudioRecord> audioRecord = mAudioRecord; 302 sp<IMemory> iMem = mCblkMemory; 303 audio_track_cblk_t* cblk = mCblk; 304 if (mActive == 0) { 305 mActive = 1; 306 307 pid_t tid; 308 if (t != 0) { 309 mReadyToRun = WOULD_BLOCK; 310 t->run("AudioRecord", ANDROID_PRIORITY_AUDIO); 311 tid = t->getTid(); // pid_t is unknown until run() 312 ALOGV("getTid=%d", tid); 313 if (tid == -1) { 314 tid = 0; 315 } 316 // thread blocks in readyToRun() 317 } else { 318 tid = 0; // not gettid() 319 } 320 321 cblk->lock.lock(); 322 if (!(cblk->flags & CBLK_INVALID_MSK)) { 323 cblk->lock.unlock(); 324 ALOGV("mAudioRecord->start()"); 325 ret = mAudioRecord->start(event, triggerSession); 326 cblk->lock.lock(); 327 if (ret == DEAD_OBJECT) { 328 android_atomic_or(CBLK_INVALID_ON, &cblk->flags); 329 } 330 } 331 if (cblk->flags & CBLK_INVALID_MSK) { 332 ret = restoreRecord_l(cblk); 333 } 334 cblk->lock.unlock(); 335 if (ret == NO_ERROR) { 336 mNewPosition = cblk->user + mUpdatePeriod; 337 cblk->bufferTimeoutMs = (event == AudioSystem::SYNC_EVENT_NONE) ? MAX_RUN_TIMEOUT_MS : 338 AudioSystem::kSyncRecordStartTimeOutMs; 339 cblk->waitTimeMs = 0; 340 if (t != 0) { 341 // thread unblocks in readyToRun() and returns NO_ERROR 342 mReadyToRun = NO_ERROR; 343 mCondition.signal(); 344 } else { 345 mPreviousPriority = getpriority(PRIO_PROCESS, 0); 346 get_sched_policy(0, &mPreviousSchedulingGroup); 347 androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO); 348 } 349 } else { 350 mActive = 0; 351 // thread unblocks in readyToRun() and returns NO_INIT 352 mReadyToRun = NO_INIT; 353 mCondition.signal(); 354 } 355 } 356 357 return ret; 358 } 359 360 status_t AudioRecord::stop() 361 { 362 sp<ClientRecordThread> t = mClientRecordThread; 363 364 ALOGV("stop"); 365 366 AutoMutex lock(mLock); 367 if (mActive == 1) { 368 mActive = 0; 369 mCblk->cv.signal(); 370 mAudioRecord->stop(); 371 // the record head position will reset to 0, so if a marker is set, we need 372 // to activate it again 373 mMarkerReached = false; 374 if (t != 0) { 375 t->requestExit(); 376 } else { 377 setpriority(PRIO_PROCESS, 0, mPreviousPriority); 378 set_sched_policy(0, mPreviousSchedulingGroup); 379 } 380 } 381 382 return NO_ERROR; 383 } 384 385 bool AudioRecord::stopped() const 386 { 387 return !mActive; 388 } 389 390 uint32_t AudioRecord::getSampleRate() const 391 { 392 AutoMutex lock(mLock); 393 return mCblk->sampleRate; 394 } 395 396 status_t AudioRecord::setMarkerPosition(uint32_t marker) 397 { 398 if (mCbf == NULL) return INVALID_OPERATION; 399 400 mMarkerPosition = marker; 401 mMarkerReached = false; 402 403 return NO_ERROR; 404 } 405 406 status_t AudioRecord::getMarkerPosition(uint32_t *marker) const 407 { 408 if (marker == NULL) return BAD_VALUE; 409 410 *marker = mMarkerPosition; 411 412 return NO_ERROR; 413 } 414 415 status_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod) 416 { 417 if (mCbf == NULL) return INVALID_OPERATION; 418 419 uint32_t curPosition; 420 getPosition(&curPosition); 421 mNewPosition = curPosition + updatePeriod; 422 mUpdatePeriod = updatePeriod; 423 424 return NO_ERROR; 425 } 426 427 status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) const 428 { 429 if (updatePeriod == NULL) return BAD_VALUE; 430 431 *updatePeriod = mUpdatePeriod; 432 433 return NO_ERROR; 434 } 435 436 status_t AudioRecord::getPosition(uint32_t *position) const 437 { 438 if (position == NULL) return BAD_VALUE; 439 440 AutoMutex lock(mLock); 441 *position = mCblk->user; 442 443 return NO_ERROR; 444 } 445 446 unsigned int AudioRecord::getInputFramesLost() const 447 { 448 if (mActive) 449 return AudioSystem::getInputFramesLost(mInput); 450 else 451 return 0; 452 } 453 454 // ------------------------------------------------------------------------- 455 456 // must be called with mLock held 457 status_t AudioRecord::openRecord_l( 458 uint32_t sampleRate, 459 audio_format_t format, 460 uint32_t channelMask, 461 int frameCount, 462 audio_io_handle_t input) 463 { 464 status_t status; 465 const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); 466 if (audioFlinger == 0) { 467 return NO_INIT; 468 } 469 470 sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), input, 471 sampleRate, format, 472 channelMask, 473 frameCount, 474 IAudioFlinger::TRACK_DEFAULT, 475 &mSessionId, 476 &status); 477 478 if (record == 0) { 479 ALOGE("AudioFlinger could not create record track, status: %d", status); 480 return status; 481 } 482 sp<IMemory> cblk = record->getCblk(); 483 if (cblk == 0) { 484 ALOGE("Could not get control block"); 485 return NO_INIT; 486 } 487 mAudioRecord.clear(); 488 mAudioRecord = record; 489 mCblkMemory.clear(); 490 mCblkMemory = cblk; 491 mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); 492 mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); 493 android_atomic_and(~CBLK_DIRECTION_MSK, &mCblk->flags); 494 mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 495 mCblk->waitTimeMs = 0; 496 return NO_ERROR; 497 } 498 499 status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) 500 { 501 AutoMutex lock(mLock); 502 int active; 503 status_t result = NO_ERROR; 504 audio_track_cblk_t* cblk = mCblk; 505 uint32_t framesReq = audioBuffer->frameCount; 506 uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS; 507 508 audioBuffer->frameCount = 0; 509 audioBuffer->size = 0; 510 511 uint32_t framesReady = cblk->framesReady(); 512 513 if (framesReady == 0) { 514 cblk->lock.lock(); 515 goto start_loop_here; 516 while (framesReady == 0) { 517 active = mActive; 518 if (CC_UNLIKELY(!active)) { 519 cblk->lock.unlock(); 520 return NO_MORE_BUFFERS; 521 } 522 if (CC_UNLIKELY(!waitCount)) { 523 cblk->lock.unlock(); 524 return WOULD_BLOCK; 525 } 526 if (!(cblk->flags & CBLK_INVALID_MSK)) { 527 mLock.unlock(); 528 result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs)); 529 cblk->lock.unlock(); 530 mLock.lock(); 531 if (mActive == 0) { 532 return status_t(STOPPED); 533 } 534 cblk->lock.lock(); 535 } 536 if (cblk->flags & CBLK_INVALID_MSK) { 537 goto create_new_record; 538 } 539 if (CC_UNLIKELY(result != NO_ERROR)) { 540 cblk->waitTimeMs += waitTimeMs; 541 if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) { 542 ALOGW( "obtainBuffer timed out (is the CPU pegged?) " 543 "user=%08x, server=%08x", cblk->user, cblk->server); 544 cblk->lock.unlock(); 545 // callback thread or sync event hasn't changed 546 result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0); 547 cblk->lock.lock(); 548 if (result == DEAD_OBJECT) { 549 android_atomic_or(CBLK_INVALID_ON, &cblk->flags); 550 create_new_record: 551 result = AudioRecord::restoreRecord_l(cblk); 552 } 553 if (result != NO_ERROR) { 554 ALOGW("obtainBuffer create Track error %d", result); 555 cblk->lock.unlock(); 556 return result; 557 } 558 cblk->waitTimeMs = 0; 559 } 560 if (--waitCount == 0) { 561 cblk->lock.unlock(); 562 return TIMED_OUT; 563 } 564 } 565 // read the server count again 566 start_loop_here: 567 framesReady = cblk->framesReady(); 568 } 569 cblk->lock.unlock(); 570 } 571 572 cblk->waitTimeMs = 0; 573 // reset time out to running value after obtaining a buffer 574 cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 575 576 if (framesReq > framesReady) { 577 framesReq = framesReady; 578 } 579 580 uint32_t u = cblk->user; 581 uint32_t bufferEnd = cblk->userBase + cblk->frameCount; 582 583 if (framesReq > bufferEnd - u) { 584 framesReq = bufferEnd - u; 585 } 586 587 audioBuffer->flags = 0; 588 audioBuffer->channelCount= mChannelCount; 589 audioBuffer->format = mFormat; 590 audioBuffer->frameCount = framesReq; 591 audioBuffer->size = framesReq*cblk->frameSize; 592 audioBuffer->raw = (int8_t*)cblk->buffer(u); 593 active = mActive; 594 return active ? status_t(NO_ERROR) : status_t(STOPPED); 595 } 596 597 void AudioRecord::releaseBuffer(Buffer* audioBuffer) 598 { 599 AutoMutex lock(mLock); 600 mCblk->stepUser(audioBuffer->frameCount); 601 } 602 603 audio_io_handle_t AudioRecord::getInput() const 604 { 605 AutoMutex lock(mLock); 606 return mInput; 607 } 608 609 // must be called with mLock held 610 audio_io_handle_t AudioRecord::getInput_l() 611 { 612 mInput = AudioSystem::getInput(mInputSource, 613 mCblk->sampleRate, 614 mFormat, 615 mChannelMask, 616 (audio_in_acoustics_t)mFlags, 617 mSessionId); 618 return mInput; 619 } 620 621 int AudioRecord::getSessionId() const 622 { 623 return mSessionId; 624 } 625 626 // ------------------------------------------------------------------------- 627 628 ssize_t AudioRecord::read(void* buffer, size_t userSize) 629 { 630 ssize_t read = 0; 631 Buffer audioBuffer; 632 int8_t *dst = static_cast<int8_t*>(buffer); 633 634 if (ssize_t(userSize) < 0) { 635 // sanity-check. user is most-likely passing an error code. 636 ALOGE("AudioRecord::read(buffer=%p, size=%u (%d)", 637 buffer, userSize, userSize); 638 return BAD_VALUE; 639 } 640 641 mLock.lock(); 642 // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed 643 // while we are accessing the cblk 644 sp<IAudioRecord> audioRecord = mAudioRecord; 645 sp<IMemory> iMem = mCblkMemory; 646 mLock.unlock(); 647 648 do { 649 650 audioBuffer.frameCount = userSize/frameSize(); 651 652 // By using a wait count corresponding to twice the timeout period in 653 // obtainBuffer() we give a chance to recover once for a read timeout 654 // (if media_server crashed for instance) before returning a length of 655 // 0 bytes read to the client 656 status_t err = obtainBuffer(&audioBuffer, ((2 * MAX_RUN_TIMEOUT_MS) / WAIT_PERIOD_MS)); 657 if (err < 0) { 658 // out of buffers, return #bytes written 659 if (err == status_t(NO_MORE_BUFFERS)) 660 break; 661 if (err == status_t(TIMED_OUT)) 662 err = 0; 663 return ssize_t(err); 664 } 665 666 size_t bytesRead = audioBuffer.size; 667 memcpy(dst, audioBuffer.i8, bytesRead); 668 669 dst += bytesRead; 670 userSize -= bytesRead; 671 read += bytesRead; 672 673 releaseBuffer(&audioBuffer); 674 } while (userSize); 675 676 return read; 677 } 678 679 // ------------------------------------------------------------------------- 680 681 bool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread) 682 { 683 Buffer audioBuffer; 684 uint32_t frames = mRemainingFrames; 685 size_t readSize; 686 687 mLock.lock(); 688 // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed 689 // while we are accessing the cblk 690 sp<IAudioRecord> audioRecord = mAudioRecord; 691 sp<IMemory> iMem = mCblkMemory; 692 audio_track_cblk_t* cblk = mCblk; 693 mLock.unlock(); 694 695 // Manage marker callback 696 if (!mMarkerReached && (mMarkerPosition > 0)) { 697 if (cblk->user >= mMarkerPosition) { 698 mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition); 699 mMarkerReached = true; 700 } 701 } 702 703 // Manage new position callback 704 if (mUpdatePeriod > 0) { 705 while (cblk->user >= mNewPosition) { 706 mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition); 707 mNewPosition += mUpdatePeriod; 708 } 709 } 710 711 do { 712 audioBuffer.frameCount = frames; 713 // Calling obtainBuffer() with a wait count of 1 714 // limits wait time to WAIT_PERIOD_MS. This prevents from being 715 // stuck here not being able to handle timed events (position, markers). 716 status_t err = obtainBuffer(&audioBuffer, 1); 717 if (err < NO_ERROR) { 718 if (err != TIMED_OUT) { 719 ALOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up."); 720 return false; 721 } 722 break; 723 } 724 if (err == status_t(STOPPED)) return false; 725 726 size_t reqSize = audioBuffer.size; 727 mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); 728 readSize = audioBuffer.size; 729 730 // Sanity check on returned size 731 if (ssize_t(readSize) <= 0) { 732 // The callback is done filling buffers 733 // Keep this thread going to handle timed events and 734 // still try to get more data in intervals of WAIT_PERIOD_MS 735 // but don't just loop and block the CPU, so wait 736 usleep(WAIT_PERIOD_MS*1000); 737 break; 738 } 739 if (readSize > reqSize) readSize = reqSize; 740 741 audioBuffer.size = readSize; 742 audioBuffer.frameCount = readSize/frameSize(); 743 frames -= audioBuffer.frameCount; 744 745 releaseBuffer(&audioBuffer); 746 747 } while (frames); 748 749 750 // Manage overrun callback 751 if (mActive && (cblk->framesAvailable() == 0)) { 752 ALOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags); 753 if (!(android_atomic_or(CBLK_UNDERRUN_ON, &cblk->flags) & CBLK_UNDERRUN_MSK)) { 754 mCbf(EVENT_OVERRUN, mUserData, 0); 755 } 756 } 757 758 if (frames == 0) { 759 mRemainingFrames = mNotificationFrames; 760 } else { 761 mRemainingFrames = frames; 762 } 763 return true; 764 } 765 766 // must be called with mLock and cblk.lock held. Callers must also hold strong references on 767 // the IAudioRecord and IMemory in case they are recreated here. 768 // If the IAudioRecord is successfully restored, the cblk pointer is updated 769 status_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& cblk) 770 { 771 status_t result; 772 773 if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) { 774 ALOGW("dead IAudioRecord, creating a new one"); 775 // signal old cblk condition so that other threads waiting for available buffers stop 776 // waiting now 777 cblk->cv.broadcast(); 778 cblk->lock.unlock(); 779 780 // if the new IAudioRecord is created, openRecord_l() will modify the 781 // following member variables: mAudioRecord, mCblkMemory and mCblk. 782 // It will also delete the strong references on previous IAudioRecord and IMemory 783 result = openRecord_l(cblk->sampleRate, mFormat, mChannelMask, 784 mFrameCount, getInput_l()); 785 if (result == NO_ERROR) { 786 // callback thread or sync event hasn't changed 787 result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0); 788 } 789 if (result != NO_ERROR) { 790 mActive = false; 791 } 792 793 // signal old cblk condition for other threads waiting for restore completion 794 android_atomic_or(CBLK_RESTORED_ON, &cblk->flags); 795 cblk->cv.broadcast(); 796 } else { 797 if (!(cblk->flags & CBLK_RESTORED_MSK)) { 798 ALOGW("dead IAudioRecord, waiting for a new one to be created"); 799 mLock.unlock(); 800 result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS)); 801 cblk->lock.unlock(); 802 mLock.lock(); 803 } else { 804 ALOGW("dead IAudioRecord, already restored"); 805 result = NO_ERROR; 806 cblk->lock.unlock(); 807 } 808 if (result != NO_ERROR || mActive == 0) { 809 result = status_t(STOPPED); 810 } 811 } 812 ALOGV("restoreRecord_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x", 813 result, mActive, mCblk, cblk, mCblk->flags, cblk->flags); 814 815 if (result == NO_ERROR) { 816 // from now on we switch to the newly created cblk 817 cblk = mCblk; 818 } 819 cblk->lock.lock(); 820 821 ALOGW_IF(result != NO_ERROR, "restoreRecord_l() error %d", result); 822 823 return result; 824 } 825 826 // ========================================================================= 827 828 AudioRecord::ClientRecordThread::ClientRecordThread(AudioRecord& receiver, bool bCanCallJava) 829 : Thread(bCanCallJava), mReceiver(receiver) 830 { 831 } 832 833 bool AudioRecord::ClientRecordThread::threadLoop() 834 { 835 return mReceiver.processAudioBuffer(this); 836 } 837 838 status_t AudioRecord::ClientRecordThread::readyToRun() 839 { 840 AutoMutex(mReceiver.mLock); 841 while (mReceiver.mReadyToRun == WOULD_BLOCK) { 842 mReceiver.mCondition.wait(mReceiver.mLock); 843 } 844 return mReceiver.mReadyToRun; 845 } 846 847 // ------------------------------------------------------------------------- 848 849 }; // namespace android 850