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