Tracks.cpp revision 0bcfa88149e2404b34d13c622e3921e1b846cdf8
1/* 2** 3** Copyright 2012, 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 19#define LOG_TAG "AudioFlinger" 20//#define LOG_NDEBUG 0 21 22#include "Configuration.h" 23#include <math.h> 24#include <utils/Log.h> 25 26#include <private/media/AudioTrackShared.h> 27 28#include <common_time/cc_helper.h> 29#include <common_time/local_clock.h> 30 31#include "AudioMixer.h" 32#include "AudioFlinger.h" 33#include "ServiceUtilities.h" 34 35#include <media/nbaio/Pipe.h> 36#include <media/nbaio/PipeReader.h> 37 38// ---------------------------------------------------------------------------- 39 40// Note: the following macro is used for extremely verbose logging message. In 41// order to run with ALOG_ASSERT turned on, we need to have LOG_NDEBUG set to 42// 0; but one side effect of this is to turn all LOGV's as well. Some messages 43// are so verbose that we want to suppress them even when we have ALOG_ASSERT 44// turned on. Do not uncomment the #def below unless you really know what you 45// are doing and want to see all of the extremely verbose messages. 46//#define VERY_VERY_VERBOSE_LOGGING 47#ifdef VERY_VERY_VERBOSE_LOGGING 48#define ALOGVV ALOGV 49#else 50#define ALOGVV(a...) do { } while(0) 51#endif 52 53namespace android { 54 55// ---------------------------------------------------------------------------- 56// TrackBase 57// ---------------------------------------------------------------------------- 58 59static volatile int32_t nextTrackId = 55; 60 61// TrackBase constructor must be called with AudioFlinger::mLock held 62AudioFlinger::ThreadBase::TrackBase::TrackBase( 63 ThreadBase *thread, 64 const sp<Client>& client, 65 uint32_t sampleRate, 66 audio_format_t format, 67 audio_channel_mask_t channelMask, 68 size_t frameCount, 69 const sp<IMemory>& sharedBuffer, 70 int sessionId, 71 int clientUid, 72 bool isOut) 73 : RefBase(), 74 mThread(thread), 75 mClient(client), 76 mCblk(NULL), 77 // mBuffer 78 mState(IDLE), 79 mSampleRate(sampleRate), 80 mFormat(format), 81 mChannelMask(channelMask), 82 mChannelCount(popcount(channelMask)), 83 mFrameSize(audio_is_linear_pcm(format) ? 84 mChannelCount * audio_bytes_per_sample(format) : sizeof(int8_t)), 85 mFrameCount(frameCount), 86 mSessionId(sessionId), 87 mIsOut(isOut), 88 mServerProxy(NULL), 89 mId(android_atomic_inc(&nextTrackId)), 90 mTerminated(false) 91{ 92 // if the caller is us, trust the specified uid 93 if (IPCThreadState::self()->getCallingPid() != getpid_cached || clientUid == -1) { 94 int newclientUid = IPCThreadState::self()->getCallingUid(); 95 if (clientUid != -1 && clientUid != newclientUid) { 96 ALOGW("uid %d tried to pass itself off as %d", newclientUid, clientUid); 97 } 98 clientUid = newclientUid; 99 } 100 // clientUid contains the uid of the app that is responsible for this track, so we can blame 101 // battery usage on it. 102 mUid = clientUid; 103 104 // client == 0 implies sharedBuffer == 0 105 ALOG_ASSERT(!(client == 0 && sharedBuffer != 0)); 106 107 ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), 108 sharedBuffer->size()); 109 110 // ALOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize); 111 size_t size = sizeof(audio_track_cblk_t); 112 size_t bufferSize = (sharedBuffer == 0 ? roundup(frameCount) : frameCount) * mFrameSize; 113 if (sharedBuffer == 0) { 114 size += bufferSize; 115 } 116 117 if (client != 0) { 118 mCblkMemory = client->heap()->allocate(size); 119 if (mCblkMemory == 0 || 120 (mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer())) == NULL) { 121 ALOGE("not enough memory for AudioTrack size=%u", size); 122 client->heap()->dump("AudioTrack"); 123 mCblkMemory.clear(); 124 return; 125 } 126 } else { 127 // this syntax avoids calling the audio_track_cblk_t constructor twice 128 mCblk = (audio_track_cblk_t *) new uint8_t[size]; 129 // assume mCblk != NULL 130 } 131 132 // construct the shared structure in-place. 133 if (mCblk != NULL) { 134 new(mCblk) audio_track_cblk_t(); 135 // clear all buffers 136 mCblk->frameCount_ = frameCount; 137 if (sharedBuffer == 0) { 138 mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t); 139 memset(mBuffer, 0, bufferSize); 140 } else { 141 mBuffer = sharedBuffer->pointer(); 142#if 0 143 mCblk->mFlags = CBLK_FORCEREADY; // FIXME hack, need to fix the track ready logic 144#endif 145 } 146 147#ifdef TEE_SINK 148 if (mTeeSinkTrackEnabled) { 149 NBAIO_Format pipeFormat = Format_from_SR_C(mSampleRate, mChannelCount); 150 if (pipeFormat != Format_Invalid) { 151 Pipe *pipe = new Pipe(mTeeSinkTrackFrames, pipeFormat); 152 size_t numCounterOffers = 0; 153 const NBAIO_Format offers[1] = {pipeFormat}; 154 ssize_t index = pipe->negotiate(offers, 1, NULL, numCounterOffers); 155 ALOG_ASSERT(index == 0); 156 PipeReader *pipeReader = new PipeReader(*pipe); 157 numCounterOffers = 0; 158 index = pipeReader->negotiate(offers, 1, NULL, numCounterOffers); 159 ALOG_ASSERT(index == 0); 160 mTeeSink = pipe; 161 mTeeSource = pipeReader; 162 } 163 } 164#endif 165 166 } 167} 168 169AudioFlinger::ThreadBase::TrackBase::~TrackBase() 170{ 171#ifdef TEE_SINK 172 dumpTee(-1, mTeeSource, mId); 173#endif 174 // delete the proxy before deleting the shared memory it refers to, to avoid dangling reference 175 delete mServerProxy; 176 if (mCblk != NULL) { 177 if (mClient == 0) { 178 delete mCblk; 179 } else { 180 mCblk->~audio_track_cblk_t(); // destroy our shared-structure. 181 } 182 } 183 mCblkMemory.clear(); // free the shared memory before releasing the heap it belongs to 184 if (mClient != 0) { 185 // Client destructor must run with AudioFlinger mutex locked 186 Mutex::Autolock _l(mClient->audioFlinger()->mLock); 187 // If the client's reference count drops to zero, the associated destructor 188 // must run with AudioFlinger lock held. Thus the explicit clear() rather than 189 // relying on the automatic clear() at end of scope. 190 mClient.clear(); 191 } 192} 193 194// AudioBufferProvider interface 195// getNextBuffer() = 0; 196// This implementation of releaseBuffer() is used by Track and RecordTrack, but not TimedTrack 197void AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer) 198{ 199#ifdef TEE_SINK 200 if (mTeeSink != 0) { 201 (void) mTeeSink->write(buffer->raw, buffer->frameCount); 202 } 203#endif 204 205 ServerProxy::Buffer buf; 206 buf.mFrameCount = buffer->frameCount; 207 buf.mRaw = buffer->raw; 208 buffer->frameCount = 0; 209 buffer->raw = NULL; 210 mServerProxy->releaseBuffer(&buf); 211} 212 213status_t AudioFlinger::ThreadBase::TrackBase::setSyncEvent(const sp<SyncEvent>& event) 214{ 215 mSyncEvents.add(event); 216 return NO_ERROR; 217} 218 219// ---------------------------------------------------------------------------- 220// Playback 221// ---------------------------------------------------------------------------- 222 223AudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::PlaybackThread::Track>& track) 224 : BnAudioTrack(), 225 mTrack(track) 226{ 227} 228 229AudioFlinger::TrackHandle::~TrackHandle() { 230 // just stop the track on deletion, associated resources 231 // will be freed from the main thread once all pending buffers have 232 // been played. Unless it's not in the active track list, in which 233 // case we free everything now... 234 mTrack->destroy(); 235} 236 237sp<IMemory> AudioFlinger::TrackHandle::getCblk() const { 238 return mTrack->getCblk(); 239} 240 241status_t AudioFlinger::TrackHandle::start() { 242 return mTrack->start(); 243} 244 245void AudioFlinger::TrackHandle::stop() { 246 mTrack->stop(); 247} 248 249void AudioFlinger::TrackHandle::flush() { 250 mTrack->flush(); 251} 252 253void AudioFlinger::TrackHandle::pause() { 254 mTrack->pause(); 255} 256 257status_t AudioFlinger::TrackHandle::attachAuxEffect(int EffectId) 258{ 259 return mTrack->attachAuxEffect(EffectId); 260} 261 262status_t AudioFlinger::TrackHandle::allocateTimedBuffer(size_t size, 263 sp<IMemory>* buffer) { 264 if (!mTrack->isTimedTrack()) 265 return INVALID_OPERATION; 266 267 PlaybackThread::TimedTrack* tt = 268 reinterpret_cast<PlaybackThread::TimedTrack*>(mTrack.get()); 269 return tt->allocateTimedBuffer(size, buffer); 270} 271 272status_t AudioFlinger::TrackHandle::queueTimedBuffer(const sp<IMemory>& buffer, 273 int64_t pts) { 274 if (!mTrack->isTimedTrack()) 275 return INVALID_OPERATION; 276 277 if (buffer == 0 || buffer->pointer() == NULL) { 278 ALOGE("queueTimedBuffer() buffer is 0 or has NULL pointer()"); 279 return BAD_VALUE; 280 } 281 282 PlaybackThread::TimedTrack* tt = 283 reinterpret_cast<PlaybackThread::TimedTrack*>(mTrack.get()); 284 return tt->queueTimedBuffer(buffer, pts); 285} 286 287status_t AudioFlinger::TrackHandle::setMediaTimeTransform( 288 const LinearTransform& xform, int target) { 289 290 if (!mTrack->isTimedTrack()) 291 return INVALID_OPERATION; 292 293 PlaybackThread::TimedTrack* tt = 294 reinterpret_cast<PlaybackThread::TimedTrack*>(mTrack.get()); 295 return tt->setMediaTimeTransform( 296 xform, static_cast<TimedAudioTrack::TargetTimeline>(target)); 297} 298 299status_t AudioFlinger::TrackHandle::setParameters(const String8& keyValuePairs) { 300 return mTrack->setParameters(keyValuePairs); 301} 302 303status_t AudioFlinger::TrackHandle::getTimestamp(AudioTimestamp& timestamp) 304{ 305 return mTrack->getTimestamp(timestamp); 306} 307 308 309void AudioFlinger::TrackHandle::signal() 310{ 311 return mTrack->signal(); 312} 313 314status_t AudioFlinger::TrackHandle::onTransact( 315 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 316{ 317 return BnAudioTrack::onTransact(code, data, reply, flags); 318} 319 320// ---------------------------------------------------------------------------- 321 322// Track constructor must be called with AudioFlinger::mLock and ThreadBase::mLock held 323AudioFlinger::PlaybackThread::Track::Track( 324 PlaybackThread *thread, 325 const sp<Client>& client, 326 audio_stream_type_t streamType, 327 uint32_t sampleRate, 328 audio_format_t format, 329 audio_channel_mask_t channelMask, 330 size_t frameCount, 331 const sp<IMemory>& sharedBuffer, 332 int sessionId, 333 int uid, 334 IAudioFlinger::track_flags_t flags) 335 : TrackBase(thread, client, sampleRate, format, channelMask, frameCount, sharedBuffer, 336 sessionId, uid, true /*isOut*/), 337 mFillingUpStatus(FS_INVALID), 338 // mRetryCount initialized later when needed 339 mSharedBuffer(sharedBuffer), 340 mStreamType(streamType), 341 mName(-1), // see note below 342 mMainBuffer(thread->mixBuffer()), 343 mAuxBuffer(NULL), 344 mAuxEffectId(0), mHasVolumeController(false), 345 mPresentationCompleteFrames(0), 346 mFlags(flags), 347 mFastIndex(-1), 348 mCachedVolume(1.0), 349 mIsInvalid(false), 350 mAudioTrackServerProxy(NULL), 351 mResumeToStopping(false) 352{ 353 if (mCblk != NULL) { 354 if (sharedBuffer == 0) { 355 mAudioTrackServerProxy = new AudioTrackServerProxy(mCblk, mBuffer, frameCount, 356 mFrameSize); 357 } else { 358 mAudioTrackServerProxy = new StaticAudioTrackServerProxy(mCblk, mBuffer, frameCount, 359 mFrameSize); 360 } 361 mServerProxy = mAudioTrackServerProxy; 362 // to avoid leaking a track name, do not allocate one unless there is an mCblk 363 mName = thread->getTrackName_l(channelMask, sessionId); 364 if (mName < 0) { 365 ALOGE("no more track names available"); 366 return; 367 } 368 // only allocate a fast track index if we were able to allocate a normal track name 369 if (flags & IAudioFlinger::TRACK_FAST) { 370 mAudioTrackServerProxy->framesReadyIsCalledByMultipleThreads(); 371 ALOG_ASSERT(thread->mFastTrackAvailMask != 0); 372 int i = __builtin_ctz(thread->mFastTrackAvailMask); 373 ALOG_ASSERT(0 < i && i < (int)FastMixerState::kMaxFastTracks); 374 // FIXME This is too eager. We allocate a fast track index before the 375 // fast track becomes active. Since fast tracks are a scarce resource, 376 // this means we are potentially denying other more important fast tracks from 377 // being created. It would be better to allocate the index dynamically. 378 mFastIndex = i; 379 // Read the initial underruns because this field is never cleared by the fast mixer 380 mObservedUnderruns = thread->getFastTrackUnderruns(i); 381 thread->mFastTrackAvailMask &= ~(1 << i); 382 } 383 } 384 ALOGV("Track constructor name %d, calling pid %d", mName, 385 IPCThreadState::self()->getCallingPid()); 386} 387 388AudioFlinger::PlaybackThread::Track::~Track() 389{ 390 ALOGV("PlaybackThread::Track destructor"); 391 392 // The destructor would clear mSharedBuffer, 393 // but it will not push the decremented reference count, 394 // leaving the client's IMemory dangling indefinitely. 395 // This prevents that leak. 396 if (mSharedBuffer != 0) { 397 mSharedBuffer.clear(); 398 // flush the binder command buffer 399 IPCThreadState::self()->flushCommands(); 400 } 401} 402 403status_t AudioFlinger::PlaybackThread::Track::initCheck() const 404{ 405 status_t status = TrackBase::initCheck(); 406 if (status == NO_ERROR && mName < 0) { 407 status = NO_MEMORY; 408 } 409 return status; 410} 411 412void AudioFlinger::PlaybackThread::Track::destroy() 413{ 414 // NOTE: destroyTrack_l() can remove a strong reference to this Track 415 // by removing it from mTracks vector, so there is a risk that this Tracks's 416 // destructor is called. As the destructor needs to lock mLock, 417 // we must acquire a strong reference on this Track before locking mLock 418 // here so that the destructor is called only when exiting this function. 419 // On the other hand, as long as Track::destroy() is only called by 420 // TrackHandle destructor, the TrackHandle still holds a strong ref on 421 // this Track with its member mTrack. 422 sp<Track> keep(this); 423 { // scope for mLock 424 sp<ThreadBase> thread = mThread.promote(); 425 if (thread != 0) { 426 Mutex::Autolock _l(thread->mLock); 427 PlaybackThread *playbackThread = (PlaybackThread *)thread.get(); 428 bool wasActive = playbackThread->destroyTrack_l(this); 429 if (!isOutputTrack() && !wasActive) { 430 AudioSystem::releaseOutput(thread->id()); 431 } 432 } 433 } 434} 435 436/*static*/ void AudioFlinger::PlaybackThread::Track::appendDumpHeader(String8& result) 437{ 438 result.append(" Name Client Type Fmt Chn mask Session fCount S F SRate " 439 "L dB R dB Server Main buf Aux Buf Flags UndFrmCnt\n"); 440} 441 442void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size) 443{ 444 uint32_t vlr = mAudioTrackServerProxy->getVolumeLR(); 445 if (isFastTrack()) { 446 sprintf(buffer, " F %2d", mFastIndex); 447 } else { 448 sprintf(buffer, " %4d", mName - AudioMixer::TRACK0); 449 } 450 track_state state = mState; 451 char stateChar; 452 if (isTerminated()) { 453 stateChar = 'T'; 454 } else { 455 switch (state) { 456 case IDLE: 457 stateChar = 'I'; 458 break; 459 case STOPPING_1: 460 stateChar = 's'; 461 break; 462 case STOPPING_2: 463 stateChar = '5'; 464 break; 465 case STOPPED: 466 stateChar = 'S'; 467 break; 468 case RESUMING: 469 stateChar = 'R'; 470 break; 471 case ACTIVE: 472 stateChar = 'A'; 473 break; 474 case PAUSING: 475 stateChar = 'p'; 476 break; 477 case PAUSED: 478 stateChar = 'P'; 479 break; 480 case FLUSHED: 481 stateChar = 'F'; 482 break; 483 default: 484 stateChar = '?'; 485 break; 486 } 487 } 488 char nowInUnderrun; 489 switch (mObservedUnderruns.mBitFields.mMostRecent) { 490 case UNDERRUN_FULL: 491 nowInUnderrun = ' '; 492 break; 493 case UNDERRUN_PARTIAL: 494 nowInUnderrun = '<'; 495 break; 496 case UNDERRUN_EMPTY: 497 nowInUnderrun = '*'; 498 break; 499 default: 500 nowInUnderrun = '?'; 501 break; 502 } 503 snprintf(&buffer[7], size-7, " %6u %4u %08X %08X %7u %6u %1c %1d %5u %5.2g %5.2g " 504 "%08X %08X %08X 0x%03X %9u%c\n", 505 (mClient == 0) ? getpid_cached : mClient->pid(), 506 mStreamType, 507 mFormat, 508 mChannelMask, 509 mSessionId, 510 mFrameCount, 511 stateChar, 512 mFillingUpStatus, 513 mAudioTrackServerProxy->getSampleRate(), 514 20.0 * log10((vlr & 0xFFFF) / 4096.0), 515 20.0 * log10((vlr >> 16) / 4096.0), 516 mCblk->mServer, 517 (int)mMainBuffer, 518 (int)mAuxBuffer, 519 mCblk->mFlags, 520 mAudioTrackServerProxy->getUnderrunFrames(), 521 nowInUnderrun); 522} 523 524uint32_t AudioFlinger::PlaybackThread::Track::sampleRate() const { 525 return mAudioTrackServerProxy->getSampleRate(); 526} 527 528// AudioBufferProvider interface 529status_t AudioFlinger::PlaybackThread::Track::getNextBuffer( 530 AudioBufferProvider::Buffer* buffer, int64_t pts) 531{ 532 ServerProxy::Buffer buf; 533 size_t desiredFrames = buffer->frameCount; 534 buf.mFrameCount = desiredFrames; 535 status_t status = mServerProxy->obtainBuffer(&buf); 536 buffer->frameCount = buf.mFrameCount; 537 buffer->raw = buf.mRaw; 538 if (buf.mFrameCount == 0) { 539 mAudioTrackServerProxy->tallyUnderrunFrames(desiredFrames); 540 } 541 return status; 542} 543 544// releaseBuffer() is not overridden 545 546// ExtendedAudioBufferProvider interface 547 548// Note that framesReady() takes a mutex on the control block using tryLock(). 549// This could result in priority inversion if framesReady() is called by the normal mixer, 550// as the normal mixer thread runs at lower 551// priority than the client's callback thread: there is a short window within framesReady() 552// during which the normal mixer could be preempted, and the client callback would block. 553// Another problem can occur if framesReady() is called by the fast mixer: 554// the tryLock() could block for up to 1 ms, and a sequence of these could delay fast mixer. 555// FIXME Replace AudioTrackShared control block implementation by a non-blocking FIFO queue. 556size_t AudioFlinger::PlaybackThread::Track::framesReady() const { 557 return mAudioTrackServerProxy->framesReady(); 558} 559 560size_t AudioFlinger::PlaybackThread::Track::framesReleased() const 561{ 562 return mAudioTrackServerProxy->framesReleased(); 563} 564 565// Don't call for fast tracks; the framesReady() could result in priority inversion 566bool AudioFlinger::PlaybackThread::Track::isReady() const { 567 if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing() || isStopping()) { 568 return true; 569 } 570 571 if (framesReady() >= mFrameCount || 572 (mCblk->mFlags & CBLK_FORCEREADY)) { 573 mFillingUpStatus = FS_FILLED; 574 android_atomic_and(~CBLK_FORCEREADY, &mCblk->mFlags); 575 return true; 576 } 577 return false; 578} 579 580status_t AudioFlinger::PlaybackThread::Track::start(AudioSystem::sync_event_t event, 581 int triggerSession) 582{ 583 status_t status = NO_ERROR; 584 ALOGV("start(%d), calling pid %d session %d", 585 mName, IPCThreadState::self()->getCallingPid(), mSessionId); 586 587 sp<ThreadBase> thread = mThread.promote(); 588 if (thread != 0) { 589 if (isOffloaded()) { 590 Mutex::Autolock _laf(thread->mAudioFlinger->mLock); 591 Mutex::Autolock _lth(thread->mLock); 592 sp<EffectChain> ec = thread->getEffectChain_l(mSessionId); 593 if (thread->mAudioFlinger->isNonOffloadableGlobalEffectEnabled_l() || 594 (ec != 0 && ec->isNonOffloadableEnabled())) { 595 invalidate(); 596 return PERMISSION_DENIED; 597 } 598 } 599 Mutex::Autolock _lth(thread->mLock); 600 track_state state = mState; 601 // here the track could be either new, or restarted 602 // in both cases "unstop" the track 603 604 if (state == PAUSED) { 605 if (mResumeToStopping) { 606 // happened we need to resume to STOPPING_1 607 mState = TrackBase::STOPPING_1; 608 ALOGV("PAUSED => STOPPING_1 (%d) on thread %p", mName, this); 609 } else { 610 mState = TrackBase::RESUMING; 611 ALOGV("PAUSED => RESUMING (%d) on thread %p", mName, this); 612 } 613 } else { 614 mState = TrackBase::ACTIVE; 615 ALOGV("? => ACTIVE (%d) on thread %p", mName, this); 616 } 617 618 PlaybackThread *playbackThread = (PlaybackThread *)thread.get(); 619 status = playbackThread->addTrack_l(this); 620 if (status == INVALID_OPERATION || status == PERMISSION_DENIED) { 621 triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE); 622 // restore previous state if start was rejected by policy manager 623 if (status == PERMISSION_DENIED) { 624 mState = state; 625 } 626 } 627 // track was already in the active list, not a problem 628 if (status == ALREADY_EXISTS) { 629 status = NO_ERROR; 630 } else { 631 // Acknowledge any pending flush(), so that subsequent new data isn't discarded. 632 // It is usually unsafe to access the server proxy from a binder thread. 633 // But in this case we know the mixer thread (whether normal mixer or fast mixer) 634 // isn't looking at this track yet: we still hold the normal mixer thread lock, 635 // and for fast tracks the track is not yet in the fast mixer thread's active set. 636 ServerProxy::Buffer buffer; 637 buffer.mFrameCount = 1; 638 (void) mAudioTrackServerProxy->obtainBuffer(&buffer, true /*ackFlush*/); 639 } 640 } else { 641 status = BAD_VALUE; 642 } 643 return status; 644} 645 646void AudioFlinger::PlaybackThread::Track::stop() 647{ 648 ALOGV("stop(%d), calling pid %d", mName, IPCThreadState::self()->getCallingPid()); 649 sp<ThreadBase> thread = mThread.promote(); 650 if (thread != 0) { 651 Mutex::Autolock _l(thread->mLock); 652 track_state state = mState; 653 if (state == RESUMING || state == ACTIVE || state == PAUSING || state == PAUSED) { 654 // If the track is not active (PAUSED and buffers full), flush buffers 655 PlaybackThread *playbackThread = (PlaybackThread *)thread.get(); 656 if (playbackThread->mActiveTracks.indexOf(this) < 0) { 657 reset(); 658 mState = STOPPED; 659 } else if (!isFastTrack() && !isOffloaded()) { 660 mState = STOPPED; 661 } else { 662 // For fast tracks prepareTracks_l() will set state to STOPPING_2 663 // presentation is complete 664 // For an offloaded track this starts a drain and state will 665 // move to STOPPING_2 when drain completes and then STOPPED 666 mState = STOPPING_1; 667 } 668 ALOGV("not stopping/stopped => stopping/stopped (%d) on thread %p", mName, 669 playbackThread); 670 } 671 } 672} 673 674void AudioFlinger::PlaybackThread::Track::pause() 675{ 676 ALOGV("pause(%d), calling pid %d", mName, IPCThreadState::self()->getCallingPid()); 677 sp<ThreadBase> thread = mThread.promote(); 678 if (thread != 0) { 679 Mutex::Autolock _l(thread->mLock); 680 PlaybackThread *playbackThread = (PlaybackThread *)thread.get(); 681 switch (mState) { 682 case STOPPING_1: 683 case STOPPING_2: 684 if (!isOffloaded()) { 685 /* nothing to do if track is not offloaded */ 686 break; 687 } 688 689 // Offloaded track was draining, we need to carry on draining when resumed 690 mResumeToStopping = true; 691 // fall through... 692 case ACTIVE: 693 case RESUMING: 694 mState = PAUSING; 695 ALOGV("ACTIVE/RESUMING => PAUSING (%d) on thread %p", mName, thread.get()); 696 playbackThread->broadcast_l(); 697 break; 698 699 default: 700 break; 701 } 702 } 703} 704 705void AudioFlinger::PlaybackThread::Track::flush() 706{ 707 ALOGV("flush(%d)", mName); 708 sp<ThreadBase> thread = mThread.promote(); 709 if (thread != 0) { 710 Mutex::Autolock _l(thread->mLock); 711 PlaybackThread *playbackThread = (PlaybackThread *)thread.get(); 712 713 if (isOffloaded()) { 714 // If offloaded we allow flush during any state except terminated 715 // and keep the track active to avoid problems if user is seeking 716 // rapidly and underlying hardware has a significant delay handling 717 // a pause 718 if (isTerminated()) { 719 return; 720 } 721 722 ALOGV("flush: offload flush"); 723 reset(); 724 725 if (mState == STOPPING_1 || mState == STOPPING_2) { 726 ALOGV("flushed in STOPPING_1 or 2 state, change state to ACTIVE"); 727 mState = ACTIVE; 728 } 729 730 if (mState == ACTIVE) { 731 ALOGV("flush called in active state, resetting buffer time out retry count"); 732 mRetryCount = PlaybackThread::kMaxTrackRetriesOffload; 733 } 734 735 mResumeToStopping = false; 736 } else { 737 if (mState != STOPPING_1 && mState != STOPPING_2 && mState != STOPPED && 738 mState != PAUSED && mState != PAUSING && mState != IDLE && mState != FLUSHED) { 739 return; 740 } 741 // No point remaining in PAUSED state after a flush => go to 742 // FLUSHED state 743 mState = FLUSHED; 744 // do not reset the track if it is still in the process of being stopped or paused. 745 // this will be done by prepareTracks_l() when the track is stopped. 746 // prepareTracks_l() will see mState == FLUSHED, then 747 // remove from active track list, reset(), and trigger presentation complete 748 if (playbackThread->mActiveTracks.indexOf(this) < 0) { 749 reset(); 750 } 751 } 752 // Prevent flush being lost if the track is flushed and then resumed 753 // before mixer thread can run. This is important when offloading 754 // because the hardware buffer could hold a large amount of audio 755 playbackThread->flushOutput_l(); 756 playbackThread->broadcast_l(); 757 } 758} 759 760void AudioFlinger::PlaybackThread::Track::reset() 761{ 762 // Do not reset twice to avoid discarding data written just after a flush and before 763 // the audioflinger thread detects the track is stopped. 764 if (!mResetDone) { 765 // Force underrun condition to avoid false underrun callback until first data is 766 // written to buffer 767 android_atomic_and(~CBLK_FORCEREADY, &mCblk->mFlags); 768 mFillingUpStatus = FS_FILLING; 769 mResetDone = true; 770 if (mState == FLUSHED) { 771 mState = IDLE; 772 } 773 } 774} 775 776status_t AudioFlinger::PlaybackThread::Track::setParameters(const String8& keyValuePairs) 777{ 778 sp<ThreadBase> thread = mThread.promote(); 779 if (thread == 0) { 780 ALOGE("thread is dead"); 781 return FAILED_TRANSACTION; 782 } else if ((thread->type() == ThreadBase::DIRECT) || 783 (thread->type() == ThreadBase::OFFLOAD)) { 784 return thread->setParameters(keyValuePairs); 785 } else { 786 return PERMISSION_DENIED; 787 } 788} 789 790status_t AudioFlinger::PlaybackThread::Track::getTimestamp(AudioTimestamp& timestamp) 791{ 792 // Client should implement this using SSQ; the unpresented frame count in latch is irrelevant 793 if (isFastTrack()) { 794 return INVALID_OPERATION; 795 } 796 sp<ThreadBase> thread = mThread.promote(); 797 if (thread == 0) { 798 return INVALID_OPERATION; 799 } 800 Mutex::Autolock _l(thread->mLock); 801 PlaybackThread *playbackThread = (PlaybackThread *)thread.get(); 802 if (!isOffloaded()) { 803 if (!playbackThread->mLatchQValid) { 804 return INVALID_OPERATION; 805 } 806 uint32_t unpresentedFrames = 807 ((int64_t) playbackThread->mLatchQ.mUnpresentedFrames * mSampleRate) / 808 playbackThread->mSampleRate; 809 uint32_t framesWritten = mAudioTrackServerProxy->framesReleased(); 810 if (framesWritten < unpresentedFrames) { 811 return INVALID_OPERATION; 812 } 813 timestamp.mPosition = framesWritten - unpresentedFrames; 814 timestamp.mTime = playbackThread->mLatchQ.mTimestamp.mTime; 815 return NO_ERROR; 816 } 817 818 return playbackThread->getTimestamp_l(timestamp); 819} 820 821status_t AudioFlinger::PlaybackThread::Track::attachAuxEffect(int EffectId) 822{ 823 status_t status = DEAD_OBJECT; 824 sp<ThreadBase> thread = mThread.promote(); 825 if (thread != 0) { 826 PlaybackThread *playbackThread = (PlaybackThread *)thread.get(); 827 sp<AudioFlinger> af = mClient->audioFlinger(); 828 829 Mutex::Autolock _l(af->mLock); 830 831 sp<PlaybackThread> srcThread = af->getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, EffectId); 832 833 if (EffectId != 0 && srcThread != 0 && playbackThread != srcThread.get()) { 834 Mutex::Autolock _dl(playbackThread->mLock); 835 Mutex::Autolock _sl(srcThread->mLock); 836 sp<EffectChain> chain = srcThread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX); 837 if (chain == 0) { 838 return INVALID_OPERATION; 839 } 840 841 sp<EffectModule> effect = chain->getEffectFromId_l(EffectId); 842 if (effect == 0) { 843 return INVALID_OPERATION; 844 } 845 srcThread->removeEffect_l(effect); 846 status = playbackThread->addEffect_l(effect); 847 if (status != NO_ERROR) { 848 srcThread->addEffect_l(effect); 849 return INVALID_OPERATION; 850 } 851 // removeEffect_l() has stopped the effect if it was active so it must be restarted 852 if (effect->state() == EffectModule::ACTIVE || 853 effect->state() == EffectModule::STOPPING) { 854 effect->start(); 855 } 856 857 sp<EffectChain> dstChain = effect->chain().promote(); 858 if (dstChain == 0) { 859 srcThread->addEffect_l(effect); 860 return INVALID_OPERATION; 861 } 862 AudioSystem::unregisterEffect(effect->id()); 863 AudioSystem::registerEffect(&effect->desc(), 864 srcThread->id(), 865 dstChain->strategy(), 866 AUDIO_SESSION_OUTPUT_MIX, 867 effect->id()); 868 AudioSystem::setEffectEnabled(effect->id(), effect->isEnabled()); 869 } 870 status = playbackThread->attachAuxEffect(this, EffectId); 871 } 872 return status; 873} 874 875void AudioFlinger::PlaybackThread::Track::setAuxBuffer(int EffectId, int32_t *buffer) 876{ 877 mAuxEffectId = EffectId; 878 mAuxBuffer = buffer; 879} 880 881bool AudioFlinger::PlaybackThread::Track::presentationComplete(size_t framesWritten, 882 size_t audioHalFrames) 883{ 884 // a track is considered presented when the total number of frames written to audio HAL 885 // corresponds to the number of frames written when presentationComplete() is called for the 886 // first time (mPresentationCompleteFrames == 0) plus the buffer filling status at that time. 887 // For an offloaded track the HAL+h/w delay is variable so a HAL drain() is used 888 // to detect when all frames have been played. In this case framesWritten isn't 889 // useful because it doesn't always reflect whether there is data in the h/w 890 // buffers, particularly if a track has been paused and resumed during draining 891 ALOGV("presentationComplete() mPresentationCompleteFrames %d framesWritten %d", 892 mPresentationCompleteFrames, framesWritten); 893 if (mPresentationCompleteFrames == 0) { 894 mPresentationCompleteFrames = framesWritten + audioHalFrames; 895 ALOGV("presentationComplete() reset: mPresentationCompleteFrames %d audioHalFrames %d", 896 mPresentationCompleteFrames, audioHalFrames); 897 } 898 899 if (framesWritten >= mPresentationCompleteFrames || isOffloaded()) { 900 ALOGV("presentationComplete() session %d complete: framesWritten %d", 901 mSessionId, framesWritten); 902 triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE); 903 mAudioTrackServerProxy->setStreamEndDone(); 904 return true; 905 } 906 return false; 907} 908 909void AudioFlinger::PlaybackThread::Track::triggerEvents(AudioSystem::sync_event_t type) 910{ 911 for (int i = 0; i < (int)mSyncEvents.size(); i++) { 912 if (mSyncEvents[i]->type() == type) { 913 mSyncEvents[i]->trigger(); 914 mSyncEvents.removeAt(i); 915 i--; 916 } 917 } 918} 919 920// implement VolumeBufferProvider interface 921 922uint32_t AudioFlinger::PlaybackThread::Track::getVolumeLR() 923{ 924 // called by FastMixer, so not allowed to take any locks, block, or do I/O including logs 925 ALOG_ASSERT(isFastTrack() && (mCblk != NULL)); 926 uint32_t vlr = mAudioTrackServerProxy->getVolumeLR(); 927 uint32_t vl = vlr & 0xFFFF; 928 uint32_t vr = vlr >> 16; 929 // track volumes come from shared memory, so can't be trusted and must be clamped 930 if (vl > MAX_GAIN_INT) { 931 vl = MAX_GAIN_INT; 932 } 933 if (vr > MAX_GAIN_INT) { 934 vr = MAX_GAIN_INT; 935 } 936 // now apply the cached master volume and stream type volume; 937 // this is trusted but lacks any synchronization or barrier so may be stale 938 float v = mCachedVolume; 939 vl *= v; 940 vr *= v; 941 // re-combine into U4.16 942 vlr = (vr << 16) | (vl & 0xFFFF); 943 // FIXME look at mute, pause, and stop flags 944 return vlr; 945} 946 947status_t AudioFlinger::PlaybackThread::Track::setSyncEvent(const sp<SyncEvent>& event) 948{ 949 if (isTerminated() || mState == PAUSED || 950 ((framesReady() == 0) && ((mSharedBuffer != 0) || 951 (mState == STOPPED)))) { 952 ALOGW("Track::setSyncEvent() in invalid state %d on session %d %s mode, framesReady %d ", 953 mState, mSessionId, (mSharedBuffer != 0) ? "static" : "stream", framesReady()); 954 event->cancel(); 955 return INVALID_OPERATION; 956 } 957 (void) TrackBase::setSyncEvent(event); 958 return NO_ERROR; 959} 960 961void AudioFlinger::PlaybackThread::Track::invalidate() 962{ 963 // FIXME should use proxy, and needs work 964 audio_track_cblk_t* cblk = mCblk; 965 android_atomic_or(CBLK_INVALID, &cblk->mFlags); 966 android_atomic_release_store(0x40000000, &cblk->mFutex); 967 // client is not in server, so FUTEX_WAKE is needed instead of FUTEX_WAKE_PRIVATE 968 (void) __futex_syscall3(&cblk->mFutex, FUTEX_WAKE, INT_MAX); 969 mIsInvalid = true; 970} 971 972void AudioFlinger::PlaybackThread::Track::signal() 973{ 974 sp<ThreadBase> thread = mThread.promote(); 975 if (thread != 0) { 976 PlaybackThread *t = (PlaybackThread *)thread.get(); 977 Mutex::Autolock _l(t->mLock); 978 t->broadcast_l(); 979 } 980} 981 982// ---------------------------------------------------------------------------- 983 984sp<AudioFlinger::PlaybackThread::TimedTrack> 985AudioFlinger::PlaybackThread::TimedTrack::create( 986 PlaybackThread *thread, 987 const sp<Client>& client, 988 audio_stream_type_t streamType, 989 uint32_t sampleRate, 990 audio_format_t format, 991 audio_channel_mask_t channelMask, 992 size_t frameCount, 993 const sp<IMemory>& sharedBuffer, 994 int sessionId, 995 int uid) { 996 if (!client->reserveTimedTrack()) 997 return 0; 998 999 return new TimedTrack( 1000 thread, client, streamType, sampleRate, format, channelMask, frameCount, 1001 sharedBuffer, sessionId, uid); 1002} 1003 1004AudioFlinger::PlaybackThread::TimedTrack::TimedTrack( 1005 PlaybackThread *thread, 1006 const sp<Client>& client, 1007 audio_stream_type_t streamType, 1008 uint32_t sampleRate, 1009 audio_format_t format, 1010 audio_channel_mask_t channelMask, 1011 size_t frameCount, 1012 const sp<IMemory>& sharedBuffer, 1013 int sessionId, 1014 int uid) 1015 : Track(thread, client, streamType, sampleRate, format, channelMask, 1016 frameCount, sharedBuffer, sessionId, uid, IAudioFlinger::TRACK_TIMED), 1017 mQueueHeadInFlight(false), 1018 mTrimQueueHeadOnRelease(false), 1019 mFramesPendingInQueue(0), 1020 mTimedSilenceBuffer(NULL), 1021 mTimedSilenceBufferSize(0), 1022 mTimedAudioOutputOnTime(false), 1023 mMediaTimeTransformValid(false) 1024{ 1025 LocalClock lc; 1026 mLocalTimeFreq = lc.getLocalFreq(); 1027 1028 mLocalTimeToSampleTransform.a_zero = 0; 1029 mLocalTimeToSampleTransform.b_zero = 0; 1030 mLocalTimeToSampleTransform.a_to_b_numer = sampleRate; 1031 mLocalTimeToSampleTransform.a_to_b_denom = mLocalTimeFreq; 1032 LinearTransform::reduce(&mLocalTimeToSampleTransform.a_to_b_numer, 1033 &mLocalTimeToSampleTransform.a_to_b_denom); 1034 1035 mMediaTimeToSampleTransform.a_zero = 0; 1036 mMediaTimeToSampleTransform.b_zero = 0; 1037 mMediaTimeToSampleTransform.a_to_b_numer = sampleRate; 1038 mMediaTimeToSampleTransform.a_to_b_denom = 1000000; 1039 LinearTransform::reduce(&mMediaTimeToSampleTransform.a_to_b_numer, 1040 &mMediaTimeToSampleTransform.a_to_b_denom); 1041} 1042 1043AudioFlinger::PlaybackThread::TimedTrack::~TimedTrack() { 1044 mClient->releaseTimedTrack(); 1045 delete [] mTimedSilenceBuffer; 1046} 1047 1048status_t AudioFlinger::PlaybackThread::TimedTrack::allocateTimedBuffer( 1049 size_t size, sp<IMemory>* buffer) { 1050 1051 Mutex::Autolock _l(mTimedBufferQueueLock); 1052 1053 trimTimedBufferQueue_l(); 1054 1055 // lazily initialize the shared memory heap for timed buffers 1056 if (mTimedMemoryDealer == NULL) { 1057 const int kTimedBufferHeapSize = 512 << 10; 1058 1059 mTimedMemoryDealer = new MemoryDealer(kTimedBufferHeapSize, 1060 "AudioFlingerTimed"); 1061 if (mTimedMemoryDealer == NULL) { 1062 return NO_MEMORY; 1063 } 1064 } 1065 1066 sp<IMemory> newBuffer = mTimedMemoryDealer->allocate(size); 1067 if (newBuffer == 0 || newBuffer->pointer() == NULL) { 1068 return NO_MEMORY; 1069 } 1070 1071 *buffer = newBuffer; 1072 return NO_ERROR; 1073} 1074 1075// caller must hold mTimedBufferQueueLock 1076void AudioFlinger::PlaybackThread::TimedTrack::trimTimedBufferQueue_l() { 1077 int64_t mediaTimeNow; 1078 { 1079 Mutex::Autolock mttLock(mMediaTimeTransformLock); 1080 if (!mMediaTimeTransformValid) 1081 return; 1082 1083 int64_t targetTimeNow; 1084 status_t res = (mMediaTimeTransformTarget == TimedAudioTrack::COMMON_TIME) 1085 ? mCCHelper.getCommonTime(&targetTimeNow) 1086 : mCCHelper.getLocalTime(&targetTimeNow); 1087 1088 if (OK != res) 1089 return; 1090 1091 if (!mMediaTimeTransform.doReverseTransform(targetTimeNow, 1092 &mediaTimeNow)) { 1093 return; 1094 } 1095 } 1096 1097 size_t trimEnd; 1098 for (trimEnd = 0; trimEnd < mTimedBufferQueue.size(); trimEnd++) { 1099 int64_t bufEnd; 1100 1101 if ((trimEnd + 1) < mTimedBufferQueue.size()) { 1102 // We have a next buffer. Just use its PTS as the PTS of the frame 1103 // following the last frame in this buffer. If the stream is sparse 1104 // (ie, there are deliberate gaps left in the stream which should be 1105 // filled with silence by the TimedAudioTrack), then this can result 1106 // in one extra buffer being left un-trimmed when it could have 1107 // been. In general, this is not typical, and we would rather 1108 // optimized away the TS calculation below for the more common case 1109 // where PTSes are contiguous. 1110 bufEnd = mTimedBufferQueue[trimEnd + 1].pts(); 1111 } else { 1112 // We have no next buffer. Compute the PTS of the frame following 1113 // the last frame in this buffer by computing the duration of of 1114 // this frame in media time units and adding it to the PTS of the 1115 // buffer. 1116 int64_t frameCount = mTimedBufferQueue[trimEnd].buffer()->size() 1117 / mFrameSize; 1118 1119 if (!mMediaTimeToSampleTransform.doReverseTransform(frameCount, 1120 &bufEnd)) { 1121 ALOGE("Failed to convert frame count of %lld to media time" 1122 " duration" " (scale factor %d/%u) in %s", 1123 frameCount, 1124 mMediaTimeToSampleTransform.a_to_b_numer, 1125 mMediaTimeToSampleTransform.a_to_b_denom, 1126 __PRETTY_FUNCTION__); 1127 break; 1128 } 1129 bufEnd += mTimedBufferQueue[trimEnd].pts(); 1130 } 1131 1132 if (bufEnd > mediaTimeNow) 1133 break; 1134 1135 // Is the buffer we want to use in the middle of a mix operation right 1136 // now? If so, don't actually trim it. Just wait for the releaseBuffer 1137 // from the mixer which should be coming back shortly. 1138 if (!trimEnd && mQueueHeadInFlight) { 1139 mTrimQueueHeadOnRelease = true; 1140 } 1141 } 1142 1143 size_t trimStart = mTrimQueueHeadOnRelease ? 1 : 0; 1144 if (trimStart < trimEnd) { 1145 // Update the bookkeeping for framesReady() 1146 for (size_t i = trimStart; i < trimEnd; ++i) { 1147 updateFramesPendingAfterTrim_l(mTimedBufferQueue[i], "trim"); 1148 } 1149 1150 // Now actually remove the buffers from the queue. 1151 mTimedBufferQueue.removeItemsAt(trimStart, trimEnd); 1152 } 1153} 1154 1155void AudioFlinger::PlaybackThread::TimedTrack::trimTimedBufferQueueHead_l( 1156 const char* logTag) { 1157 ALOG_ASSERT(mTimedBufferQueue.size() > 0, 1158 "%s called (reason \"%s\"), but timed buffer queue has no" 1159 " elements to trim.", __FUNCTION__, logTag); 1160 1161 updateFramesPendingAfterTrim_l(mTimedBufferQueue[0], logTag); 1162 mTimedBufferQueue.removeAt(0); 1163} 1164 1165void AudioFlinger::PlaybackThread::TimedTrack::updateFramesPendingAfterTrim_l( 1166 const TimedBuffer& buf, 1167 const char* logTag) { 1168 uint32_t bufBytes = buf.buffer()->size(); 1169 uint32_t consumedAlready = buf.position(); 1170 1171 ALOG_ASSERT(consumedAlready <= bufBytes, 1172 "Bad bookkeeping while updating frames pending. Timed buffer is" 1173 " only %u bytes long, but claims to have consumed %u" 1174 " bytes. (update reason: \"%s\")", 1175 bufBytes, consumedAlready, logTag); 1176 1177 uint32_t bufFrames = (bufBytes - consumedAlready) / mFrameSize; 1178 ALOG_ASSERT(mFramesPendingInQueue >= bufFrames, 1179 "Bad bookkeeping while updating frames pending. Should have at" 1180 " least %u queued frames, but we think we have only %u. (update" 1181 " reason: \"%s\")", 1182 bufFrames, mFramesPendingInQueue, logTag); 1183 1184 mFramesPendingInQueue -= bufFrames; 1185} 1186 1187status_t AudioFlinger::PlaybackThread::TimedTrack::queueTimedBuffer( 1188 const sp<IMemory>& buffer, int64_t pts) { 1189 1190 { 1191 Mutex::Autolock mttLock(mMediaTimeTransformLock); 1192 if (!mMediaTimeTransformValid) 1193 return INVALID_OPERATION; 1194 } 1195 1196 Mutex::Autolock _l(mTimedBufferQueueLock); 1197 1198 uint32_t bufFrames = buffer->size() / mFrameSize; 1199 mFramesPendingInQueue += bufFrames; 1200 mTimedBufferQueue.add(TimedBuffer(buffer, pts)); 1201 1202 return NO_ERROR; 1203} 1204 1205status_t AudioFlinger::PlaybackThread::TimedTrack::setMediaTimeTransform( 1206 const LinearTransform& xform, TimedAudioTrack::TargetTimeline target) { 1207 1208 ALOGVV("setMediaTimeTransform az=%lld bz=%lld n=%d d=%u tgt=%d", 1209 xform.a_zero, xform.b_zero, xform.a_to_b_numer, xform.a_to_b_denom, 1210 target); 1211 1212 if (!(target == TimedAudioTrack::LOCAL_TIME || 1213 target == TimedAudioTrack::COMMON_TIME)) { 1214 return BAD_VALUE; 1215 } 1216 1217 Mutex::Autolock lock(mMediaTimeTransformLock); 1218 mMediaTimeTransform = xform; 1219 mMediaTimeTransformTarget = target; 1220 mMediaTimeTransformValid = true; 1221 1222 return NO_ERROR; 1223} 1224 1225#define min(a, b) ((a) < (b) ? (a) : (b)) 1226 1227// implementation of getNextBuffer for tracks whose buffers have timestamps 1228status_t AudioFlinger::PlaybackThread::TimedTrack::getNextBuffer( 1229 AudioBufferProvider::Buffer* buffer, int64_t pts) 1230{ 1231 if (pts == AudioBufferProvider::kInvalidPTS) { 1232 buffer->raw = NULL; 1233 buffer->frameCount = 0; 1234 mTimedAudioOutputOnTime = false; 1235 return INVALID_OPERATION; 1236 } 1237 1238 Mutex::Autolock _l(mTimedBufferQueueLock); 1239 1240 ALOG_ASSERT(!mQueueHeadInFlight, 1241 "getNextBuffer called without releaseBuffer!"); 1242 1243 while (true) { 1244 1245 // if we have no timed buffers, then fail 1246 if (mTimedBufferQueue.isEmpty()) { 1247 buffer->raw = NULL; 1248 buffer->frameCount = 0; 1249 return NOT_ENOUGH_DATA; 1250 } 1251 1252 TimedBuffer& head = mTimedBufferQueue.editItemAt(0); 1253 1254 // calculate the PTS of the head of the timed buffer queue expressed in 1255 // local time 1256 int64_t headLocalPTS; 1257 { 1258 Mutex::Autolock mttLock(mMediaTimeTransformLock); 1259 1260 ALOG_ASSERT(mMediaTimeTransformValid, "media time transform invalid"); 1261 1262 if (mMediaTimeTransform.a_to_b_denom == 0) { 1263 // the transform represents a pause, so yield silence 1264 timedYieldSilence_l(buffer->frameCount, buffer); 1265 return NO_ERROR; 1266 } 1267 1268 int64_t transformedPTS; 1269 if (!mMediaTimeTransform.doForwardTransform(head.pts(), 1270 &transformedPTS)) { 1271 // the transform failed. this shouldn't happen, but if it does 1272 // then just drop this buffer 1273 ALOGW("timedGetNextBuffer transform failed"); 1274 buffer->raw = NULL; 1275 buffer->frameCount = 0; 1276 trimTimedBufferQueueHead_l("getNextBuffer; no transform"); 1277 return NO_ERROR; 1278 } 1279 1280 if (mMediaTimeTransformTarget == TimedAudioTrack::COMMON_TIME) { 1281 if (OK != mCCHelper.commonTimeToLocalTime(transformedPTS, 1282 &headLocalPTS)) { 1283 buffer->raw = NULL; 1284 buffer->frameCount = 0; 1285 return INVALID_OPERATION; 1286 } 1287 } else { 1288 headLocalPTS = transformedPTS; 1289 } 1290 } 1291 1292 uint32_t sr = sampleRate(); 1293 1294 // adjust the head buffer's PTS to reflect the portion of the head buffer 1295 // that has already been consumed 1296 int64_t effectivePTS = headLocalPTS + 1297 ((head.position() / mFrameSize) * mLocalTimeFreq / sr); 1298 1299 // Calculate the delta in samples between the head of the input buffer 1300 // queue and the start of the next output buffer that will be written. 1301 // If the transformation fails because of over or underflow, it means 1302 // that the sample's position in the output stream is so far out of 1303 // whack that it should just be dropped. 1304 int64_t sampleDelta; 1305 if (llabs(effectivePTS - pts) >= (static_cast<int64_t>(1) << 31)) { 1306 ALOGV("*** head buffer is too far from PTS: dropped buffer"); 1307 trimTimedBufferQueueHead_l("getNextBuffer, buf pts too far from" 1308 " mix"); 1309 continue; 1310 } 1311 if (!mLocalTimeToSampleTransform.doForwardTransform( 1312 (effectivePTS - pts) << 32, &sampleDelta)) { 1313 ALOGV("*** too late during sample rate transform: dropped buffer"); 1314 trimTimedBufferQueueHead_l("getNextBuffer, bad local to sample"); 1315 continue; 1316 } 1317 1318 ALOGVV("*** getNextBuffer head.pts=%lld head.pos=%d pts=%lld" 1319 " sampleDelta=[%d.%08x]", 1320 head.pts(), head.position(), pts, 1321 static_cast<int32_t>((sampleDelta >= 0 ? 0 : 1) 1322 + (sampleDelta >> 32)), 1323 static_cast<uint32_t>(sampleDelta & 0xFFFFFFFF)); 1324 1325 // if the delta between the ideal placement for the next input sample and 1326 // the current output position is within this threshold, then we will 1327 // concatenate the next input samples to the previous output 1328 const int64_t kSampleContinuityThreshold = 1329 (static_cast<int64_t>(sr) << 32) / 250; 1330 1331 // if this is the first buffer of audio that we're emitting from this track 1332 // then it should be almost exactly on time. 1333 const int64_t kSampleStartupThreshold = 1LL << 32; 1334 1335 if ((mTimedAudioOutputOnTime && llabs(sampleDelta) <= kSampleContinuityThreshold) || 1336 (!mTimedAudioOutputOnTime && llabs(sampleDelta) <= kSampleStartupThreshold)) { 1337 // the next input is close enough to being on time, so concatenate it 1338 // with the last output 1339 timedYieldSamples_l(buffer); 1340 1341 ALOGVV("*** on time: head.pos=%d frameCount=%u", 1342 head.position(), buffer->frameCount); 1343 return NO_ERROR; 1344 } 1345 1346 // Looks like our output is not on time. Reset our on timed status. 1347 // Next time we mix samples from our input queue, then should be within 1348 // the StartupThreshold. 1349 mTimedAudioOutputOnTime = false; 1350 if (sampleDelta > 0) { 1351 // the gap between the current output position and the proper start of 1352 // the next input sample is too big, so fill it with silence 1353 uint32_t framesUntilNextInput = (sampleDelta + 0x80000000) >> 32; 1354 1355 timedYieldSilence_l(framesUntilNextInput, buffer); 1356 ALOGV("*** silence: frameCount=%u", buffer->frameCount); 1357 return NO_ERROR; 1358 } else { 1359 // the next input sample is late 1360 uint32_t lateFrames = static_cast<uint32_t>(-((sampleDelta + 0x80000000) >> 32)); 1361 size_t onTimeSamplePosition = 1362 head.position() + lateFrames * mFrameSize; 1363 1364 if (onTimeSamplePosition > head.buffer()->size()) { 1365 // all the remaining samples in the head are too late, so 1366 // drop it and move on 1367 ALOGV("*** too late: dropped buffer"); 1368 trimTimedBufferQueueHead_l("getNextBuffer, dropped late buffer"); 1369 continue; 1370 } else { 1371 // skip over the late samples 1372 head.setPosition(onTimeSamplePosition); 1373 1374 // yield the available samples 1375 timedYieldSamples_l(buffer); 1376 1377 ALOGV("*** late: head.pos=%d frameCount=%u", head.position(), buffer->frameCount); 1378 return NO_ERROR; 1379 } 1380 } 1381 } 1382} 1383 1384// Yield samples from the timed buffer queue head up to the given output 1385// buffer's capacity. 1386// 1387// Caller must hold mTimedBufferQueueLock 1388void AudioFlinger::PlaybackThread::TimedTrack::timedYieldSamples_l( 1389 AudioBufferProvider::Buffer* buffer) { 1390 1391 const TimedBuffer& head = mTimedBufferQueue[0]; 1392 1393 buffer->raw = (static_cast<uint8_t*>(head.buffer()->pointer()) + 1394 head.position()); 1395 1396 uint32_t framesLeftInHead = ((head.buffer()->size() - head.position()) / 1397 mFrameSize); 1398 size_t framesRequested = buffer->frameCount; 1399 buffer->frameCount = min(framesLeftInHead, framesRequested); 1400 1401 mQueueHeadInFlight = true; 1402 mTimedAudioOutputOnTime = true; 1403} 1404 1405// Yield samples of silence up to the given output buffer's capacity 1406// 1407// Caller must hold mTimedBufferQueueLock 1408void AudioFlinger::PlaybackThread::TimedTrack::timedYieldSilence_l( 1409 uint32_t numFrames, AudioBufferProvider::Buffer* buffer) { 1410 1411 // lazily allocate a buffer filled with silence 1412 if (mTimedSilenceBufferSize < numFrames * mFrameSize) { 1413 delete [] mTimedSilenceBuffer; 1414 mTimedSilenceBufferSize = numFrames * mFrameSize; 1415 mTimedSilenceBuffer = new uint8_t[mTimedSilenceBufferSize]; 1416 memset(mTimedSilenceBuffer, 0, mTimedSilenceBufferSize); 1417 } 1418 1419 buffer->raw = mTimedSilenceBuffer; 1420 size_t framesRequested = buffer->frameCount; 1421 buffer->frameCount = min(numFrames, framesRequested); 1422 1423 mTimedAudioOutputOnTime = false; 1424} 1425 1426// AudioBufferProvider interface 1427void AudioFlinger::PlaybackThread::TimedTrack::releaseBuffer( 1428 AudioBufferProvider::Buffer* buffer) { 1429 1430 Mutex::Autolock _l(mTimedBufferQueueLock); 1431 1432 // If the buffer which was just released is part of the buffer at the head 1433 // of the queue, be sure to update the amt of the buffer which has been 1434 // consumed. If the buffer being returned is not part of the head of the 1435 // queue, its either because the buffer is part of the silence buffer, or 1436 // because the head of the timed queue was trimmed after the mixer called 1437 // getNextBuffer but before the mixer called releaseBuffer. 1438 if (buffer->raw == mTimedSilenceBuffer) { 1439 ALOG_ASSERT(!mQueueHeadInFlight, 1440 "Queue head in flight during release of silence buffer!"); 1441 goto done; 1442 } 1443 1444 ALOG_ASSERT(mQueueHeadInFlight, 1445 "TimedTrack::releaseBuffer of non-silence buffer, but no queue" 1446 " head in flight."); 1447 1448 if (mTimedBufferQueue.size()) { 1449 TimedBuffer& head = mTimedBufferQueue.editItemAt(0); 1450 1451 void* start = head.buffer()->pointer(); 1452 void* end = reinterpret_cast<void*>( 1453 reinterpret_cast<uint8_t*>(head.buffer()->pointer()) 1454 + head.buffer()->size()); 1455 1456 ALOG_ASSERT((buffer->raw >= start) && (buffer->raw < end), 1457 "released buffer not within the head of the timed buffer" 1458 " queue; qHead = [%p, %p], released buffer = %p", 1459 start, end, buffer->raw); 1460 1461 head.setPosition(head.position() + 1462 (buffer->frameCount * mFrameSize)); 1463 mQueueHeadInFlight = false; 1464 1465 ALOG_ASSERT(mFramesPendingInQueue >= buffer->frameCount, 1466 "Bad bookkeeping during releaseBuffer! Should have at" 1467 " least %u queued frames, but we think we have only %u", 1468 buffer->frameCount, mFramesPendingInQueue); 1469 1470 mFramesPendingInQueue -= buffer->frameCount; 1471 1472 if ((static_cast<size_t>(head.position()) >= head.buffer()->size()) 1473 || mTrimQueueHeadOnRelease) { 1474 trimTimedBufferQueueHead_l("releaseBuffer"); 1475 mTrimQueueHeadOnRelease = false; 1476 } 1477 } else { 1478 LOG_FATAL("TimedTrack::releaseBuffer of non-silence buffer with no" 1479 " buffers in the timed buffer queue"); 1480 } 1481 1482done: 1483 buffer->raw = 0; 1484 buffer->frameCount = 0; 1485} 1486 1487size_t AudioFlinger::PlaybackThread::TimedTrack::framesReady() const { 1488 Mutex::Autolock _l(mTimedBufferQueueLock); 1489 return mFramesPendingInQueue; 1490} 1491 1492AudioFlinger::PlaybackThread::TimedTrack::TimedBuffer::TimedBuffer() 1493 : mPTS(0), mPosition(0) {} 1494 1495AudioFlinger::PlaybackThread::TimedTrack::TimedBuffer::TimedBuffer( 1496 const sp<IMemory>& buffer, int64_t pts) 1497 : mBuffer(buffer), mPTS(pts), mPosition(0) {} 1498 1499 1500// ---------------------------------------------------------------------------- 1501 1502AudioFlinger::PlaybackThread::OutputTrack::OutputTrack( 1503 PlaybackThread *playbackThread, 1504 DuplicatingThread *sourceThread, 1505 uint32_t sampleRate, 1506 audio_format_t format, 1507 audio_channel_mask_t channelMask, 1508 size_t frameCount, 1509 int uid) 1510 : Track(playbackThread, NULL, AUDIO_STREAM_CNT, sampleRate, format, channelMask, frameCount, 1511 NULL, 0, uid, IAudioFlinger::TRACK_DEFAULT), 1512 mActive(false), mSourceThread(sourceThread), mClientProxy(NULL) 1513{ 1514 1515 if (mCblk != NULL) { 1516 mOutBuffer.frameCount = 0; 1517 playbackThread->mTracks.add(this); 1518 ALOGV("OutputTrack constructor mCblk %p, mBuffer %p, " 1519 "mCblk->frameCount_ %u, mChannelMask 0x%08x", 1520 mCblk, mBuffer, 1521 mCblk->frameCount_, mChannelMask); 1522 // since client and server are in the same process, 1523 // the buffer has the same virtual address on both sides 1524 mClientProxy = new AudioTrackClientProxy(mCblk, mBuffer, mFrameCount, mFrameSize); 1525 mClientProxy->setVolumeLR((uint32_t(uint16_t(0x1000)) << 16) | uint16_t(0x1000)); 1526 mClientProxy->setSendLevel(0.0); 1527 mClientProxy->setSampleRate(sampleRate); 1528 mClientProxy = new AudioTrackClientProxy(mCblk, mBuffer, mFrameCount, mFrameSize, 1529 true /*clientInServer*/); 1530 } else { 1531 ALOGW("Error creating output track on thread %p", playbackThread); 1532 } 1533} 1534 1535AudioFlinger::PlaybackThread::OutputTrack::~OutputTrack() 1536{ 1537 clearBufferQueue(); 1538 delete mClientProxy; 1539 // superclass destructor will now delete the server proxy and shared memory both refer to 1540} 1541 1542status_t AudioFlinger::PlaybackThread::OutputTrack::start(AudioSystem::sync_event_t event, 1543 int triggerSession) 1544{ 1545 status_t status = Track::start(event, triggerSession); 1546 if (status != NO_ERROR) { 1547 return status; 1548 } 1549 1550 mActive = true; 1551 mRetryCount = 127; 1552 return status; 1553} 1554 1555void AudioFlinger::PlaybackThread::OutputTrack::stop() 1556{ 1557 Track::stop(); 1558 clearBufferQueue(); 1559 mOutBuffer.frameCount = 0; 1560 mActive = false; 1561} 1562 1563bool AudioFlinger::PlaybackThread::OutputTrack::write(int16_t* data, uint32_t frames) 1564{ 1565 Buffer *pInBuffer; 1566 Buffer inBuffer; 1567 uint32_t channelCount = mChannelCount; 1568 bool outputBufferFull = false; 1569 inBuffer.frameCount = frames; 1570 inBuffer.i16 = data; 1571 1572 uint32_t waitTimeLeftMs = mSourceThread->waitTimeMs(); 1573 1574 if (!mActive && frames != 0) { 1575 start(); 1576 sp<ThreadBase> thread = mThread.promote(); 1577 if (thread != 0) { 1578 MixerThread *mixerThread = (MixerThread *)thread.get(); 1579 if (mFrameCount > frames) { 1580 if (mBufferQueue.size() < kMaxOverFlowBuffers) { 1581 uint32_t startFrames = (mFrameCount - frames); 1582 pInBuffer = new Buffer; 1583 pInBuffer->mBuffer = new int16_t[startFrames * channelCount]; 1584 pInBuffer->frameCount = startFrames; 1585 pInBuffer->i16 = pInBuffer->mBuffer; 1586 memset(pInBuffer->raw, 0, startFrames * channelCount * sizeof(int16_t)); 1587 mBufferQueue.add(pInBuffer); 1588 } else { 1589 ALOGW("OutputTrack::write() %p no more buffers in queue", this); 1590 } 1591 } 1592 } 1593 } 1594 1595 while (waitTimeLeftMs) { 1596 // First write pending buffers, then new data 1597 if (mBufferQueue.size()) { 1598 pInBuffer = mBufferQueue.itemAt(0); 1599 } else { 1600 pInBuffer = &inBuffer; 1601 } 1602 1603 if (pInBuffer->frameCount == 0) { 1604 break; 1605 } 1606 1607 if (mOutBuffer.frameCount == 0) { 1608 mOutBuffer.frameCount = pInBuffer->frameCount; 1609 nsecs_t startTime = systemTime(); 1610 status_t status = obtainBuffer(&mOutBuffer, waitTimeLeftMs); 1611 if (status != NO_ERROR) { 1612 ALOGV("OutputTrack::write() %p thread %p no more output buffers; status %d", this, 1613 mThread.unsafe_get(), status); 1614 outputBufferFull = true; 1615 break; 1616 } 1617 uint32_t waitTimeMs = (uint32_t)ns2ms(systemTime() - startTime); 1618 if (waitTimeLeftMs >= waitTimeMs) { 1619 waitTimeLeftMs -= waitTimeMs; 1620 } else { 1621 waitTimeLeftMs = 0; 1622 } 1623 } 1624 1625 uint32_t outFrames = pInBuffer->frameCount > mOutBuffer.frameCount ? mOutBuffer.frameCount : 1626 pInBuffer->frameCount; 1627 memcpy(mOutBuffer.raw, pInBuffer->raw, outFrames * channelCount * sizeof(int16_t)); 1628 Proxy::Buffer buf; 1629 buf.mFrameCount = outFrames; 1630 buf.mRaw = NULL; 1631 mClientProxy->releaseBuffer(&buf); 1632 pInBuffer->frameCount -= outFrames; 1633 pInBuffer->i16 += outFrames * channelCount; 1634 mOutBuffer.frameCount -= outFrames; 1635 mOutBuffer.i16 += outFrames * channelCount; 1636 1637 if (pInBuffer->frameCount == 0) { 1638 if (mBufferQueue.size()) { 1639 mBufferQueue.removeAt(0); 1640 delete [] pInBuffer->mBuffer; 1641 delete pInBuffer; 1642 ALOGV("OutputTrack::write() %p thread %p released overflow buffer %d", this, 1643 mThread.unsafe_get(), mBufferQueue.size()); 1644 } else { 1645 break; 1646 } 1647 } 1648 } 1649 1650 // If we could not write all frames, allocate a buffer and queue it for next time. 1651 if (inBuffer.frameCount) { 1652 sp<ThreadBase> thread = mThread.promote(); 1653 if (thread != 0 && !thread->standby()) { 1654 if (mBufferQueue.size() < kMaxOverFlowBuffers) { 1655 pInBuffer = new Buffer; 1656 pInBuffer->mBuffer = new int16_t[inBuffer.frameCount * channelCount]; 1657 pInBuffer->frameCount = inBuffer.frameCount; 1658 pInBuffer->i16 = pInBuffer->mBuffer; 1659 memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * channelCount * 1660 sizeof(int16_t)); 1661 mBufferQueue.add(pInBuffer); 1662 ALOGV("OutputTrack::write() %p thread %p adding overflow buffer %d", this, 1663 mThread.unsafe_get(), mBufferQueue.size()); 1664 } else { 1665 ALOGW("OutputTrack::write() %p thread %p no more overflow buffers", 1666 mThread.unsafe_get(), this); 1667 } 1668 } 1669 } 1670 1671 // Calling write() with a 0 length buffer, means that no more data will be written: 1672 // If no more buffers are pending, fill output track buffer to make sure it is started 1673 // by output mixer. 1674 if (frames == 0 && mBufferQueue.size() == 0) { 1675 // FIXME borken, replace by getting framesReady() from proxy 1676 size_t user = 0; // was mCblk->user 1677 if (user < mFrameCount) { 1678 frames = mFrameCount - user; 1679 pInBuffer = new Buffer; 1680 pInBuffer->mBuffer = new int16_t[frames * channelCount]; 1681 pInBuffer->frameCount = frames; 1682 pInBuffer->i16 = pInBuffer->mBuffer; 1683 memset(pInBuffer->raw, 0, frames * channelCount * sizeof(int16_t)); 1684 mBufferQueue.add(pInBuffer); 1685 } else if (mActive) { 1686 stop(); 1687 } 1688 } 1689 1690 return outputBufferFull; 1691} 1692 1693status_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer( 1694 AudioBufferProvider::Buffer* buffer, uint32_t waitTimeMs) 1695{ 1696 ClientProxy::Buffer buf; 1697 buf.mFrameCount = buffer->frameCount; 1698 struct timespec timeout; 1699 timeout.tv_sec = waitTimeMs / 1000; 1700 timeout.tv_nsec = (int) (waitTimeMs % 1000) * 1000000; 1701 status_t status = mClientProxy->obtainBuffer(&buf, &timeout); 1702 buffer->frameCount = buf.mFrameCount; 1703 buffer->raw = buf.mRaw; 1704 return status; 1705} 1706 1707void AudioFlinger::PlaybackThread::OutputTrack::clearBufferQueue() 1708{ 1709 size_t size = mBufferQueue.size(); 1710 1711 for (size_t i = 0; i < size; i++) { 1712 Buffer *pBuffer = mBufferQueue.itemAt(i); 1713 delete [] pBuffer->mBuffer; 1714 delete pBuffer; 1715 } 1716 mBufferQueue.clear(); 1717} 1718 1719 1720// ---------------------------------------------------------------------------- 1721// Record 1722// ---------------------------------------------------------------------------- 1723 1724AudioFlinger::RecordHandle::RecordHandle( 1725 const sp<AudioFlinger::RecordThread::RecordTrack>& recordTrack) 1726 : BnAudioRecord(), 1727 mRecordTrack(recordTrack) 1728{ 1729} 1730 1731AudioFlinger::RecordHandle::~RecordHandle() { 1732 stop_nonvirtual(); 1733 mRecordTrack->destroy(); 1734} 1735 1736sp<IMemory> AudioFlinger::RecordHandle::getCblk() const { 1737 return mRecordTrack->getCblk(); 1738} 1739 1740status_t AudioFlinger::RecordHandle::start(int /*AudioSystem::sync_event_t*/ event, 1741 int triggerSession) { 1742 ALOGV("RecordHandle::start()"); 1743 return mRecordTrack->start((AudioSystem::sync_event_t)event, triggerSession); 1744} 1745 1746void AudioFlinger::RecordHandle::stop() { 1747 stop_nonvirtual(); 1748} 1749 1750void AudioFlinger::RecordHandle::stop_nonvirtual() { 1751 ALOGV("RecordHandle::stop()"); 1752 mRecordTrack->stop(); 1753} 1754 1755status_t AudioFlinger::RecordHandle::onTransact( 1756 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 1757{ 1758 return BnAudioRecord::onTransact(code, data, reply, flags); 1759} 1760 1761// ---------------------------------------------------------------------------- 1762 1763// RecordTrack constructor must be called with AudioFlinger::mLock held 1764AudioFlinger::RecordThread::RecordTrack::RecordTrack( 1765 RecordThread *thread, 1766 const sp<Client>& client, 1767 uint32_t sampleRate, 1768 audio_format_t format, 1769 audio_channel_mask_t channelMask, 1770 size_t frameCount, 1771 int sessionId, 1772 int uid) 1773 : TrackBase(thread, client, sampleRate, format, 1774 channelMask, frameCount, 0 /*sharedBuffer*/, sessionId, uid, false /*isOut*/), 1775 mOverflow(false) 1776{ 1777 ALOGV("RecordTrack constructor"); 1778 if (mCblk != NULL) { 1779 mServerProxy = new AudioRecordServerProxy(mCblk, mBuffer, frameCount, mFrameSize); 1780 } 1781} 1782 1783AudioFlinger::RecordThread::RecordTrack::~RecordTrack() 1784{ 1785 ALOGV("%s", __func__); 1786} 1787 1788// AudioBufferProvider interface 1789status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer, 1790 int64_t pts) 1791{ 1792 ServerProxy::Buffer buf; 1793 buf.mFrameCount = buffer->frameCount; 1794 status_t status = mServerProxy->obtainBuffer(&buf); 1795 buffer->frameCount = buf.mFrameCount; 1796 buffer->raw = buf.mRaw; 1797 if (buf.mFrameCount == 0) { 1798 // FIXME also wake futex so that overrun is noticed more quickly 1799 (void) android_atomic_or(CBLK_OVERRUN, &mCblk->mFlags); 1800 } 1801 return status; 1802} 1803 1804status_t AudioFlinger::RecordThread::RecordTrack::start(AudioSystem::sync_event_t event, 1805 int triggerSession) 1806{ 1807 sp<ThreadBase> thread = mThread.promote(); 1808 if (thread != 0) { 1809 RecordThread *recordThread = (RecordThread *)thread.get(); 1810 return recordThread->start(this, event, triggerSession); 1811 } else { 1812 return BAD_VALUE; 1813 } 1814} 1815 1816void AudioFlinger::RecordThread::RecordTrack::stop() 1817{ 1818 sp<ThreadBase> thread = mThread.promote(); 1819 if (thread != 0) { 1820 RecordThread *recordThread = (RecordThread *)thread.get(); 1821 if (recordThread->stop(this)) { 1822 AudioSystem::stopInput(recordThread->id()); 1823 } 1824 } 1825} 1826 1827void AudioFlinger::RecordThread::RecordTrack::destroy() 1828{ 1829 // see comments at AudioFlinger::PlaybackThread::Track::destroy() 1830 sp<RecordTrack> keep(this); 1831 { 1832 sp<ThreadBase> thread = mThread.promote(); 1833 if (thread != 0) { 1834 if (mState == ACTIVE || mState == RESUMING) { 1835 AudioSystem::stopInput(thread->id()); 1836 } 1837 AudioSystem::releaseInput(thread->id()); 1838 Mutex::Autolock _l(thread->mLock); 1839 RecordThread *recordThread = (RecordThread *) thread.get(); 1840 recordThread->destroyTrack_l(this); 1841 } 1842 } 1843} 1844 1845void AudioFlinger::RecordThread::RecordTrack::invalidate() 1846{ 1847 // FIXME should use proxy, and needs work 1848 audio_track_cblk_t* cblk = mCblk; 1849 android_atomic_or(CBLK_INVALID, &cblk->mFlags); 1850 android_atomic_release_store(0x40000000, &cblk->mFutex); 1851 // client is not in server, so FUTEX_WAKE is needed instead of FUTEX_WAKE_PRIVATE 1852 (void) __futex_syscall3(&cblk->mFutex, FUTEX_WAKE, INT_MAX); 1853} 1854 1855 1856/*static*/ void AudioFlinger::RecordThread::RecordTrack::appendDumpHeader(String8& result) 1857{ 1858 result.append("Client Fmt Chn mask Session S Server fCount\n"); 1859} 1860 1861void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size) 1862{ 1863 snprintf(buffer, size, "%6u %3u %08X %7u %1d %08X %6u\n", 1864 (mClient == 0) ? getpid_cached : mClient->pid(), 1865 mFormat, 1866 mChannelMask, 1867 mSessionId, 1868 mState, 1869 mCblk->mServer, 1870 mFrameCount); 1871} 1872 1873}; // namespace android 1874