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

Commit e5198b62 authored by The Android Open Source Project's avatar The Android Open Source Project
Browse files

auto import from //branches/cupcake/...@127101

parent 54ffb8ab
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -275,7 +275,7 @@ public:
            STOPPED = 1
        };

            status_t    obtainBuffer(Buffer* audioBuffer, bool blocking);
            status_t    obtainBuffer(Buffer* audioBuffer, int32_t waitCount);
            void        releaseBuffer(Buffer* audioBuffer);


+1 −1
Original line number Diff line number Diff line
@@ -358,7 +358,7 @@ public:
            STOPPED = 1
        };

            status_t    obtainBuffer(Buffer* audioBuffer, bool blocking);
            status_t    obtainBuffer(Buffer* audioBuffer, int32_t waitCount);
            void        releaseBuffer(Buffer* audioBuffer);


+1 −1
Original line number Diff line number Diff line
@@ -134,7 +134,7 @@ private:
    Condition mWaitCbkCond; // condition enabling interface to wait for audio callback completion after a change is requested
    float mVolume;  // Volume applied to audio track
    int mStreamType; // Audio stream used for output
    int mProcessSize;  // Size of audio blocks generated at a time by audioCallback() (in PCM frames).
    unsigned int mProcessSize;  // Size of audio blocks generated at a time by audioCallback() (in PCM frames).

    bool initAudioTrack();
    static void audioCallback(int event, void* user, void *info);
+8 −1
Original line number Diff line number Diff line
@@ -28,6 +28,11 @@ namespace android {

#define MAX_SAMPLE_RATE     65535
#define THREAD_PRIORITY_AUDIO_CLIENT (ANDROID_PRIORITY_AUDIO)
// Maximum cumulated timeout milliseconds before restarting audioflinger thread
#define MAX_STARTUP_TIMEOUT_MS  3000    // Longer timeout period at startup to cope with A2DP init time
#define MAX_RUN_TIMEOUT_MS      1000
#define WAIT_PERIOD_MS          10


struct audio_track_cblk_t
{
@@ -55,9 +60,11 @@ struct audio_track_cblk_t
                int16_t     flowControlFlag; // underrun (out) or overrrun (in) indication
                uint8_t     out;        // out equals 1 for AudioTrack and 0 for AudioRecord
                uint8_t     forceReady; 
                uint16_t    bufferTimeoutMs; // Maximum cumulated timeout before restarting audioflinger
                uint16_t    waitTimeMs;      // Cumulated wait time
                // Padding ensuring that data buffer starts on a cache line boundary (32 bytes). 
                // See AudioFlinger::TrackBase constructor
                int32_t     Padding[4];
                int32_t     Padding[3];
                
                            audio_track_cblk_t();
                uint32_t    stepUser(uint32_t frameCount);
+27 −19
Original line number Diff line number Diff line
@@ -245,6 +245,8 @@ status_t AudioRecord::start()

    if (android_atomic_or(1, &mActive) == 0) {
        mNewPosition = mCblk->user + mUpdatePeriod;
        mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
        mCblk->waitTimeMs = 0;
        if (t != 0) {
           t->run("ClientRecordThread", THREAD_PRIORITY_AUDIO_CLIENT);
        } else {
@@ -342,7 +344,7 @@ status_t AudioRecord::getPosition(uint32_t *position)

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

status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, bool blocking)
status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
{
    int active;
    int timeout = 0;
@@ -362,14 +364,21 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, bool blocking)
            active = mActive;
            if (UNLIKELY(!active))
                return NO_MORE_BUFFERS;
            if (UNLIKELY(!blocking))
            if (UNLIKELY(!waitCount))
                return WOULD_BLOCK;
            timeout = 0;
            result = cblk->cv.waitRelative(cblk->lock, seconds(1));
            result = cblk->cv.waitRelative(cblk->lock, milliseconds(WAIT_PERIOD_MS));
            if (__builtin_expect(result!=NO_ERROR, false)) {
                cblk->waitTimeMs += WAIT_PERIOD_MS;
                if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) {
                    LOGW(   "obtainBuffer timed out (is the CPU pegged?) "
                            "user=%08x, server=%08x", cblk->user, cblk->server);
                    timeout = 1;
                    cblk->waitTimeMs = 0;
                }
                if (--waitCount == 0) {
                    return TIMED_OUT;
                }
            }
            // read the server count again
        start_loop_here:
@@ -382,6 +391,8 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, bool blocking)
        "but didn't need to be locked. We recovered, but "
        "this shouldn't happen (user=%08x, server=%08x)", cblk->user, cblk->server);

    cblk->waitTimeMs = 0;
    
    if (framesReq > framesReady) {
        framesReq = framesReady;
    }
@@ -430,7 +441,9 @@ ssize_t AudioRecord::read(void* buffer, size_t userSize)

        audioBuffer.frameCount = userSize/mChannelCount/sizeof(int16_t);

        status_t err = obtainBuffer(&audioBuffer, true);
        // Calling obtainBuffer() with a negative wait count causes
        // an (almost) infinite wait time.
        status_t err = obtainBuffer(&audioBuffer, -1);
        if (err < 0) {
            // out of buffers, return #bytes written
            if (err == status_t(NO_MORE_BUFFERS))
@@ -457,7 +470,7 @@ bool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread)
{
    Buffer audioBuffer;
    uint32_t frames = mRemainingFrames;
    size_t readSize = 0;
    size_t readSize;

    // Manage marker callback
    if (mMarkerPosition > 0) {
@@ -477,17 +490,19 @@ bool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread)

    do {
        audioBuffer.frameCount = frames;
        status_t err = obtainBuffer(&audioBuffer, false);
        // Calling obtainBuffer() with a wait count of 1 
        // limits wait time to WAIT_PERIOD_MS. This prevents from being 
        // stuck here not being able to handle timed events (position, markers).
        status_t err = obtainBuffer(&audioBuffer, 1);
        if (err < NO_ERROR) {
            if (err != WOULD_BLOCK) {
            if (err != TIMED_OUT) {
                LOGE("Error obtaining an audio buffer, giving up.");
                return false;
            }
            break;
        }
        if (err == status_t(STOPPED)) return false;

        if (audioBuffer.size == 0) break;

        size_t reqSize = audioBuffer.size;
        mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer);
        readSize = audioBuffer.size;
@@ -514,13 +529,6 @@ bool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread)
        }
    }

    // If no data was read, it is likely that obtainBuffer() did
    // not find available data in PCM buffer: we release the processor for
    // a few millisecond before polling again for available data.
    if (readSize == 0) {
        usleep(5000);
    } 

    if (frames == 0) {
        mRemainingFrames = mNotificationFrames;
    } else {
Loading