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