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 43 #define LIKELY( exp ) (__builtin_expect( (exp) != 0, true )) 44 #define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) 45 46 namespace android { 47 // --------------------------------------------------------------------------- 48 49 // static 50 status_t AudioRecord::getMinFrameCount( 51 int* frameCount, 52 uint32_t sampleRate, 53 int format, 54 int channelCount) 55 { 56 size_t size = 0; 57 if (AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &size) 58 != NO_ERROR) { 59 LOGE("AudioSystem could not query the input buffer size."); 60 return NO_INIT; 61 } 62 63 if (size == 0) { 64 LOGE("Unsupported configuration: sampleRate %d, format %d, channelCount %d", 65 sampleRate, format, channelCount); 66 return BAD_VALUE; 67 } 68 69 // We double the size of input buffer for ping pong use of record buffer. 70 size <<= 1; 71 72 if (audio_is_linear_pcm(format)) { 73 size /= channelCount * audio_bytes_per_sample(format); 74 } 75 76 *frameCount = size; 77 return NO_ERROR; 78 } 79 80 // --------------------------------------------------------------------------- 81 82 AudioRecord::AudioRecord() 83 : mStatus(NO_INIT), mSessionId(0) 84 { 85 } 86 87 AudioRecord::AudioRecord( 88 int inputSource, 89 uint32_t sampleRate, 90 int format, 91 uint32_t channelMask, 92 int frameCount, 93 uint32_t flags, 94 callback_t cbf, 95 void* user, 96 int notificationFrames, 97 int sessionId) 98 : mStatus(NO_INIT), mSessionId(0) 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 int inputSource, 123 uint32_t sampleRate, 124 int format, 125 uint32_t channelMask, 126 int frameCount, 127 uint32_t flags, 128 callback_t cbf, 129 void* user, 130 int notificationFrames, 131 bool threadCanCallJava, 132 int sessionId) 133 { 134 135 LOGV("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 == 0) { 152 format = AUDIO_FORMAT_PCM_16_BIT; 153 } 154 // validate parameters 155 if (!audio_is_valid_format(format)) { 156 LOGE("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 LOGV("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 LOGE("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 LOGV("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, flags, input); 205 if (status != NO_ERROR) { 206 return status; 207 } 208 209 if (cbf != 0) { 210 mClientRecordThread = new ClientRecordThread(*this, threadCanCallJava); 211 if (mClientRecordThread == 0) { 212 return NO_INIT; 213 } 214 } 215 216 mStatus = NO_ERROR; 217 218 mFormat = format; 219 // Update buffer size in case it has been limited by AudioFlinger during track creation 220 mFrameCount = mCblk->frameCount; 221 mChannelCount = (uint8_t)channelCount; 222 mChannelMask = channelMask; 223 mActive = 0; 224 mCbf = cbf; 225 mNotificationFrames = notificationFrames; 226 mRemainingFrames = notificationFrames; 227 mUserData = user; 228 // TODO: add audio hardware input latency here 229 mLatency = (1000*mFrameCount) / sampleRate; 230 mMarkerPosition = 0; 231 mMarkerReached = false; 232 mNewPosition = 0; 233 mUpdatePeriod = 0; 234 mInputSource = (uint8_t)inputSource; 235 mFlags = flags; 236 mInput = input; 237 AudioSystem::acquireAudioSessionId(mSessionId); 238 239 return NO_ERROR; 240 } 241 242 status_t AudioRecord::initCheck() const 243 { 244 return mStatus; 245 } 246 247 // ------------------------------------------------------------------------- 248 249 uint32_t AudioRecord::latency() const 250 { 251 return mLatency; 252 } 253 254 int AudioRecord::format() const 255 { 256 return mFormat; 257 } 258 259 int AudioRecord::channelCount() const 260 { 261 return mChannelCount; 262 } 263 264 uint32_t AudioRecord::frameCount() const 265 { 266 return mFrameCount; 267 } 268 269 int AudioRecord::frameSize() const 270 { 271 if (audio_is_linear_pcm(mFormat)) { 272 return channelCount()*audio_bytes_per_sample(mFormat); 273 } else { 274 return sizeof(uint8_t); 275 } 276 } 277 278 int AudioRecord::inputSource() const 279 { 280 return (int)mInputSource; 281 } 282 283 // ------------------------------------------------------------------------- 284 285 status_t AudioRecord::start() 286 { 287 status_t ret = NO_ERROR; 288 sp<ClientRecordThread> t = mClientRecordThread; 289 290 LOGV("start"); 291 292 if (t != 0) { 293 if (t->exitPending()) { 294 if (t->requestExitAndWait() == WOULD_BLOCK) { 295 LOGE("AudioRecord::start called from thread"); 296 return WOULD_BLOCK; 297 } 298 } 299 t->mLock.lock(); 300 } 301 302 AutoMutex lock(mLock); 303 // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed 304 // while we are accessing the cblk 305 sp <IAudioRecord> audioRecord = mAudioRecord; 306 sp <IMemory> iMem = mCblkMemory; 307 audio_track_cblk_t* cblk = mCblk; 308 if (mActive == 0) { 309 mActive = 1; 310 311 cblk->lock.lock(); 312 if (!(cblk->flags & CBLK_INVALID_MSK)) { 313 cblk->lock.unlock(); 314 ret = mAudioRecord->start(); 315 cblk->lock.lock(); 316 if (ret == DEAD_OBJECT) { 317 android_atomic_or(CBLK_INVALID_ON, &cblk->flags); 318 } 319 } 320 if (cblk->flags & CBLK_INVALID_MSK) { 321 ret = restoreRecord_l(cblk); 322 } 323 cblk->lock.unlock(); 324 if (ret == NO_ERROR) { 325 mNewPosition = cblk->user + mUpdatePeriod; 326 cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 327 cblk->waitTimeMs = 0; 328 if (t != 0) { 329 t->run("ClientRecordThread", ANDROID_PRIORITY_AUDIO); 330 } else { 331 setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO); 332 } 333 } else { 334 mActive = 0; 335 } 336 } 337 338 if (t != 0) { 339 t->mLock.unlock(); 340 } 341 342 return ret; 343 } 344 345 status_t AudioRecord::stop() 346 { 347 sp<ClientRecordThread> t = mClientRecordThread; 348 349 LOGV("stop"); 350 351 if (t != 0) { 352 t->mLock.lock(); 353 } 354 355 AutoMutex lock(mLock); 356 if (mActive == 1) { 357 mActive = 0; 358 mCblk->cv.signal(); 359 mAudioRecord->stop(); 360 // the record head position will reset to 0, so if a marker is set, we need 361 // to activate it again 362 mMarkerReached = false; 363 if (t != 0) { 364 t->requestExit(); 365 } else { 366 setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL); 367 } 368 } 369 370 if (t != 0) { 371 t->mLock.unlock(); 372 } 373 374 return NO_ERROR; 375 } 376 377 bool AudioRecord::stopped() const 378 { 379 return !mActive; 380 } 381 382 uint32_t AudioRecord::getSampleRate() 383 { 384 AutoMutex lock(mLock); 385 return mCblk->sampleRate; 386 } 387 388 status_t AudioRecord::setMarkerPosition(uint32_t marker) 389 { 390 if (mCbf == 0) return INVALID_OPERATION; 391 392 mMarkerPosition = marker; 393 mMarkerReached = false; 394 395 return NO_ERROR; 396 } 397 398 status_t AudioRecord::getMarkerPosition(uint32_t *marker) 399 { 400 if (marker == 0) return BAD_VALUE; 401 402 *marker = mMarkerPosition; 403 404 return NO_ERROR; 405 } 406 407 status_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod) 408 { 409 if (mCbf == 0) return INVALID_OPERATION; 410 411 uint32_t curPosition; 412 getPosition(&curPosition); 413 mNewPosition = curPosition + updatePeriod; 414 mUpdatePeriod = updatePeriod; 415 416 return NO_ERROR; 417 } 418 419 status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) 420 { 421 if (updatePeriod == 0) return BAD_VALUE; 422 423 *updatePeriod = mUpdatePeriod; 424 425 return NO_ERROR; 426 } 427 428 status_t AudioRecord::getPosition(uint32_t *position) 429 { 430 if (position == 0) return BAD_VALUE; 431 432 AutoMutex lock(mLock); 433 *position = mCblk->user; 434 435 return NO_ERROR; 436 } 437 438 unsigned int AudioRecord::getInputFramesLost() 439 { 440 if (mActive) 441 return AudioSystem::getInputFramesLost(mInput); 442 else 443 return 0; 444 } 445 446 // ------------------------------------------------------------------------- 447 448 // must be called with mLock held 449 status_t AudioRecord::openRecord_l( 450 uint32_t sampleRate, 451 uint32_t format, 452 uint32_t channelMask, 453 int frameCount, 454 uint32_t flags, 455 audio_io_handle_t input) 456 { 457 status_t status; 458 const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); 459 if (audioFlinger == 0) { 460 return NO_INIT; 461 } 462 463 sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), input, 464 sampleRate, format, 465 channelMask, 466 frameCount, 467 ((uint16_t)flags) << 16, 468 &mSessionId, 469 &status); 470 471 if (record == 0) { 472 LOGE("AudioFlinger could not create record track, status: %d", status); 473 return status; 474 } 475 sp<IMemory> cblk = record->getCblk(); 476 if (cblk == 0) { 477 LOGE("Could not get control block"); 478 return NO_INIT; 479 } 480 mAudioRecord.clear(); 481 mAudioRecord = record; 482 mCblkMemory.clear(); 483 mCblkMemory = cblk; 484 mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); 485 mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); 486 android_atomic_and(~CBLK_DIRECTION_MSK, &mCblk->flags); 487 mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 488 mCblk->waitTimeMs = 0; 489 return NO_ERROR; 490 } 491 492 status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) 493 { 494 AutoMutex lock(mLock); 495 int active; 496 status_t result = NO_ERROR; 497 audio_track_cblk_t* cblk = mCblk; 498 uint32_t framesReq = audioBuffer->frameCount; 499 uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS; 500 501 audioBuffer->frameCount = 0; 502 audioBuffer->size = 0; 503 504 uint32_t framesReady = cblk->framesReady(); 505 506 if (framesReady == 0) { 507 cblk->lock.lock(); 508 goto start_loop_here; 509 while (framesReady == 0) { 510 active = mActive; 511 if (UNLIKELY(!active)) { 512 cblk->lock.unlock(); 513 return NO_MORE_BUFFERS; 514 } 515 if (UNLIKELY(!waitCount)) { 516 cblk->lock.unlock(); 517 return WOULD_BLOCK; 518 } 519 if (!(cblk->flags & CBLK_INVALID_MSK)) { 520 mLock.unlock(); 521 result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs)); 522 cblk->lock.unlock(); 523 mLock.lock(); 524 if (mActive == 0) { 525 return status_t(STOPPED); 526 } 527 cblk->lock.lock(); 528 } 529 if (cblk->flags & CBLK_INVALID_MSK) { 530 goto create_new_record; 531 } 532 if (__builtin_expect(result!=NO_ERROR, false)) { 533 cblk->waitTimeMs += waitTimeMs; 534 if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) { 535 LOGW( "obtainBuffer timed out (is the CPU pegged?) " 536 "user=%08x, server=%08x", cblk->user, cblk->server); 537 cblk->lock.unlock(); 538 result = mAudioRecord->start(); 539 cblk->lock.lock(); 540 if (result == DEAD_OBJECT) { 541 android_atomic_or(CBLK_INVALID_ON, &cblk->flags); 542 create_new_record: 543 result = AudioRecord::restoreRecord_l(cblk); 544 } 545 if (result != NO_ERROR) { 546 LOGW("obtainBuffer create Track error %d", result); 547 cblk->lock.unlock(); 548 return result; 549 } 550 cblk->waitTimeMs = 0; 551 } 552 if (--waitCount == 0) { 553 cblk->lock.unlock(); 554 return TIMED_OUT; 555 } 556 } 557 // read the server count again 558 start_loop_here: 559 framesReady = cblk->framesReady(); 560 } 561 cblk->lock.unlock(); 562 } 563 564 cblk->waitTimeMs = 0; 565 566 if (framesReq > framesReady) { 567 framesReq = framesReady; 568 } 569 570 uint32_t u = cblk->user; 571 uint32_t bufferEnd = cblk->userBase + cblk->frameCount; 572 573 if (u + framesReq > bufferEnd) { 574 framesReq = bufferEnd - u; 575 } 576 577 audioBuffer->flags = 0; 578 audioBuffer->channelCount= mChannelCount; 579 audioBuffer->format = mFormat; 580 audioBuffer->frameCount = framesReq; 581 audioBuffer->size = framesReq*cblk->frameSize; 582 audioBuffer->raw = (int8_t*)cblk->buffer(u); 583 active = mActive; 584 return active ? status_t(NO_ERROR) : status_t(STOPPED); 585 } 586 587 void AudioRecord::releaseBuffer(Buffer* audioBuffer) 588 { 589 AutoMutex lock(mLock); 590 mCblk->stepUser(audioBuffer->frameCount); 591 } 592 593 audio_io_handle_t AudioRecord::getInput() 594 { 595 AutoMutex lock(mLock); 596 return mInput; 597 } 598 599 // must be called with mLock held 600 audio_io_handle_t AudioRecord::getInput_l() 601 { 602 mInput = AudioSystem::getInput(mInputSource, 603 mCblk->sampleRate, 604 mFormat, 605 mChannelMask, 606 (audio_in_acoustics_t)mFlags, 607 mSessionId); 608 return mInput; 609 } 610 611 int AudioRecord::getSessionId() 612 { 613 return mSessionId; 614 } 615 616 // ------------------------------------------------------------------------- 617 618 ssize_t AudioRecord::read(void* buffer, size_t userSize) 619 { 620 ssize_t read = 0; 621 Buffer audioBuffer; 622 int8_t *dst = static_cast<int8_t*>(buffer); 623 624 if (ssize_t(userSize) < 0) { 625 // sanity-check. user is most-likely passing an error code. 626 LOGE("AudioRecord::read(buffer=%p, size=%u (%d)", 627 buffer, userSize, userSize); 628 return BAD_VALUE; 629 } 630 631 mLock.lock(); 632 // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed 633 // while we are accessing the cblk 634 sp <IAudioRecord> audioRecord = mAudioRecord; 635 sp <IMemory> iMem = mCblkMemory; 636 mLock.unlock(); 637 638 do { 639 640 audioBuffer.frameCount = userSize/frameSize(); 641 642 // By using a wait count corresponding to twice the timeout period in 643 // obtainBuffer() we give a chance to recover once for a read timeout 644 // (if media_server crashed for instance) before returning a length of 645 // 0 bytes read to the client 646 status_t err = obtainBuffer(&audioBuffer, ((2 * MAX_RUN_TIMEOUT_MS) / WAIT_PERIOD_MS)); 647 if (err < 0) { 648 // out of buffers, return #bytes written 649 if (err == status_t(NO_MORE_BUFFERS)) 650 break; 651 if (err == status_t(TIMED_OUT)) 652 err = 0; 653 return ssize_t(err); 654 } 655 656 size_t bytesRead = audioBuffer.size; 657 memcpy(dst, audioBuffer.i8, bytesRead); 658 659 dst += bytesRead; 660 userSize -= bytesRead; 661 read += bytesRead; 662 663 releaseBuffer(&audioBuffer); 664 } while (userSize); 665 666 return read; 667 } 668 669 // ------------------------------------------------------------------------- 670 671 bool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread) 672 { 673 Buffer audioBuffer; 674 uint32_t frames = mRemainingFrames; 675 size_t readSize; 676 677 mLock.lock(); 678 // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed 679 // while we are accessing the cblk 680 sp <IAudioRecord> audioRecord = mAudioRecord; 681 sp <IMemory> iMem = mCblkMemory; 682 audio_track_cblk_t* cblk = mCblk; 683 mLock.unlock(); 684 685 // Manage marker callback 686 if (!mMarkerReached && (mMarkerPosition > 0)) { 687 if (cblk->user >= mMarkerPosition) { 688 mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition); 689 mMarkerReached = true; 690 } 691 } 692 693 // Manage new position callback 694 if (mUpdatePeriod > 0) { 695 while (cblk->user >= mNewPosition) { 696 mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition); 697 mNewPosition += mUpdatePeriod; 698 } 699 } 700 701 do { 702 audioBuffer.frameCount = frames; 703 // Calling obtainBuffer() with a wait count of 1 704 // limits wait time to WAIT_PERIOD_MS. This prevents from being 705 // stuck here not being able to handle timed events (position, markers). 706 status_t err = obtainBuffer(&audioBuffer, 1); 707 if (err < NO_ERROR) { 708 if (err != TIMED_OUT) { 709 LOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up."); 710 return false; 711 } 712 break; 713 } 714 if (err == status_t(STOPPED)) return false; 715 716 size_t reqSize = audioBuffer.size; 717 mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); 718 readSize = audioBuffer.size; 719 720 // Sanity check on returned size 721 if (ssize_t(readSize) <= 0) { 722 // The callback is done filling buffers 723 // Keep this thread going to handle timed events and 724 // still try to get more data in intervals of WAIT_PERIOD_MS 725 // but don't just loop and block the CPU, so wait 726 usleep(WAIT_PERIOD_MS*1000); 727 break; 728 } 729 if (readSize > reqSize) readSize = reqSize; 730 731 audioBuffer.size = readSize; 732 audioBuffer.frameCount = readSize/frameSize(); 733 frames -= audioBuffer.frameCount; 734 735 releaseBuffer(&audioBuffer); 736 737 } while (frames); 738 739 740 // Manage overrun callback 741 if (mActive && (cblk->framesAvailable() == 0)) { 742 LOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags); 743 if (!(android_atomic_or(CBLK_UNDERRUN_ON, &cblk->flags) & CBLK_UNDERRUN_MSK)) { 744 mCbf(EVENT_OVERRUN, mUserData, 0); 745 } 746 } 747 748 if (frames == 0) { 749 mRemainingFrames = mNotificationFrames; 750 } else { 751 mRemainingFrames = frames; 752 } 753 return true; 754 } 755 756 // must be called with mLock and cblk.lock held. Callers must also hold strong references on 757 // the IAudioRecord and IMemory in case they are recreated here. 758 // If the IAudioRecord is successfully restored, the cblk pointer is updated 759 status_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& cblk) 760 { 761 status_t result; 762 763 if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) { 764 LOGW("dead IAudioRecord, creating a new one"); 765 // signal old cblk condition so that other threads waiting for available buffers stop 766 // waiting now 767 cblk->cv.broadcast(); 768 cblk->lock.unlock(); 769 770 // if the new IAudioRecord is created, openRecord_l() will modify the 771 // following member variables: mAudioRecord, mCblkMemory and mCblk. 772 // It will also delete the strong references on previous IAudioRecord and IMemory 773 result = openRecord_l(cblk->sampleRate, mFormat, mChannelMask, 774 mFrameCount, mFlags, getInput_l()); 775 if (result == NO_ERROR) { 776 result = mAudioRecord->start(); 777 } 778 if (result != NO_ERROR) { 779 mActive = false; 780 } 781 782 // signal old cblk condition for other threads waiting for restore completion 783 android_atomic_or(CBLK_RESTORED_ON, &cblk->flags); 784 cblk->cv.broadcast(); 785 } else { 786 if (!(cblk->flags & CBLK_RESTORED_MSK)) { 787 LOGW("dead IAudioRecord, waiting for a new one to be created"); 788 mLock.unlock(); 789 result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS)); 790 cblk->lock.unlock(); 791 mLock.lock(); 792 } else { 793 LOGW("dead IAudioRecord, already restored"); 794 result = NO_ERROR; 795 cblk->lock.unlock(); 796 } 797 if (result != NO_ERROR || mActive == 0) { 798 result = status_t(STOPPED); 799 } 800 } 801 LOGV("restoreRecord_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x", 802 result, mActive, mCblk, cblk, mCblk->flags, cblk->flags); 803 804 if (result == NO_ERROR) { 805 // from now on we switch to the newly created cblk 806 cblk = mCblk; 807 } 808 cblk->lock.lock(); 809 810 LOGW_IF(result != NO_ERROR, "restoreRecord_l() error %d", result); 811 812 return result; 813 } 814 815 // ========================================================================= 816 817 AudioRecord::ClientRecordThread::ClientRecordThread(AudioRecord& receiver, bool bCanCallJava) 818 : Thread(bCanCallJava), mReceiver(receiver) 819 { 820 } 821 822 bool AudioRecord::ClientRecordThread::threadLoop() 823 { 824 return mReceiver.processAudioBuffer(this); 825 } 826 827 // ------------------------------------------------------------------------- 828 829 }; // namespace android 830 831