OSDN Git Service

MediaPlayerService: fix AudioSink latency
authorEric Laurent <elaurent@google.com>
Tue, 6 Mar 2012 01:27:11 +0000 (17:27 -0800)
committerEric Laurent <elaurent@google.com>
Tue, 6 Mar 2012 01:27:11 +0000 (17:27 -0800)
The AudioSink latency is currently cached when the associated AudioTrack
is created. However, the AudioTrack latency can change if the AudioTrack is moved
from one output stream to another.
The AudioPlayer must also periodically update its view of the latency
as it is needed to compensate the real audio time used for A/V sync.

This fixes an A/V sync problem seen when switching A2DP on and off while
playing a video.

Change-Id: I28b24049ca114e1af3e24791dcc900f463536ba4

media/libmediaplayerservice/MediaPlayerService.cpp
media/libmediaplayerservice/MediaPlayerService.h
media/libstagefright/AudioPlayer.cpp

index 1e2abf0..318a6ad 100644 (file)
@@ -325,7 +325,7 @@ status_t MediaPlayerService::AudioOutput::dump(int fd, const Vector<String16>& a
             mStreamType, mLeftVolume, mRightVolume);
     result.append(buffer);
     snprintf(buffer, 255, "  msec per frame(%f), latency (%d)\n",
-            mMsecsPerFrame, mLatency);
+            mMsecsPerFrame, (mTrack != 0) ? mTrack->latency() : -1);
     result.append(buffer);
     snprintf(buffer, 255, "  aux effect id(%d), send level (%f)\n",
             mAuxEffectId, mSendLevel);
@@ -1384,7 +1384,6 @@ MediaPlayerService::AudioOutput::AudioOutput(int sessionId)
     mRightVolume = 1.0;
     mPlaybackRatePermille = 1000;
     mSampleRateHz = 0;
-    mLatency = 0;
     mMsecsPerFrame = 0;
     mAuxEffectId = 0;
     mSendLevel = 0.0;
@@ -1443,7 +1442,8 @@ ssize_t MediaPlayerService::AudioOutput::frameSize() const
 
 uint32_t MediaPlayerService::AudioOutput::latency () const
 {
-    return mLatency;
+    if (mTrack == 0) return 0;
+    return mTrack->latency();
 }
 
 float MediaPlayerService::AudioOutput::msecsPerFrame() const
@@ -1523,7 +1523,6 @@ status_t MediaPlayerService::AudioOutput::open(
 
     mSampleRateHz = sampleRate;
     mMsecsPerFrame = mPlaybackRatePermille / (float) sampleRate;
-    mLatency = t->latency();
     mTrack = t;
 
     status_t res = t->setSampleRate(mPlaybackRatePermille * mSampleRateHz / 1000);
index 53847ed..90606a3 100644 (file)
@@ -118,7 +118,6 @@ class MediaPlayerService : public BnMediaPlayerService
         int32_t                 mPlaybackRatePermille;
         uint32_t                mSampleRateHz; // sample rate of the content, as set in open()
         float                   mMsecsPerFrame;
-        uint32_t                mLatency;
         int                     mSessionId;
         float                   mSendLevel;
         int                     mAuxEffectId;
index df27566..175d6b5 100644 (file)
@@ -418,6 +418,12 @@ size_t AudioPlayer::fillBuffer(void *data, size_t size) {
                 break;
             }
 
+            if (mAudioSink != NULL) {
+                mLatencyUs = (int64_t)mAudioSink->latency() * 1000;
+            } else {
+                mLatencyUs = (int64_t)mAudioTrack->latency() * 1000;
+            }
+
             CHECK(mInputBuffer->meta_data()->findInt64(
                         kKeyTime, &mPositionTimeMediaUs));