Home | History | Annotate | Download | only in media
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ANDROID_AUDIO_TRACK_SHARED_H
     18 #define ANDROID_AUDIO_TRACK_SHARED_H
     19 
     20 #include <stdint.h>
     21 #include <sys/types.h>
     22 
     23 #include <audio_utils/minifloat.h>
     24 #include <utils/threads.h>
     25 #include <utils/Log.h>
     26 #include <utils/RefBase.h>
     27 #include <audio_utils/roundup.h>
     28 #include <media/AudioResamplerPublic.h>
     29 #include <media/SingleStateQueue.h>
     30 
     31 namespace android {
     32 
     33 // ----------------------------------------------------------------------------
     34 
     35 // for audio_track_cblk_t::mFlags
     36 #define CBLK_UNDERRUN   0x01 // set by server immediately on output underrun, cleared by client
     37 #define CBLK_FORCEREADY 0x02 // set: track is considered ready immediately by AudioFlinger,
     38                              // clear: track is ready when buffer full
     39 #define CBLK_INVALID    0x04 // track buffer invalidated by AudioFlinger, need to re-create
     40 #define CBLK_DISABLED   0x08 // output track disabled by AudioFlinger due to underrun,
     41                              // need to re-start.  Unlike CBLK_UNDERRUN, this is not set
     42                              // immediately, but only after a long string of underruns.
     43 // 0x10 unused
     44 #define CBLK_LOOP_CYCLE 0x20 // set by server each time a loop cycle other than final one completes
     45 #define CBLK_LOOP_FINAL 0x40 // set by server when the final loop cycle completes
     46 #define CBLK_BUFFER_END 0x80 // set by server when the position reaches end of buffer if not looping
     47 #define CBLK_OVERRUN   0x100 // set by server immediately on input overrun, cleared by client
     48 #define CBLK_INTERRUPT 0x200 // set by client on interrupt(), cleared by client in obtainBuffer()
     49 #define CBLK_STREAM_END_DONE 0x400 // set by server on render completion, cleared by client
     50 
     51 //EL_FIXME 20 seconds may not be enough and must be reconciled with new obtainBuffer implementation
     52 #define MAX_RUN_OFFLOADED_TIMEOUT_MS 20000 // assuming up to a maximum of 20 seconds of offloaded
     53 
     54 struct AudioTrackSharedStreaming {
     55     // similar to NBAIO MonoPipe
     56     // in continuously incrementing frame units, take modulo buffer size, which must be a power of 2
     57     volatile int32_t mFront;    // read by consumer (output: server, input: client)
     58     volatile int32_t mRear;     // written by producer (output: client, input: server)
     59     volatile int32_t mFlush;    // incremented by client to indicate a request to flush;
     60                                 // server notices and discards all data between mFront and mRear
     61     volatile uint32_t mUnderrunFrames;  // server increments for each unavailable but desired frame
     62 };
     63 
     64 // Represents a single state of an AudioTrack that was created in static mode (shared memory buffer
     65 // supplied by the client).  This state needs to be communicated from the client to server.  As this
     66 // state is too large to be updated atomically without a mutex, and mutexes aren't allowed here, the
     67 // state is wrapped by a SingleStateQueue.
     68 struct StaticAudioTrackState {
     69     // Do not define constructors, destructors, or virtual methods as this is part of a
     70     // union in shared memory and they will not get called properly.
     71 
     72     // These fields should both be size_t, but since they are located in shared memory we
     73     // force to 32-bit.  The client and server may have different typedefs for size_t.
     74 
     75     // The state has a sequence counter to indicate whether changes are made to loop or position.
     76     // The sequence counter also currently indicates whether loop or position is first depending
     77     // on which is greater; it jumps by max(mLoopSequence, mPositionSequence) + 1.
     78 
     79     uint32_t    mLoopStart;
     80     uint32_t    mLoopEnd;
     81     int32_t     mLoopCount;
     82     uint32_t    mLoopSequence; // a sequence counter to indicate changes to loop
     83     uint32_t    mPosition;
     84     uint32_t    mPositionSequence; // a sequence counter to indicate changes to position
     85 };
     86 
     87 typedef SingleStateQueue<StaticAudioTrackState> StaticAudioTrackSingleStateQueue;
     88 
     89 struct StaticAudioTrackPosLoop {
     90     // Do not define constructors, destructors, or virtual methods as this is part of a
     91     // union in shared memory and will not get called properly.
     92 
     93     // These fields should both be size_t, but since they are located in shared memory we
     94     // force to 32-bit.  The client and server may have different typedefs for size_t.
     95 
     96     // This struct information is stored in a single state queue to communicate the
     97     // static AudioTrack server state to the client while data is consumed.
     98     // It is smaller than StaticAudioTrackState to prevent unnecessary information from
     99     // being sent.
    100 
    101     uint32_t mBufferPosition;
    102     int32_t  mLoopCount;
    103 };
    104 
    105 typedef SingleStateQueue<StaticAudioTrackPosLoop> StaticAudioTrackPosLoopQueue;
    106 
    107 struct AudioTrackSharedStatic {
    108     // client requests to the server for loop or position changes.
    109     StaticAudioTrackSingleStateQueue::Shared
    110                     mSingleStateQueue;
    111     // position info updated asynchronously by server and read by client,
    112     // "for entertainment purposes only"
    113     StaticAudioTrackPosLoopQueue::Shared
    114                     mPosLoopQueue;
    115 };
    116 
    117 typedef SingleStateQueue<AudioPlaybackRate> PlaybackRateQueue;
    118 
    119 // ----------------------------------------------------------------------------
    120 
    121 // Important: do not add any virtual methods, including ~
    122 struct audio_track_cblk_t
    123 {
    124                 // Since the control block is always located in shared memory, this constructor
    125                 // is only used for placement new().  It is never used for regular new() or stack.
    126                             audio_track_cblk_t();
    127                 /*virtual*/ ~audio_track_cblk_t() { }
    128 
    129                 friend class Proxy;
    130                 friend class ClientProxy;
    131                 friend class AudioTrackClientProxy;
    132                 friend class AudioRecordClientProxy;
    133                 friend class ServerProxy;
    134                 friend class AudioTrackServerProxy;
    135                 friend class AudioRecordServerProxy;
    136 
    137     // The data members are grouped so that members accessed frequently and in the same context
    138     // are in the same line of data cache.
    139 
    140                 uint32_t    mServer;    // Number of filled frames consumed by server (mIsOut),
    141                                         // or filled frames provided by server (!mIsOut).
    142                                         // It is updated asynchronously by server without a barrier.
    143                                         // The value should be used
    144                                         // "for entertainment purposes only",
    145                                         // which means don't make important decisions based on it.
    146 
    147                 uint32_t    mPad1;      // unused
    148 
    149     volatile    int32_t     mFutex;     // event flag: down (P) by client,
    150                                         // up (V) by server or binderDied() or interrupt()
    151 #define CBLK_FUTEX_WAKE 1               // if event flag bit is set, then a deferred wake is pending
    152 
    153 private:
    154 
    155                 // This field should be a size_t, but since it is located in shared memory we
    156                 // force to 32-bit.  The client and server may have different typedefs for size_t.
    157                 uint32_t    mMinimum;       // server wakes up client if available >= mMinimum
    158 
    159                 // Stereo gains for AudioTrack only, not used by AudioRecord.
    160                 gain_minifloat_packed_t mVolumeLR;
    161 
    162                 uint32_t    mSampleRate;    // AudioTrack only: client's requested sample rate in Hz
    163                                             // or 0 == default. Write-only client, read-only server.
    164 
    165                 PlaybackRateQueue::Shared mPlaybackRateQueue;
    166 
    167                 // client write-only, server read-only
    168                 uint16_t    mSendLevel;      // Fixed point U4.12 so 0x1000 means 1.0
    169 
    170                 uint16_t    mPad2;           // unused
    171 
    172 public:
    173 
    174     volatile    int32_t     mFlags;         // combinations of CBLK_*
    175 
    176                 // Cache line boundary (32 bytes)
    177 
    178 public:
    179                 union {
    180                     AudioTrackSharedStreaming   mStreaming;
    181                     AudioTrackSharedStatic      mStatic;
    182                     int                         mAlign[8];
    183                 } u;
    184 
    185                 // Cache line boundary (32 bytes)
    186 };
    187 
    188 // ----------------------------------------------------------------------------
    189 
    190 // Proxy for shared memory control block, to isolate callers from needing to know the details.
    191 // There is exactly one ClientProxy and one ServerProxy per shared memory control block.
    192 // The proxies are located in normal memory, and are not multi-thread safe within a given side.
    193 class Proxy : public RefBase {
    194 protected:
    195     Proxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize, bool isOut,
    196             bool clientInServer);
    197     virtual ~Proxy() { }
    198 
    199 public:
    200     struct Buffer {
    201         size_t  mFrameCount;            // number of frames available in this buffer
    202         void*   mRaw;                   // pointer to first frame
    203         size_t  mNonContig;             // number of additional non-contiguous frames available
    204     };
    205 
    206 protected:
    207     // These refer to shared memory, and are virtual addresses with respect to the current process.
    208     // They may have different virtual addresses within the other process.
    209     audio_track_cblk_t* const   mCblk;  // the control block
    210     void* const     mBuffers;           // starting address of buffers
    211 
    212     const size_t    mFrameCount;        // not necessarily a power of 2
    213     const size_t    mFrameSize;         // in bytes
    214     const size_t    mFrameCountP2;      // mFrameCount rounded to power of 2, streaming mode
    215     const bool      mIsOut;             // true for AudioTrack, false for AudioRecord
    216     const bool      mClientInServer;    // true for OutputTrack, false for AudioTrack & AudioRecord
    217     bool            mIsShutdown;        // latch set to true when shared memory corruption detected
    218     size_t          mUnreleased;        // unreleased frames remaining from most recent obtainBuffer
    219 };
    220 
    221 // ----------------------------------------------------------------------------
    222 
    223 // Proxy seen by AudioTrack client and AudioRecord client
    224 class ClientProxy : public Proxy {
    225 public:
    226     ClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize,
    227             bool isOut, bool clientInServer);
    228     virtual ~ClientProxy() { }
    229 
    230     static const struct timespec kForever;
    231     static const struct timespec kNonBlocking;
    232 
    233     // Obtain a buffer with filled frames (reading) or empty frames (writing).
    234     // It is permitted to call obtainBuffer() multiple times in succession, without any intervening
    235     // calls to releaseBuffer().  In that case, the final obtainBuffer() is the one that effectively
    236     // sets or extends the unreleased frame count.
    237     // On entry:
    238     //  buffer->mFrameCount should be initialized to maximum number of desired frames,
    239     //      which must be > 0.
    240     //  buffer->mNonContig is unused.
    241     //  buffer->mRaw is unused.
    242     //  requested is the requested timeout in local monotonic delta time units:
    243     //      NULL or &kNonBlocking means non-blocking (zero timeout).
    244     //      &kForever means block forever (infinite timeout).
    245     //      Other values mean a specific timeout in local monotonic delta time units.
    246     //  elapsed is a pointer to a location that will hold the total local monotonic time that
    247     //      elapsed while blocked, or NULL if not needed.
    248     // On exit:
    249     //  buffer->mFrameCount has the actual number of contiguous available frames,
    250     //      which is always 0 when the return status != NO_ERROR.
    251     //  buffer->mNonContig is the number of additional non-contiguous available frames.
    252     //  buffer->mRaw is a pointer to the first available frame,
    253     //      or NULL when buffer->mFrameCount == 0.
    254     // The return status is one of:
    255     //  NO_ERROR    Success, buffer->mFrameCount > 0.
    256     //  WOULD_BLOCK Non-blocking mode and no frames are available.
    257     //  TIMED_OUT   Timeout occurred before any frames became available.
    258     //              This can happen even for infinite timeout, due to a spurious wakeup.
    259     //              In this case, the caller should investigate and then re-try as appropriate.
    260     //  DEAD_OBJECT Server has died or invalidated, caller should destroy this proxy and re-create.
    261     //  -EINTR      Call has been interrupted.  Look around to see why, and then perhaps try again.
    262     //  NO_INIT     Shared memory is corrupt.
    263     // Assertion failure on entry, if buffer == NULL or buffer->mFrameCount == 0.
    264     status_t    obtainBuffer(Buffer* buffer, const struct timespec *requested = NULL,
    265             struct timespec *elapsed = NULL);
    266 
    267     // Release (some of) the frames last obtained.
    268     // On entry, buffer->mFrameCount should have the number of frames to release,
    269     // which must (cumulatively) be <= the number of frames last obtained but not yet released.
    270     // buffer->mRaw is ignored, but is normally same pointer returned by last obtainBuffer().
    271     // It is permitted to call releaseBuffer() multiple times to release the frames in chunks.
    272     // On exit:
    273     //  buffer->mFrameCount is zero.
    274     //  buffer->mRaw is NULL.
    275     void        releaseBuffer(Buffer* buffer);
    276 
    277     // Call after detecting server's death
    278     void        binderDied();
    279 
    280     // Call to force an obtainBuffer() to return quickly with -EINTR
    281     void        interrupt();
    282 
    283     size_t      getPosition() {
    284         return mEpoch + mCblk->mServer;
    285     }
    286 
    287     void        setEpoch(size_t epoch) {
    288         mEpoch = epoch;
    289     }
    290 
    291     void        setMinimum(size_t minimum) {
    292         // This can only happen on a 64-bit client
    293         if (minimum > UINT32_MAX) {
    294             minimum = UINT32_MAX;
    295         }
    296         mCblk->mMinimum = (uint32_t) minimum;
    297     }
    298 
    299     // Return the number of frames that would need to be obtained and released
    300     // in order for the client to be aligned at start of buffer
    301     virtual size_t  getMisalignment();
    302 
    303     size_t      getEpoch() const {
    304         return mEpoch;
    305     }
    306 
    307     size_t      getFramesFilled();
    308 
    309 private:
    310     size_t      mEpoch;
    311 };
    312 
    313 // ----------------------------------------------------------------------------
    314 
    315 // Proxy used by AudioTrack client, which also includes AudioFlinger::PlaybackThread::OutputTrack
    316 class AudioTrackClientProxy : public ClientProxy {
    317 public:
    318     AudioTrackClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
    319             size_t frameSize, bool clientInServer = false)
    320         : ClientProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/,
    321           clientInServer),
    322           mPlaybackRateMutator(&cblk->mPlaybackRateQueue) { }
    323     virtual ~AudioTrackClientProxy() { }
    324 
    325     // No barriers on the following operations, so the ordering of loads/stores
    326     // with respect to other parameters is UNPREDICTABLE. That's considered safe.
    327 
    328     // caller must limit to 0.0 <= sendLevel <= 1.0
    329     void        setSendLevel(float sendLevel) {
    330         mCblk->mSendLevel = uint16_t(sendLevel * 0x1000);
    331     }
    332 
    333     // set stereo gains
    334     void        setVolumeLR(gain_minifloat_packed_t volumeLR) {
    335         mCblk->mVolumeLR = volumeLR;
    336     }
    337 
    338     void        setSampleRate(uint32_t sampleRate) {
    339         mCblk->mSampleRate = sampleRate;
    340     }
    341 
    342     void        setPlaybackRate(const AudioPlaybackRate& playbackRate) {
    343         mPlaybackRateMutator.push(playbackRate);
    344     }
    345 
    346     virtual void flush();
    347 
    348     virtual uint32_t    getUnderrunFrames() const {
    349         return mCblk->u.mStreaming.mUnderrunFrames;
    350     }
    351 
    352     bool        clearStreamEndDone();   // and return previous value
    353 
    354     bool        getStreamEndDone() const;
    355 
    356     status_t    waitStreamEndDone(const struct timespec *requested);
    357 
    358 private:
    359     PlaybackRateQueue::Mutator   mPlaybackRateMutator;
    360 };
    361 
    362 class StaticAudioTrackClientProxy : public AudioTrackClientProxy {
    363 public:
    364     StaticAudioTrackClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
    365             size_t frameSize);
    366     virtual ~StaticAudioTrackClientProxy() { }
    367 
    368     virtual void    flush();
    369 
    370 #define MIN_LOOP    16  // minimum length of each loop iteration in frames
    371 
    372             // setLoop(), setBufferPosition(), and setBufferPositionAndLoop() set the
    373             // static buffer position and looping parameters.  These commands are not
    374             // synchronous (they do not wait or block); instead they take effect at the
    375             // next buffer data read from the server side. However, the client side
    376             // getters will read a cached version of the position and loop variables
    377             // until the setting takes effect.
    378             //
    379             // setBufferPositionAndLoop() is equivalent to calling, in order, setLoop() and
    380             // setBufferPosition().
    381             //
    382             // The functions should not be relied upon to do parameter or state checking.
    383             // That is done at the AudioTrack level.
    384 
    385             void    setLoop(size_t loopStart, size_t loopEnd, int loopCount);
    386             void    setBufferPosition(size_t position);
    387             void    setBufferPositionAndLoop(size_t position, size_t loopStart, size_t loopEnd,
    388                                              int loopCount);
    389             size_t  getBufferPosition();
    390                     // getBufferPositionAndLoopCount() provides the proper snapshot of
    391                     // position and loopCount together.
    392             void    getBufferPositionAndLoopCount(size_t *position, int *loopCount);
    393 
    394     virtual size_t  getMisalignment() {
    395         return 0;
    396     }
    397 
    398     virtual uint32_t    getUnderrunFrames() const {
    399         return 0;
    400     }
    401 
    402 private:
    403     StaticAudioTrackSingleStateQueue::Mutator   mMutator;
    404     StaticAudioTrackPosLoopQueue::Observer      mPosLoopObserver;
    405                         StaticAudioTrackState   mState;   // last communicated state to server
    406                         StaticAudioTrackPosLoop mPosLoop; // snapshot of position and loop.
    407 };
    408 
    409 // ----------------------------------------------------------------------------
    410 
    411 // Proxy used by AudioRecord client
    412 class AudioRecordClientProxy : public ClientProxy {
    413 public:
    414     AudioRecordClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
    415             size_t frameSize)
    416         : ClientProxy(cblk, buffers, frameCount, frameSize,
    417             false /*isOut*/, false /*clientInServer*/) { }
    418     ~AudioRecordClientProxy() { }
    419 };
    420 
    421 // ----------------------------------------------------------------------------
    422 
    423 // Proxy used by AudioFlinger server
    424 class ServerProxy : public Proxy {
    425 protected:
    426     ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize,
    427             bool isOut, bool clientInServer);
    428 public:
    429     virtual ~ServerProxy() { }
    430 
    431     // Obtain a buffer with filled frames (writing) or empty frames (reading).
    432     // It is permitted to call obtainBuffer() multiple times in succession, without any intervening
    433     // calls to releaseBuffer().  In that case, the final obtainBuffer() is the one that effectively
    434     // sets or extends the unreleased frame count.
    435     // Always non-blocking.
    436     // On entry:
    437     //  buffer->mFrameCount should be initialized to maximum number of desired frames,
    438     //      which must be > 0.
    439     //  buffer->mNonContig is unused.
    440     //  buffer->mRaw is unused.
    441     //  ackFlush is true iff being called from Track::start to acknowledge a pending flush.
    442     // On exit:
    443     //  buffer->mFrameCount has the actual number of contiguous available frames,
    444     //      which is always 0 when the return status != NO_ERROR.
    445     //  buffer->mNonContig is the number of additional non-contiguous available frames.
    446     //  buffer->mRaw is a pointer to the first available frame,
    447     //      or NULL when buffer->mFrameCount == 0.
    448     // The return status is one of:
    449     //  NO_ERROR    Success, buffer->mFrameCount > 0.
    450     //  WOULD_BLOCK No frames are available.
    451     //  NO_INIT     Shared memory is corrupt.
    452     virtual status_t    obtainBuffer(Buffer* buffer, bool ackFlush = false);
    453 
    454     // Release (some of) the frames last obtained.
    455     // On entry, buffer->mFrameCount should have the number of frames to release,
    456     // which must (cumulatively) be <= the number of frames last obtained but not yet released.
    457     // It is permitted to call releaseBuffer() multiple times to release the frames in chunks.
    458     // buffer->mRaw is ignored, but is normally same pointer returned by last obtainBuffer().
    459     // On exit:
    460     //  buffer->mFrameCount is zero.
    461     //  buffer->mRaw is NULL.
    462     virtual void        releaseBuffer(Buffer* buffer);
    463 
    464 protected:
    465     size_t      mAvailToClient; // estimated frames available to client prior to releaseBuffer()
    466     int32_t     mFlush;         // our copy of cblk->u.mStreaming.mFlush, for streaming output only
    467 };
    468 
    469 // Proxy used by AudioFlinger for servicing AudioTrack
    470 class AudioTrackServerProxy : public ServerProxy {
    471 public:
    472     AudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
    473             size_t frameSize, bool clientInServer = false, uint32_t sampleRate = 0)
    474         : ServerProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, clientInServer),
    475           mPlaybackRateObserver(&cblk->mPlaybackRateQueue) {
    476         mCblk->mSampleRate = sampleRate;
    477         mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
    478     }
    479 protected:
    480     virtual ~AudioTrackServerProxy() { }
    481 
    482 public:
    483     // return value of these methods must be validated by the caller
    484     uint32_t    getSampleRate() const { return mCblk->mSampleRate; }
    485     uint16_t    getSendLevel_U4_12() const { return mCblk->mSendLevel; }
    486     gain_minifloat_packed_t getVolumeLR() const { return mCblk->mVolumeLR; }
    487 
    488     // estimated total number of filled frames available to server to read,
    489     // which may include non-contiguous frames
    490     virtual size_t      framesReady();
    491 
    492     // Currently AudioFlinger will call framesReady() for a fast track from two threads:
    493     // FastMixer thread, and normal mixer thread.  This is dangerous, as the proxy is intended
    494     // to be called from at most one thread of server, and one thread of client.
    495     // As a temporary workaround, this method informs the proxy implementation that it
    496     // should avoid doing a state queue poll from within framesReady().
    497     // FIXME Change AudioFlinger to not call framesReady() from normal mixer thread.
    498     virtual void        framesReadyIsCalledByMultipleThreads() { }
    499 
    500     bool     setStreamEndDone();    // and return previous value
    501 
    502     // Add to the tally of underrun frames, and inform client of underrun
    503     virtual void        tallyUnderrunFrames(uint32_t frameCount);
    504 
    505     // Return the total number of frames which AudioFlinger desired but were unavailable,
    506     // and thus which resulted in an underrun.
    507     virtual uint32_t    getUnderrunFrames() const { return mCblk->u.mStreaming.mUnderrunFrames; }
    508 
    509     // Return the total number of frames that AudioFlinger has obtained and released
    510     virtual size_t      framesReleased() const { return mCblk->mServer; }
    511 
    512     // Return the playback speed and pitch read atomically. Not multi-thread safe on server side.
    513     AudioPlaybackRate getPlaybackRate();
    514 
    515 private:
    516     AudioPlaybackRate             mPlaybackRate;  // last observed playback rate
    517     PlaybackRateQueue::Observer   mPlaybackRateObserver;
    518 };
    519 
    520 class StaticAudioTrackServerProxy : public AudioTrackServerProxy {
    521 public:
    522     StaticAudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
    523             size_t frameSize);
    524 protected:
    525     virtual ~StaticAudioTrackServerProxy() { }
    526 
    527 public:
    528     virtual size_t      framesReady();
    529     virtual void        framesReadyIsCalledByMultipleThreads();
    530     virtual status_t    obtainBuffer(Buffer* buffer, bool ackFlush);
    531     virtual void        releaseBuffer(Buffer* buffer);
    532     virtual void        tallyUnderrunFrames(uint32_t frameCount);
    533     virtual uint32_t    getUnderrunFrames() const { return 0; }
    534 
    535 private:
    536     status_t            updateStateWithLoop(StaticAudioTrackState *localState,
    537                                             const StaticAudioTrackState &update) const;
    538     status_t            updateStateWithPosition(StaticAudioTrackState *localState,
    539                                                 const StaticAudioTrackState &update) const;
    540     ssize_t             pollPosition(); // poll for state queue update, and return current position
    541     StaticAudioTrackSingleStateQueue::Observer  mObserver;
    542     StaticAudioTrackPosLoopQueue::Mutator       mPosLoopMutator;
    543     size_t              mFramesReadySafe; // Assuming size_t read/writes are atomic on 32 / 64 bit
    544                                           // processors, this is a thread-safe version of
    545                                           // mFramesReady.
    546     int64_t             mFramesReady;     // The number of frames ready in the static buffer
    547                                           // including loops.  This is 64 bits since loop mode
    548                                           // can cause a track to appear to have a large number
    549                                           // of frames. INT64_MAX means an infinite loop.
    550     bool                mFramesReadyIsCalledByMultipleThreads;
    551     StaticAudioTrackState mState;         // Server side state. Any updates from client must be
    552                                           // passed by the mObserver SingleStateQueue.
    553 };
    554 
    555 // Proxy used by AudioFlinger for servicing AudioRecord
    556 class AudioRecordServerProxy : public ServerProxy {
    557 public:
    558     AudioRecordServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
    559             size_t frameSize, bool clientInServer)
    560         : ServerProxy(cblk, buffers, frameCount, frameSize, false /*isOut*/, clientInServer) { }
    561 protected:
    562     virtual ~AudioRecordServerProxy() { }
    563 };
    564 
    565 // ----------------------------------------------------------------------------
    566 
    567 }; // namespace android
    568 
    569 #endif // ANDROID_AUDIO_TRACK_SHARED_H
    570