Fix time vs. bytes units bug in getRenderPosition

Rename correctLatency since it requires thread to be locked.
Use size_t for byte and frame counts.

Change-Id: I178fdd18bdb823813b9563927bdff8c0d28ca5a5
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index 79c3361..a010bb6 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -506,7 +506,7 @@
         return reply.readInt32();
     }
 
-    virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
+    virtual status_t getRenderPosition(size_t *halFrames, size_t *dspFrames,
             audio_io_handle_t output) const
     {
         Parcel data, reply;
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 384f268..cb66d21 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1042,7 +1042,7 @@
     return ret;
 }
 
-status_t AudioFlinger::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
+status_t AudioFlinger::getRenderPosition(size_t *halFrames, size_t *dspFrames,
         audio_io_handle_t output) const
 {
     status_t status;
@@ -1889,7 +1889,7 @@
     return track;
 }
 
-uint32_t AudioFlinger::MixerThread::correctLatency(uint32_t latency) const
+uint32_t AudioFlinger::MixerThread::correctLatency_l(uint32_t latency) const
 {
     if (mFastMixer != NULL) {
         MonoPipe *pipe = (MonoPipe *)mPipeSink.get();
@@ -1898,7 +1898,7 @@
     return latency;
 }
 
-uint32_t AudioFlinger::PlaybackThread::correctLatency(uint32_t latency) const
+uint32_t AudioFlinger::PlaybackThread::correctLatency_l(uint32_t latency) const
 {
     return latency;
 }
@@ -1911,7 +1911,7 @@
 uint32_t AudioFlinger::PlaybackThread::latency_l() const
 {
     if (initCheck() == NO_ERROR) {
-        return correctLatency(mOutput->stream->get_latency(mOutput->stream));
+        return correctLatency_l(mOutput->stream->get_latency(mOutput->stream));
     } else {
         return 0;
     }
@@ -2140,7 +2140,7 @@
 }
 
 
-status_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames)
+status_t AudioFlinger::PlaybackThread::getRenderPosition(size_t *halFrames, size_t *dspFrames)
 {
     if (halFrames == NULL || dspFrames == NULL) {
         return BAD_VALUE;
@@ -2149,15 +2149,13 @@
     if (initCheck() != NO_ERROR) {
         return INVALID_OPERATION;
     }
-    *halFrames = mBytesWritten / audio_stream_frame_size(&mOutput->stream->common);
+    size_t framesWritten = mBytesWritten / mFrameSize;
+    *halFrames = framesWritten;
 
     if (isSuspended()) {
         // return an estimation of rendered frames when the output is suspended
-        int32_t frames = mBytesWritten - latency_l();
-        if (frames < 0) {
-            frames = 0;
-        }
-        *dspFrames = (uint32_t)frames;
+        size_t latencyFrames = (latency_l() * mSampleRate) / 1000;
+        *dspFrames = framesWritten >= latencyFrames ? framesWritten - latencyFrames : 0;
         return NO_ERROR;
     } else {
         return mOutput->stream->get_render_position(mOutput->stream, dspFrames);
@@ -2916,7 +2914,7 @@
     } else if (mBytesWritten != 0 || (mMixerStatus == MIXER_TRACKS_ENABLED)) {
         memset (mMixBuffer, 0, mixBufferSize);
         sleepTime = 0;
-        ALOGV_IF((mBytesWritten == 0 && (mMixerStatus == MIXER_TRACKS_ENABLED)),
+        ALOGV_IF(mBytesWritten == 0 && (mMixerStatus == MIXER_TRACKS_ENABLED),
                 "anticipated start");
     }
     // TODO add standby time extension fct of effect tail
@@ -3057,8 +3055,7 @@
                 {
                     size_t audioHALFrames =
                             (mOutput->stream->get_latency(mOutput->stream)*mSampleRate) / 1000;
-                    size_t framesWritten =
-                            mBytesWritten / audio_stream_frame_size(&mOutput->stream->common);
+                    size_t framesWritten = mBytesWritten / mFrameSize;
                     if (!(mStandby || track->presentationComplete(framesWritten, audioHALFrames))) {
                         // track stays in active list until presentation is complete
                         break;
@@ -3305,8 +3302,7 @@
                 // TODO: use actual buffer filling status instead of latency when available from
                 // audio HAL
                 size_t audioHALFrames = (latency_l() * mSampleRate) / 1000;
-                size_t framesWritten =
-                        mBytesWritten / audio_stream_frame_size(&mOutput->stream->common);
+                size_t framesWritten = mBytesWritten / mFrameSize;
                 if (mStandby || track->presentationComplete(framesWritten, audioHALFrames)) {
                     if (track->isStopped()) {
                         track->reset();
@@ -3837,8 +3833,7 @@
                 // Remove it from the list of active tracks.
                 // TODO: implement behavior for compressed audio
                 size_t audioHALFrames = (latency_l() * mSampleRate) / 1000;
-                size_t framesWritten =
-                        mBytesWritten / audio_stream_frame_size(&mOutput->stream->common);
+                size_t framesWritten = mBytesWritten / mFrameSize;
                 if (mStandby || track->presentationComplete(framesWritten, audioHALFrames)) {
                     if (track->isStopped()) {
                         track->reset();
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 830dfe9..50dbd27 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -174,7 +174,7 @@
 
     virtual status_t setVoiceVolume(float volume);
 
-    virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
+    virtual status_t getRenderPosition(size_t *halFrames, size_t *dspFrames,
                                        audio_io_handle_t output) const;
 
     virtual     unsigned int  getInputFramesLost(audio_io_handle_t ioHandle) const;
@@ -1125,7 +1125,7 @@
 
         virtual     String8     getParameters(const String8& keys);
         virtual     void        audioConfigChanged_l(int event, int param = 0);
-                    status_t    getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames);
+                    status_t    getRenderPosition(size_t *halFrames, size_t *dspFrames);
                     int16_t     *mixBuffer() const { return mMixBuffer; };
 
         virtual     void detachAuxEffect_l(int effectId);
@@ -1155,7 +1155,9 @@
         // 'volatile' means accessed via atomic operations and no lock.
         volatile int32_t                mSuspended;
 
-        int                             mBytesWritten;
+        // FIXME overflows every 6+ hours at 44.1 kHz stereo 16-bit samples
+        // mFramesWritten would be better, or 64-bit even better
+        size_t                          mBytesWritten;
     private:
         // mMasterMute is in both PlaybackThread and in AudioFlinger.  When a
         // PlaybackThread needs to find out if master-muted, it checks it's local
@@ -1187,7 +1189,7 @@
         // Cache various calculated values, at threadLoop() entry and after a parameter change
         virtual     void        cacheParameters_l();
 
-        virtual     uint32_t    correctLatency(uint32_t latency) const;
+        virtual     uint32_t    correctLatency_l(uint32_t latency) const;
 
     private:
 
@@ -1296,7 +1298,7 @@
         virtual     void        threadLoop_mix();
         virtual     void        threadLoop_sleepTime();
         virtual     void        threadLoop_removeTracks(const Vector< sp<Track> >& tracksToRemove);
-        virtual     uint32_t    correctLatency(uint32_t latency) const;
+        virtual     uint32_t    correctLatency_l(uint32_t latency) const;
 
                     AudioMixer* mAudioMixer;    // normal mixer
     private: