diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
new file mode 100644
index 0000000..e79f336
--- /dev/null
+++ b/media/libmedia/AudioTrack.cpp
@@ -0,0 +1,1021 @@
+/* //device/extlibs/pv/android/AudioTrack.cpp
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "AudioTrack"
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <limits.h>
+
+#include <sched.h>
+#include <sys/resource.h>
+
+#include <private/media/AudioTrackShared.h>
+
+#include <media/AudioSystem.h>
+#include <media/AudioTrack.h>
+
+#include <utils/Log.h>
+#include <utils/MemoryDealer.h>
+#include <utils/Parcel.h>
+#include <utils/IPCThreadState.h>
+#include <utils/Timers.h>
+#include <cutils/atomic.h>
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+AudioTrack::AudioTrack()
+    : mStatus(NO_INIT)
+{
+}
+
+AudioTrack::AudioTrack(
+        int streamType,
+        uint32_t sampleRate,
+        int format,
+        int channelCount,
+        int frameCount,
+        uint32_t flags,
+        callback_t cbf,
+        void* user,
+        int notificationFrames)
+    : mStatus(NO_INIT)
+{
+    mStatus = set(streamType, sampleRate, format, channelCount,
+            frameCount, flags, cbf, user, notificationFrames, 0);
+}
+
+AudioTrack::AudioTrack(
+        int streamType,
+        uint32_t sampleRate,
+        int format,
+        int channelCount,
+        const sp<IMemory>& sharedBuffer,
+        uint32_t flags,
+        callback_t cbf,
+        void* user,
+        int notificationFrames)
+    : mStatus(NO_INIT)
+{
+    mStatus = set(streamType, sampleRate, format, channelCount,
+            0, flags, cbf, user, notificationFrames, sharedBuffer);
+}
+
+AudioTrack::~AudioTrack()
+{
+    LOGV_IF(mSharedBuffer != 0, "Destructor sharedBuffer: %p", mSharedBuffer->pointer());
+
+    if (mStatus == NO_ERROR) {
+        // Make sure that callback function exits in the case where
+        // it is looping on buffer full condition in obtainBuffer().
+        // Otherwise the callback thread will never exit.
+        stop();
+        if (mAudioTrackThread != 0) {
+            mCblk->cv.signal();
+            mAudioTrackThread->requestExitAndWait();
+            mAudioTrackThread.clear();
+        }
+        mAudioTrack.clear();
+        IPCThreadState::self()->flushCommands();
+    }
+}
+
+status_t AudioTrack::set(
+        int streamType,
+        uint32_t sampleRate,
+        int format,
+        int channelCount,
+        int frameCount,
+        uint32_t flags,
+        callback_t cbf,
+        void* user,
+        int notificationFrames,
+        const sp<IMemory>& sharedBuffer,
+        bool threadCanCallJava)
+{
+
+    LOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());
+
+    if (mAudioFlinger != 0) {
+        LOGE("Track already in use");
+        return INVALID_OPERATION;
+    }
+
+    const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
+    if (audioFlinger == 0) {
+       LOGE("Could not get audioflinger");
+       return NO_INIT;
+    }
+    int afSampleRate;
+    if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
+        return NO_INIT;
+    }
+    int afFrameCount;
+    if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) {
+        return NO_INIT;
+    }
+    uint32_t afLatency;
+    if (AudioSystem::getOutputLatency(&afLatency, streamType) != NO_ERROR) {
+        return NO_INIT;
+    }
+
+    // handle default values first.
+    if (streamType == AudioSystem::DEFAULT) {
+        streamType = AudioSystem::MUSIC;
+    }
+    if (sampleRate == 0) {
+        sampleRate = afSampleRate;
+    }
+    // these below should probably come from the audioFlinger too...
+    if (format == 0) {
+        format = AudioSystem::PCM_16_BIT;
+    }
+    if (channelCount == 0) {
+        channelCount = 2;
+    }
+
+    // validate parameters
+    if (((format != AudioSystem::PCM_8_BIT) || sharedBuffer != 0) &&
+        (format != AudioSystem::PCM_16_BIT)) {
+        LOGE("Invalid format");
+        return BAD_VALUE;
+    }
+    if (channelCount != 1 && channelCount != 2) {
+        LOGE("Invalid channel number");
+        return BAD_VALUE;
+    }
+
+    // Ensure that buffer depth covers at least audio hardware latency
+    uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate);
+    if (minBufCount < 2) minBufCount = 2;
+
+    // When playing from shared buffer, playback will start even if last audioflinger
+    // block is partly filled.
+    if (sharedBuffer != 0 && minBufCount > 1) {
+        minBufCount--;
+    }
+
+    int minFrameCount = (afFrameCount*sampleRate*minBufCount)/afSampleRate;
+
+    if (sharedBuffer == 0) {
+        if (frameCount == 0) {
+            frameCount = minFrameCount;
+        }
+        if (notificationFrames == 0) {
+            notificationFrames = frameCount/2;
+        }
+        // Make sure that application is notified with sufficient margin
+        // before underrun
+        if (notificationFrames > frameCount/2) {
+            notificationFrames = frameCount/2;
+        }
+    } else {
+        // Ensure that buffer alignment matches channelcount
+        if (((uint32_t)sharedBuffer->pointer() & (channelCount | 1)) != 0) {
+            LOGE("Invalid buffer alignement: address %p, channelCount %d", sharedBuffer->pointer(), channelCount);
+            return BAD_VALUE;
+        }
+        frameCount = sharedBuffer->size()/channelCount/sizeof(int16_t);
+    }
+
+    if (frameCount < minFrameCount) {
+      LOGE("Invalid buffer size: minFrameCount %d, frameCount %d", minFrameCount, frameCount);
+      return BAD_VALUE;
+    }
+
+    // create the track
+    status_t status;
+    sp<IAudioTrack> track = audioFlinger->createTrack(getpid(),
+                streamType, sampleRate, format, channelCount, frameCount, flags, sharedBuffer, &status);
+
+    if (track == 0) {
+        LOGE("AudioFlinger could not create track, status: %d", status);
+        return status;
+    }
+    sp<IMemory> cblk = track->getCblk();
+    if (cblk == 0) {
+        LOGE("Could not get control block");
+        return NO_INIT;
+    }
+    if (cbf != 0) {
+        mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava);
+        if (mAudioTrackThread == 0) {
+          LOGE("Could not create callback thread");
+          return NO_INIT;
+        }
+    }
+
+    mStatus = NO_ERROR;
+
+    mAudioFlinger = audioFlinger;
+    mAudioTrack = track;
+    mCblkMemory = cblk;
+    mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
+    mCblk->out = 1;
+    // Update buffer size in case it has been limited by AudioFlinger during track creation
+    mFrameCount = mCblk->frameCount;
+    if (sharedBuffer == 0) {
+        mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
+    } else {
+        mCblk->buffers = sharedBuffer->pointer();
+         // Force buffer full condition as data is already present in shared memory
+        mCblk->stepUser(mFrameCount);
+    }
+    mCblk->volume[0] = mCblk->volume[1] = 0x1000;
+    mVolume[LEFT] = 1.0f;
+    mVolume[RIGHT] = 1.0f;
+    mSampleRate = sampleRate;
+    mStreamType = streamType;
+    mFormat = format;
+    mChannelCount = channelCount;
+    mSharedBuffer = sharedBuffer;
+    mMuted = false;
+    mActive = 0;
+    mCbf = cbf;
+    mNotificationFrames = notificationFrames;
+    mRemainingFrames = notificationFrames;
+    mUserData = user;
+    mLatency = afLatency + (1000*mFrameCount) / mSampleRate;
+    mLoopCount = 0;
+    mMarkerPosition = 0;
+    mNewPosition = 0;
+    mUpdatePeriod = 0;
+
+    return NO_ERROR;
+}
+
+status_t AudioTrack::initCheck() const
+{
+    return mStatus;
+}
+
+// -------------------------------------------------------------------------
+
+uint32_t AudioTrack::latency() const
+{
+    return mLatency;
+}
+
+int AudioTrack::streamType() const
+{
+    return mStreamType;
+}
+
+uint32_t AudioTrack::sampleRate() const
+{
+    return mSampleRate;
+}
+
+int AudioTrack::format() const
+{
+    return mFormat;
+}
+
+int AudioTrack::channelCount() const
+{
+    return mChannelCount;
+}
+
+uint32_t AudioTrack::frameCount() const
+{
+    return mFrameCount;
+}
+
+int AudioTrack::frameSize() const
+{
+    return channelCount()*((format() == AudioSystem::PCM_8_BIT) ? sizeof(uint8_t) : sizeof(int16_t));
+}
+
+sp<IMemory>& AudioTrack::sharedBuffer()
+{
+    return mSharedBuffer;
+}
+
+// -------------------------------------------------------------------------
+
+void AudioTrack::start()
+{
+    sp<AudioTrackThread> t = mAudioTrackThread;
+
+    LOGV("start %p", this);
+    if (t != 0) {
+        if (t->exitPending()) {
+            if (t->requestExitAndWait() == WOULD_BLOCK) {
+                LOGE("AudioTrack::start called from thread");
+                return;
+            }
+        }
+        t->mLock.lock();
+     }
+
+    if (android_atomic_or(1, &mActive) == 0) {
+        mNewPosition = mCblk->server + mUpdatePeriod;
+        mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
+        mCblk->waitTimeMs = 0;
+        if (t != 0) {
+           t->run("AudioTrackThread", THREAD_PRIORITY_AUDIO_CLIENT);
+        } else {
+            setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT);
+        }
+        mAudioTrack->start();
+    }
+
+    if (t != 0) {
+        t->mLock.unlock();
+    }
+}
+
+void AudioTrack::stop()
+{
+    sp<AudioTrackThread> t = mAudioTrackThread;
+
+    LOGV("stop %p", this);
+    if (t != 0) {
+        t->mLock.lock();
+    }
+
+    if (android_atomic_and(~1, &mActive) == 1) {
+        mAudioTrack->stop();
+        // Cancel loops (If we are in the middle of a loop, playback
+        // would not stop until loopCount reaches 0).
+        setLoop(0, 0, 0);
+        // Force flush if a shared buffer is used otherwise audioflinger
+        // will not stop before end of buffer is reached.
+        if (mSharedBuffer != 0) {
+            flush();
+        }
+        if (t != 0) {
+            t->requestExit();
+        } else {
+            setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL);
+        }
+    }
+
+    if (t != 0) {
+        t->mLock.unlock();
+    }
+}
+
+bool AudioTrack::stopped() const
+{
+    return !mActive;
+}
+
+void AudioTrack::flush()
+{
+    LOGV("flush");
+
+    if (!mActive) {
+        mCblk->lock.lock();
+        mAudioTrack->flush();
+        // Release AudioTrack callback thread in case it was waiting for new buffers
+        // in AudioTrack::obtainBuffer()
+        mCblk->cv.signal();
+        mCblk->lock.unlock();
+    }
+}
+
+void AudioTrack::pause()
+{
+    LOGV("pause");
+    if (android_atomic_and(~1, &mActive) == 1) {
+        mActive = 0;
+        mAudioTrack->pause();
+    }
+}
+
+void AudioTrack::mute(bool e)
+{
+    mAudioTrack->mute(e);
+    mMuted = e;
+}
+
+bool AudioTrack::muted() const
+{
+    return mMuted;
+}
+
+void AudioTrack::setVolume(float left, float right)
+{
+    mVolume[LEFT] = left;
+    mVolume[RIGHT] = right;
+
+    // write must be atomic
+    mCblk->volumeLR = (int32_t(int16_t(left * 0x1000)) << 16) | int16_t(right * 0x1000);
+}
+
+void AudioTrack::getVolume(float* left, float* right)
+{
+    *left  = mVolume[LEFT];
+    *right = mVolume[RIGHT];
+}
+
+void AudioTrack::setSampleRate(int rate)
+{
+    int afSamplingRate;
+
+    if (AudioSystem::getOutputSamplingRate(&afSamplingRate, mStreamType) != NO_ERROR) {
+        return;
+    }
+    // Resampler implementation limits input sampling rate to 2 x output sampling rate.
+    if (rate <= 0) rate = 1;
+    if (rate > afSamplingRate*2) rate = afSamplingRate*2;
+    if (rate > MAX_SAMPLE_RATE) rate = MAX_SAMPLE_RATE;
+
+    mCblk->sampleRate = rate;
+}
+
+uint32_t AudioTrack::getSampleRate()
+{
+    return uint32_t(mCblk->sampleRate);
+}
+
+status_t AudioTrack::setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount)
+{
+    audio_track_cblk_t* cblk = mCblk;
+
+
+    Mutex::Autolock _l(cblk->lock);
+
+    if (loopCount == 0) {
+        cblk->loopStart = UINT_MAX;
+        cblk->loopEnd = UINT_MAX;
+        cblk->loopCount = 0;
+        mLoopCount = 0;
+        return NO_ERROR;
+    }
+
+    if (loopStart >= loopEnd ||
+        loopEnd - loopStart > mFrameCount) {
+        LOGE("setLoop invalid value: loopStart %d, loopEnd %d, loopCount %d, framecount %d, user %d", loopStart, loopEnd, loopCount, mFrameCount, cblk->user);
+        return BAD_VALUE;
+    }
+
+    if ((mSharedBuffer != 0) && (loopEnd   > mFrameCount)) {
+        LOGE("setLoop invalid value: loop markers beyond data: loopStart %d, loopEnd %d, framecount %d",
+            loopStart, loopEnd, mFrameCount);
+        return BAD_VALUE;
+    }   
+
+    cblk->loopStart = loopStart;
+    cblk->loopEnd = loopEnd;
+    cblk->loopCount = loopCount;
+    mLoopCount = loopCount;
+
+    return NO_ERROR;
+}
+
+status_t AudioTrack::getLoop(uint32_t *loopStart, uint32_t *loopEnd, int *loopCount)
+{
+    if (loopStart != 0) {
+        *loopStart = mCblk->loopStart;
+    }
+    if (loopEnd != 0) {
+        *loopEnd = mCblk->loopEnd;
+    }
+    if (loopCount != 0) {
+        if (mCblk->loopCount < 0) {
+            *loopCount = -1;
+        } else {
+            *loopCount = mCblk->loopCount;
+        }
+    }
+
+    return NO_ERROR;
+}
+
+status_t AudioTrack::setMarkerPosition(uint32_t marker)
+{
+    if (mCbf == 0) return INVALID_OPERATION;
+
+    mMarkerPosition = marker;
+
+    return NO_ERROR;
+}
+
+status_t AudioTrack::getMarkerPosition(uint32_t *marker)
+{
+    if (marker == 0) return BAD_VALUE;
+
+    *marker = mMarkerPosition;
+
+    return NO_ERROR;
+}
+
+status_t AudioTrack::setPositionUpdatePeriod(uint32_t updatePeriod)
+{
+    if (mCbf == 0) return INVALID_OPERATION;
+
+    uint32_t curPosition;
+    getPosition(&curPosition);
+    mNewPosition = curPosition + updatePeriod;
+    mUpdatePeriod = updatePeriod;
+
+    return NO_ERROR;
+}
+
+status_t AudioTrack::getPositionUpdatePeriod(uint32_t *updatePeriod)
+{
+    if (updatePeriod == 0) return BAD_VALUE;
+
+    *updatePeriod = mUpdatePeriod;
+
+    return NO_ERROR;
+}
+
+status_t AudioTrack::setPosition(uint32_t position)
+{
+    Mutex::Autolock _l(mCblk->lock);
+
+    if (!stopped()) return INVALID_OPERATION;
+
+    if (position > mCblk->user) return BAD_VALUE;
+
+    mCblk->server = position;
+    mCblk->forceReady = 1;
+    
+    return NO_ERROR;
+}
+
+status_t AudioTrack::getPosition(uint32_t *position)
+{
+    if (position == 0) return BAD_VALUE;
+
+    *position = mCblk->server;
+
+    return NO_ERROR;
+}
+
+status_t AudioTrack::reload()
+{
+    if (!stopped()) return INVALID_OPERATION;
+    
+    flush();
+
+    mCblk->stepUser(mFrameCount);
+
+    return NO_ERROR;
+}
+
+// -------------------------------------------------------------------------
+
+status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
+{
+    int active;
+    int timeout = 0;
+    status_t result;
+    audio_track_cblk_t* cblk = mCblk;
+    uint32_t framesReq = audioBuffer->frameCount;
+
+    audioBuffer->frameCount  = 0;
+    audioBuffer->size = 0;
+
+    uint32_t framesAvail = cblk->framesAvailable();
+
+    if (framesAvail == 0) {
+        Mutex::Autolock _l(cblk->lock);
+        goto start_loop_here;
+        while (framesAvail == 0) {
+            active = mActive;
+            if (UNLIKELY(!active)) {
+                LOGV("Not active and NO_MORE_BUFFERS");
+                return NO_MORE_BUFFERS;
+            }
+            if (UNLIKELY(!waitCount))
+                return WOULD_BLOCK;
+            timeout = 0;
+            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) {
+                    // timing out when a loop has been set and we have already written upto loop end
+                    // is a normal condition: no need to wake AudioFlinger up.
+                    if (cblk->user < cblk->loopEnd) {
+                        LOGW(   "obtainBuffer timed out (is the CPU pegged?) %p "
+                                "user=%08x, server=%08x", this, cblk->user, cblk->server);
+                        //unlock cblk mutex before calling mAudioTrack->start() (see issue #1617140) 
+                        cblk->lock.unlock();
+                        mAudioTrack->start();
+                        cblk->lock.lock();
+                        timeout = 1;
+                    }
+                    cblk->waitTimeMs = 0;
+                }
+                
+                if (--waitCount == 0) {
+                    return TIMED_OUT;
+                }
+            }
+            // read the server count again
+        start_loop_here:
+            framesAvail = cblk->framesAvailable_l();
+        }
+    }
+
+    cblk->waitTimeMs = 0;
+    
+    if (framesReq > framesAvail) {
+        framesReq = framesAvail;
+    }
+
+    uint32_t u = cblk->user;
+    uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
+
+    if (u + framesReq > bufferEnd) {
+        framesReq = bufferEnd - u;
+    }
+
+    LOGW_IF(timeout,
+        "*** SERIOUS WARNING *** obtainBuffer() timed out "
+        "but didn't need to be locked. We recovered, but "
+        "this shouldn't happen (user=%08x, server=%08x)", cblk->user, cblk->server);
+
+    audioBuffer->flags       = mMuted ? Buffer::MUTE : 0;
+    audioBuffer->channelCount= mChannelCount;
+    audioBuffer->format      = AudioSystem::PCM_16_BIT;
+    audioBuffer->frameCount  = framesReq;
+    audioBuffer->size = framesReq*mChannelCount*sizeof(int16_t);
+    audioBuffer->raw         = (int8_t *)cblk->buffer(u);
+    active = mActive;
+    return active ? status_t(NO_ERROR) : status_t(STOPPED);
+}
+
+void AudioTrack::releaseBuffer(Buffer* audioBuffer)
+{
+    audio_track_cblk_t* cblk = mCblk;
+    cblk->stepUser(audioBuffer->frameCount);
+}
+
+// -------------------------------------------------------------------------
+
+ssize_t AudioTrack::write(const void* buffer, size_t userSize)
+{
+
+    if (mSharedBuffer != 0) return INVALID_OPERATION;
+
+    if (ssize_t(userSize) < 0) {
+        // sanity-check. user is most-likely passing an error code.
+        LOGE("AudioTrack::write(buffer=%p, size=%u (%d)",
+                buffer, userSize, userSize);
+        return BAD_VALUE;
+    }
+
+    LOGV("write %p: %d bytes, mActive=%d", this, userSize, mActive);
+
+    ssize_t written = 0;
+    const int8_t *src = (const int8_t *)buffer;
+    Buffer audioBuffer;
+
+    do {
+        audioBuffer.frameCount = userSize/mChannelCount;
+        if (mFormat == AudioSystem::PCM_16_BIT) {
+            audioBuffer.frameCount >>= 1;
+        }
+        // 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))
+                break;
+            return ssize_t(err);
+        }
+
+        size_t toWrite;
+        if (mFormat == AudioSystem::PCM_8_BIT) {
+            // Divide capacity by 2 to take expansion into account
+            toWrite = audioBuffer.size>>1;
+            // 8 to 16 bit conversion
+            int count = toWrite;
+            int16_t *dst = (int16_t *)(audioBuffer.i8);
+            while(count--) {
+                *dst++ = (int16_t)(*src++^0x80) << 8;
+            }
+        }else {
+            toWrite = audioBuffer.size;
+            memcpy(audioBuffer.i8, src, toWrite);
+            src += toWrite;
+        }
+        userSize -= toWrite;
+        written += toWrite;
+
+        releaseBuffer(&audioBuffer);
+    } while (userSize);
+
+    return written;
+}
+
+// -------------------------------------------------------------------------
+
+bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)
+{
+    Buffer audioBuffer;
+    uint32_t frames;
+    size_t writtenSize;
+
+    // Manage underrun callback
+    if (mActive && (mCblk->framesReady() == 0)) {
+        LOGV("Underrun user: %x, server: %x, flowControlFlag %d", mCblk->user, mCblk->server, mCblk->flowControlFlag);
+        if (mCblk->flowControlFlag == 0) {
+            mCbf(EVENT_UNDERRUN, mUserData, 0);
+            if (mCblk->server == mCblk->frameCount) {
+                mCbf(EVENT_BUFFER_END, mUserData, 0);                
+            }
+            mCblk->flowControlFlag = 1;
+            if (mSharedBuffer != 0) return false;
+        }
+    }
+    
+    // Manage loop end callback
+    while (mLoopCount > mCblk->loopCount) {
+        int loopCount = -1;
+        mLoopCount--;
+        if (mLoopCount >= 0) loopCount = mLoopCount;
+
+        mCbf(EVENT_LOOP_END, mUserData, (void *)&loopCount);
+    }
+
+    // Manage marker callback
+    if(mMarkerPosition > 0) {
+        if (mCblk->server >= mMarkerPosition) {
+            mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition);
+            mMarkerPosition = 0;
+        }
+    }
+
+    // Manage new position callback
+    if(mUpdatePeriod > 0) {
+        while (mCblk->server >= mNewPosition) {
+            mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition);
+            mNewPosition += mUpdatePeriod;
+        }
+    }
+
+    // If Shared buffer is used, no data is requested from client.
+    if (mSharedBuffer != 0) {
+        frames = 0;
+    } else {
+        frames = mRemainingFrames;
+    }
+
+    do {
+
+        audioBuffer.frameCount = frames;
+        
+        // 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, loops). 
+        status_t err = obtainBuffer(&audioBuffer, 1);
+        if (err < NO_ERROR) {
+            if (err != TIMED_OUT) {
+                LOGE("Error obtaining an audio buffer, giving up.");
+                return false;
+            }
+            break;
+        }
+        if (err == status_t(STOPPED)) return false;
+
+        // Divide buffer size by 2 to take into account the expansion
+        // due to 8 to 16 bit conversion: the callback must fill only half
+        // of the destination buffer
+        if (mFormat == AudioSystem::PCM_8_BIT) {
+            audioBuffer.size >>= 1;
+        }
+
+        size_t reqSize = audioBuffer.size;
+        mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer);
+        writtenSize = audioBuffer.size;
+
+        // Sanity check on returned size
+        if (ssize_t(writtenSize) <= 0) break;
+        if (writtenSize > reqSize) writtenSize = reqSize;
+
+        if (mFormat == AudioSystem::PCM_8_BIT) {
+            // 8 to 16 bit conversion
+            const int8_t *src = audioBuffer.i8 + writtenSize-1;
+            int count = writtenSize;
+            int16_t *dst = audioBuffer.i16 + writtenSize-1;
+            while(count--) {
+                *dst-- = (int16_t)(*src--^0x80) << 8;
+            }
+            writtenSize <<= 1;
+        }
+
+        audioBuffer.size = writtenSize;
+        audioBuffer.frameCount = writtenSize/mChannelCount/sizeof(int16_t);
+        frames -= audioBuffer.frameCount;
+
+        releaseBuffer(&audioBuffer);
+    }
+    while (frames);
+
+    if (frames == 0) {
+        mRemainingFrames = mNotificationFrames;
+    } else {
+        mRemainingFrames = frames;
+    }
+    return true;
+}
+
+status_t AudioTrack::dump(int fd, const Vector<String16>& args) const
+{
+
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    result.append(" AudioTrack::dump\n");
+    snprintf(buffer, 255, "  stream type(%d), left - right volume(%f, %f)\n", mStreamType, mVolume[0], mVolume[1]);
+    result.append(buffer);
+    snprintf(buffer, 255, "  format(%d), channel count(%d), frame count(%d)\n", mFormat, mChannelCount, mFrameCount);
+    result.append(buffer);
+    snprintf(buffer, 255, "  sample rate(%d), status(%d), muted(%d)\n", mSampleRate, mStatus, mMuted);
+    result.append(buffer);
+    snprintf(buffer, 255, "  active(%d), latency (%d)\n", mActive, mLatency);
+    result.append(buffer);
+    ::write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+// =========================================================================
+
+AudioTrack::AudioTrackThread::AudioTrackThread(AudioTrack& receiver, bool bCanCallJava)
+    : Thread(bCanCallJava), mReceiver(receiver)
+{
+}
+
+bool AudioTrack::AudioTrackThread::threadLoop()
+{
+    return mReceiver.processAudioBuffer(this);
+}
+
+status_t AudioTrack::AudioTrackThread::readyToRun()
+{
+    return NO_ERROR;
+}
+
+void AudioTrack::AudioTrackThread::onFirstRef()
+{
+}
+
+// =========================================================================
+
+audio_track_cblk_t::audio_track_cblk_t()
+    : user(0), server(0), userBase(0), serverBase(0), buffers(0), frameCount(0),
+    loopStart(UINT_MAX), loopEnd(UINT_MAX), loopCount(0), volumeLR(0), flowControlFlag(1), forceReady(0)
+{
+}
+
+uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount)
+{
+    uint32_t u = this->user;
+
+    u += frameCount;
+    // Ensure that user is never ahead of server for AudioRecord
+    if (out) {
+        // If stepServer() has been called once, switch to normal obtainBuffer() timeout period
+        if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS-1) {
+            bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
+        }
+    } else if (u > this->server) {
+        LOGW("stepServer occured after track reset");
+        u = this->server;
+    }
+
+    if (u >= userBase + this->frameCount) {
+        userBase += this->frameCount;
+    }
+
+    this->user = u;
+
+    // Clear flow control error condition as new data has been written/read to/from buffer.
+    flowControlFlag = 0;
+
+    return u;
+}
+
+bool audio_track_cblk_t::stepServer(uint32_t frameCount)
+{
+    // the code below simulates lock-with-timeout
+    // we MUST do this to protect the AudioFlinger server
+    // as this lock is shared with the client.
+    status_t err;
+
+    err = lock.tryLock();
+    if (err == -EBUSY) { // just wait a bit
+        usleep(1000);
+        err = lock.tryLock();
+    }
+    if (err != NO_ERROR) {
+        // probably, the client just died.
+        return false;
+    }
+
+    uint32_t s = this->server;
+
+    s += frameCount;
+    if (out) {
+        // Mark that we have read the first buffer so that next time stepUser() is called
+        // we switch to normal obtainBuffer() timeout period
+        if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS) {
+            bufferTimeoutMs = MAX_RUN_TIMEOUT_MS - 1;
+        }        
+        // It is possible that we receive a flush()
+        // while the mixer is processing a block: in this case,
+        // stepServer() is called After the flush() has reset u & s and
+        // we have s > u
+        if (s > this->user) {
+            LOGW("stepServer occured after track reset");
+            s = this->user;
+        }
+    }
+
+    if (s >= loopEnd) {
+        LOGW_IF(s > loopEnd, "stepServer: s %u > loopEnd %u", s, loopEnd);
+        s = loopStart;
+        if (--loopCount == 0) {
+            loopEnd = UINT_MAX;
+            loopStart = UINT_MAX;
+        }
+    }
+    if (s >= serverBase + this->frameCount) {
+        serverBase += this->frameCount;
+    }
+
+    this->server = s;
+
+    cv.signal();
+    lock.unlock();
+    return true;
+}
+
+void* audio_track_cblk_t::buffer(uint32_t offset) const
+{
+    return (int16_t *)this->buffers + (offset-userBase)*this->channels;
+}
+
+uint32_t audio_track_cblk_t::framesAvailable()
+{
+    Mutex::Autolock _l(lock);
+    return framesAvailable_l();
+}
+
+uint32_t audio_track_cblk_t::framesAvailable_l()
+{
+    uint32_t u = this->user;
+    uint32_t s = this->server;
+
+    if (out) {
+        uint32_t limit = (s < loopStart) ? s : loopStart;
+        return limit + frameCount - u;
+    } else {
+        return frameCount + u - s;
+    }
+}
+
+uint32_t audio_track_cblk_t::framesReady()
+{
+    uint32_t u = this->user;
+    uint32_t s = this->server;
+
+    if (out) {
+        if (u < loopEnd) {
+            return u - s;
+        } else {
+            Mutex::Autolock _l(lock);
+            if (loopCount >= 0) {
+                return (loopEnd - loopStart)*loopCount + u - s;
+            } else {
+                return UINT_MAX;
+            }
+        }
+    } else {
+        return s - u;
+    }
+}
+
+// -------------------------------------------------------------------------
+
+}; // namespace android
+
