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