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 <utils/threads.h>
     24 #include <utils/Log.h>
     25 #include <utils/RefBase.h>
     26 #include <media/nbaio/roundup.h>
     27 #include <media/SingleStateQueue.h>
     28 #include <private/media/StaticAudioTrackState.h>
     29 
     30 namespace android {
     31 
     32 // ----------------------------------------------------------------------------
     33 
     34 // for audio_track_cblk_t::mFlags
     35 #define CBLK_UNDERRUN   0x01 // set by server immediately on output underrun, cleared by client
     36 #define CBLK_FORCEREADY 0x02 // set: track is considered ready immediately by AudioFlinger,
     37                              // clear: track is ready when buffer full
     38 #define CBLK_INVALID    0x04 // track buffer invalidated by AudioFlinger, need to re-create
     39 #define CBLK_DISABLED   0x08 // output track disabled by AudioFlinger due to underrun,
     40                              // need to re-start.  Unlike CBLK_UNDERRUN, this is not set
     41                              // immediately, but only after a long string of underruns.
     42 // 0x10 unused
     43 #define CBLK_LOOP_CYCLE 0x20 // set by server each time a loop cycle other than final one completes
     44 #define CBLK_LOOP_FINAL 0x40 // set by server when the final loop cycle completes
     45 #define CBLK_BUFFER_END 0x80 // set by server when the position reaches end of buffer if not looping
     46 #define CBLK_OVERRUN   0x100 // set by server immediately on input overrun, cleared by client
     47 #define CBLK_INTERRUPT 0x200 // set by client on interrupt(), cleared by client in obtainBuffer()
     48 #define CBLK_STREAM_END_DONE 0x400 // set by server on render completion, cleared by client
     49 
     50 //EL_FIXME 20 seconds may not be enough and must be reconciled with new obtainBuffer implementation
     51 #define MAX_RUN_OFFLOADED_TIMEOUT_MS 20000 //assuming upto a maximum of 20 seconds of offloaded
     52 
     53 struct AudioTrackSharedStreaming {
     54     // similar to NBAIO MonoPipe
     55     // in continuously incrementing frame units, take modulo buffer size, which must be a power of 2
     56     volatile int32_t mFront;    // read by server
     57     volatile int32_t mRear;     // write by client
     58     volatile int32_t mFlush;    // incremented by client to indicate a request to flush;
     59                                 // server notices and discards all data between mFront and mRear
     60     volatile uint32_t mUnderrunFrames;  // server increments for each unavailable but desired frame
     61 };
     62 
     63 typedef SingleStateQueue<StaticAudioTrackState> StaticAudioTrackSingleStateQueue;
     64 
     65 struct AudioTrackSharedStatic {
     66     StaticAudioTrackSingleStateQueue::Shared
     67                     mSingleStateQueue;
     68     size_t          mBufferPosition;    // updated asynchronously by server,
     69                                         // "for entertainment purposes only"
     70 };
     71 
     72 // ----------------------------------------------------------------------------
     73 
     74 // Important: do not add any virtual methods, including ~
     75 struct audio_track_cblk_t
     76 {
     77                 // Since the control block is always located in shared memory, this constructor
     78                 // is only used for placement new().  It is never used for regular new() or stack.
     79                             audio_track_cblk_t();
     80                 /*virtual*/ ~audio_track_cblk_t() { }
     81 
     82                 friend class Proxy;
     83                 friend class ClientProxy;
     84                 friend class AudioTrackClientProxy;
     85                 friend class AudioRecordClientProxy;
     86                 friend class ServerProxy;
     87                 friend class AudioTrackServerProxy;
     88                 friend class AudioRecordServerProxy;
     89 
     90     // The data members are grouped so that members accessed frequently and in the same context
     91     // are in the same line of data cache.
     92 
     93                 uint32_t    mServer;    // Number of filled frames consumed by server (mIsOut),
     94                                         // or filled frames provided by server (!mIsOut).
     95                                         // It is updated asynchronously by server without a barrier.
     96                                         // The value should be used "for entertainment purposes only",
     97                                         // which means don't make important decisions based on it.
     98 
     99                 size_t      frameCount_;    // used during creation to pass actual track buffer size
    100                                             // from AudioFlinger to client, and not referenced again
    101                                             // FIXME remove here and replace by createTrack() in/out
    102                                             // parameter
    103                                             // renamed to "_" to detect incorrect use
    104 
    105     volatile    int32_t     mFutex;     // event flag: down (P) by client,
    106                                         // up (V) by server or binderDied() or interrupt()
    107 #define CBLK_FUTEX_WAKE 1               // if event flag bit is set, then a deferred wake is pending
    108 
    109 private:
    110 
    111                 size_t      mMinimum;       // server wakes up client if available >= mMinimum
    112 
    113                 // Channel volumes are fixed point U4.12, so 0x1000 means 1.0.
    114                 // Left channel is in [0:15], right channel is in [16:31].
    115                 // Always read and write the combined pair atomically.
    116                 // For AudioTrack only, not used by AudioRecord.
    117                 uint32_t    mVolumeLR;
    118 
    119                 uint32_t    mSampleRate;    // AudioTrack only: client's requested sample rate in Hz
    120                                             // or 0 == default. Write-only client, read-only server.
    121 
    122                 // client write-only, server read-only
    123                 uint16_t    mSendLevel;      // Fixed point U4.12 so 0x1000 means 1.0
    124 
    125                 uint16_t    mPad2;           // unused
    126 
    127 public:
    128 
    129     volatile    int32_t     mFlags;         // combinations of CBLK_*
    130 
    131                 // Cache line boundary (32 bytes)
    132 
    133 public:
    134                 union {
    135                     AudioTrackSharedStreaming   mStreaming;
    136                     AudioTrackSharedStatic      mStatic;
    137                     int                         mAlign[8];
    138                 } u;
    139 
    140                 // Cache line boundary (32 bytes)
    141 };
    142 
    143 // ----------------------------------------------------------------------------
    144 
    145 // Proxy for shared memory control block, to isolate callers from needing to know the details.
    146 // There is exactly one ClientProxy and one ServerProxy per shared memory control block.
    147 // The proxies are located in normal memory, and are not multi-thread safe within a given side.
    148 class Proxy : public RefBase {
    149 protected:
    150     Proxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize, bool isOut,
    151             bool clientInServer);
    152     virtual ~Proxy() { }
    153 
    154 public:
    155     struct Buffer {
    156         size_t  mFrameCount;            // number of frames available in this buffer
    157         void*   mRaw;                   // pointer to first frame
    158         size_t  mNonContig;             // number of additional non-contiguous frames available
    159     };
    160 
    161 protected:
    162     // These refer to shared memory, and are virtual addresses with respect to the current process.
    163     // They may have different virtual addresses within the other process.
    164     audio_track_cblk_t* const   mCblk;  // the control block
    165     void* const     mBuffers;           // starting address of buffers
    166 
    167     const size_t    mFrameCount;        // not necessarily a power of 2
    168     const size_t    mFrameSize;         // in bytes
    169     const size_t    mFrameCountP2;      // mFrameCount rounded to power of 2, streaming mode
    170     const bool      mIsOut;             // true for AudioTrack, false for AudioRecord
    171     const bool      mClientInServer;    // true for OutputTrack, false for AudioTrack & AudioRecord
    172     bool            mIsShutdown;        // latch set to true when shared memory corruption detected
    173     size_t          mUnreleased;        // unreleased frames remaining from most recent obtainBuffer
    174 };
    175 
    176 // ----------------------------------------------------------------------------
    177 
    178 // Proxy seen by AudioTrack client and AudioRecord client
    179 class ClientProxy : public Proxy {
    180 protected:
    181     ClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize,
    182             bool isOut, bool clientInServer);
    183     virtual ~ClientProxy() { }
    184 
    185 public:
    186     static const struct timespec kForever;
    187     static const struct timespec kNonBlocking;
    188 
    189     // Obtain a buffer with filled frames (reading) or empty frames (writing).
    190     // It is permitted to call obtainBuffer() multiple times in succession, without any intervening
    191     // calls to releaseBuffer().  In that case, the final obtainBuffer() is the one that effectively
    192     // sets or extends the unreleased frame count.
    193     // On entry:
    194     //  buffer->mFrameCount should be initialized to maximum number of desired frames,
    195     //      which must be > 0.
    196     //  buffer->mNonContig is unused.
    197     //  buffer->mRaw is unused.
    198     //  requested is the requested timeout in local monotonic delta time units:
    199     //      NULL or &kNonBlocking means non-blocking (zero timeout).
    200     //      &kForever means block forever (infinite timeout).
    201     //      Other values mean a specific timeout in local monotonic delta time units.
    202     //  elapsed is a pointer to a location that will hold the total local monotonic time that
    203     //      elapsed while blocked, or NULL if not needed.
    204     // On exit:
    205     //  buffer->mFrameCount has the actual number of contiguous available frames,
    206     //      which is always 0 when the return status != NO_ERROR.
    207     //  buffer->mNonContig is the number of additional non-contiguous available frames.
    208     //  buffer->mRaw is a pointer to the first available frame,
    209     //      or NULL when buffer->mFrameCount == 0.
    210     // The return status is one of:
    211     //  NO_ERROR    Success, buffer->mFrameCount > 0.
    212     //  WOULD_BLOCK Non-blocking mode and no frames are available.
    213     //  TIMED_OUT   Timeout occurred before any frames became available.
    214     //              This can happen even for infinite timeout, due to a spurious wakeup.
    215     //              In this case, the caller should investigate and then re-try as appropriate.
    216     //  DEAD_OBJECT Server has died or invalidated, caller should destroy this proxy and re-create.
    217     //  -EINTR      Call has been interrupted.  Look around to see why, and then perhaps try again.
    218     //  NO_INIT     Shared memory is corrupt.
    219     // Assertion failure on entry, if buffer == NULL or buffer->mFrameCount == 0.
    220     status_t    obtainBuffer(Buffer* buffer, const struct timespec *requested = NULL,
    221             struct timespec *elapsed = NULL);
    222 
    223     // Release (some of) the frames last obtained.
    224     // On entry, buffer->mFrameCount should have the number of frames to release,
    225     // which must (cumulatively) be <= the number of frames last obtained but not yet released.
    226     // buffer->mRaw is ignored, but is normally same pointer returned by last obtainBuffer().
    227     // It is permitted to call releaseBuffer() multiple times to release the frames in chunks.
    228     // On exit:
    229     //  buffer->mFrameCount is zero.
    230     //  buffer->mRaw is NULL.
    231     void        releaseBuffer(Buffer* buffer);
    232 
    233     // Call after detecting server's death
    234     void        binderDied();
    235 
    236     // Call to force an obtainBuffer() to return quickly with -EINTR
    237     void        interrupt();
    238 
    239     size_t      getPosition() {
    240         return mEpoch + mCblk->mServer;
    241     }
    242 
    243     void        setEpoch(size_t epoch) {
    244         mEpoch = epoch;
    245     }
    246 
    247     void        setMinimum(size_t minimum) {
    248         mCblk->mMinimum = minimum;
    249     }
    250 
    251     // Return the number of frames that would need to be obtained and released
    252     // in order for the client to be aligned at start of buffer
    253     virtual size_t  getMisalignment();
    254 
    255     size_t      getEpoch() const {
    256         return mEpoch;
    257     }
    258 
    259     size_t      getFramesFilled();
    260 
    261 private:
    262     size_t      mEpoch;
    263 };
    264 
    265 // ----------------------------------------------------------------------------
    266 
    267 // Proxy used by AudioTrack client, which also includes AudioFlinger::PlaybackThread::OutputTrack
    268 class AudioTrackClientProxy : public ClientProxy {
    269 public:
    270     AudioTrackClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
    271             size_t frameSize, bool clientInServer = false)
    272         : ClientProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/,
    273           clientInServer) { }
    274     virtual ~AudioTrackClientProxy() { }
    275 
    276     // No barriers on the following operations, so the ordering of loads/stores
    277     // with respect to other parameters is UNPREDICTABLE. That's considered safe.
    278 
    279     // caller must limit to 0.0 <= sendLevel <= 1.0
    280     void        setSendLevel(float sendLevel) {
    281         mCblk->mSendLevel = uint16_t(sendLevel * 0x1000);
    282     }
    283 
    284     // caller must limit to 0 <= volumeLR <= 0x10001000
    285     void        setVolumeLR(uint32_t volumeLR) {
    286         mCblk->mVolumeLR = volumeLR;
    287     }
    288 
    289     void        setSampleRate(uint32_t sampleRate) {
    290         mCblk->mSampleRate = sampleRate;
    291     }
    292 
    293     virtual void flush();
    294 
    295     virtual uint32_t    getUnderrunFrames() const {
    296         return mCblk->u.mStreaming.mUnderrunFrames;
    297     }
    298 
    299     bool        clearStreamEndDone();   // and return previous value
    300 
    301     bool        getStreamEndDone() const;
    302 
    303     status_t    waitStreamEndDone(const struct timespec *requested);
    304 };
    305 
    306 class StaticAudioTrackClientProxy : public AudioTrackClientProxy {
    307 public:
    308     StaticAudioTrackClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
    309             size_t frameSize);
    310     virtual ~StaticAudioTrackClientProxy() { }
    311 
    312     virtual void    flush();
    313 
    314 #define MIN_LOOP    16  // minimum length of each loop iteration in frames
    315             void    setLoop(size_t loopStart, size_t loopEnd, int loopCount);
    316             size_t  getBufferPosition();
    317 
    318     virtual size_t  getMisalignment() {
    319         return 0;
    320     }
    321 
    322     virtual uint32_t    getUnderrunFrames() const {
    323         return 0;
    324     }
    325 
    326 private:
    327     StaticAudioTrackSingleStateQueue::Mutator   mMutator;
    328     size_t          mBufferPosition;    // so that getBufferPosition() appears to be synchronous
    329 };
    330 
    331 // ----------------------------------------------------------------------------
    332 
    333 // Proxy used by AudioRecord client
    334 class AudioRecordClientProxy : public ClientProxy {
    335 public:
    336     AudioRecordClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
    337             size_t frameSize)
    338         : ClientProxy(cblk, buffers, frameCount, frameSize,
    339             false /*isOut*/, false /*clientInServer*/) { }
    340     ~AudioRecordClientProxy() { }
    341 };
    342 
    343 // ----------------------------------------------------------------------------
    344 
    345 // Proxy used by AudioFlinger server
    346 class ServerProxy : public Proxy {
    347 protected:
    348     ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize,
    349             bool isOut, bool clientInServer);
    350 public:
    351     virtual ~ServerProxy() { }
    352 
    353     // Obtain a buffer with filled frames (writing) or empty frames (reading).
    354     // It is permitted to call obtainBuffer() multiple times in succession, without any intervening
    355     // calls to releaseBuffer().  In that case, the final obtainBuffer() is the one that effectively
    356     // sets or extends the unreleased frame count.
    357     // Always non-blocking.
    358     // On entry:
    359     //  buffer->mFrameCount should be initialized to maximum number of desired frames,
    360     //      which must be > 0.
    361     //  buffer->mNonContig is unused.
    362     //  buffer->mRaw is unused.
    363     //  ackFlush is true iff being called from Track::start to acknowledge a pending flush.
    364     // On exit:
    365     //  buffer->mFrameCount has the actual number of contiguous available frames,
    366     //      which is always 0 when the return status != NO_ERROR.
    367     //  buffer->mNonContig is the number of additional non-contiguous available frames.
    368     //  buffer->mRaw is a pointer to the first available frame,
    369     //      or NULL when buffer->mFrameCount == 0.
    370     // The return status is one of:
    371     //  NO_ERROR    Success, buffer->mFrameCount > 0.
    372     //  WOULD_BLOCK No frames are available.
    373     //  NO_INIT     Shared memory is corrupt.
    374     virtual status_t    obtainBuffer(Buffer* buffer, bool ackFlush = false);
    375 
    376     // Release (some of) the frames last obtained.
    377     // On entry, buffer->mFrameCount should have the number of frames to release,
    378     // which must (cumulatively) be <= the number of frames last obtained but not yet released.
    379     // It is permitted to call releaseBuffer() multiple times to release the frames in chunks.
    380     // buffer->mRaw is ignored, but is normally same pointer returned by last obtainBuffer().
    381     // On exit:
    382     //  buffer->mFrameCount is zero.
    383     //  buffer->mRaw is NULL.
    384     virtual void        releaseBuffer(Buffer* buffer);
    385 
    386 protected:
    387     size_t      mAvailToClient; // estimated frames available to client prior to releaseBuffer()
    388     int32_t     mFlush;         // our copy of cblk->u.mStreaming.mFlush, for streaming output only
    389 };
    390 
    391 // Proxy used by AudioFlinger for servicing AudioTrack
    392 class AudioTrackServerProxy : public ServerProxy {
    393 public:
    394     AudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
    395             size_t frameSize, bool clientInServer = false)
    396         : ServerProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, clientInServer) { }
    397 protected:
    398     virtual ~AudioTrackServerProxy() { }
    399 
    400 public:
    401     // return value of these methods must be validated by the caller
    402     uint32_t    getSampleRate() const { return mCblk->mSampleRate; }
    403     uint16_t    getSendLevel_U4_12() const { return mCblk->mSendLevel; }
    404     uint32_t    getVolumeLR() const { return mCblk->mVolumeLR; }
    405 
    406     // estimated total number of filled frames available to server to read,
    407     // which may include non-contiguous frames
    408     virtual size_t      framesReady();
    409 
    410     // Currently AudioFlinger will call framesReady() for a fast track from two threads:
    411     // FastMixer thread, and normal mixer thread.  This is dangerous, as the proxy is intended
    412     // to be called from at most one thread of server, and one thread of client.
    413     // As a temporary workaround, this method informs the proxy implementation that it
    414     // should avoid doing a state queue poll from within framesReady().
    415     // FIXME Change AudioFlinger to not call framesReady() from normal mixer thread.
    416     virtual void        framesReadyIsCalledByMultipleThreads() { }
    417 
    418     bool     setStreamEndDone();    // and return previous value
    419 
    420     // Add to the tally of underrun frames, and inform client of underrun
    421     virtual void        tallyUnderrunFrames(uint32_t frameCount);
    422 
    423     // Return the total number of frames which AudioFlinger desired but were unavailable,
    424     // and thus which resulted in an underrun.
    425     virtual uint32_t    getUnderrunFrames() const { return mCblk->u.mStreaming.mUnderrunFrames; }
    426 
    427     // Return the total number of frames that AudioFlinger has obtained and released
    428     virtual size_t      framesReleased() const { return mCblk->mServer; }
    429 };
    430 
    431 class StaticAudioTrackServerProxy : public AudioTrackServerProxy {
    432 public:
    433     StaticAudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
    434             size_t frameSize);
    435 protected:
    436     virtual ~StaticAudioTrackServerProxy() { }
    437 
    438 public:
    439     virtual size_t      framesReady();
    440     virtual void        framesReadyIsCalledByMultipleThreads();
    441     virtual status_t    obtainBuffer(Buffer* buffer, bool ackFlush);
    442     virtual void        releaseBuffer(Buffer* buffer);
    443     virtual void        tallyUnderrunFrames(uint32_t frameCount);
    444     virtual uint32_t    getUnderrunFrames() const { return 0; }
    445 
    446 private:
    447     ssize_t             pollPosition(); // poll for state queue update, and return current position
    448     StaticAudioTrackSingleStateQueue::Observer  mObserver;
    449     size_t              mPosition;  // server's current play position in frames, relative to 0
    450     size_t              mEnd;       // cached value computed from mState, safe for asynchronous read
    451     bool                mFramesReadyIsCalledByMultipleThreads;
    452     StaticAudioTrackState   mState;
    453 };
    454 
    455 // Proxy used by AudioFlinger for servicing AudioRecord
    456 class AudioRecordServerProxy : public ServerProxy {
    457 public:
    458     AudioRecordServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
    459             size_t frameSize)
    460         : ServerProxy(cblk, buffers, frameCount, frameSize, false /*isOut*/,
    461             false /*clientInServer*/) { }
    462 protected:
    463     virtual ~AudioRecordServerProxy() { }
    464 };
    465 
    466 // ----------------------------------------------------------------------------
    467 
    468 }; // namespace android
    469 
    470 #endif // ANDROID_AUDIO_TRACK_SHARED_H
    471