AudioRecord.cpp revision 3e1acc0c58b337dec4054d78c28b48b2e77e0784
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 32namespace android { 33// --------------------------------------------------------------------------- 34 35// static 36status_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 68AudioRecord::AudioRecord(const String16 &opPackageName) 69 : mActive(false), mStatus(NO_INIT), mOpPackageName(opPackageName), 70 mSessionId(AUDIO_SESSION_ALLOCATE), 71 mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT), 72 mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE), mRoutedDeviceId(AUDIO_PORT_HANDLE_NONE) 73{ 74} 75 76AudioRecord::AudioRecord( 77 audio_source_t inputSource, 78 uint32_t sampleRate, 79 audio_format_t format, 80 audio_channel_mask_t channelMask, 81 const String16& opPackageName, 82 size_t frameCount, 83 callback_t cbf, 84 void* user, 85 uint32_t notificationFrames, 86 audio_session_t sessionId, 87 transfer_type transferType, 88 audio_input_flags_t flags, 89 uid_t uid, 90 pid_t pid, 91 const audio_attributes_t* pAttributes, 92 audio_port_handle_t selectedDeviceId) 93 : mActive(false), 94 mStatus(NO_INIT), 95 mOpPackageName(opPackageName), 96 mSessionId(AUDIO_SESSION_ALLOCATE), 97 mPreviousPriority(ANDROID_PRIORITY_NORMAL), 98 mPreviousSchedulingGroup(SP_DEFAULT), 99 mProxy(NULL) 100{ 101 (void)set(inputSource, sampleRate, format, channelMask, frameCount, cbf, user, 102 notificationFrames, false /*threadCanCallJava*/, sessionId, transferType, flags, 103 uid, pid, pAttributes, selectedDeviceId); 104} 105 106AudioRecord::~AudioRecord() 107{ 108 if (mStatus == NO_ERROR) { 109 // Make sure that callback function exits in the case where 110 // it is looping on buffer empty condition in obtainBuffer(). 111 // Otherwise the callback thread will never exit. 112 stop(); 113 if (mAudioRecordThread != 0) { 114 mProxy->interrupt(); 115 mAudioRecordThread->requestExit(); // see comment in AudioRecord.h 116 mAudioRecordThread->requestExitAndWait(); 117 mAudioRecordThread.clear(); 118 } 119 // No lock here: worst case we remove a NULL callback which will be a nop 120 if (mDeviceCallback != 0 && mInput != AUDIO_IO_HANDLE_NONE) { 121 AudioSystem::removeAudioDeviceCallback(this, mInput); 122 } 123 IInterface::asBinder(mAudioRecord)->unlinkToDeath(mDeathNotifier, this); 124 mAudioRecord.clear(); 125 mCblkMemory.clear(); 126 mBufferMemory.clear(); 127 IPCThreadState::self()->flushCommands(); 128 ALOGV("~AudioRecord, releasing session id %d", 129 mSessionId); 130 AudioSystem::releaseAudioSessionId(mSessionId, -1 /*pid*/); 131 } 132} 133 134status_t AudioRecord::set( 135 audio_source_t inputSource, 136 uint32_t sampleRate, 137 audio_format_t format, 138 audio_channel_mask_t channelMask, 139 size_t frameCount, 140 callback_t cbf, 141 void* user, 142 uint32_t notificationFrames, 143 bool threadCanCallJava, 144 audio_session_t sessionId, 145 transfer_type transferType, 146 audio_input_flags_t flags, 147 uid_t uid, 148 pid_t pid, 149 const audio_attributes_t* pAttributes, 150 audio_port_handle_t selectedDeviceId) 151{ 152 status_t status = NO_ERROR; 153 uint32_t channelCount; 154 pid_t callingPid; 155 pid_t myPid; 156 157 ALOGV("set(): inputSource %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, " 158 "notificationFrames %u, sessionId %d, transferType %d, flags %#x, opPackageName %s " 159 "uid %d, pid %d", 160 inputSource, sampleRate, format, channelMask, frameCount, notificationFrames, 161 sessionId, transferType, flags, String8(mOpPackageName).string(), uid, pid); 162 163 mSelectedDeviceId = selectedDeviceId; 164 165 switch (transferType) { 166 case TRANSFER_DEFAULT: 167 if (cbf == NULL || threadCanCallJava) { 168 transferType = TRANSFER_SYNC; 169 } else { 170 transferType = TRANSFER_CALLBACK; 171 } 172 break; 173 case TRANSFER_CALLBACK: 174 if (cbf == NULL) { 175 ALOGE("Transfer type TRANSFER_CALLBACK but cbf == NULL"); 176 status = BAD_VALUE; 177 goto exit; 178 } 179 break; 180 case TRANSFER_OBTAIN: 181 case TRANSFER_SYNC: 182 break; 183 default: 184 ALOGE("Invalid transfer type %d", transferType); 185 status = BAD_VALUE; 186 goto exit; 187 } 188 mTransfer = transferType; 189 190 // invariant that mAudioRecord != 0 is true only after set() returns successfully 191 if (mAudioRecord != 0) { 192 ALOGE("Track already in use"); 193 status = INVALID_OPERATION; 194 goto exit; 195 } 196 197 if (pAttributes == NULL) { 198 memset(&mAttributes, 0, sizeof(audio_attributes_t)); 199 mAttributes.source = inputSource; 200 } else { 201 // stream type shouldn't be looked at, this track has audio attributes 202 memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t)); 203 ALOGV("Building AudioRecord with attributes: source=%d flags=0x%x tags=[%s]", 204 mAttributes.source, mAttributes.flags, mAttributes.tags); 205 } 206 207 mSampleRate = sampleRate; 208 209 // these below should probably come from the audioFlinger too... 210 if (format == AUDIO_FORMAT_DEFAULT) { 211 format = AUDIO_FORMAT_PCM_16_BIT; 212 } 213 214 // validate parameters 215 // AudioFlinger capture only supports linear PCM 216 if (!audio_is_valid_format(format) || !audio_is_linear_pcm(format)) { 217 ALOGE("Format %#x is not linear pcm", format); 218 status = BAD_VALUE; 219 goto exit; 220 } 221 mFormat = format; 222 223 if (!audio_is_input_channel(channelMask)) { 224 ALOGE("Invalid channel mask %#x", channelMask); 225 status = BAD_VALUE; 226 goto exit; 227 } 228 mChannelMask = channelMask; 229 channelCount = audio_channel_count_from_in_mask(channelMask); 230 mChannelCount = channelCount; 231 232 if (audio_is_linear_pcm(format)) { 233 mFrameSize = channelCount * audio_bytes_per_sample(format); 234 } else { 235 mFrameSize = sizeof(uint8_t); 236 } 237 238 // mFrameCount is initialized in createRecord_l 239 mReqFrameCount = frameCount; 240 241 mNotificationFramesReq = notificationFrames; 242 // mNotificationFramesAct is initialized in createRecord_l 243 244 mSessionId = sessionId; 245 ALOGV("set(): mSessionId %d", mSessionId); 246 247 callingPid = IPCThreadState::self()->getCallingPid(); 248 myPid = getpid(); 249 if (uid == AUDIO_UID_INVALID || (callingPid != myPid)) { 250 mClientUid = IPCThreadState::self()->getCallingUid(); 251 } else { 252 mClientUid = uid; 253 } 254 if (pid == -1 || (callingPid != myPid)) { 255 mClientPid = callingPid; 256 } else { 257 mClientPid = pid; 258 } 259 260 mOrigFlags = mFlags = flags; 261 mCbf = cbf; 262 263 if (cbf != NULL) { 264 mAudioRecordThread = new AudioRecordThread(*this, threadCanCallJava); 265 mAudioRecordThread->run("AudioRecord", ANDROID_PRIORITY_AUDIO); 266 // thread begins in paused state, and will not reference us until start() 267 } 268 269 // create the IAudioRecord 270 status = createRecord_l(0 /*epoch*/, mOpPackageName); 271 272 if (status != NO_ERROR) { 273 if (mAudioRecordThread != 0) { 274 mAudioRecordThread->requestExit(); // see comment in AudioRecord.h 275 mAudioRecordThread->requestExitAndWait(); 276 mAudioRecordThread.clear(); 277 } 278 goto exit; 279 } 280 281 mUserData = user; 282 // TODO: add audio hardware input latency here 283 mLatency = (1000LL * mFrameCount) / mSampleRate; 284 mMarkerPosition = 0; 285 mMarkerReached = false; 286 mNewPosition = 0; 287 mUpdatePeriod = 0; 288 AudioSystem::acquireAudioSessionId(mSessionId, -1); 289 mSequence = 1; 290 mObservedSequence = mSequence; 291 mInOverrun = false; 292 mFramesRead = 0; 293 mFramesReadServerOffset = 0; 294 295exit: 296 mStatus = status; 297 return status; 298} 299 300// ------------------------------------------------------------------------- 301 302status_t AudioRecord::start(AudioSystem::sync_event_t event, audio_session_t triggerSession) 303{ 304 ALOGV("start, sync event %d trigger session %d", event, triggerSession); 305 306 AutoMutex lock(mLock); 307 if (mActive) { 308 return NO_ERROR; 309 } 310 311 // discard data in buffer 312 const uint32_t framesFlushed = mProxy->flush(); 313 mFramesReadServerOffset -= mFramesRead + framesFlushed; 314 mFramesRead = 0; 315 mProxy->clearTimestamp(); // timestamp is invalid until next server push 316 317 // reset current position as seen by client to 0 318 mProxy->setEpoch(mProxy->getEpoch() - mProxy->getPosition()); 319 // force refresh of remaining frames by processAudioBuffer() as last 320 // read before stop could be partial. 321 mRefreshRemaining = true; 322 323 mNewPosition = mProxy->getPosition() + mUpdatePeriod; 324 int32_t flags = android_atomic_acquire_load(&mCblk->mFlags); 325 326 // we reactivate markers (mMarkerPosition != 0) as the position is reset to 0. 327 // This is legacy behavior. This is not done in stop() to avoid a race condition 328 // where the last marker event is issued twice. 329 mMarkerReached = false; 330 mActive = true; 331 332 status_t status = NO_ERROR; 333 if (!(flags & CBLK_INVALID)) { 334 status = mAudioRecord->start(event, triggerSession).transactionError(); 335 if (status == DEAD_OBJECT) { 336 flags |= CBLK_INVALID; 337 } 338 } 339 if (flags & CBLK_INVALID) { 340 status = restoreRecord_l("start"); 341 } 342 343 if (status != NO_ERROR) { 344 mActive = false; 345 ALOGE("start() status %d", status); 346 } else { 347 sp<AudioRecordThread> t = mAudioRecordThread; 348 if (t != 0) { 349 t->resume(); 350 } else { 351 mPreviousPriority = getpriority(PRIO_PROCESS, 0); 352 get_sched_policy(0, &mPreviousSchedulingGroup); 353 androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO); 354 } 355 } 356 357 return status; 358} 359 360void AudioRecord::stop() 361{ 362 AutoMutex lock(mLock); 363 if (!mActive) { 364 return; 365 } 366 367 mActive = false; 368 mProxy->interrupt(); 369 mAudioRecord->stop(); 370 371 // Note: legacy handling - stop does not clear record marker and 372 // periodic update position; we update those on start(). 373 374 sp<AudioRecordThread> t = mAudioRecordThread; 375 if (t != 0) { 376 t->pause(); 377 } else { 378 setpriority(PRIO_PROCESS, 0, mPreviousPriority); 379 set_sched_policy(0, mPreviousSchedulingGroup); 380 } 381} 382 383bool AudioRecord::stopped() const 384{ 385 AutoMutex lock(mLock); 386 return !mActive; 387} 388 389status_t AudioRecord::setMarkerPosition(uint32_t marker) 390{ 391 // The only purpose of setting marker position is to get a callback 392 if (mCbf == NULL) { 393 return INVALID_OPERATION; 394 } 395 396 AutoMutex lock(mLock); 397 mMarkerPosition = marker; 398 mMarkerReached = false; 399 400 sp<AudioRecordThread> t = mAudioRecordThread; 401 if (t != 0) { 402 t->wake(); 403 } 404 return NO_ERROR; 405} 406 407status_t AudioRecord::getMarkerPosition(uint32_t *marker) const 408{ 409 if (marker == NULL) { 410 return BAD_VALUE; 411 } 412 413 AutoMutex lock(mLock); 414 mMarkerPosition.getValue(marker); 415 416 return NO_ERROR; 417} 418 419status_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod) 420{ 421 // The only purpose of setting position update period is to get a callback 422 if (mCbf == NULL) { 423 return INVALID_OPERATION; 424 } 425 426 AutoMutex lock(mLock); 427 mNewPosition = mProxy->getPosition() + updatePeriod; 428 mUpdatePeriod = updatePeriod; 429 430 sp<AudioRecordThread> t = mAudioRecordThread; 431 if (t != 0) { 432 t->wake(); 433 } 434 return NO_ERROR; 435} 436 437status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) const 438{ 439 if (updatePeriod == NULL) { 440 return BAD_VALUE; 441 } 442 443 AutoMutex lock(mLock); 444 *updatePeriod = mUpdatePeriod; 445 446 return NO_ERROR; 447} 448 449status_t AudioRecord::getPosition(uint32_t *position) const 450{ 451 if (position == NULL) { 452 return BAD_VALUE; 453 } 454 455 AutoMutex lock(mLock); 456 mProxy->getPosition().getValue(position); 457 458 return NO_ERROR; 459} 460 461uint32_t AudioRecord::getInputFramesLost() const 462{ 463 // no need to check mActive, because if inactive this will return 0, which is what we want 464 return AudioSystem::getInputFramesLost(getInputPrivate()); 465} 466 467status_t AudioRecord::getTimestamp(ExtendedTimestamp *timestamp) 468{ 469 if (timestamp == nullptr) { 470 return BAD_VALUE; 471 } 472 AutoMutex lock(mLock); 473 status_t status = mProxy->getTimestamp(timestamp); 474 if (status == OK) { 475 timestamp->mPosition[ExtendedTimestamp::LOCATION_CLIENT] = mFramesRead; 476 timestamp->mTimeNs[ExtendedTimestamp::LOCATION_CLIENT] = 0; 477 // server side frame offset in case AudioRecord has been restored. 478 for (int i = ExtendedTimestamp::LOCATION_SERVER; 479 i < ExtendedTimestamp::LOCATION_MAX; ++i) { 480 if (timestamp->mTimeNs[i] >= 0) { 481 timestamp->mPosition[i] += mFramesReadServerOffset; 482 } 483 } 484 } 485 return status; 486} 487 488// ---- Explicit Routing --------------------------------------------------- 489status_t AudioRecord::setInputDevice(audio_port_handle_t deviceId) { 490 AutoMutex lock(mLock); 491 if (mSelectedDeviceId != deviceId) { 492 mSelectedDeviceId = deviceId; 493 if (mStatus == NO_ERROR) { 494 // stop capture so that audio policy manager does not reject the new instance start request 495 // as only one capture can be active at a time. 496 if (mAudioRecord != 0 && mActive) { 497 mAudioRecord->stop(); 498 } 499 android_atomic_or(CBLK_INVALID, &mCblk->mFlags); 500 mProxy->interrupt(); 501 } 502 } 503 return NO_ERROR; 504} 505 506audio_port_handle_t AudioRecord::getInputDevice() { 507 AutoMutex lock(mLock); 508 return mSelectedDeviceId; 509} 510 511// must be called with mLock held 512void AudioRecord::updateRoutedDeviceId_l() 513{ 514 // if the record is inactive, do not update actual device as the input stream maybe routed 515 // from a device not relevant to this client because of other active use cases. 516 if (!mActive) { 517 return; 518 } 519 if (mInput != AUDIO_IO_HANDLE_NONE) { 520 audio_port_handle_t deviceId = AudioSystem::getDeviceIdForIo(mInput); 521 if (deviceId != AUDIO_PORT_HANDLE_NONE) { 522 mRoutedDeviceId = deviceId; 523 } 524 } 525} 526 527audio_port_handle_t AudioRecord::getRoutedDeviceId() { 528 AutoMutex lock(mLock); 529 updateRoutedDeviceId_l(); 530 return mRoutedDeviceId; 531} 532 533// ------------------------------------------------------------------------- 534// TODO Move this macro to a common header file for enum to string conversion in audio framework. 535#define MEDIA_CASE_ENUM(name) case name: return #name 536const char * AudioRecord::convertTransferToText(transfer_type transferType) { 537 switch (transferType) { 538 MEDIA_CASE_ENUM(TRANSFER_DEFAULT); 539 MEDIA_CASE_ENUM(TRANSFER_CALLBACK); 540 MEDIA_CASE_ENUM(TRANSFER_OBTAIN); 541 MEDIA_CASE_ENUM(TRANSFER_SYNC); 542 default: 543 return "UNRECOGNIZED"; 544 } 545} 546 547// must be called with mLock held 548status_t AudioRecord::createRecord_l(const Modulo<uint32_t> &epoch, const String16& opPackageName) 549{ 550 const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); 551 IAudioFlinger::CreateRecordInput input; 552 IAudioFlinger::CreateRecordOutput output; 553 audio_session_t originalSessionId; 554 sp<media::IAudioRecord> record; 555 void *iMemPointer; 556 audio_track_cblk_t* cblk; 557 status_t status; 558 559 if (audioFlinger == 0) { 560 ALOGE("Could not get audioflinger"); 561 status = NO_INIT; 562 goto exit; 563 } 564 565 // mFlags (not mOrigFlags) is modified depending on whether fast request is accepted. 566 // After fast request is denied, we will request again if IAudioRecord is re-created. 567 568 // Now that we have a reference to an I/O handle and have not yet handed it off to AudioFlinger, 569 // we must release it ourselves if anything goes wrong. 570 571 // Client can only express a preference for FAST. Server will perform additional tests. 572 if (mFlags & AUDIO_INPUT_FLAG_FAST) { 573 bool useCaseAllowed = 574 // any of these use cases: 575 // use case 1: callback transfer mode 576 (mTransfer == TRANSFER_CALLBACK) || 577 // use case 2: blocking read mode 578 // The default buffer capacity at 48 kHz is 2048 frames, or ~42.6 ms. 579 // That's enough for double-buffering with our standard 20 ms rule of thumb for 580 // the minimum period of a non-SCHED_FIFO thread. 581 // This is needed so that AAudio apps can do a low latency non-blocking read from a 582 // callback running with SCHED_FIFO. 583 (mTransfer == TRANSFER_SYNC) || 584 // use case 3: obtain/release mode 585 (mTransfer == TRANSFER_OBTAIN); 586 if (!useCaseAllowed) { 587 ALOGW("AUDIO_INPUT_FLAG_FAST denied, incompatible transfer = %s", 588 convertTransferToText(mTransfer)); 589 mFlags = (audio_input_flags_t) (mFlags & ~(AUDIO_INPUT_FLAG_FAST | 590 AUDIO_INPUT_FLAG_RAW)); 591 } 592 } 593 594 input.attr = mAttributes; 595 input.config.sample_rate = mSampleRate; 596 input.config.channel_mask = mChannelMask; 597 input.config.format = mFormat; 598 input.clientInfo.clientUid = mClientUid; 599 input.clientInfo.clientPid = mClientPid; 600 input.clientInfo.clientTid = -1; 601 if (mFlags & AUDIO_INPUT_FLAG_FAST) { 602 if (mAudioRecordThread != 0) { 603 input.clientInfo.clientTid = mAudioRecordThread->getTid(); 604 } 605 } 606 input.opPackageName = opPackageName; 607 608 input.flags = mFlags; 609 // The notification frame count is the period between callbacks, as suggested by the client 610 // but moderated by the server. For record, the calculations are done entirely on server side. 611 input.frameCount = mReqFrameCount; 612 input.notificationFrameCount = mNotificationFramesReq; 613 input.selectedDeviceId = mSelectedDeviceId; 614 input.sessionId = mSessionId; 615 originalSessionId = mSessionId; 616 617 record = audioFlinger->createRecord(input, 618 output, 619 &status); 620 621 if (status != NO_ERROR) { 622 ALOGE("AudioFlinger could not create record track, status: %d", status); 623 goto exit; 624 } 625 ALOG_ASSERT(record != 0); 626 627 // AudioFlinger now owns the reference to the I/O handle, 628 // so we are no longer responsible for releasing it. 629 630 mAwaitBoost = false; 631 if (output.flags & AUDIO_INPUT_FLAG_FAST) { 632 ALOGI("AUDIO_INPUT_FLAG_FAST successful; frameCount %zu -> %zu", 633 mReqFrameCount, output.frameCount); 634 mAwaitBoost = true; 635 } 636 mFlags = output.flags; 637 mRoutedDeviceId = output.selectedDeviceId; 638 mSessionId = output.sessionId; 639 mSampleRate = output.sampleRate; 640 641 if (output.cblk == 0) { 642 ALOGE("Could not get control block"); 643 status = NO_INIT; 644 goto exit; 645 } 646 iMemPointer = output.cblk ->pointer(); 647 if (iMemPointer == NULL) { 648 ALOGE("Could not get control block pointer"); 649 status = NO_INIT; 650 goto exit; 651 } 652 cblk = static_cast<audio_track_cblk_t*>(iMemPointer); 653 654 // Starting address of buffers in shared memory. 655 // The buffers are either immediately after the control block, 656 // or in a separate area at discretion of server. 657 void *buffers; 658 if (output.buffers == 0) { 659 buffers = cblk + 1; 660 } else { 661 buffers = output.buffers->pointer(); 662 if (buffers == NULL) { 663 ALOGE("Could not get buffer pointer"); 664 status = NO_INIT; 665 goto exit; 666 } 667 } 668 669 // invariant that mAudioRecord != 0 is true only after set() returns successfully 670 if (mAudioRecord != 0) { 671 IInterface::asBinder(mAudioRecord)->unlinkToDeath(mDeathNotifier, this); 672 mDeathNotifier.clear(); 673 } 674 mAudioRecord = record; 675 mCblkMemory = output.cblk; 676 mBufferMemory = output.buffers; 677 IPCThreadState::self()->flushCommands(); 678 679 mCblk = cblk; 680 // note that output.frameCount is the (possibly revised) value of mReqFrameCount 681 if (output.frameCount < mReqFrameCount || (mReqFrameCount == 0 && output.frameCount == 0)) { 682 ALOGW("Requested frameCount %zu but received frameCount %zu", 683 mReqFrameCount, output.frameCount); 684 } 685 686 // Make sure that application is notified with sufficient margin before overrun. 687 // The computation is done on server side. 688 if (mNotificationFramesReq > 0 && output.notificationFrameCount != mNotificationFramesReq) { 689 ALOGW("Server adjusted notificationFrames from %u to %zu for frameCount %zu", 690 mNotificationFramesReq, output.notificationFrameCount, output.frameCount); 691 } 692 mNotificationFramesAct = (uint32_t)output.notificationFrameCount; 693 694 //mInput != input includes the case where mInput == AUDIO_IO_HANDLE_NONE for first creation 695 if (mDeviceCallback != 0 && mInput != output.inputId) { 696 if (mInput != AUDIO_IO_HANDLE_NONE) { 697 AudioSystem::removeAudioDeviceCallback(this, mInput); 698 } 699 AudioSystem::addAudioDeviceCallback(this, output.inputId); 700 } 701 702 // We retain a copy of the I/O handle, but don't own the reference 703 mInput = output.inputId; 704 mRefreshRemaining = true; 705 706 mFrameCount = output.frameCount; 707 // If IAudioRecord is re-created, don't let the requested frameCount 708 // decrease. This can confuse clients that cache frameCount(). 709 if (mFrameCount > mReqFrameCount) { 710 mReqFrameCount = mFrameCount; 711 } 712 713 // update proxy 714 mProxy = new AudioRecordClientProxy(cblk, buffers, mFrameCount, mFrameSize); 715 mProxy->setEpoch(epoch); 716 mProxy->setMinimum(mNotificationFramesAct); 717 718 mDeathNotifier = new DeathNotifier(this); 719 IInterface::asBinder(mAudioRecord)->linkToDeath(mDeathNotifier, this); 720 721exit: 722 mStatus = status; 723 // sp<IAudioTrack> track destructor will cause releaseOutput() to be called by AudioFlinger 724 return status; 725} 726 727status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount, size_t *nonContig) 728{ 729 if (audioBuffer == NULL) { 730 if (nonContig != NULL) { 731 *nonContig = 0; 732 } 733 return BAD_VALUE; 734 } 735 if (mTransfer != TRANSFER_OBTAIN) { 736 audioBuffer->frameCount = 0; 737 audioBuffer->size = 0; 738 audioBuffer->raw = NULL; 739 if (nonContig != NULL) { 740 *nonContig = 0; 741 } 742 return INVALID_OPERATION; 743 } 744 745 const struct timespec *requested; 746 struct timespec timeout; 747 if (waitCount == -1) { 748 requested = &ClientProxy::kForever; 749 } else if (waitCount == 0) { 750 requested = &ClientProxy::kNonBlocking; 751 } else if (waitCount > 0) { 752 long long ms = WAIT_PERIOD_MS * (long long) waitCount; 753 timeout.tv_sec = ms / 1000; 754 timeout.tv_nsec = (int) (ms % 1000) * 1000000; 755 requested = &timeout; 756 } else { 757 ALOGE("%s invalid waitCount %d", __func__, waitCount); 758 requested = NULL; 759 } 760 return obtainBuffer(audioBuffer, requested, NULL /*elapsed*/, nonContig); 761} 762 763status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, const struct timespec *requested, 764 struct timespec *elapsed, size_t *nonContig) 765{ 766 // previous and new IAudioRecord sequence numbers are used to detect track re-creation 767 uint32_t oldSequence = 0; 768 uint32_t newSequence; 769 770 Proxy::Buffer buffer; 771 status_t status = NO_ERROR; 772 773 static const int32_t kMaxTries = 5; 774 int32_t tryCounter = kMaxTries; 775 776 do { 777 // obtainBuffer() is called with mutex unlocked, so keep extra references to these fields to 778 // keep them from going away if another thread re-creates the track during obtainBuffer() 779 sp<AudioRecordClientProxy> proxy; 780 sp<IMemory> iMem; 781 sp<IMemory> bufferMem; 782 { 783 // start of lock scope 784 AutoMutex lock(mLock); 785 786 newSequence = mSequence; 787 // did previous obtainBuffer() fail due to media server death or voluntary invalidation? 788 if (status == DEAD_OBJECT) { 789 // re-create track, unless someone else has already done so 790 if (newSequence == oldSequence) { 791 status = restoreRecord_l("obtainBuffer"); 792 if (status != NO_ERROR) { 793 buffer.mFrameCount = 0; 794 buffer.mRaw = NULL; 795 buffer.mNonContig = 0; 796 break; 797 } 798 } 799 } 800 oldSequence = newSequence; 801 802 // Keep the extra references 803 proxy = mProxy; 804 iMem = mCblkMemory; 805 bufferMem = mBufferMemory; 806 807 // Non-blocking if track is stopped 808 if (!mActive) { 809 requested = &ClientProxy::kNonBlocking; 810 } 811 812 } // end of lock scope 813 814 buffer.mFrameCount = audioBuffer->frameCount; 815 // FIXME starts the requested timeout and elapsed over from scratch 816 status = proxy->obtainBuffer(&buffer, requested, elapsed); 817 818 } while ((status == DEAD_OBJECT) && (tryCounter-- > 0)); 819 820 audioBuffer->frameCount = buffer.mFrameCount; 821 audioBuffer->size = buffer.mFrameCount * mFrameSize; 822 audioBuffer->raw = buffer.mRaw; 823 if (nonContig != NULL) { 824 *nonContig = buffer.mNonContig; 825 } 826 return status; 827} 828 829void AudioRecord::releaseBuffer(const Buffer* audioBuffer) 830{ 831 // FIXME add error checking on mode, by adding an internal version 832 833 size_t stepCount = audioBuffer->size / mFrameSize; 834 if (stepCount == 0) { 835 return; 836 } 837 838 Proxy::Buffer buffer; 839 buffer.mFrameCount = stepCount; 840 buffer.mRaw = audioBuffer->raw; 841 842 AutoMutex lock(mLock); 843 mInOverrun = false; 844 mProxy->releaseBuffer(&buffer); 845 846 // the server does not automatically disable recorder on overrun, so no need to restart 847} 848 849audio_io_handle_t AudioRecord::getInputPrivate() const 850{ 851 AutoMutex lock(mLock); 852 return mInput; 853} 854 855// ------------------------------------------------------------------------- 856 857ssize_t AudioRecord::read(void* buffer, size_t userSize, bool blocking) 858{ 859 if (mTransfer != TRANSFER_SYNC) { 860 return INVALID_OPERATION; 861 } 862 863 if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) { 864 // sanity-check. user is most-likely passing an error code, and it would 865 // make the return value ambiguous (actualSize vs error). 866 ALOGE("AudioRecord::read(buffer=%p, size=%zu (%zu)", buffer, userSize, userSize); 867 return BAD_VALUE; 868 } 869 870 ssize_t read = 0; 871 Buffer audioBuffer; 872 873 while (userSize >= mFrameSize) { 874 audioBuffer.frameCount = userSize / mFrameSize; 875 876 status_t err = obtainBuffer(&audioBuffer, 877 blocking ? &ClientProxy::kForever : &ClientProxy::kNonBlocking); 878 if (err < 0) { 879 if (read > 0) { 880 break; 881 } 882 if (err == TIMED_OUT || err == -EINTR) { 883 err = WOULD_BLOCK; 884 } 885 return ssize_t(err); 886 } 887 888 size_t bytesRead = audioBuffer.size; 889 memcpy(buffer, audioBuffer.i8, bytesRead); 890 buffer = ((char *) buffer) + bytesRead; 891 userSize -= bytesRead; 892 read += bytesRead; 893 894 releaseBuffer(&audioBuffer); 895 } 896 if (read > 0) { 897 mFramesRead += read / mFrameSize; 898 // mFramesReadTime = systemTime(SYSTEM_TIME_MONOTONIC); // not provided at this time. 899 } 900 return read; 901} 902 903// ------------------------------------------------------------------------- 904 905nsecs_t AudioRecord::processAudioBuffer() 906{ 907 mLock.lock(); 908 if (mAwaitBoost) { 909 mAwaitBoost = false; 910 mLock.unlock(); 911 static const int32_t kMaxTries = 5; 912 int32_t tryCounter = kMaxTries; 913 uint32_t pollUs = 10000; 914 do { 915 int policy = sched_getscheduler(0) & ~SCHED_RESET_ON_FORK; 916 if (policy == SCHED_FIFO || policy == SCHED_RR) { 917 break; 918 } 919 usleep(pollUs); 920 pollUs <<= 1; 921 } while (tryCounter-- > 0); 922 if (tryCounter < 0) { 923 ALOGE("did not receive expected priority boost on time"); 924 } 925 // Run again immediately 926 return 0; 927 } 928 929 // Can only reference mCblk while locked 930 int32_t flags = android_atomic_and(~CBLK_OVERRUN, &mCblk->mFlags); 931 932 // Check for track invalidation 933 if (flags & CBLK_INVALID) { 934 (void) restoreRecord_l("processAudioBuffer"); 935 mLock.unlock(); 936 // Run again immediately, but with a new IAudioRecord 937 return 0; 938 } 939 940 bool active = mActive; 941 942 // Manage overrun callback, must be done under lock to avoid race with releaseBuffer() 943 bool newOverrun = false; 944 if (flags & CBLK_OVERRUN) { 945 if (!mInOverrun) { 946 mInOverrun = true; 947 newOverrun = true; 948 } 949 } 950 951 // Get current position of server 952 Modulo<uint32_t> position(mProxy->getPosition()); 953 954 // Manage marker callback 955 bool markerReached = false; 956 Modulo<uint32_t> markerPosition(mMarkerPosition); 957 // FIXME fails for wraparound, need 64 bits 958 if (!mMarkerReached && markerPosition.value() > 0 && position >= markerPosition) { 959 mMarkerReached = markerReached = true; 960 } 961 962 // Determine the number of new position callback(s) that will be needed, while locked 963 size_t newPosCount = 0; 964 Modulo<uint32_t> newPosition(mNewPosition); 965 uint32_t updatePeriod = mUpdatePeriod; 966 // FIXME fails for wraparound, need 64 bits 967 if (updatePeriod > 0 && position >= newPosition) { 968 newPosCount = ((position - newPosition).value() / updatePeriod) + 1; 969 mNewPosition += updatePeriod * newPosCount; 970 } 971 972 // Cache other fields that will be needed soon 973 uint32_t notificationFrames = mNotificationFramesAct; 974 if (mRefreshRemaining) { 975 mRefreshRemaining = false; 976 mRemainingFrames = notificationFrames; 977 mRetryOnPartialBuffer = false; 978 } 979 size_t misalignment = mProxy->getMisalignment(); 980 uint32_t sequence = mSequence; 981 982 // These fields don't need to be cached, because they are assigned only by set(): 983 // mTransfer, mCbf, mUserData, mSampleRate, mFrameSize 984 985 mLock.unlock(); 986 987 // perform callbacks while unlocked 988 if (newOverrun) { 989 mCbf(EVENT_OVERRUN, mUserData, NULL); 990 } 991 if (markerReached) { 992 mCbf(EVENT_MARKER, mUserData, &markerPosition); 993 } 994 while (newPosCount > 0) { 995 size_t temp = newPosition.value(); // FIXME size_t != uint32_t 996 mCbf(EVENT_NEW_POS, mUserData, &temp); 997 newPosition += updatePeriod; 998 newPosCount--; 999 } 1000 if (mObservedSequence != sequence) { 1001 mObservedSequence = sequence; 1002 mCbf(EVENT_NEW_IAUDIORECORD, mUserData, NULL); 1003 } 1004 1005 // if inactive, then don't run me again until re-started 1006 if (!active) { 1007 return NS_INACTIVE; 1008 } 1009 1010 // Compute the estimated time until the next timed event (position, markers) 1011 uint32_t minFrames = ~0; 1012 if (!markerReached && position < markerPosition) { 1013 minFrames = (markerPosition - position).value(); 1014 } 1015 if (updatePeriod > 0) { 1016 uint32_t remaining = (newPosition - position).value(); 1017 if (remaining < minFrames) { 1018 minFrames = remaining; 1019 } 1020 } 1021 1022 // If > 0, poll periodically to recover from a stuck server. A good value is 2. 1023 static const uint32_t kPoll = 0; 1024 if (kPoll > 0 && mTransfer == TRANSFER_CALLBACK && kPoll * notificationFrames < minFrames) { 1025 minFrames = kPoll * notificationFrames; 1026 } 1027 1028 // Convert frame units to time units 1029 nsecs_t ns = NS_WHENEVER; 1030 if (minFrames != (uint32_t) ~0) { 1031 // This "fudge factor" avoids soaking CPU, and compensates for late progress by server 1032 static const nsecs_t kFudgeNs = 10000000LL; // 10 ms 1033 ns = ((minFrames * 1000000000LL) / mSampleRate) + kFudgeNs; 1034 } 1035 1036 // If not supplying data by EVENT_MORE_DATA, then we're done 1037 if (mTransfer != TRANSFER_CALLBACK) { 1038 return ns; 1039 } 1040 1041 struct timespec timeout; 1042 const struct timespec *requested = &ClientProxy::kForever; 1043 if (ns != NS_WHENEVER) { 1044 timeout.tv_sec = ns / 1000000000LL; 1045 timeout.tv_nsec = ns % 1000000000LL; 1046 ALOGV("timeout %ld.%03d", timeout.tv_sec, (int) timeout.tv_nsec / 1000000); 1047 requested = &timeout; 1048 } 1049 1050 size_t readFrames = 0; 1051 while (mRemainingFrames > 0) { 1052 1053 Buffer audioBuffer; 1054 audioBuffer.frameCount = mRemainingFrames; 1055 size_t nonContig; 1056 status_t err = obtainBuffer(&audioBuffer, requested, NULL, &nonContig); 1057 LOG_ALWAYS_FATAL_IF((err != NO_ERROR) != (audioBuffer.frameCount == 0), 1058 "obtainBuffer() err=%d frameCount=%zu", err, audioBuffer.frameCount); 1059 requested = &ClientProxy::kNonBlocking; 1060 size_t avail = audioBuffer.frameCount + nonContig; 1061 ALOGV("obtainBuffer(%u) returned %zu = %zu + %zu err %d", 1062 mRemainingFrames, avail, audioBuffer.frameCount, nonContig, err); 1063 if (err != NO_ERROR) { 1064 if (err == TIMED_OUT || err == WOULD_BLOCK || err == -EINTR) { 1065 break; 1066 } 1067 ALOGE("Error %d obtaining an audio buffer, giving up.", err); 1068 return NS_NEVER; 1069 } 1070 1071 if (mRetryOnPartialBuffer) { 1072 mRetryOnPartialBuffer = false; 1073 if (avail < mRemainingFrames) { 1074 int64_t myns = ((mRemainingFrames - avail) * 1075 1100000000LL) / mSampleRate; 1076 if (ns < 0 || myns < ns) { 1077 ns = myns; 1078 } 1079 return ns; 1080 } 1081 } 1082 1083 size_t reqSize = audioBuffer.size; 1084 mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); 1085 size_t readSize = audioBuffer.size; 1086 1087 // Sanity check on returned size 1088 if (ssize_t(readSize) < 0 || readSize > reqSize) { 1089 ALOGE("EVENT_MORE_DATA requested %zu bytes but callback returned %zd bytes", 1090 reqSize, ssize_t(readSize)); 1091 return NS_NEVER; 1092 } 1093 1094 if (readSize == 0) { 1095 // The callback is done consuming buffers 1096 // Keep this thread going to handle timed events and 1097 // still try to provide more data in intervals of WAIT_PERIOD_MS 1098 // but don't just loop and block the CPU, so wait 1099 return WAIT_PERIOD_MS * 1000000LL; 1100 } 1101 1102 size_t releasedFrames = readSize / mFrameSize; 1103 audioBuffer.frameCount = releasedFrames; 1104 mRemainingFrames -= releasedFrames; 1105 if (misalignment >= releasedFrames) { 1106 misalignment -= releasedFrames; 1107 } else { 1108 misalignment = 0; 1109 } 1110 1111 releaseBuffer(&audioBuffer); 1112 readFrames += releasedFrames; 1113 1114 // FIXME here is where we would repeat EVENT_MORE_DATA again on same advanced buffer 1115 // if callback doesn't like to accept the full chunk 1116 if (readSize < reqSize) { 1117 continue; 1118 } 1119 1120 // There could be enough non-contiguous frames available to satisfy the remaining request 1121 if (mRemainingFrames <= nonContig) { 1122 continue; 1123 } 1124 1125#if 0 1126 // This heuristic tries to collapse a series of EVENT_MORE_DATA that would total to a 1127 // sum <= notificationFrames. It replaces that series by at most two EVENT_MORE_DATA 1128 // that total to a sum == notificationFrames. 1129 if (0 < misalignment && misalignment <= mRemainingFrames) { 1130 mRemainingFrames = misalignment; 1131 return (mRemainingFrames * 1100000000LL) / mSampleRate; 1132 } 1133#endif 1134 1135 } 1136 if (readFrames > 0) { 1137 AutoMutex lock(mLock); 1138 mFramesRead += readFrames; 1139 // mFramesReadTime = systemTime(SYSTEM_TIME_MONOTONIC); // not provided at this time. 1140 } 1141 mRemainingFrames = notificationFrames; 1142 mRetryOnPartialBuffer = true; 1143 1144 // A lot has transpired since ns was calculated, so run again immediately and re-calculate 1145 return 0; 1146} 1147 1148status_t AudioRecord::restoreRecord_l(const char *from) 1149{ 1150 ALOGW("dead IAudioRecord, creating a new one from %s()", from); 1151 ++mSequence; 1152 1153 mFlags = mOrigFlags; 1154 1155 // if the new IAudioRecord is created, createRecord_l() will modify the 1156 // following member variables: mAudioRecord, mCblkMemory, mCblk, mBufferMemory. 1157 // It will also delete the strong references on previous IAudioRecord and IMemory 1158 Modulo<uint32_t> position(mProxy->getPosition()); 1159 mNewPosition = position + mUpdatePeriod; 1160 status_t result = createRecord_l(position, mOpPackageName); 1161 if (result == NO_ERROR) { 1162 if (mActive) { 1163 // callback thread or sync event hasn't changed 1164 // FIXME this fails if we have a new AudioFlinger instance 1165 result = mAudioRecord->start( 1166 AudioSystem::SYNC_EVENT_SAME, AUDIO_SESSION_NONE).transactionError(); 1167 } 1168 mFramesReadServerOffset = mFramesRead; // server resets to zero so we need an offset. 1169 } 1170 if (result != NO_ERROR) { 1171 ALOGW("restoreRecord_l() failed status %d", result); 1172 mActive = false; 1173 } 1174 1175 return result; 1176} 1177 1178status_t AudioRecord::addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback) 1179{ 1180 if (callback == 0) { 1181 ALOGW("%s adding NULL callback!", __FUNCTION__); 1182 return BAD_VALUE; 1183 } 1184 AutoMutex lock(mLock); 1185 if (mDeviceCallback.unsafe_get() == callback.get()) { 1186 ALOGW("%s adding same callback!", __FUNCTION__); 1187 return INVALID_OPERATION; 1188 } 1189 status_t status = NO_ERROR; 1190 if (mInput != AUDIO_IO_HANDLE_NONE) { 1191 if (mDeviceCallback != 0) { 1192 ALOGW("%s callback already present!", __FUNCTION__); 1193 AudioSystem::removeAudioDeviceCallback(this, mInput); 1194 } 1195 status = AudioSystem::addAudioDeviceCallback(this, mInput); 1196 } 1197 mDeviceCallback = callback; 1198 return status; 1199} 1200 1201status_t AudioRecord::removeAudioDeviceCallback( 1202 const sp<AudioSystem::AudioDeviceCallback>& callback) 1203{ 1204 if (callback == 0) { 1205 ALOGW("%s removing NULL callback!", __FUNCTION__); 1206 return BAD_VALUE; 1207 } 1208 AutoMutex lock(mLock); 1209 if (mDeviceCallback.unsafe_get() != callback.get()) { 1210 ALOGW("%s removing different callback!", __FUNCTION__); 1211 return INVALID_OPERATION; 1212 } 1213 mDeviceCallback.clear(); 1214 if (mInput != AUDIO_IO_HANDLE_NONE) { 1215 AudioSystem::removeAudioDeviceCallback(this, mInput); 1216 } 1217 return NO_ERROR; 1218} 1219 1220void AudioRecord::onAudioDeviceUpdate(audio_io_handle_t audioIo, 1221 audio_port_handle_t deviceId) 1222{ 1223 sp<AudioSystem::AudioDeviceCallback> callback; 1224 { 1225 AutoMutex lock(mLock); 1226 if (audioIo != mInput) { 1227 return; 1228 } 1229 callback = mDeviceCallback.promote(); 1230 // only update device if the record is active as route changes due to other use cases are 1231 // irrelevant for this client 1232 if (mActive) { 1233 mRoutedDeviceId = deviceId; 1234 } 1235 } 1236 if (callback.get() != nullptr) { 1237 callback->onAudioDeviceUpdate(mInput, mRoutedDeviceId); 1238 } 1239} 1240 1241// ========================================================================= 1242 1243void AudioRecord::DeathNotifier::binderDied(const wp<IBinder>& who __unused) 1244{ 1245 sp<AudioRecord> audioRecord = mAudioRecord.promote(); 1246 if (audioRecord != 0) { 1247 AutoMutex lock(audioRecord->mLock); 1248 audioRecord->mProxy->binderDied(); 1249 } 1250} 1251 1252// ========================================================================= 1253 1254AudioRecord::AudioRecordThread::AudioRecordThread(AudioRecord& receiver, bool bCanCallJava) 1255 : Thread(bCanCallJava), mReceiver(receiver), mPaused(true), mPausedInt(false), mPausedNs(0LL), 1256 mIgnoreNextPausedInt(false) 1257{ 1258} 1259 1260AudioRecord::AudioRecordThread::~AudioRecordThread() 1261{ 1262} 1263 1264bool AudioRecord::AudioRecordThread::threadLoop() 1265{ 1266 { 1267 AutoMutex _l(mMyLock); 1268 if (mPaused) { 1269 // TODO check return value and handle or log 1270 mMyCond.wait(mMyLock); 1271 // caller will check for exitPending() 1272 return true; 1273 } 1274 if (mIgnoreNextPausedInt) { 1275 mIgnoreNextPausedInt = false; 1276 mPausedInt = false; 1277 } 1278 if (mPausedInt) { 1279 if (mPausedNs > 0) { 1280 // TODO check return value and handle or log 1281 (void) mMyCond.waitRelative(mMyLock, mPausedNs); 1282 } else { 1283 // TODO check return value and handle or log 1284 mMyCond.wait(mMyLock); 1285 } 1286 mPausedInt = false; 1287 return true; 1288 } 1289 } 1290 if (exitPending()) { 1291 return false; 1292 } 1293 nsecs_t ns = mReceiver.processAudioBuffer(); 1294 switch (ns) { 1295 case 0: 1296 return true; 1297 case NS_INACTIVE: 1298 pauseInternal(); 1299 return true; 1300 case NS_NEVER: 1301 return false; 1302 case NS_WHENEVER: 1303 // Event driven: call wake() when callback notifications conditions change. 1304 ns = INT64_MAX; 1305 // fall through 1306 default: 1307 LOG_ALWAYS_FATAL_IF(ns < 0, "processAudioBuffer() returned %" PRId64, ns); 1308 pauseInternal(ns); 1309 return true; 1310 } 1311} 1312 1313void AudioRecord::AudioRecordThread::requestExit() 1314{ 1315 // must be in this order to avoid a race condition 1316 Thread::requestExit(); 1317 resume(); 1318} 1319 1320void AudioRecord::AudioRecordThread::pause() 1321{ 1322 AutoMutex _l(mMyLock); 1323 mPaused = true; 1324} 1325 1326void AudioRecord::AudioRecordThread::resume() 1327{ 1328 AutoMutex _l(mMyLock); 1329 mIgnoreNextPausedInt = true; 1330 if (mPaused || mPausedInt) { 1331 mPaused = false; 1332 mPausedInt = false; 1333 mMyCond.signal(); 1334 } 1335} 1336 1337void AudioRecord::AudioRecordThread::wake() 1338{ 1339 AutoMutex _l(mMyLock); 1340 if (!mPaused) { 1341 // wake() might be called while servicing a callback - ignore the next 1342 // pause time and call processAudioBuffer. 1343 mIgnoreNextPausedInt = true; 1344 if (mPausedInt && mPausedNs > 0) { 1345 // audio record is active and internally paused with timeout. 1346 mPausedInt = false; 1347 mMyCond.signal(); 1348 } 1349 } 1350} 1351 1352void AudioRecord::AudioRecordThread::pauseInternal(nsecs_t ns) 1353{ 1354 AutoMutex _l(mMyLock); 1355 mPausedInt = true; 1356 mPausedNs = ns; 1357} 1358 1359// ------------------------------------------------------------------------- 1360 1361} // namespace android 1362