Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9f80dd22 authored by Glenn Kasten's avatar Glenn Kasten
Browse files

New control block for AudioTrack and AudioRecord

Main differences between old and new control block:
 - removes the mutex, which was a potential source of priority inversion
 - circular indices into shared buffer, which is now always a power-of-2 size

Change-Id: I4e9b7fa99858b488ac98a441fa70e31dbba1b865
parent 9fef8d45
Loading
Loading
Loading
Loading
+15 −0
Original line number Original line Diff line number Diff line
@@ -26,6 +26,8 @@ class AudioBufferProvider
{
{
public:
public:


    // FIXME merge with AudioTrackShared::Buffer, AudioTrack::Buffer, and AudioRecord::Buffer
    //       and rename getNextBuffer() to obtainBuffer()
    struct Buffer {
    struct Buffer {
        Buffer() : raw(NULL), frameCount(0) { }
        Buffer() : raw(NULL), frameCount(0) { }
        union {
        union {
@@ -44,6 +46,19 @@ public:
    // pts is the local time when the next sample yielded by getNextBuffer
    // pts is the local time when the next sample yielded by getNextBuffer
    // will be rendered.
    // will be rendered.
    // Pass kInvalidPTS if the PTS is unknown or not applicable.
    // Pass kInvalidPTS if the PTS is unknown or not applicable.
    // On entry:
    //  buffer              != NULL
    //  buffer->raw         unused
    //  buffer->frameCount  maximum number of desired frames
    // On successful return:
    //  status              NO_ERROR
    //  buffer->raw         non-NULL pointer to buffer->frameCount contiguous available frames
    //  buffer->frameCount  number of contiguous available frames at buffer->raw,
    //                      0 < buffer->frameCount <= entry value
    // On error return:
    //  status              != NO_ERROR
    //  buffer->raw         NULL
    //  buffer->frameCount  0
    virtual status_t getNextBuffer(Buffer* buffer, int64_t pts = kInvalidPTS) = 0;
    virtual status_t getNextBuffer(Buffer* buffer, int64_t pts = kInvalidPTS) = 0;


    virtual void releaseBuffer(Buffer* buffer) = 0;
    virtual void releaseBuffer(Buffer* buffer) = 0;
+175 −76
Original line number Original line Diff line number Diff line
@@ -14,26 +14,24 @@
 * limitations under the License.
 * limitations under the License.
 */
 */


#ifndef AUDIORECORD_H_
#ifndef ANDROID_AUDIORECORD_H
#define AUDIORECORD_H_
#define ANDROID_AUDIORECORD_H


#include <binder/IMemory.h>
#include <cutils/sched_policy.h>
#include <cutils/sched_policy.h>
#include <media/AudioSystem.h>
#include <media/AudioSystem.h>
#include <media/IAudioRecord.h>
#include <media/IAudioRecord.h>
#include <system/audio.h>
#include <utils/RefBase.h>
#include <utils/Errors.h>
#include <utils/threads.h>
#include <utils/threads.h>


namespace android {
namespace android {


// ----------------------------------------------------------------------------

class audio_track_cblk_t;
class audio_track_cblk_t;
class AudioRecordClientProxy;
class AudioRecordClientProxy;


// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------


class AudioRecord : virtual public RefBase
class AudioRecord : public RefBase
{
{
public:
public:


@@ -49,6 +47,8 @@ public:
                                    // (See setMarkerPosition()).
                                    // (See setMarkerPosition()).
        EVENT_NEW_POS = 3,          // Record head is at a new position
        EVENT_NEW_POS = 3,          // Record head is at a new position
                                    // (See setPositionUpdatePeriod()).
                                    // (See setPositionUpdatePeriod()).
        EVENT_NEW_IAUDIORECORD = 4, // IAudioRecord was re-created, either due to re-routing and
                                    // voluntary invalidation by mediaserver, or mediaserver crash.
    };
    };


    /* Client should declare Buffer on the stack and pass address to obtainBuffer()
    /* Client should declare Buffer on the stack and pass address to obtainBuffer()
@@ -58,11 +58,16 @@ public:
    class Buffer
    class Buffer
    {
    {
    public:
    public:
        // FIXME use m prefix
        size_t      frameCount;     // number of sample frames corresponding to size;
        size_t      frameCount;     // number of sample frames corresponding to size;
                                    // on input it is the number of frames available,
                                    // on input it is the number of frames available,
                                    // on output is the number of frames actually drained
                                    // on output is the number of frames actually drained


        size_t      size;           // total size in bytes == frameCount * frameSize
        size_t      size;           // input/output in bytes == frameCount * frameSize
                                    // FIXME this is redundant with respect to frameCount,
                                    // and TRANSFER_OBTAIN mode is broken for 8-bit data
                                    // since we don't define the frame format

        union {
        union {
            void*       raw;
            void*       raw;
            short*      i16;        // signed 16-bit
            short*      i16;        // signed 16-bit
@@ -84,6 +89,7 @@ public:
     *          - EVENT_OVERRUN: unused.
     *          - EVENT_OVERRUN: unused.
     *          - EVENT_MARKER: pointer to const uint32_t containing the marker position in frames.
     *          - EVENT_MARKER: pointer to const uint32_t containing the marker position in frames.
     *          - EVENT_NEW_POS: pointer to const uint32_t containing the new position in frames.
     *          - EVENT_NEW_POS: pointer to const uint32_t containing the new position in frames.
     *          - EVENT_NEW_IAUDIORECORD: unused.
     */
     */


    typedef void (*callback_t)(int event, void* user, void *info);
    typedef void (*callback_t)(int event, void* user, void *info);
@@ -101,20 +107,28 @@ public:
                                      audio_format_t format,
                                      audio_format_t format,
                                      audio_channel_mask_t channelMask);
                                      audio_channel_mask_t channelMask);


    /* How data is transferred from AudioRecord
     */
    enum transfer_type {
        TRANSFER_DEFAULT,   // not specified explicitly; determine from other parameters
        TRANSFER_CALLBACK,  // callback EVENT_MORE_DATA
        TRANSFER_OBTAIN,    // FIXME deprecated: call obtainBuffer() and releaseBuffer()
        TRANSFER_SYNC,      // synchronous read()
    };

    /* Constructs an uninitialized AudioRecord. No connection with
    /* Constructs an uninitialized AudioRecord. No connection with
     * AudioFlinger takes place.
     * AudioFlinger takes place.  Use set() after this.
     */
     */
                        AudioRecord();
                        AudioRecord();


    /* Creates an AudioRecord object and registers it with AudioFlinger.
    /* Creates an AudioRecord object and registers it with AudioFlinger.
     * Once created, the track needs to be started before it can be used.
     * Once created, the track needs to be started before it can be used.
     * Unspecified values are set to the audio hardware's current
     * Unspecified values are set to appropriate default values.
     * values.
     *
     *
     * Parameters:
     * Parameters:
     *
     *
     * inputSource:        Select the audio input to record to (e.g. AUDIO_SOURCE_DEFAULT).
     * inputSource:        Select the audio input to record from (e.g. AUDIO_SOURCE_DEFAULT).
     * sampleRate:         Track sampling rate in Hz.
     * sampleRate:         Data sink sampling rate in Hz.
     * format:             Audio format (e.g AUDIO_FORMAT_PCM_16_BIT for signed
     * format:             Audio format (e.g AUDIO_FORMAT_PCM_16_BIT for signed
     *                     16 bits per sample).
     *                     16 bits per sample).
     * channelMask:        Channel mask.
     * channelMask:        Channel mask.
@@ -124,11 +138,13 @@ public:
     *                     be larger if the requested size is not compatible with current audio HAL
     *                     be larger if the requested size is not compatible with current audio HAL
     *                     latency.  Zero means to use a default value.
     *                     latency.  Zero means to use a default value.
     * cbf:                Callback function. If not null, this function is called periodically
     * cbf:                Callback function. If not null, this function is called periodically
     *                     to consume new PCM data.
     *                     to consume new PCM data and inform of marker, position updates, etc.
     * user:               Context for use by the callback receiver.
     * user:               Context for use by the callback receiver.
     * notificationFrames: The callback function is called each time notificationFrames PCM
     * notificationFrames: The callback function is called each time notificationFrames PCM
     *                     frames are ready in record track output buffer.
     *                     frames are ready in record track output buffer.
     * sessionId:          Not yet supported.
     * sessionId:          Not yet supported.
     * transferType:       How data is transferred from AudioRecord.
     * threadCanCallJava:  Not present in parameter list, and so is fixed at false.
     */
     */


                        AudioRecord(audio_source_t inputSource,
                        AudioRecord(audio_source_t inputSource,
@@ -139,22 +155,26 @@ public:
                                    callback_t cbf = NULL,
                                    callback_t cbf = NULL,
                                    void* user = NULL,
                                    void* user = NULL,
                                    int notificationFrames = 0,
                                    int notificationFrames = 0,
                                    int sessionId = 0);
                                    int sessionId = 0,

                                    transfer_type transferType = TRANSFER_DEFAULT);


    /* Terminates the AudioRecord and unregisters it from AudioFlinger.
    /* Terminates the AudioRecord and unregisters it from AudioFlinger.
     * Also destroys all resources associated with the AudioRecord.
     * Also destroys all resources associated with the AudioRecord.
     */
     */
                        ~AudioRecord();
                        ~AudioRecord();



    /* Initialize an AudioRecord that was created using the AudioRecord() constructor.
    /* Initialize an uninitialized AudioRecord.
     * Don't call set() more than once, or after an AudioRecord() constructor that takes parameters.
     * Returned status (from utils/Errors.h) can be:
     * Returned status (from utils/Errors.h) can be:
     *  - NO_ERROR: successful intialization
     *  - NO_ERROR: successful intialization
     *  - INVALID_OPERATION: AudioRecord is already intitialized or record device is already in use
     *  - INVALID_OPERATION: AudioRecord is already initialized or record device is already in use
     *  - BAD_VALUE: invalid parameter (channels, format, sampleRate...)
     *  - BAD_VALUE: invalid parameter (channels, format, sampleRate...)
     *  - NO_INIT: audio server or audio hardware not initialized
     *  - NO_INIT: audio server or audio hardware not initialized
     *  - PERMISSION_DENIED: recording is not allowed for the requesting process
     *  - PERMISSION_DENIED: recording is not allowed for the requesting process
     *
     * Parameters not listed in the AudioRecord constructors above:
     *
     * threadCanCallJava:  Whether callbacks are made from an attached thread and thus can call JNI.
     */
     */
            status_t    set(audio_source_t inputSource = AUDIO_SOURCE_DEFAULT,
            status_t    set(audio_source_t inputSource = AUDIO_SOURCE_DEFAULT,
                            uint32_t sampleRate = 0,
                            uint32_t sampleRate = 0,
@@ -165,30 +185,29 @@ public:
                            void* user = NULL,
                            void* user = NULL,
                            int notificationFrames = 0,
                            int notificationFrames = 0,
                            bool threadCanCallJava = false,
                            bool threadCanCallJava = false,
                            int sessionId = 0);
                            int sessionId = 0,

                            transfer_type transferType = TRANSFER_DEFAULT);


    /* Result of constructing the AudioRecord. This must be checked
    /* Result of constructing the AudioRecord. This must be checked
     * before using any AudioRecord API (except for set()), because using
     * before using any AudioRecord API (except for set()), because using
     * an uninitialized AudioRecord produces undefined results.
     * an uninitialized AudioRecord produces undefined results.
     * See set() method above for possible return codes.
     * See set() method above for possible return codes.
     */
     */
            status_t    initCheck() const;
            status_t    initCheck() const   { return mStatus; }


    /* Returns this track's estimated latency in milliseconds.
    /* Returns this track's estimated latency in milliseconds.
     * This includes the latency due to AudioRecord buffer size,
     * This includes the latency due to AudioRecord buffer size,
     * and audio hardware driver.
     * and audio hardware driver.
     */
     */
            uint32_t     latency() const;
            uint32_t    latency() const     { return mLatency; }


   /* getters, see constructor and set() */
   /* getters, see constructor and set() */


            audio_format_t format() const;
            audio_format_t format() const   { return mFormat; }
            uint32_t    channelCount() const;
            uint32_t    channelCount() const    { return mChannelCount; }
            size_t      frameCount() const;
            size_t      frameCount() const  { return mFrameCount; }
            size_t      frameSize() const   { return mFrameSize; }
            size_t      frameSize() const   { return mFrameSize; }
            audio_source_t inputSource() const;
            audio_source_t inputSource() const  { return mInputSource; }



    /* After it's created the track is not active. Call start() to
    /* After it's created the track is not active. Call start() to
     * make it active. If set, the callback will start being called.
     * make it active. If set, the callback will start being called.
@@ -198,26 +217,29 @@ public:
            status_t    start(AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE,
            status_t    start(AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE,
                              int triggerSession = 0);
                              int triggerSession = 0);


    /* Stop a track. If set, the callback will cease being called and
    /* Stop a track. If set, the callback will cease being called.  Note that obtainBuffer() still
     * obtainBuffer returns STOPPED. Note that obtainBuffer() still works
     * works and will drain buffers until the pool is exhausted, and then will return WOULD_BLOCK.
     * and will drain buffers until the pool is exhausted.
     */
     */
            void        stop();
            void        stop();
            bool        stopped() const;
            bool        stopped() const;


    /* Get sample rate for this record track in Hz.
    /* Return the sink sample rate for this record track in Hz.
     * Unlike AudioTrack, the sample rate is const after initialization, so doesn't need a lock.
     */
     */
            uint32_t    getSampleRate() const;
            uint32_t    getSampleRate() const   { return mSampleRate; }


    /* Sets marker position. When record reaches the number of frames specified,
    /* Sets marker position. When record reaches the number of frames specified,
     * a callback with event type EVENT_MARKER is called. Calling setMarkerPosition
     * a callback with event type EVENT_MARKER is called. Calling setMarkerPosition
     * with marker == 0 cancels marker notification callback.
     * with marker == 0 cancels marker notification callback.
     * To set a marker at a position which would compute as 0,
     * a workaround is to the set the marker at a nearby position such as ~0 or 1.
     * If the AudioRecord has been opened with no callback function associated,
     * If the AudioRecord has been opened with no callback function associated,
     * the operation will fail.
     * the operation will fail.
     *
     *
     * Parameters:
     * Parameters:
     *
     *
     * marker:   marker position expressed in frames.
     * marker:   marker position expressed in wrapping (overflow) frame units,
     *           like the return value of getPosition().
     *
     *
     * Returned status (from utils/Errors.h) can be:
     * Returned status (from utils/Errors.h) can be:
     *  - NO_ERROR: successful operation
     *  - NO_ERROR: successful operation
@@ -226,13 +248,13 @@ public:
            status_t    setMarkerPosition(uint32_t marker);
            status_t    setMarkerPosition(uint32_t marker);
            status_t    getMarkerPosition(uint32_t *marker) const;
            status_t    getMarkerPosition(uint32_t *marker) const;



    /* Sets position update period. Every time the number of frames specified has been recorded,
    /* Sets position update period. Every time the number of frames specified has been recorded,
     * a callback with event type EVENT_NEW_POS is called.
     * a callback with event type EVENT_NEW_POS is called.
     * Calling setPositionUpdatePeriod with updatePeriod == 0 cancels new position notification
     * Calling setPositionUpdatePeriod with updatePeriod == 0 cancels new position notification
     * callback.
     * callback.
     * If the AudioRecord has been opened with no callback function associated,
     * If the AudioRecord has been opened with no callback function associated,
     * the operation will fail.
     * the operation will fail.
     * Extremely small values may be rounded up to a value the implementation can support.
     *
     *
     * Parameters:
     * Parameters:
     *
     *
@@ -245,13 +267,13 @@ public:
            status_t    setPositionUpdatePeriod(uint32_t updatePeriod);
            status_t    setPositionUpdatePeriod(uint32_t updatePeriod);
            status_t    getPositionUpdatePeriod(uint32_t *updatePeriod) const;
            status_t    getPositionUpdatePeriod(uint32_t *updatePeriod) const;



    /* Return the total number of frames recorded since recording started.
    /* Gets record head position. The position is the total number of frames
     * The counter will wrap (overflow) periodically, e.g. every ~27 hours at 44.1 kHz.
     * recorded since record start.
     * It is reset to zero by stop().
     *
     *
     * Parameters:
     * Parameters:
     *
     *
     *  position:  Address where to return record head position within AudioRecord buffer.
     *  position:  Address where to return record head position.
     *
     *
     * Returned status (from utils/Errors.h) can be:
     * Returned status (from utils/Errors.h) can be:
     *  - NO_ERROR: successful operation
     *  - NO_ERROR: successful operation
@@ -276,38 +298,70 @@ public:
     *
     *
     * Returned value:
     * Returned value:
     *  AudioRecord session ID.
     *  AudioRecord session ID.
     *
     * No lock needed because session ID doesn't change after first set().
     */
     */
            int    getSessionId() const;
            int    getSessionId() const { return mSessionId; }


    /* Obtains a buffer of "frameCount" frames. The buffer must be
    /* Obtains a buffer of up to "audioBuffer->frameCount" full frames.
     * drained entirely, and then released with releaseBuffer().
     * After draining these frames of data, the caller should release them with releaseBuffer().
     * If the track is stopped, obtainBuffer() returns
     * If the track buffer is not empty, obtainBuffer() returns as many contiguous
     * STOPPED instead of NO_ERROR as long as there are buffers available,
     * full frames as are available immediately.
     * at which point NO_MORE_BUFFERS is returned.
     * If the track buffer is empty and track is stopped, obtainBuffer() returns WOULD_BLOCK
     * regardless of the value of waitCount.
     * If the track buffer is empty and track is not stopped, obtainBuffer() blocks with a
     * maximum timeout based on waitCount; see chart below.
     * Buffers will be returned until the pool
     * Buffers will be returned until the pool
     * is exhausted, at which point obtainBuffer() will either block
     * is exhausted, at which point obtainBuffer() will either block
     * or return WOULD_BLOCK depending on the value of the "blocking"
     * or return WOULD_BLOCK depending on the value of the "waitCount"
     * parameter.
     * parameter.
     *
     *
     * obtainBuffer() and releaseBuffer() are deprecated for direct use by applications,
     * which should use read() or callback EVENT_MORE_DATA instead.
     *
     * Interpretation of waitCount:
     * Interpretation of waitCount:
     *  +n  limits wait time to n * WAIT_PERIOD_MS,
     *  +n  limits wait time to n * WAIT_PERIOD_MS,
     *  -1  causes an (almost) infinite wait time,
     *  -1  causes an (almost) infinite wait time,
     *   0  non-blocking.
     *   0  non-blocking.
     *
     * Buffer fields
     * On entry:
     *  frameCount  number of frames requested
     * After error return:
     *  frameCount  0
     *  size        0
     *  raw         undefined
     * After successful return:
     *  frameCount  actual number of frames available, <= number requested
     *  size        actual number of bytes available
     *  raw         pointer to the buffer
     */
     */


        enum {
    /* FIXME Deprecated public API for TRANSFER_OBTAIN mode */
            NO_MORE_BUFFERS = 0x80000001,   // same name in AudioFlinger.h, ok to be different value
            status_t    obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
            STOPPED = 1
                                __attribute__((__deprecated__));
        };


            status_t    obtainBuffer(Buffer* audioBuffer, int32_t waitCount);
private:
    /* New internal API.
     * If nonContig is non-NULL, it is an output parameter that will be set to the number of
     * additional non-contiguous frames that are available immediately.
     * FIXME We could pass an array of Buffers instead of only one Buffer to obtainBuffer(),
     * in case the requested amount of frames is in two or more non-contiguous regions.
     * FIXME requested and elapsed are both relative times.  Consider changing to absolute time.
     */
            status_t    obtainBuffer(Buffer* audioBuffer, const struct timespec *requested,
                                     struct timespec *elapsed = NULL, size_t *nonContig = NULL);
public:


    /* Release an emptied buffer of "frameCount" frames for AudioFlinger to re-fill. */
    /* Release an emptied buffer of "audioBuffer->frameCount" frames for AudioFlinger to re-fill. */
    // FIXME make private when obtainBuffer() for TRANSFER_OBTAIN is removed
            void        releaseBuffer(Buffer* audioBuffer);
            void        releaseBuffer(Buffer* audioBuffer);



    /* As a convenience we provide a read() interface to the audio buffer.
    /* As a convenience we provide a read() interface to the audio buffer.
     * This is implemented on top of obtainBuffer/releaseBuffer.
     * Input parameter 'size' is in byte units.
     * This is implemented on top of obtainBuffer/releaseBuffer. For best
     * performance use callbacks. Returns actual number of bytes read >= 0,
     * or a negative status code.
     */
     */
            ssize_t     read(void* buffer, size_t size);
            ssize_t     read(void* buffer, size_t size);


@@ -336,6 +390,8 @@ private:


                void        pause();    // suspend thread from execution at next loop boundary
                void        pause();    // suspend thread from execution at next loop boundary
                void        resume();   // allow thread to execute, if not requested to exit
                void        resume();   // allow thread to execute, if not requested to exit
                void        pauseConditional();
                                        // like pause(), but only if prior resume() wasn't latched


    private:
    private:
        friend class AudioRecord;
        friend class AudioRecord;
@@ -345,59 +401,102 @@ private:
        Mutex               mMyLock;    // Thread::mLock is private
        Mutex               mMyLock;    // Thread::mLock is private
        Condition           mMyCond;    // Thread::mThreadExitedCondition is private
        Condition           mMyCond;    // Thread::mThreadExitedCondition is private
        bool                mPaused;    // whether thread is currently paused
        bool                mPaused;    // whether thread is currently paused
        bool                mResumeLatch;   // whether next pauseConditional() will be a nop
    };
    };


            // body of AudioRecordThread::threadLoop()
            // body of AudioRecordThread::threadLoop()
            bool processAudioBuffer(const sp<AudioRecordThread>& thread);
            // returns the maximum amount of time before we would like to run again, where:

            //      0           immediately
            //      > 0         no later than this many nanoseconds from now
            //      NS_WHENEVER still active but no particular deadline
            //      NS_INACTIVE inactive so don't run again until re-started
            //      NS_NEVER    never again
            static const nsecs_t NS_WHENEVER = -1, NS_INACTIVE = -2, NS_NEVER = -3;
            nsecs_t processAudioBuffer(const sp<AudioRecordThread>& thread);

            // caller must hold lock on mLock for all _l methods
            status_t openRecord_l(uint32_t sampleRate,
            status_t openRecord_l(uint32_t sampleRate,
                                audio_format_t format,
                                audio_format_t format,
                                size_t frameCount,
                                size_t frameCount,
                                audio_io_handle_t input);
                                audio_io_handle_t input,
                                size_t epoch);

            audio_io_handle_t getInput_l();
            audio_io_handle_t getInput_l();
            status_t restoreRecord_l(audio_track_cblk_t*& cblk);

            // FIXME enum is faster than strcmp() for parameter 'from'
            status_t restoreRecord_l(const char *from);


    sp<AudioRecordThread>   mAudioRecordThread;
    sp<AudioRecordThread>   mAudioRecordThread;
    mutable Mutex           mLock;
    mutable Mutex           mLock;


    bool                    mActive;            // protected by mLock
    // Current client state:  false = stopped, true = active.  Protected by mLock.  If more states
    // are added, consider changing this to enum State { ... } mState as in AudioTrack.
    bool                    mActive;


    // for client callback handler
    // for client callback handler
    callback_t              mCbf;               // callback handler for events, or NULL
    callback_t              mCbf;               // callback handler for events, or NULL
    void*                   mUserData;
    void*                   mUserData;          // for client callback handler


    // for notification APIs
    // for notification APIs
    uint32_t                mNotificationFrames;
    uint32_t                mNotificationFrames; // frames between each notification callback
    uint32_t                mRemainingFrames;
    bool                    mRefreshRemaining;  // processAudioBuffer() should refresh next 2
    uint32_t                mMarkerPosition;    // in frames

    // These are private to processAudioBuffer(), and are not protected by a lock
    uint32_t                mRemainingFrames;       // number of frames to request in obtainBuffer()
    bool                    mRetryOnPartialBuffer;  // sleep and retry after partial obtainBuffer()
    int                     mObservedSequence;      // last observed value of mSequence

    uint32_t                mMarkerPosition;    // in wrapping (overflow) frame units
    bool                    mMarkerReached;
    bool                    mMarkerReached;
    uint32_t                mNewPosition;       // in frames
    uint32_t                mNewPosition;       // in frames
    uint32_t                mUpdatePeriod;      // in ms
    uint32_t                mUpdatePeriod;      // in frames, zero means no EVENT_NEW_POS

    status_t                mStatus;


    // constant after constructor or set()
    // constant after constructor or set()
    uint32_t                mSampleRate;
    uint32_t                mSampleRate;
    size_t                  mFrameCount;
    size_t                  mFrameCount;
    audio_format_t          mFormat;
    audio_format_t          mFormat;
    uint8_t                 mChannelCount;
    uint32_t                mChannelCount;
    size_t                  mFrameSize;         // app-level frame size == AudioFlinger frame size
    size_t                  mFrameSize;         // app-level frame size == AudioFlinger frame size
    audio_source_t          mInputSource;
    audio_source_t          mInputSource;
    status_t                mStatus;
    uint32_t                mLatency;           // in ms
    uint32_t                mLatency;
    audio_channel_mask_t    mChannelMask;
    audio_channel_mask_t    mChannelMask;
    audio_io_handle_t       mInput;                     // returned by AudioSystem::getInput()
    int                     mSessionId;
    int                     mSessionId;
    transfer_type           mTransfer;

    audio_io_handle_t       mInput;             // returned by AudioSystem::getInput()


    // may be changed if IAudioRecord object is re-created
    // may be changed if IAudioRecord object is re-created
    sp<IAudioRecord>        mAudioRecord;
    sp<IAudioRecord>        mAudioRecord;
    sp<IMemory>             mCblkMemory;
    sp<IMemory>             mCblkMemory;
    audio_track_cblk_t*     mCblk;
    audio_track_cblk_t*     mCblk;              // re-load after mLock.unlock()
    void*                   mBuffers;           // starting address of buffers in shared memory


    int                     mPreviousPriority;  // before start()
    int                     mPreviousPriority;  // before start()
    SchedPolicy             mPreviousSchedulingGroup;
    SchedPolicy             mPreviousSchedulingGroup;
    AudioRecordClientProxy* mProxy;

    // The proxy should only be referenced while a lock is held because the proxy isn't
    // multi-thread safe.
    // An exception is that a blocking ClientProxy::obtainBuffer() may be called without a lock,
    // provided that the caller also holds an extra reference to the proxy and shared memory to keep
    sp<AudioRecordClientProxy> mProxy;

    bool                    mInOverrun;         // whether recorder is currently in overrun state

private:
    class DeathNotifier : public IBinder::DeathRecipient {
    public:
        DeathNotifier(AudioRecord* audioRecord) : mAudioRecord(audioRecord) { }
    protected:
        virtual void        binderDied(const wp<IBinder>& who);
    private:
        const wp<AudioRecord> mAudioRecord;
    };

    sp<DeathNotifier>       mDeathNotifier;
    uint32_t                mSequence;              // incremented for each new IAudioRecord attempt
};
};


}; // namespace android
}; // namespace android


#endif /*AUDIORECORD_H_*/
#endif // ANDROID_AUDIORECORD_H
Loading