• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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();
~audio_track_cblk_taudio_track_cblk_t80                 /*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);
~Proxy()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);
~ClientProxy()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 
getPosition()239     size_t      getPosition() {
240         return mEpoch + mCblk->mServer;
241     }
242 
setEpoch(size_t epoch)243     void        setEpoch(size_t epoch) {
244         mEpoch = epoch;
245     }
246 
setMinimum(size_t minimum)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 
getEpoch()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)
ClientProxy(cblk,buffers,frameCount,frameSize,true,clientInServer)272         : ClientProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/,
273           clientInServer) { }
~AudioTrackClientProxy()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
setSendLevel(float sendLevel)280     void        setSendLevel(float sendLevel) {
281         mCblk->mSendLevel = uint16_t(sendLevel * 0x1000);
282     }
283 
284     // caller must limit to 0 <= volumeLR <= 0x10001000
setVolumeLR(uint32_t volumeLR)285     void        setVolumeLR(uint32_t volumeLR) {
286         mCblk->mVolumeLR = volumeLR;
287     }
288 
setSampleRate(uint32_t sampleRate)289     void        setSampleRate(uint32_t sampleRate) {
290         mCblk->mSampleRate = sampleRate;
291     }
292 
293     virtual void flush();
294 
getUnderrunFrames()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);
~StaticAudioTrackClientProxy()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 
getMisalignment()318     virtual size_t  getMisalignment() {
319         return 0;
320     }
321 
getUnderrunFrames()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:
AudioRecordClientProxy(audio_track_cblk_t * cblk,void * buffers,size_t frameCount,size_t frameSize)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*/) { }
~AudioRecordClientProxy()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:
~ServerProxy()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)
ServerProxy(cblk,buffers,frameCount,frameSize,true,clientInServer)396         : ServerProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, clientInServer) { }
397 protected:
~AudioTrackServerProxy()398     virtual ~AudioTrackServerProxy() { }
399 
400 public:
401     // return value of these methods must be validated by the caller
getSampleRate()402     uint32_t    getSampleRate() const { return mCblk->mSampleRate; }
getSendLevel_U4_12()403     uint16_t    getSendLevel_U4_12() const { return mCblk->mSendLevel; }
getVolumeLR()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.
framesReadyIsCalledByMultipleThreads()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.
getUnderrunFrames()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
framesReleased()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:
~StaticAudioTrackServerProxy()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);
getUnderrunFrames()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:
AudioRecordServerProxy(audio_track_cblk_t * cblk,void * buffers,size_t frameCount,size_t frameSize)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:
~AudioRecordServerProxy()463     virtual ~AudioRecordServerProxy() { }
464 };
465 
466 // ----------------------------------------------------------------------------
467 
468 }; // namespace android
469 
470 #endif // ANDROID_AUDIO_TRACK_SHARED_H
471